diff options
301 files changed, 7721 insertions, 4389 deletions
diff --git a/.gitignore b/.gitignore index 8ace3c7123..479889cb78 100644 --- a/.gitignore +++ b/.gitignore @@ -102,6 +102,7 @@ linux-coverage-build linux-build win32-build qa/pull-tester/tests_config.py +qa/pull-tester/tests_config.ini qa/cache/* !src/leveldb*/Makefile diff --git a/.travis.yml b/.travis.yml index 4087a854b4..ce6cdc2db0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -51,6 +51,9 @@ before_script: - if [ -n "$OSX_SDK" -a -f depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz ]; then tar -C depends/SDKs -xf depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz; fi - make $MAKEJOBS -C depends HOST=$HOST $DEP_OPTS script: + - if [ "$CHECK_DOC" = 1 -a "$TRAVIS_REPO_SLUG" = "bitcoin/bitcoin" -a "$TRAVIS_PULL_REQUEST" = "false" ]; then while read LINE; do travis_retry gpg --keyserver hkp://pool.sks-keyservers.net --recv-keys $LINE; done < contrib/verify-commits/trusted-keys; fi + - if [ "$CHECK_DOC" = 1 -a "$TRAVIS_REPO_SLUG" = "bitcoin/bitcoin" -a "$TRAVIS_PULL_REQUEST" = "false" ]; then git fetch --unshallow; fi + - if [ "$CHECK_DOC" = 1 -a "$TRAVIS_REPO_SLUG" = "bitcoin/bitcoin" -a "$TRAVIS_PULL_REQUEST" = "false" ]; then contrib/verify-commits/verify-commits.sh; fi - export TRAVIS_COMMIT_LOG=`git log --format=fuller -1` - if [ -n "$USE_SHELL" ]; then export CONFIG_SHELL="$USE_SHELL"; fi - OUTDIR=$BASE_OUTDIR/$TRAVIS_PULL_REQUEST/$TRAVIS_JOB_NUMBER-$HOST diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 47648cde22..fc8d58d97d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -38,7 +38,7 @@ fixes or code moves with actual code changes. Commit messages should be verbose by default consisting of a short subject line (50 chars max), a blank line and detailed explanatory text as separate paragraph(s); unless the title alone is self-explanatory (like "Corrected typo -in main.cpp") then a single title line is sufficient. Commit messages should be +in init.cpp") then a single title line is sufficient. Commit messages should be helpful to people reading your code in the future, so explain the reasoning for your decisions. Further explanation [here](http://chris.beams.io/posts/git-commit/). @@ -79,7 +79,7 @@ Examples: Consensus: Add new opcode for BIP-XXXX OP_CHECKAWESOMESIG Net: Automatically create hidden service, listen on Tor Qt: Add feed bump button - Trivial: Fix typo in main.cpp + Trivial: Fix typo in init.cpp If a pull request is specifically not to be considered for merging (yet) please prefix the title with [WIP] or use [Tasks Lists](https://help.github.com/articles/basic-writing-and-formatting-syntax/#task-lists) @@ -194,7 +194,7 @@ request. Typically reviewers will review the code for obvious errors, as well as test out the patch set and opine on the technical merits of the patch. Project maintainers take into account the peer review when determining if there is consensus to merge a pull request (remember that discussions may have been -spread out over github, mailing list and IRC discussions). The following +spread out over GitHub, mailing list and IRC discussions). The following language is used within pull-request comments: - ACK means "I have tested the code and I agree it should be merged"; @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2009-2016 The Bitcoin Core developers +Copyright (c) 2009-2017 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 6a8c1b761b..1ee2dfb734 100644 --- a/Makefile.am +++ b/Makefile.am @@ -227,9 +227,6 @@ EXTRA_DIST = $(top_srcdir)/share/genbuild.sh qa/pull-tester/rpc-tests.py qa/rpc- CLEANFILES = $(OSX_DMG) $(BITCOIN_WIN_INSTALLER) -# This file is problematic for out-of-tree builds if it exists. -DISTCLEANFILES = qa/pull-tester/tests_config.pyc - .INTERMEDIATE: $(COVERAGE_INFO) DISTCHECK_CONFIGURE_FLAGS = --enable-man diff --git a/build-aux/m4/ax_cxx_compile_stdcxx.m4 b/build-aux/m4/ax_cxx_compile_stdcxx.m4 index 2c18e49c56..f147cee3b1 100644 --- a/build-aux/m4/ax_cxx_compile_stdcxx.m4 +++ b/build-aux/m4/ax_cxx_compile_stdcxx.m4 @@ -57,8 +57,14 @@ AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl [$3], [mandatory], [ax_cxx_compile_cxx$1_required=true], [$3], [optional], [ax_cxx_compile_cxx$1_required=false], [m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])]) + m4_if([$4], [], [ax_cxx_compile_cxx$1_try_default=true], + [$4], [default], [ax_cxx_compile_cxx$1_try_default=true], + [$4], [nodefault], [ax_cxx_compile_cxx$1_try_default=false], + [m4_fatal([invalid fourth argument `$4' to AX_CXX_COMPILE_STDCXX])]) AC_LANG_PUSH([C++])dnl ac_success=no + + m4_if([$4], [nodefault], [], [dnl AC_CACHE_CHECK(whether $CXX supports C++$1 features by default, ax_cv_cxx_compile_cxx$1, [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], @@ -66,7 +72,7 @@ AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl [ax_cv_cxx_compile_cxx$1=no])]) if test x$ax_cv_cxx_compile_cxx$1 = xyes; then ac_success=yes - fi + fi]) m4_if([$2], [noext], [], [dnl if test x$ac_success = xno; then diff --git a/build-aux/m4/bitcoin_find_bdb48.m4 b/build-aux/m4/bitcoin_find_bdb48.m4 index 0c3d49c2bc..980f1e8f19 100644 --- a/build-aux/m4/bitcoin_find_bdb48.m4 +++ b/build-aux/m4/bitcoin_find_bdb48.m4 @@ -3,68 +3,76 @@ dnl Distributed under the MIT software license, see the accompanying dnl file COPYING or http://www.opensource.org/licenses/mit-license.php. AC_DEFUN([BITCOIN_FIND_BDB48],[ - AC_MSG_CHECKING([for Berkeley DB C++ headers]) - BDB_CPPFLAGS= - BDB_LIBS= - bdbpath=X - bdb48path=X - bdbdirlist= - for _vn in 4.8 48 4 5 ''; do - for _pfx in b lib ''; do - bdbdirlist="$bdbdirlist ${_pfx}db${_vn}" + AC_ARG_VAR(BDB_CFLAGS, [C compiler flags for BerkeleyDB, bypasses autodetection]) + AC_ARG_VAR(BDB_LIBS, [Linker flags for BerkeleyDB, bypasses autodetection]) + + if test "x$BDB_CFLAGS" = "x"; then + AC_MSG_CHECKING([for Berkeley DB C++ headers]) + BDB_CPPFLAGS= + bdbpath=X + bdb48path=X + bdbdirlist= + for _vn in 4.8 48 4 5 ''; do + for _pfx in b lib ''; do + bdbdirlist="$bdbdirlist ${_pfx}db${_vn}" + done + done + for searchpath in $bdbdirlist ''; do + test -n "${searchpath}" && searchpath="${searchpath}/" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + #include <${searchpath}db_cxx.h> + ]],[[ + #if !((DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 8) || DB_VERSION_MAJOR > 4) + #error "failed to find bdb 4.8+" + #endif + ]])],[ + if test "x$bdbpath" = "xX"; then + bdbpath="${searchpath}" + fi + ],[ + continue + ]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + #include <${searchpath}db_cxx.h> + ]],[[ + #if !(DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR == 8) + #error "failed to find bdb 4.8" + #endif + ]])],[ + bdb48path="${searchpath}" + break + ],[]) done - done - for searchpath in $bdbdirlist ''; do - test -n "${searchpath}" && searchpath="${searchpath}/" - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ - #include <${searchpath}db_cxx.h> - ]],[[ - #if !((DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 8) || DB_VERSION_MAJOR > 4) - #error "failed to find bdb 4.8+" - #endif - ]])],[ - if test "x$bdbpath" = "xX"; then - bdbpath="${searchpath}" - fi - ],[ - continue - ]) - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ - #include <${searchpath}db_cxx.h> - ]],[[ - #if !(DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR == 8) - #error "failed to find bdb 4.8" - #endif - ]])],[ - bdb48path="${searchpath}" - break - ],[]) - done - if test "x$bdbpath" = "xX"; then - AC_MSG_RESULT([no]) - AC_MSG_ERROR([libdb_cxx headers missing, ]AC_PACKAGE_NAME[ requires this library for wallet functionality (--disable-wallet to disable wallet functionality)]) - elif test "x$bdb48path" = "xX"; then - BITCOIN_SUBDIR_TO_INCLUDE(BDB_CPPFLAGS,[${bdbpath}],db_cxx) - AC_ARG_WITH([incompatible-bdb],[AS_HELP_STRING([--with-incompatible-bdb], [allow using a bdb version other than 4.8])],[ - AC_MSG_WARN([Found Berkeley DB other than 4.8; wallets opened by this build will not be portable!]) - ],[ - AC_MSG_ERROR([Found Berkeley DB other than 4.8, required for portable wallets (--with-incompatible-bdb to ignore or --disable-wallet to disable wallet functionality)]) - ]) + if test "x$bdbpath" = "xX"; then + AC_MSG_RESULT([no]) + AC_MSG_ERROR([libdb_cxx headers missing, ]AC_PACKAGE_NAME[ requires this library for wallet functionality (--disable-wallet to disable wallet functionality)]) + elif test "x$bdb48path" = "xX"; then + BITCOIN_SUBDIR_TO_INCLUDE(BDB_CPPFLAGS,[${bdbpath}],db_cxx) + AC_ARG_WITH([incompatible-bdb],[AS_HELP_STRING([--with-incompatible-bdb], [allow using a bdb version other than 4.8])],[ + AC_MSG_WARN([Found Berkeley DB other than 4.8; wallets opened by this build will not be portable!]) + ],[ + AC_MSG_ERROR([Found Berkeley DB other than 4.8, required for portable wallets (--with-incompatible-bdb to ignore or --disable-wallet to disable wallet functionality)]) + ]) + else + BITCOIN_SUBDIR_TO_INCLUDE(BDB_CPPFLAGS,[${bdb48path}],db_cxx) + bdbpath="${bdb48path}" + fi else - BITCOIN_SUBDIR_TO_INCLUDE(BDB_CPPFLAGS,[${bdb48path}],db_cxx) - bdbpath="${bdb48path}" + BDB_CPPFLAGS=${BDB_CFLAGS} fi AC_SUBST(BDB_CPPFLAGS) - # TODO: Ideally this could find the library version and make sure it matches the headers being used - for searchlib in db_cxx-4.8 db_cxx; do - AC_CHECK_LIB([$searchlib],[main],[ - BDB_LIBS="-l${searchlib}" - break - ]) - done if test "x$BDB_LIBS" = "x"; then - AC_MSG_ERROR([libdb_cxx missing, ]AC_PACKAGE_NAME[ requires this library for wallet functionality (--disable-wallet to disable wallet functionality)]) + # TODO: Ideally this could find the library version and make sure it matches the headers being used + for searchlib in db_cxx-4.8 db_cxx; do + AC_CHECK_LIB([$searchlib],[main],[ + BDB_LIBS="-l${searchlib}" + break + ]) + done + if test "x$BDB_LIBS" = "x"; then + AC_MSG_ERROR([libdb_cxx missing, ]AC_PACKAGE_NAME[ requires this library for wallet functionality (--disable-wallet to disable wallet functionality)]) + fi fi AC_SUBST(BDB_LIBS) ]) diff --git a/build-aux/m4/bitcoin_qt.m4 b/build-aux/m4/bitcoin_qt.m4 index 509283a0b9..f43fc3037f 100644 --- a/build-aux/m4/bitcoin_qt.m4 +++ b/build-aux/m4/bitcoin_qt.m4 @@ -473,8 +473,8 @@ AC_DEFUN([_BITCOIN_QT_FIND_LIBS_WITHOUT_PKGCONFIG],[ ]) BITCOIN_QT_CHECK(AC_CHECK_LIB([z] ,[main],,AC_MSG_WARN([zlib not found. Assuming qt has it built-in]))) - BITCOIN_QT_CHECK(AC_CHECK_LIB([png] ,[main],,AC_MSG_WARN([libpng not found. Assuming qt has it built-in]))) - BITCOIN_QT_CHECK(AC_CHECK_LIB([jpeg] ,[main],,AC_MSG_WARN([libjpeg not found. Assuming qt has it built-in]))) + BITCOIN_QT_CHECK(AC_SEARCH_LIBS([png_error] ,[qtpng png],,AC_MSG_WARN([libpng not found. Assuming qt has it built-in]))) + BITCOIN_QT_CHECK(AC_SEARCH_LIBS([jpeg_create_decompress] ,[qtjpeg jpeg],,AC_MSG_WARN([libjpeg not found. Assuming qt has it built-in]))) BITCOIN_QT_CHECK(AC_SEARCH_LIBS([pcre16_exec], [qtpcre pcre16],,AC_MSG_WARN([libpcre16 not found. Assuming qt has it built-in]))) BITCOIN_QT_CHECK(AC_SEARCH_LIBS([hb_ot_tags_from_script] ,[qtharfbuzzng harfbuzz],,AC_MSG_WARN([libharfbuzz not found. Assuming qt has it built-in or support is disabled]))) BITCOIN_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}Core] ,[main],,BITCOIN_QT_FAIL(lib$QT_LIB_PREFIXCore not found))) diff --git a/configure.ac b/configure.ac index 4723c69d5d..0de89288d0 100644 --- a/configure.ac +++ b/configure.ac @@ -1,11 +1,11 @@ dnl require autoconf 2.60 (AS_ECHO/AS_ECHO_N) AC_PREREQ([2.60]) define(_CLIENT_VERSION_MAJOR, 0) -define(_CLIENT_VERSION_MINOR, 13) +define(_CLIENT_VERSION_MINOR, 14) define(_CLIENT_VERSION_REVISION, 99) define(_CLIENT_VERSION_BUILD, 0) define(_CLIENT_VERSION_IS_RELEASE, false) -define(_COPYRIGHT_YEAR, 2016) +define(_COPYRIGHT_YEAR, 2017) 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],[https://bitcoincore.org/]) @@ -55,7 +55,7 @@ case $host in ;; esac dnl Require C++11 compiler (no GNU extensions) -AX_CXX_COMPILE_STDCXX([11], [noext], [mandatory]) +AX_CXX_COMPILE_STDCXX([11], [noext], [mandatory], [nodefault]) dnl Check if -latomic is required for <std::atomic> CHECK_ATOMIC @@ -192,6 +192,13 @@ AC_ARG_ENABLE([debug], [enable_debug=$enableval], [enable_debug=no]) +# Turn warnings into errors +AC_ARG_ENABLE([werror], + [AS_HELP_STRING([--enable-werror], + [Treat certain compiler warnings as errors (default is no)])], + [enable_werror=$enableval], + [enable_werror=no]) + AC_LANG_PUSH([C++]) AX_CHECK_COMPILE_FLAG([-Werror],[CXXFLAG_WERROR="-Werror"],[CXXFLAG_WERROR=""]) @@ -206,10 +213,19 @@ if test "x$enable_debug" = xyes; then fi fi +ERROR_CXXFLAGS= +if test "x$enable_werror" = "xyes"; then + if test "x$CXXFLAG_WERROR" = "x"; then + AC_MSG_ERROR("enable-werror set but -Werror is not usable") + fi + AX_CHECK_COMPILE_FLAG([-Werror=vla],[ERROR_CXXFLAGS="$ERROR_CXXFLAGS -Werror=vla"],,[[$CXXFLAG_WERROR]]) +fi + if test "x$CXXFLAGS_overridden" = "xno"; then AX_CHECK_COMPILE_FLAG([-Wall],[CXXFLAGS="$CXXFLAGS -Wall"],,[[$CXXFLAG_WERROR]]) AX_CHECK_COMPILE_FLAG([-Wextra],[CXXFLAGS="$CXXFLAGS -Wextra"],,[[$CXXFLAG_WERROR]]) AX_CHECK_COMPILE_FLAG([-Wformat],[CXXFLAGS="$CXXFLAGS -Wformat"],,[[$CXXFLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Wvla],[CXXFLAGS="$CXXFLAGS -Wvla"],,[[$CXXFLAG_WERROR]]) AX_CHECK_COMPILE_FLAG([-Wformat-security],[CXXFLAGS="$CXXFLAGS -Wformat-security"],,[[$CXXFLAG_WERROR]]) ## Some compilers (gcc) ignore unknown -Wno-* options, but warn about all @@ -558,6 +574,33 @@ AC_LINK_IFELSE([AC_LANG_SOURCE([ ] ) +# Check for different ways of gathering OS randomness +AC_MSG_CHECKING(for Linux getrandom syscall) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <unistd.h> + #include <sys/syscall.h> + #include <linux/random.h>]], + [[ syscall(SYS_getrandom, nullptr, 32, 0); ]])], + [ AC_MSG_RESULT(yes); AC_DEFINE(HAVE_SYS_GETRANDOM, 1,[Define this symbol if the Linux getrandom system call is available]) ], + [ AC_MSG_RESULT(no)] +) + +AC_MSG_CHECKING(for getentropy) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <unistd.h>]], + [[ getentropy(nullptr, 32) ]])], + [ AC_MSG_RESULT(yes); AC_DEFINE(HAVE_GETENTROPY, 1,[Define this symbol if the BSD getentropy system call is available]) ], + [ AC_MSG_RESULT(no)] +) + +AC_MSG_CHECKING(for sysctl KERN_ARND) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/types.h> + #include <sys/sysctl.h>]], + [[ static const int name[2] = {CTL_KERN, KERN_ARND}; + sysctl(name, 2, nullptr, nullptr, nullptr, 0); ]])], + [ AC_MSG_RESULT(yes); AC_DEFINE(HAVE_SYSCTL_ARND, 1,[Define this symbol if the BSD sysctl(KERN_ARND) is available]) ], + [ AC_MSG_RESULT(no)] +) + +# Check for reduced exports if test x$use_reduce_exports = xyes; then AX_CHECK_COMPILE_FLAG([-fvisibility=hidden],[RE_CXXFLAGS="-fvisibility=hidden"], [AC_MSG_ERROR([Cannot set default symbol visibility. Use --disable-reduce-exports.])]) @@ -1066,6 +1109,7 @@ AC_SUBST(BITCOIN_CLI_NAME) AC_SUBST(BITCOIN_TX_NAME) AC_SUBST(RELDFLAGS) +AC_SUBST(ERROR_CXXFLAGS) AC_SUBST(HARDENED_CXXFLAGS) AC_SUBST(HARDENED_CPPFLAGS) AC_SUBST(HARDENED_LDFLAGS) @@ -1087,7 +1131,7 @@ AC_SUBST(ZMQ_LIBS) AC_SUBST(PROTOBUF_LIBS) AC_SUBST(QR_LIBS) AC_CONFIG_FILES([Makefile src/Makefile doc/man/Makefile share/setup.nsi share/qt/Info.plist src/test/buildenv.py]) -AC_CONFIG_FILES([qa/pull-tester/tests_config.py],[chmod +x qa/pull-tester/tests_config.py]) +AC_CONFIG_FILES([qa/pull-tester/tests_config.ini],[chmod +x qa/pull-tester/tests_config.ini]) AC_CONFIG_FILES([contrib/devtools/split-debug.sh],[chmod +x contrib/devtools/split-debug.sh]) AC_CONFIG_LINKS([qa/pull-tester/rpc-tests.py:qa/pull-tester/rpc-tests.py]) @@ -1155,6 +1199,7 @@ echo " with test = $use_tests" echo " with bench = $use_bench" echo " with upnp = $use_upnp" echo " debug enabled = $enable_debug" +echo " werror = $enable_werror" echo echo " target os = $TARGET_OS" echo " build os = $BUILD_OS" diff --git a/contrib/README.md b/contrib/README.md index 4ea9700f59..6f750106e4 100644 --- a/contrib/README.md +++ b/contrib/README.md @@ -3,7 +3,7 @@ Repository Tools ### [Developer tools](/contrib/devtools) ### Specific tools for developers working on this repository. -Contains the script `github-merge.py` 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.py` script. diff --git a/contrib/debian/copyright b/contrib/debian/copyright index 0fa06f1aa9..72d64ce62d 100644 --- a/contrib/debian/copyright +++ b/contrib/debian/copyright @@ -5,7 +5,7 @@ Upstream-Contact: Satoshi Nakamoto <satoshin@gmx.com> Source: https://github.com/bitcoin/bitcoin Files: * -Copyright: 2009-2016, Bitcoin Core Developers +Copyright: 2009-2017, 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. diff --git a/contrib/devtools/README.md b/contrib/devtools/README.md index 6c0047833f..67c5e15a15 100644 --- a/contrib/devtools/README.md +++ b/contrib/devtools/README.md @@ -8,11 +8,6 @@ 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. - clang-format-diff.py =================== @@ -24,6 +19,7 @@ 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 ``` + copyright\_header.py ==================== @@ -129,7 +125,7 @@ check or whatever). This means that there are no potential race conditions (where a pullreq gets updated while you're reviewing it, but before you click -merge), and when using GPG signatures, that even a compromised github +merge), and when using GPG signatures, that even a compromised GitHub couldn't mess with the sources. Setup diff --git a/contrib/devtools/clang-format.py b/contrib/devtools/clang-format.py deleted file mode 100755 index cee99047ac..0000000000 --- a/contrib/devtools/clang-format.py +++ /dev/null @@ -1,62 +0,0 @@ -#!/usr/bin/env python -''' -Wrapper script for clang-format - -Copyright (c) 2015 MarcoFalke -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 os -import sys -import subprocess - -tested_versions = ['3.6.0', '3.6.1', '3.6.2'] # A set of versions known to produce the same output -accepted_file_extensions = ('.h', '.cpp') # Files to format - -def check_clang_format_version(clang_format_exe): - try: - output = subprocess.check_output([clang_format_exe, '-version']) - for ver in tested_versions: - if ver in output: - print "Detected clang-format version " + ver - return - raise RuntimeError("Untested version: " + output) - except Exception as e: - print 'Could not verify version of ' + clang_format_exe + '.' - raise e - -def check_command_line_args(argv): - required_args = ['{clang-format-exe}', '{files}'] - example_args = ['clang-format-3.x', 'src/main.cpp', 'src/wallet/*'] - - if(len(argv) < len(required_args) + 1): - for word in (['Usage:', argv[0]] + required_args): - print word, - print '' - for word in (['E.g:', argv[0]] + example_args): - print word, - print '' - sys.exit(1) - -def run_clang_format(clang_format_exe, files): - for target in files: - if os.path.isdir(target): - for path, dirs, files in os.walk(target): - run_clang_format(clang_format_exe, (os.path.join(path, f) for f in files)) - elif target.endswith(accepted_file_extensions): - print "Format " + target - subprocess.check_call([clang_format_exe, '-i', '-style=file', target], stdout=open(os.devnull, 'wb'), stderr=subprocess.STDOUT) - else: - print "Skip " + target - -def main(argv): - check_command_line_args(argv) - clang_format_exe = argv[1] - files = argv[2:] - check_clang_format_version(clang_format_exe) - run_clang_format(clang_format_exe, files) - -if __name__ == "__main__": - main(sys.argv) diff --git a/contrib/devtools/github-merge.py b/contrib/devtools/github-merge.py index 0cee0921b1..bb6ffb0253 100755 --- a/contrib/devtools/github-merge.py +++ b/contrib/devtools/github-merge.py @@ -18,6 +18,7 @@ from __future__ import division,print_function,unicode_literals import os from sys import stdin,stdout,stderr import argparse +import hashlib import subprocess import json,codecs try: @@ -69,6 +70,27 @@ def ask_prompt(text): print("",file=stderr) return reply +def tree_sha512sum(): + files = sorted(subprocess.check_output([GIT, 'ls-tree', '--full-tree', '-r', '--name-only', 'HEAD']).splitlines()) + overall = hashlib.sha512() + for f in files: + intern = hashlib.sha512() + fi = open(f, 'rb') + while True: + piece = fi.read(65536) + if piece: + intern.update(piece) + else: + break + fi.close() + dig = intern.hexdigest() + overall.update(dig.encode("utf-8")) + overall.update(" ".encode("utf-8")) + overall.update(f) + overall.update("\n".encode("utf-8")) + return overall.hexdigest() + + def parse_arguments(): epilog = ''' In addition, you can set the following git configuration variables: @@ -157,6 +179,9 @@ def main(): subprocess.check_call([GIT,'checkout','-q','-b',local_merge_branch]) try: + # Go up to the repository's root. + toplevel = subprocess.check_output([GIT,'rev-parse','--show-toplevel']).strip() + os.chdir(toplevel) # Create unsigned merge commit. if title: firstline = 'Merge #%s: %s' % (pull,title) @@ -175,14 +200,29 @@ def main(): print("ERROR: Creating merge failed (already merged?).",file=stderr) exit(4) + # Put tree SHA512 into the message + try: + first_sha512 = tree_sha512sum() + message += '\n\nTree-SHA512: ' + first_sha512 + except subprocess.CalledProcessError as e: + printf("ERROR: Unable to compute tree hash") + exit(4) + try: + subprocess.check_call([GIT,'commit','--amend','-m',message.encode('utf-8')]) + except subprocess.CalledProcessError as e: + printf("ERROR: Cannot update message.",file=stderr) + exit(4) + second_sha512 = tree_sha512sum() + if first_sha512 != second_sha512: + print("ERROR: Tree hash changed unexpectedly",file=stderr) + exit(4) + print('%s#%s%s %s %sinto %s%s' % (ATTR_RESET+ATTR_PR,pull,ATTR_RESET,title,ATTR_RESET+ATTR_PR,branch,ATTR_RESET)) 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) diff --git a/contrib/devtools/update-translations.py b/contrib/devtools/update-translations.py index 78b9f9d179..2011841005 100755 --- a/contrib/devtools/update-translations.py +++ b/contrib/devtools/update-translations.py @@ -65,6 +65,14 @@ def split_format_specifiers(specifiers): else: other.append(s) + # If both numeric format specifiers and "others" are used, assume we're dealing + # with a Qt-formatted message. In the case of Qt formatting (see https://doc.qt.io/qt-5/qstring.html#arg) + # only numeric formats are replaced at all. This means "(percentage: %1%)" is valid, without needing + # any kind of escaping that would be necessary for strprintf. Without this, this function + # would wrongly detect '%)' as a printf format specifier. + if numeric: + other = [] + # numeric (Qt) can be present in any order, others (strprintf) must be in specified order return set(numeric),other diff --git a/contrib/gitian-build.sh b/contrib/gitian-build.sh index 53c24e3a87..6ee5df4703 100755 --- a/contrib/gitian-build.sh +++ b/contrib/gitian-build.sh @@ -41,7 +41,7 @@ Options: -c|--commit Indicate that the version argument is for a commit or branch -u|--url Specify the URL of the repository. Default is https://github.com/bitcoin/bitcoin -v|--verify Verify the gitian build --b|--build Do a gitiain build +-b|--build Do a gitian build -s|--sign Make signed binaries for Windows and Mac OSX -B|--buildsign Build both signed and unsigned binaries -o|--os Specify which Operating Systems the build is for. Default is lwx. l for linux, w for windows, x for osx diff --git a/contrib/gitian-descriptors/gitian-linux.yml b/contrib/gitian-descriptors/gitian-linux.yml index 6f43119ba2..00af4bdc6f 100644 --- a/contrib/gitian-descriptors/gitian-linux.yml +++ b/contrib/gitian-descriptors/gitian-linux.yml @@ -1,5 +1,5 @@ --- -name: "bitcoin-linux-0.13" +name: "bitcoin-linux-0.15" enable_cache: true suites: - "trusty" diff --git a/contrib/gitian-descriptors/gitian-osx.yml b/contrib/gitian-descriptors/gitian-osx.yml index 991976d59e..05cc65414f 100644 --- a/contrib/gitian-descriptors/gitian-osx.yml +++ b/contrib/gitian-descriptors/gitian-osx.yml @@ -1,5 +1,5 @@ --- -name: "bitcoin-osx-0.13" +name: "bitcoin-osx-0.15" enable_cache: true suites: - "trusty" diff --git a/contrib/gitian-descriptors/gitian-win.yml b/contrib/gitian-descriptors/gitian-win.yml index fe01b5b957..6fead7c208 100644 --- a/contrib/gitian-descriptors/gitian-win.yml +++ b/contrib/gitian-descriptors/gitian-win.yml @@ -1,5 +1,5 @@ --- -name: "bitcoin-win-0.13" +name: "bitcoin-win-0.15" enable_cache: true suites: - "trusty" diff --git a/contrib/gitian-keys/jtimon-key.pgp b/contrib/gitian-keys/jtimon-key.pgp Binary files differnew file mode 100644 index 0000000000..88d0de1503 --- /dev/null +++ b/contrib/gitian-keys/jtimon-key.pgp diff --git a/contrib/linearize/README.md b/contrib/linearize/README.md index adc9a559cc..0971e7816b 100644 --- a/contrib/linearize/README.md +++ b/contrib/linearize/README.md @@ -32,8 +32,11 @@ Required configuration file settings: * `output`: Output directory for linearized `blocks/blkNNNNN.dat` output. Optional config file setting for linearize-data: -* `file_timestamp`: Set each file's last-modified time to that of the most -recent block in that file. +* `debug_output`: Some printouts may not always be desired. If true, such output +will be printed. +* `file_timestamp`: Set each file's last-accessed and last-modified times, +respectively, to the current time and to the timestamp of the most recent block +written to the script's blockchain. * `genesis`: The hash of the genesis block in the blockchain. * `input`: bitcoind blocks/ directory containing blkNNNNN.dat * `hashlist`: text file containing list of block hashes created by @@ -41,6 +44,9 @@ linearize-hashes.py. * `max_out_sz`: Maximum size for files created by the `output_file` option. (Default: `1000*1000*1000 bytes`) * `netmagic`: Network magic number. +* `out_of_order_cache_sz`: If out-of-order blocks are being read, the block can +be written to a cache so that the blockchain doesn't have to be seeked again. +This option specifies the cache size. (Default: `100*1000*1000 bytes`) * `rev_hash_bytes`: If true, the block hash list written by linearize-hashes.py will be byte-reversed when read by linearize-data.py. See the linearize-hashes entry for more information. diff --git a/contrib/linearize/example-linearize.cfg b/contrib/linearize/example-linearize.cfg index cccdd79213..2cc910edfe 100644 --- a/contrib/linearize/example-linearize.cfg +++ b/contrib/linearize/example-linearize.cfg @@ -1,4 +1,3 @@ - # bitcoind RPC settings (linearize-hashes) rpcuser=someuser rpcpassword=somepassword @@ -21,11 +20,23 @@ input=/home/example/.bitcoin/blocks #genesis=000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943 #input=/home/example/.bitcoin/testnet3/blocks +# "output" option causes blockchain files to be written to the given location, +# with "output_file" ignored. If not used, "output_file" is used instead. +# output=/home/example/blockchain_directory output_file=/home/example/Downloads/bootstrap.dat hashlist=hashlist.txt -# Maxmimum size in bytes of out-of-order blocks cache in memory +# Maximum size in bytes of out-of-order blocks cache in memory out_of_order_cache_sz = 100000000 # Do we want the reverse the hash bytes coming from getblockhash? rev_hash_bytes = False + +# On a new month, do we want to set the access and modify times of the new +# blockchain file? +file_timestamp = 0 +# Do we want to split the blockchain files given a new month or specific height? +split_timestamp = 0 + +# Do we want debug printouts? +debug_output = False diff --git a/contrib/linearize/linearize-data.py b/contrib/linearize/linearize-data.py index 3fdec134b8..afcec2b60a 100755 --- a/contrib/linearize/linearize-data.py +++ b/contrib/linearize/linearize-data.py @@ -134,7 +134,7 @@ class BlockDataCopier: if not self.fileOutput and ((self.outsz + blockSizeOnDisk) > self.maxOutSz): self.outF.close() if self.setFileTime: - os.utime(outFname, (int(time.time()), highTS)) + os.utime(self.outFname, (int(time.time()), self.highTS)) self.outF = None self.outFname = None self.outFn = self.outFn + 1 @@ -142,12 +142,12 @@ class BlockDataCopier: (blkDate, blkTS) = get_blk_dt(blk_hdr) if self.timestampSplit and (blkDate > self.lastDate): - print("New month " + blkDate.strftime("%Y-%m") + " @ " + hash_str) - lastDate = blkDate - if outF: - outF.close() - if setFileTime: - os.utime(outFname, (int(time.time()), highTS)) + print("New month " + blkDate.strftime("%Y-%m") + " @ " + self.hash_str) + self.lastDate = blkDate + if self.outF: + self.outF.close() + if self.setFileTime: + os.utime(self.outFname, (int(time.time()), self.highTS)) self.outF = None self.outFname = None self.outFn = self.outFn + 1 @@ -155,11 +155,11 @@ class BlockDataCopier: if not self.outF: if self.fileOutput: - outFname = self.settings['output_file'] + self.outFname = self.settings['output_file'] else: - outFname = os.path.join(self.settings['output'], "blk%05d.dat" % self.outFn) - print("Output file " + outFname) - self.outF = open(outFname, "wb") + self.outFname = os.path.join(self.settings['output'], "blk%05d.dat" % self.outFn) + print("Output file " + self.outFname) + self.outF = open(self.outFname, "wb") self.outF.write(inhdr) self.outF.write(blk_hdr) @@ -223,13 +223,16 @@ class BlockDataCopier: blk_hdr = self.inF.read(80) inExtent = BlockExtent(self.inFn, self.inF.tell(), inhdr, blk_hdr, inLen) - hash_str = calc_hash_str(blk_hdr) - if not hash_str in blkmap: - print("Skipping unknown block " + hash_str) + self.hash_str = calc_hash_str(blk_hdr) + if not self.hash_str in blkmap: + # Because blocks can be written to files out-of-order as of 0.10, the script + # may encounter blocks it doesn't know about. Treat as debug output. + if settings['debug_output'] == 'true': + print("Skipping unknown block " + self.hash_str) self.inF.seek(inLen, os.SEEK_CUR) continue - blkHeight = self.blkmap[hash_str] + blkHeight = self.blkmap[self.hash_str] self.blkCountIn += 1 if self.blkCountOut == blkHeight: @@ -295,12 +298,15 @@ if __name__ == '__main__': settings['max_out_sz'] = 1000 * 1000 * 1000 if 'out_of_order_cache_sz' not in settings: settings['out_of_order_cache_sz'] = 100 * 1000 * 1000 + if 'debug_output' not in settings: + settings['debug_output'] = 'false' settings['max_out_sz'] = int(settings['max_out_sz']) settings['split_timestamp'] = int(settings['split_timestamp']) settings['file_timestamp'] = int(settings['file_timestamp']) settings['netmagic'] = unhexlify(settings['netmagic'].encode('utf-8')) settings['out_of_order_cache_sz'] = int(settings['out_of_order_cache_sz']) + settings['debug_output'] = settings['debug_output'].lower() if 'output_file' not in settings and 'output' not in settings: print("Missing output file / directory") diff --git a/contrib/macdeploy/macdeployqtplus b/contrib/macdeploy/macdeployqtplus index 73d4f159d8..5995f9f438 100755 --- a/contrib/macdeploy/macdeployqtplus +++ b/contrib/macdeploy/macdeployqtplus @@ -340,7 +340,7 @@ def deployFrameworks(frameworks, bundlePath, binaryPath, strip, verbose, deploym # install_name_tool the new id into the binary changeInstallName(framework.installName, framework.deployedInstallName, binaryPath, verbose) - # Copy farmework to app bundle. + # Copy framework to app bundle. deployedBinaryPath = copyFramework(framework, bundlePath, verbose) # Skip the rest if already was deployed. if deployedBinaryPath is None: @@ -492,7 +492,7 @@ ap.add_argument("-no-strip", dest="strip", action="store_false", default=True, h ap.add_argument("-sign", dest="sign", action="store_true", default=False, help="sign .app bundle with codesign tool") ap.add_argument("-dmg", nargs="?", const="", metavar="basename", help="create a .dmg disk image; if basename is not specified, a camel-cased version of the app name is used") ap.add_argument("-fancy", nargs=1, metavar="plist", default=[], help="make a fancy looking disk image using the given plist file with instructions; requires -dmg to work") -ap.add_argument("-add-qt-tr", nargs=1, metavar="languages", default=[], help="add Qt translation files to the bundle's ressources; the language list must be separated with commas, not with whitespace") +ap.add_argument("-add-qt-tr", nargs=1, metavar="languages", default=[], help="add Qt translation files to the bundle's resources; the language list must be separated with commas, not with whitespace") ap.add_argument("-translations-dir", nargs=1, metavar="path", default=None, help="Path to Qt's translation files") ap.add_argument("-add-resources", nargs="+", metavar="path", default=[], help="list of additional files or folders to be copied into the bundle's resources; must be the last argument") ap.add_argument("-volname", nargs=1, metavar="volname", default=[], help="custom volume name for dmg") diff --git a/contrib/rpm/README.md b/contrib/rpm/README.md index aecb3ba84f..e1fd0b317b 100644 --- a/contrib/rpm/README.md +++ b/contrib/rpm/README.md @@ -31,7 +31,7 @@ through `Source23` are used. Sources 30-39 should be reserved for SELinux related files. Currently only `Source30` through `Source32` are used. Until those files are in a tagged release, the full URL specified in the RPM spec file will not work. You can get -them from the git ropository where you retrieved this file. +them from the git repository where you retrieved this file. Sources 100+ are for files that are not source tarballs and are not maintained in the bitcoin git repository. At present only an SVG version of the Bitcoin diff --git a/contrib/seeds/README.md b/contrib/seeds/README.md index c595f83eb9..afe902fd7f 100644 --- a/contrib/seeds/README.md +++ b/contrib/seeds/README.md @@ -1,11 +1,19 @@ -### Seeds ### +# Seeds 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)). +Be sure to update `PATTERN_AGENT` in `makeseeds.py` to include the current version, +and remove old versions as necessary. + 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 + python3 makeseeds.py < seeds_main.txt > nodes_main.txt + python3 generate-seeds.py . > ../../src/chainparamsseeds.h + +## Dependencies + +Ubuntu: + sudo apt-get install python3-dnspython diff --git a/contrib/seeds/generate-seeds.py b/contrib/seeds/generate-seeds.py index f43dc0b218..b0ac92ae03 100755 --- a/contrib/seeds/generate-seeds.py +++ b/contrib/seeds/generate-seeds.py @@ -1,5 +1,5 @@ -#!/usr/bin/env python -# Copyright (c) 2014 Wladimir J. van der Laan +#!/usr/bin/env python3 +# Copyright (c) 2014-2017 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. ''' @@ -31,7 +31,7 @@ The output will be two data structures with the peers in binary format: These should be pasted into `src/chainparamsseeds.h`. ''' -from __future__ import print_function, division + from base64 import b32decode from binascii import a2b_hex import sys, os diff --git a/contrib/seeds/makeseeds.py b/contrib/seeds/makeseeds.py index 95498d20e2..34f0f57671 100755 --- a/contrib/seeds/makeseeds.py +++ b/contrib/seeds/makeseeds.py @@ -1,5 +1,5 @@ -#!/usr/bin/env python -# Copyright (c) 2013-2016 The Bitcoin Core developers +#!/usr/bin/env python3 +# Copyright (c) 2013-2017 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,13 +14,13 @@ MIN_BLOCKS = 337600 # These are hosts that have been observed to be behaving strangely (e.g. # aggressively connecting to every node). -SUSPICIOUS_HOSTS = set([ +SUSPICIOUS_HOSTS = { "130.211.129.106", "178.63.107.226", "83.81.130.26", "88.198.17.7", "148.251.238.178", "176.9.46.6", "54.173.72.127", "54.174.10.182", "54.183.64.54", "54.194.231.211", "54.66.214.167", "54.66.220.137", "54.67.33.14", "54.77.251.214", "54.94.195.96", "54.94.200.247" -]) +} import re import sys @@ -30,7 +30,7 @@ import collections PATTERN_IPV4 = re.compile(r"^((\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})):(\d+)$") PATTERN_IPV6 = re.compile(r"^\[([0-9a-z:]+)\]:(\d+)$") PATTERN_ONION = re.compile(r"^([abcdefghijklmnopqrstuvwxyz234567]{16}\.onion):(\d+)$") -PATTERN_AGENT = re.compile(r"^(\/Satoshi:0\.8\.6\/|\/Satoshi:0\.9\.(2|3|4|5)\/|\/Satoshi:0\.10\.\d{1,2}\/|\/Satoshi:0\.11\.\d{1,2}\/)$") +PATTERN_AGENT = re.compile(r"^(/Satoshi:0.12.(0|1|99)/|/Satoshi:0.13.(0|1|2|99)/)$") def parseline(line): sline = line.split() @@ -104,7 +104,7 @@ def filtermultiport(ips): hist = collections.defaultdict(list) for ip in ips: hist[ip['sortkey']].append(ip) - return [value[0] for (key,value) in hist.items() if len(value)==1] + return [value[0] for (key,value) in list(hist.items()) if len(value)==1] # Based on Greg Maxwell's seed_filter.py def filterbyasn(ips, max_per_asn, max_total): @@ -164,9 +164,9 @@ def main(): for ip in ips: if ip['net'] == 'ipv6': - print '[%s]:%i' % (ip['ip'], ip['port']) + print('[%s]:%i' % (ip['ip'], ip['port'])) else: - print '%s:%i' % (ip['ip'], ip['port']) + print('%s:%i' % (ip['ip'], ip['port'])) if __name__ == '__main__': main() diff --git a/contrib/seeds/nodes_main.txt b/contrib/seeds/nodes_main.txt index f1854b27f9..0451771dae 100644 --- a/contrib/seeds/nodes_main.txt +++ b/contrib/seeds/nodes_main.txt @@ -1,937 +1,1168 @@ -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 +2.7.8.12:8333 +2.228.70.198:8333 +5.39.64.7:8333 +5.45.80.34:38333 +5.51.160.38:8333 +5.61.33.33:8333 +5.61.37.12:8333 +5.95.80.47:8333 +5.102.164.173:8333 +5.175.71.130:8333 +5.189.165.22:8333 +5.199.130.228:8333 +5.228.100.222:8333 +5.255.64.231:8333 +13.93.6.133:8333 +18.85.34.10:8333 +18.241.0.63:8333 +23.28.128.65:8333 +23.248.113.52:8333 +23.253.151.73:8333 +24.4.96.121:8333 +24.69.65.191:8333 +24.87.8.43:8333 +24.150.224.110:8333 +24.227.69.146:8333 +27.0.235.33: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 +31.184.197.96:8333 +31.214.240.56:8333 +37.1.202.134:8333 +37.18.74.232:8333 +37.34.48.17:8333 +37.48.64.140:8333 +37.97.141.116:8333 +37.120.164.16: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.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 +37.143.9.128:8333 +37.153.172.227:8333 +37.193.227.16:8333 +37.205.8.78:8333 +37.220.0.114:8333 +37.232.218.199:8333 +38.140.161.53:8333 +40.87.70.120:8333 +41.162.163.93:8333 +42.2.198.48:8333 +45.20.67.1:8333 +45.55.197.77:8333 +45.56.97.63:8333 +45.58.38.162:8333 +45.63.1.33:8333 +45.79.2.70:8333 +46.16.240.98:8333 +46.19.137.74:8333 +46.28.206.146:8333 +46.32.252.197:8333 +46.59.13.59:8333 +46.59.39.195:8333 +46.148.16.210:8333 +46.160.195.121:8333 +46.166.142.21:8333 +46.166.160.29:8330 +46.188.44.20:8333 46.229.238.187:8333 -46.234.104.48:8333 -46.239.107.74:8333 -46.244.0.138:8333 -46.254.72.195:8333 -50.5.13.44:8333 -50.7.37.114: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 +46.231.16.149:8333 +47.88.100.130:8333 +47.89.192.134:8333 +47.185.194.160:8333 +47.189.129.218:8333 +49.65.2.140:8333 +50.3.72.129:8333 +50.31.99.225:8333 +51.175.33.95:8333 +52.1.165.219:8333 +52.10.170.186:8333 +52.51.128.216:8333 +54.197.130.244:8333 +58.59.2.22:8333 +58.84.6.81:8333 +59.125.8.143:8333 +59.167.130.139:8333 +61.47.2.20:8333 62.43.130.178:8333 -62.65.39.12:8333 +62.76.96.6:8333 62.107.200.30:8333 +62.133.15.58: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.133.194.156:8333 +62.138.1.95:8333 +62.216.238.3: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 +63.137.40.207:8333 +63.231.96.109:8333 +64.78.240.150:8333 64.83.225.146:8333 -64.121.3.163:8333 -64.203.102.86: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.150.105.77:8333 +64.137.236.68:8833 +64.156.193.120:8333 +66.79.160.82:8333 +66.91.230.231:8333 +66.135.128.121:8333 66.172.10.4:8333 66.194.38.250:8333 66.194.38.253:8333 -66.194.38.254:8333 -66.231.97.172:8333 +66.215.34.26:8333 66.240.237.155:8333 -67.159.13.34:8333 -67.205.74.206:8333 +67.205.96.108:8333 +67.205.128.5:8333 +67.219.233.140:8333 67.221.193.55:8333 -67.227.72.17:8333 -68.65.120.53:8333 -68.65.205.226:9000 -68.144.4.34:8333 -69.39.49.199:8333 +68.100.196.118:8333 +68.132.193.222:8333 +68.168.118.234:8333 +69.11.97.43:8333 +69.30.229.10: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.83.194.122:8333 -72.128.32.167:8333 -72.179.136.80:8333 -72.235.38.70:8333 -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 +69.125.193.145:8333 +69.162.139.125:8333 +70.35.98.39:8333 +70.112.32.29:8333 +71.126.181.146:8333 +72.180.32.105:8333 +73.226.64.145:8333 +74.83.140.242:8333 +74.84.128.158:9333 +74.122.237.124:8333 +74.215.133.145:8333 +75.76.101.169:8333 +75.85.13.8:8333 +75.86.168.13:8333 +75.170.97.25:8333 +75.177.137.134:8333 +76.76.227.136:8333 +77.53.136.6:8333 +77.110.11.52:8333 +78.25.32.206:8333 +78.34.8.120:8333 +78.46.32.99:8333 +78.56.9.214:8333 +78.56.229.177:8333 +78.129.237.245:8333 +78.196.172.45:8333 79.132.230.144:8333 -79.133.43.63:8333 -79.134.201.66:8333 79.169.35.235:8333 -80.57.227.14:8333 +79.172.194.219: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.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 +80.89.137.115:8333 +80.93.36.173:8333 +80.101.167.100:8333 +80.114.34.158:8333 +80.127.136.50:8333 +80.188.139.82:8333 +80.222.39.77:8333 +80.223.105.69:8333 +80.229.151.187:8333 +80.240.129.221:8333 +81.7.10.238:8333 +81.7.13.84:8333 +81.27.96.92:8333 +81.35.143.98:8333 +81.82.201.5:8333 +81.83.96.5:8333 +81.169.227.36:8333 +81.171.2.119:8333 +81.171.38.130:8333 +81.175.255.118:8333 +81.207.8.49:8333 +81.228.194.187:8333 +82.9.1.77:8333 82.11.33.229:8333 -82.79.128.134:8333 -82.118.233.111:8333 -82.135.139.30:8333 +82.102.13.117:8333 +82.116.203.240:8333 +82.130.103.16:8333 +82.136.65.227:8333 +82.158.227.238:8333 +82.197.212.25:8333 82.199.102.10:8333 -82.221.106.17:8333 -82.221.108.21:8333 +82.200.204.41:8333 +82.200.204.119:8333 +82.221.105.223:8333 82.221.108.27:8333 -83.137.41.3:8333 -83.142.197.168:8333 +82.221.111.136:8333 +82.221.139.97:8333 +83.137.41.10:8333 83.143.130.19:8333 83.150.9.196: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.24.69.59:8333 +83.169.2.43:8333 +83.217.203.130:8333 +83.249.88.52:8333 +84.26.162.92: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.214.66.168: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 +84.134.194.115:8333 +84.201.32.115:8333 +84.212.232.71:8333 +84.238.140.176:8333 +85.10.104.34:8333 +85.21.144.226:8333 +85.25.194.12:8333 +85.144.79.190:8333 +85.145.228.192:8333 +85.194.238.130:8333 +85.228.201.80:8333 +85.229.228.174:8333 +85.236.233.87:8333 +86.80.204.185:8333 +86.105.227.190:8333 +86.135.39.40:8333 +87.106.139.127:8333 +87.120.8.5:8333 +87.120.37.230:8333 +87.239.101.102:8333 +87.243.197.82:8333 +88.112.112.173:8333 +88.150.192.17:8333 +88.185.155.134:8333 +88.202.202.221:8333 88.202.230.87:8333 -88.214.193.154:8343 -88.214.194.226:8343 -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 +88.208.39.182:8333 +89.34.99.41:8333 +89.163.224.187:8333 +89.169.233.150:8333 +89.184.65.85:8333 +89.212.91.219:8333 +89.249.178.36: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.145.76.156:8333 -91.152.150.35:8333 -91.192.137.17:8333 -91.196.170.110:8333 +91.65.97.157:8333 +91.107.64.143:8333 +91.114.35.107:8333 +91.135.0.187:8333 +91.145.110.95:8333 +91.157.38.151:8333 91.197.44.133:8333 -91.207.68.144:8333 -91.210.105.28:8333 -91.211.102.101:8333 -91.211.106.34:8333 -91.214.200.205:8333 -91.220.43.146:8333 -91.222.71.89:8333 -91.224.140.242:8333 -91.229.76.14:8333 +91.205.176.54:8333 +91.206.203.10:8333 +91.206.203.18:8333 +91.215.35.130:8333 +91.219.239.159:8333 +91.223.133.2:8333 +91.223.133.40:8333 +91.226.10.90:8333 +91.240.141.169:8333 92.27.7.209:8333 -92.51.167.88:8333 -92.247.229.163:8333 -93.84.114.106:8333 -93.113.36.172:8333 +92.89.67.207:8333 +92.221.201.138:8333 +93.95.187.122:8333 +93.103.73.187:8333 +93.123.80.47:8333 93.188.224.253:8333 -94.75.239.69:8333 -94.190.227.112:8333 -94.214.2.74:8333 -94.224.162.65:8333 -94.236.198.253:8333 +93.190.69.242:8333 +94.19.12.244:8333 +94.156.128.116:8333 +94.177.171.73:8333 +94.181.44.104:8333 +94.237.26.173:8333 94.242.229.158:8333 -95.84.138.99:8333 -95.95.168.87:8333 +94.255.128.98:8333 +95.79.35.50:8333 +95.91.41.39: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.164.201.208:8333 -103.224.165.48:8333 -104.128.225.223:8333 +95.128.48.209:8333 +95.183.48.71:8333 +96.23.67.85:8333 +97.64.177.10:8333 +97.104.201.95:8333 +98.29.197.149:8333 +98.169.2.107:8333 +99.232.48.72:8333 +101.100.141.55:8333 +103.7.32.40:8333 +103.53.225.69:8333 +103.249.106.74:8333 +104.128.224.13:8333 104.128.228.252: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.155.1.158:8333 +104.168.128.50:8333 +104.199.160.228:8333 +104.204.109.11:8333 +104.219.251.118:8333 +104.223.3.129:8333 +104.223.3.219: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.170.13.184:8333 -107.181.250.216:8333 -107.191.101.111:8333 -107.191.106.115:8333 +104.245.99.227:8333 +106.38.234.89:8333 +106.104.134.218:8333 +107.136.6.71:8333 +107.150.45.210:8333 +107.151.144.103:8333 +107.170.44.99:8333 +107.181.137.133:8333 +107.191.102.13:8333 +108.58.252.82:8333 +108.59.9.167: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.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 +108.162.106.215:8333 +108.168.133.164:8333 +108.173.202.101:8333 +108.180.110.190:8333 +109.29.75.40:8333 +109.120.194.136:8333 +109.230.230.88:8333 +109.235.67.115:8333 +109.235.69.120:8333 +109.236.90.199:8333 +109.255.0.107:8333 +110.10.130.12:8333 +110.10.176.94:8333 +110.132.172.251:8333 +111.90.158.17:8333 +115.66.205.171:8333 +116.31.123.139:8333 +118.192.48.46:8333 +118.193.164.98:8333 +119.29.156.231:8333 +119.63.44.133:19980 +119.81.99.27:8333 +119.106.12.169:8333 +119.147.137.155:19980 +119.185.1.182: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.127.38.195:8333 +121.254.173.23:8333 +121.254.173.40:8333 +123.56.129.45:8333 +123.203.163.128:8333 +123.206.32.198:8333 +124.189.160.221:8333 +124.189.192.232:8333 128.140.224.162:8333 -128.199.101.104:8333 -128.233.224.35:8333 -128.253.3.193:20020 -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.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 -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 +128.199.68.205:8333 +130.234.207.115:8333 +131.113.41.123:8333 +131.114.72.104:8333 +132.204.108.155:8333 +134.119.13.230:8333 +134.213.133.206:8333 +134.213.133.207:8333 +135.23.5.3:8333 +137.74.0.66:8333 +138.68.1.45:8333 +138.68.2.194:8333 +138.68.64.19:8333 +138.68.64.28:8333 +139.59.42.248:8333 +139.220.240.153:8333 +140.112.107.118:8333 +140.186.224.112:8333 +141.52.64.141:8333 +142.68.237.107:8333 +142.217.12.106:8333 +146.60.204.92:8333 +146.185.161.209:8333 +148.103.7.119:8333 +149.210.133.244:8333 +150.229.0.143:8333 +151.231.238.25:8333 +151.248.160.227:8333 +153.230.228.15:8333 +155.133.43.249:8333 +158.58.238.145:8333 +158.109.79.13:34821 +159.203.70.208:8333 +160.16.206.31:8333 162.209.1.233:8333 162.209.4.125:8333 -162.209.106.123:8333 -162.210.198.184:8333 -162.248.99.164:53011 +162.216.192.231:8333 +162.243.100.111:8333 +162.246.11.194:8333 162.248.102.117:8333 -162.251.108.53:8333 -163.44.2.48:8333 -163.158.36.17:8333 -166.230.71.67: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.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 +162.252.46.83:8333 +163.172.33.78:8333 +163.172.194.30:8333 +169.229.198.106:8333 +170.75.195.168:8333 +172.103.205.197:8333 +172.245.225.126:8333 +173.179.37.8:8333 +173.208.203.74:8333 +173.252.46.16:8333 +174.117.141.124:8333 +175.126.38.158:8333 +175.126.38.177:8333 +175.139.106.119:8333 +175.140.232.66:8333 +176.9.117.100:8333 +176.36.33.121:8333 +176.36.99.222:8333 +176.56.227.36:8333 +176.100.100.206:8333 +176.106.144.183:8333 +176.123.7.148:8333 +176.126.167.10:8333 +176.223.201.198:8333 +178.62.68.62:8333 +178.62.102.56: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.124.197.101:8333 +178.170.138.202:8333 +178.175.129.18:8333 +178.188.47.62:8333 +178.199.240.22:8333 +178.218.209.162:8333 +178.237.35.34:8333 +178.238.224.242:8333 +178.254.34.144:8333 178.254.34.161: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 +179.43.183.2:8333 +180.200.128.58:8333 +182.93.34.130:8333 +185.8.238.197:8333 +185.11.139.172: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.155.136.70:8333 +185.24.233.100:8333 +185.25.48.71:8333 +185.25.48.114:8333 +185.28.76.179:8333 +185.70.105.152:8339 +185.77.128.69:8333 +185.77.128.241:8333 +185.86.79.87:8333 +185.89.102.2:3333 +185.89.102.53:3333 +185.109.144.155:8333 +185.117.75.50:8333 +185.121.173.223:8333 +185.128.41.157:8333 +185.130.226.106:8333 +185.145.130.76:8333 +188.63.192.104:8333 +188.113.164.231:8333 188.166.229.112:8333 -188.182.108.129: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 +188.214.128.77:8333 +190.10.8.211: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.203.228.71:8333 -192.206.202.20:8333 -193.0.109.3:8333 -193.41.229.130:8333 -193.41.229.156:8333 +190.111.231.19:8333 +192.131.44.93:8333 +192.206.202.6:8333 +192.227.245.133:8333 +192.241.74.123:8333 +192.241.74.126:8333 +192.254.71.222:8333 +193.10.64.85:8333 +193.46.80.101:8333 193.49.43.219:8333 -193.147.71.120:8333 -193.179.65.233:8333 +193.93.79.215: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 -195.239.1.66:8333 -198.48.196.230:8333 -198.50.192.160:8333 -198.57.210.27:8333 -198.84.195.179:8333 -198.167.140.8:8333 +193.239.80.155:8333 +194.63.140.208:8333 +194.87.1.232:8333 +194.187.227.18:8333 +194.247.12.136:8333 +195.91.176.86:8333 +196.28.98.20:8333 +198.44.249.35:8333 +198.84.172.252:8333 198.204.224.106:8333 -199.127.226.245:8333 -199.201.110.8:8333 -199.233.234.90:8333 +198.211.97.46:8333 +199.66.64.198:8333 +199.101.100.58:8333 +199.101.100.59:8333 +199.127.224.50:8333 +200.46.241.71:8333 200.116.98.185:8333 -202.60.70.18:8333 -203.151.140.14:8333 -204.112.203.52:8333 +203.9.225.13:8333 +203.177.142.37: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 -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 +205.209.131.150:13838 +206.53.64.74:8333 +206.72.192.69:8333 +206.123.112.180:8333 +208.66.208.153:8333 +208.68.174.76:8333 +208.107.97.242:8333 +208.111.48.132:8333 +208.118.235.190:8333 +209.6.205.126:8333 +209.40.96.121:8333 +209.58.130.137:8333 +209.73.142.226: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.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.136.73.125:8333 -213.155.3.216:8333 -213.155.7.24:8333 -213.167.17.6:8333 -213.223.138.13:8333 -216.15.78.182:8333 -216.38.129.164:8333 -216.48.168.8:8333 -216.169.141.169:8333 -216.245.206.181:8333 -216.249.204.161:8333 -216.250.138.230:8333 +209.126.69.243:8333 +209.126.108.91:8333 +209.195.4.18:8333 +209.250.6.190:8333 +210.54.37.225:8333 +210.223.3.44:8333 +211.149.234.109:8333 +212.51.140.183:8333 +212.90.179.206:8333 +212.93.226.90:8333 +212.110.171.118:8333 +212.202.132.17:8333 +213.91.205.134:8333 +213.165.68.218:8333 +213.196.200.213:8333 +216.59.4.212:8333 +216.74.32.109:8333 +216.158.225.70:8333 +216.164.138.13:8333 +216.167.236.247:8333 +216.197.79.74:8333 217.11.225.189:8333 -217.12.34.158:8333 -217.12.202.33:8333 -217.20.171.43:8333 -217.23.1.126:8333 -217.23.11.138:8333 +217.12.199.207:8333 +217.20.130.72:8333 +217.23.6.148:8333 +217.23.140.103:8333 +217.28.96.180:8333 +217.35.130.42:8333 217.111.66.79:8333 -217.155.202.191:8333 217.158.9.102:8333 -217.172.32.18:20993 -220.245.196.37:8333 -[2001:1291:2bf:1::100]:8333 +217.168.143.169:8333 +217.209.32.219:8333 +218.161.33.165:8333 +221.121.144.138:8333 +[2001:0:4137:9e76:2048:3a84:bb91:e846]:8333 +[2001:0:4137:9e76:2066:e9e:b489:f8b8]:8333 +[2001:0:4137:9e76:3854:1211:b5ac:a96b]:8333 +[2001:0:4137:9e76:4e3:1f66:cd4c:829f]:8333 +[2001:0:4137:9e76:ad:1f4:9ea9:fa2e]:8333 +[2001:0:4137:9e76:e5:baa:b66f:f418]:8333 +[2001:0:53aa:64c:20a2:59c4:ad22:93ea]:8333 +[2001:0:53aa:64c:59:617f:a10d:e0]:8333 +[2001:0:5ef5:79fb:200f:3ae5:3cbc:74c9]:8333 +[2001:0:5ef5:79fb:38f2:13b4:b208:5604]:8333 +[2001:0:5ef5:79fd:200b:22a7:cc50:f52d]:8333 +[2001:0:5ef5:79fd:24ef:1aef:a994:303d]:8333 +[2001:0:5ef5:79fd:24fc:b5d:ad4f:4db2]:8333 +[2001:0:5ef5:79fd:28bf:2d23:e02e:c3ef]:8333 +[2001:0:5ef5:79fd:3cd0:3c2e:da44:a759]:8333 +[2001:0:5ef5:79fd:87e:fd7:b1c2:1b4]:8333 +[2001:0:9d38:6ab8:18db:3bda:ab90:e81e]:8333 +[2001:0:9d38:6ab8:4e7:1660:862f:a6d7]:8333 +[2001:0:9d38:6ab8:6:2b:5074:9588]:8333 +[2001:0:9d38:6abd:10f8:a7d7:bb90:f524]:8333 +[2001:13d8:1c01:1000::11]:8333 +[2001:15c0:65ff:610::2]:8333 +[2001:1608:10:156:ae::4adb]:8333 +[2001:1620:b1b:8888:20d:b9ff:fe41:6710]:8333 +[2001:1620:b1b:face:20d:b9ff:fe41:6710]: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:1680:101:1ae::1]:8333 +[2001:16d8:ff00:85de:20c:29ff:fe52:9594]:8333 +[2001:19f0:4400:434d:5400:ff:fe42:2678]:8333 +[2001:19f0:5000:8c8b:5400:ff:fe1f:c023]:8333 +[2001:19f0:5000:8ce6:5400:ff:fe1b:24a9]:8333 +[2001:19f0:5:314:5400:ff:fe2c:42e8]:8333 +[2001:19f0:5:51b:5400:ff:fe49:fe5b]:8333 +[2001:19f0:5:bc:5400:ff:fe3b:9339]:8333 +[2001:1af8:4020:a020:5::]:8333 +[2001:1bc8:1a0:590e:2e0:f4ff:fe16:3a39]:8333 +[2001:1c04:1401:8f00:f4fe:4fff:fe0c:df40]:8333 +[2001:4128:6135:10:20c:29ff:fe69:9e81]:8333 [2001:4128:6135:2010:21e:bff:fee8:a3c0]:8333 -[2001:41d0:1008:761::17c]:8333 +[2001:4128:6135:e001:5054:ff:fe37:e9eb]:8333 +[2001:41d0:1000:1024::]:8333 +[2001:41d0:1000:1433::]:8333 +[2001:41d0:1004:22ae::]:8333 +[2001:41d0:1004:2996::]:8333 +[2001:41d0:1008:11e0::1a5c:6d9d]:8333 +[2001:41d0:1008:11e0::b74:baf7]:8333 +[2001:41d0:1008:237a::]:8333 +[2001:41d0:1008:2752::]:8333 +[2001:41d0:1008:494::]:8333 [2001:41d0:1:45d8::1]:8333 -[2001:41d0:1:6cd3::]:8333 +[2001:41d0:1:5630::1]:8333 +[2001:41d0:1:6f57::1]:8333 +[2001:41d0:1:801e::1]:8333 +[2001:41d0:1:8852::1]:8333 [2001:41d0:1:8b26::1]:8333 -[2001:41d0:1:afda::]:8200 +[2001:41d0:1:a5b8::1]:8333 [2001:41d0:1:b26b::1]:8333 [2001:41d0:1:c139::1]:8333 [2001:41d0:1:c8d7::1]:8333 -[2001:41d0:1:f59f::33]:8333 -[2001:41d0:1:f7cc::1]:8333 -[2001:41d0:2:1021::1]:8333 -[2001:41d0:2:37c3::]:8200 -[2001:41d0:2:4797:2323:2323:2323:2323]:8333 -[2001:41d0:2:53df::]:8333 +[2001:41d0:1:d227::]:8333 +[2001:41d0:1:dbc4::1]:8333 +[2001:41d0:1:dc5d::1]:8333 +[2001:41d0:1:e13b::1]:8333 +[2001:41d0:1:ef5b::1]:8333 +[2001:41d0:2:16be::1]:8333 +[2001:41d0:2:203c::1]:8333 +[2001:41d0:2:38c5::1]:8333 +[2001:41d0:2:519::]:8333 [2001:41d0:2:9c94::1]:8333 -[2001:41d0:2:9d3e::1]:8333 -[2001:41d0:2:a24f::]:8333 -[2001:41d0:2:a35a::]:8333 -[2001:41d0:2:b2b8::]:8333 -[2001:41d0:2:c1d9::]:8333 -[2001:41d0:2:c6e::]:8333 +[2001:41d0:2:b792::]:8333 +[2001:41d0:2:bf2a::]:8333 +[2001:41d0:2:c793::]:8333 [2001:41d0:2:c9bf::]:8333 -[2001:41d0:2:f1a5::]:8333 -[2001:41d0:52:a00::105f]:8333 -[2001:41d0:52:cff::6f5]:8333 -[2001:41d0:52:d00::6e2]:8333 -[2001:41d0:8:3e75::1]:8333 -[2001:41d0:8:62ab::1]:8333 +[2001:41d0:303:4f0::]:8333 +[2001:41d0:8:1a8a::1]:8333 +[2001:41d0:8:3fa9::1]:8333 +[2001:41d0:8:4670::1]:8333 +[2001:41d0:8:4f48::1]:8333 [2001:41d0:8:6728::]: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:13a2::1]:8333 -[2001:41d0:a:2b18::1]: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:8:72c2:d:242:ac11:2]:8333 +[2001:41d0:8:8007::]:8333 +[2001:41d0:8:a71c::]:8333 +[2001:41d0:8:bccc::1]:8333 +[2001:41d0:8:bd45::1]:8333 +[2001:41d0:8:c67c::]:8333 +[2001:41d0:8:de3d::1]:8333 +[2001:41d0:8:e257::1]:8333 +[2001:41d0:8:e3e4::1]:8333 +[2001:41d0:a:14cc::1]:8333 +[2001:41d0:a:15b2::1]:8333 +[2001:41d0:a:1ac9::1]:8333 +[2001:41d0:a:2496::1]:8333 +[2001:41d0:a:308c::]:8333 +[2001:41d0:a:5879::]:8333 +[2001:41d0:a:6810::1]:8333 +[2001:41d0:a:682d::1]:8333 [2001:41d0:a:6c29::1]:8333 -[2001:41d0:a:f9cd::1]:8333 -[2001:41d0:d:20a4::]:8333 +[2001:41d0:a:f52a::1]:8333 +[2001:41d0:d:111c::]:8333 +[2001:41d0:e:1388::1]:8333 [2001:41d0:e:26b::1]:8333 +[2001:41d0:e:f73::1]:8333 [2001:41d0:fc8c:a200:7a24:afff:fe9d:c69b]:8333 +[2001:41f0:61:0:72f3:95ff:fe09:7521]: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:4428:200:8171:db6:2ff4:9c0e:a2da]:8333 +[2001:470:1f07:151c:baac:6fff:feb7:3ba9]:8333 +[2001:470:1f0b:ad6:a60:6eff:fec6:2323]:8333 +[2001:470:1f11:617::10f]:8333 +[2001:470:1f14:73e::2]:8333 [2001:470:1f14:7d::2]:8333 -[2001:470:27:ce::2]:8333 +[2001:470:1f15:11f8::10]:8333 +[2001:470:1f15:1b95:2c3e:8a9a:24e1:7084]:8333 +[2001:470:1f15:e9b::3ef]:8333 +[2001:470:1f1d:3a9::10]:8333 +[2001:470:25:482::2]:8333 +[2001:470:27:19f::2]:8333 +[2001:470:27:665::2]:8333 +[2001:470:28:365::4]: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:6c4f::cafe]: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:d00d:0:3664:a9ff:fe9a:5150]: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:470:727b::11:14]:8333 +[2001:470:7:2f0::2]:8333 +[2001:470:7:65::2]:8333 +[2001:470:7f85::2]:8333 +[2001:470:8:2e1:5825:39df:3e4c:54a8]:8333 +[2001:470:8:2e1::43]:8333 +[2001:470:8:2e1:ae2a:e257:4470:6350]:8333 +[2001:470:a:c13::2]: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:4b98:dc2:41:216:3eff:fe56:f659]:8333 -[2001:4ba0:fffa:5d::93]:8333 -[2001:4ba0:ffff:1be:1:1005:0:1]:8333 -[2001:4dd0:ff00:867f::3]:8333 +[2001:4ba0:babe:832::]:8333 +[2001:4ba0:cafe:379::1]:8333 +[2001:4ba0:ffee:33::10]:8333 [2001:4dd0:ff00:9a67::9]:8333 -[2001:5c0:1400:b::3cc7]:8333 [2001:610:1b19::3]:8333 [2001:610:600:a41::2]:8333 -[2001:67c:26b4::]:8333 -[2001:8d8:840:500::39:1ae]:8333 -[2001:8d8:965:4a00::10:9343]:8333 -[2001:980:4650:1:2e0:53ff:fe13:2449]:8333 +[2001:678:174:4021::2:8333]:8333 +[2001:67c:16dc:1201:5054:ff:fe17:4dac]:8333 +[2001:67c:2128:ffff:6062:36ff:fe30:6532]:8333 +[2001:67c:2564:331:3547:6e28:85a4:fb27]:8333 +[2001:6a0:200:368::2]:8333 +[2001:718:801:311:5054:ff:fe19:c483]:8333 +[2001:7b8:2ff:8f::2]:8333 +[2001:8d8:8a6:4400::3f:86c]:8333 +[2001:8d8:923:8400::87:ebd]:8333 +[2001:960:66d::2]: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: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: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 +[2001:ba8:1f1:f069::2]:8333 +[2001:bc8:225f:10e:505:6573:7573:d0a]:8333 +[2001:bc8:2706::1]:8333 +[2001:bc8:323c:100::53]:8333 +[2001:bc8:323c:100::80:4]:8333 +[2001:bc8:323c:100::cafe]:8333 +[2001:bc8:3680:4242::1]:8333 +[2001:bc8:399f:f000::1]:8333 +[2001:bc8:3cbf::5]:8333 +[2001:bc8:4700:2300::19:807]:8333 +[2001:e42:102:1805:160:16:206:31]:8333 +[2002:12f1:3f::12f1:3f]:8333 +[2002:1e2:5349::1e2:5349]:8333 +[2002:1e2:5588::1e2:5588]:8333 +[2002:2501:cf62::2501:cf62]:8333 +[2002:268c:a135::268c:a135]:8333 +[2002:2a33:99db::2a33:99db]:8332 +[2002:2ebc:2c14::7]:8333 +[2002:2f59:2c9c::2f59:2c9c]:11885 +[2002:2f5a:3619::2f5a:3619]:8333 +[2002:2f5a:36a4::2f5a:36a4]:8333 +[2002:2f5a:429::2f5a:429]:8333 +[2002:2f5a:562a::2f5a:562a]:8333 +[2002:3a3b:216::3a3b:216]:8333 +[2002:3dfa:5d23::3dfa:5d23]:8333 +[2002:424f:a052::424f:a052]:8333 +[2002:451e:e922::451e:e922]:8333 +[2002:4540:4b30::4540:4b30]:8333 +[2002:51ab:7cc::51ab:7cc]:8333 +[2002:527:de11::527:de11]:8333 +[2002:5395:7d01::5395:7d01]:8333 +[2002:5395:7d2a::5395:7d2a]:8333 +[2002:5669:e3be::5669:e3be]:8333 +[2002:566a:5d6d::566a:5d6d]:8333 +[2002:59b9:f820::59b9:f820]:8333 +[2002:59f8:ac69::59f8:ac69]:8333 +[2002:5bd4:b65a::5bd4:b65a]:8333 +[2002:5c3f:39db::5c3f:39db]:8333 +[2002:5d33:8d03::5d33:8d03]:8333 +[2002:5d67:49bb::5d67:49bb]:8333 +[2002:5dae:5d5f::5dae:5d5f]:8333 +[2002:5dbe:8cc6::5dbe:8cc6]:8333 +[2002:5dbe:9503::5dbe:9503]:8333 +[2002:5fd3:8944::5fd3:8944]:8333 +[2002:5fd3:9467::5fd3:9467]:8333 +[2002:67f9:6a48::67f9:6a48]:8333 +[2002:67f9:6a4a::67f9:6a4a]:8333 +[2002:67f9:6a95::67f9:6a95]:8333 +[2002:6a0e:3ea8::6a0e:3ea8]:10011 +[2002:6b96:375a::6b96:375a]:8333 +[2002:6ca8:cffb::6ca8:cffb]:8333 +[2002:6caf:234::6caf:234]:8333 +[2002:6dec:58f5::6dec:58f5]:8333 +[2002:6dec:5ac7::6dec:5ac7]:8333 +[2002:7237:4a02::7237:4a02]:20033 +[2002:7237:94fd::7237:94fd]:10011 +[2002:7237:e428::7237:e428]:8333 +[2002:7237:fcf6::7237:fcf6]:20188 +[2002:76c0:96e6::76c0:96e6]:8333 +[2002:7819:7e80::7819:7e80]:7743 +[2002:781a:ea86::781a:ea86]:8333 +[2002:781a:f3c2::781a:f3c2]:14475 +[2002:784c:c2c0::784c:c2c0]:8333 +[2002:784c:ec97::784c:ec97]:8333 +[2002:792b:261a::792b:261a]:8333 +[2002:88f3:8cca::88f3:8cca]:8333 +[2002:88f3:a83c::88f3:a83c]:8333 +[2002:8ac9:516f::8ac9:516f]:8333 +[2002:8b81:6d78::8b81:6d78]:50344 +[2002:8b81:6e5c::8b81:6e5c]:38176 +[2002:8bc4:90a6::8bc4:90a6]:8333 +[2002:ac52:b854::ac52:b854]:8333 +[2002:add0:c14a::add0:c14a]:8333 +[2002:b07e:a70a::b07e:a70a]:8333 +[2002:b27c:c565:1::250]:8333 +[2002:b27c:c565::1]:8333 +[2002:b94d:80f1::b94d:80f1]:8333 +[2002:b982:e26a::b982:e26a]:8333 +[2002:bcd5:3145::bcd5:3145]:8333 +[2002:c08a:d22b::c08a:d22b]:8333 +[2002:c0c7:f8e3::c0c7:f8e3]:32771 +[2002:c1a9:fc5a::c1a9:fc5a]:8333 +[2002:c23f:8fc5::c23f:8fc5]:8333 +[2002:d395:ea6d::d395:ea6d]: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:fea8:1934]:8333 -[2400:8901::f03c:91ff:fe26:c4d6]:8333 +[2002:d917:e91::d917:e91]:8333 +[2002:db71:f434::db71:f434]:8333 +[2400:2651:161:1000:6847:d40f:aaa3:4848]: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 +[2401:2500:203:10:153:120:156:83]:8333 +[2401:a400:3200:5600:14ee:f361:4bdc:1f7c]:8333 +[2403:4200:403:2::ff]:8333 [2405:aa00:2::40]:8333 -[2600:3c00::f03c:91ff:fe18:59b2]: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 +[240b:10:ca20:f0:224:e8ff:fe1f:60d9]:8333 +[240b:250:1e0:2400:b9ef:8fe3:a69a:7378]:8333 +[240d:1a:302:8600:8876:a36d:12ee:f285]:8333 +[2600:3c00::f03c:91ff:fe91:3e49]:8333 +[2600:3c00::f03c:91ff:febb:981e]:8333 [2600:3c01::f03c:91ff:fe18:6adf]: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: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:3c01::f03c:91ff:fe91:6a29]:8333 +[2600:3c01::f03c:91ff:fef1:1eaa]: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:fe28:1445]:8333 [2600:3c03::f03c:91ff:fe67:d2e]:8333 -[2600:3c03::f03c:91ff:fe6e:1803]: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 +[2600:3c03::f03c:91ff:fe89:116f]:8333 +[2600:3c03::f03c:91ff:feb0:5fc4]:8333 +[2600:3c03::f03c:91ff:fee0:233e]:8333 +[2600:3c03::f03c:91ff:fee0:51]:8333 +[2600:8805:2400:14e:226:4aff:fe02:2ba4]:8333 +[2600:8807:5080:3301:1487:83b7:33d7:eb97]:8333 +[2601:186:c100:6bcd:16bd:cea1:235d:1c19]:8333 +[2601:18c:4200:28d0:e4d:e9ff:fec5:76d0]:8333 +[2601:247:8201:6251:30e6:7b95:69bf:9248]:8333 +[2601:602:9980:f78:211:11ff:fec5:1ae]:8333 +[2602:ae:1993:de00:2c50:9a44:8f11:77a5]:8333 +[2602:ff68:0:1:21e:bff:feca:db72]:8333 +[2602:ff68:0:1:2bd:27ff:feb0:adf8]:8333 +[2602:ff68:0:1::5]:8333 +[2602:ff68:0:5:2bd:27ff:feb0:adf8]:8333 [2602:ffc5:1f::1f:2d61]:8333 [2602:ffc5:1f::1f:9211]:8333 -[2602:ffc5::75d5:c1c3]:8333 +[2602:ffc5::9e63:27a2]:8333 +[2602:ffc5::c30:1c75]:8333 [2602:ffc5::ffc5:b844]:8333 [2602:ffe8:100:2::457:936b]:8333 -[2602:ffe8:100:2::9d20:2e3c]:8333 -[2602:ffea:1001:72b::578b]:8333 -[2602:ffea:a::24c4:d9fd]:8333 -[2604:0:c1:100:1ec1:deff:fe54:2235]:8333 -[2604:180:1:1af::42a9]:8333 -[2604:180:3:702::c9de]:8333 -[2604:4080:1114:0:3285:a9ff:fe93:850c]: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 -[2607:5300:100:200::1c83]:9334 -[2607:5300:10::a1]:8333 -[2607:5300:60:1c2f::1]:8333 -[2607:5300:60:2b90::1]:8333 -[2607:5300:60:3320::1]:8333 -[2607:5300:60:385::1]:8333 -[2607:5300:60:4a85::]: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: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:1178:2:43:8983:cc27:d72:d97a]:8333 -[2a00:1328:e100:cc42:230:48ff:fe92:55c]:8333 +[2604:180:2:eee::ca46]:8333 +[2604:880:d:85::be37]:8333 +[2604:9a00:2100:a009:2::]:8333 +[2604:a880:2:d0::301:8001]:8333 +[2604:a880:2:d0::4a9:1001]:8333 +[2604:a880:2:d0::53a:c001]:8333 +[2604:a880:400:d0::ad7:e001]:8333 +[2604:a880:400:d0::dcf:f001]:8333 +[2605:4d00::50]:8333 +[2605:6000:edc8:300::ddfe]:8333 +[2605:6000:ffc0:70:74d5:225c:f553:5bb8]:8333 +[2606:6000:c148:7003:5054:ff:fe78:66ff]:8333 +[2606:6000:e6d6:d701:d428:5e44:a2c9:3ff6]:8333 +[2606:c680:1:4a:2016:d1ff:fe93:52a7]:8333 +[2607:5300:203:118:3733::1414]:8333 +[2607:5300:60:13bb::1]:8333 +[2607:5300:60:1966::1]:8333 +[2607:5300:60:2218::]:8333 +[2607:5300:60:3775::]:8333 +[2607:5300:60:3ddf::]:8333 +[2607:5300:60:a654::]:8333 +[2607:5300:60:a7a3::]:8333 +[2607:5300:60:ac0::1]:8333 +[2607:5300:60:cf97::]:8333 +[2607:f0d0:1901:19::6]:8333 +[2607:f128:40:1202:69:162:139:125]:8333 +[2607:f128:40:1703::2]:8333 +[2607:f178:0:8::106]:8333 +[2607:f1c0:84d:8900::7e:cad]:8333 +[2607:f948:0:1::1:40]:8333 +[2607:fcd0:100:2302::6094:635a]:8333 +[2607:fcd0:100:6a00::3a96:1]:8333 +[2607:fcd0:100:6a02::7ff0:1]:8333 +[2607:fcd0:100:8203::8c58:dbc]:8333 +[2607:fea8:1360:9c2:221a:6ff:fe47:776d]:8333 +[2607:fea8:4da0:9ce:5114:a8ec:20f5:a50b]:8333 +[2607:fea8:5df:fda0:feaa:14ff:feda:c79a]:8333 +[2607:fea8:84c0:163:f42c:baff:fecc:6bbf]:8333 +[2607:ff10:c5:502:225:90ff:fe32:d446]:8333 +[2607:ff48:aa81:800::96cf:1]:8333 +[2620:11c:5001:1118:d267:e5ff:fee9:e673]:8333 +[2620:b8:4000:1000::93:1]:8333 +[2800:1a0::9]:8333 +[2a00:1178:2:43:19fd:d43e:b77:edeb]:8333 +[2a00:1178:2:43:b4e3:e562:f811:d761]:8333 [2a00:14f0:e000:80d2:cd1a::1]:8333 +[2a00:1630:14::101]: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:1630:2:500::4]:8333 +[2a00:1768:2001:24::148:218]:8333 +[2a00:1768:2001:27::142:21]:8333 +[2a00:1a48:7810:101:be76:4eff:fe08:c774]: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:1dc0:2255:10::2]:8333 +[2a00:7c80:0:71::8]:8333 +[2a00:7c80:0:97::7]:8333 +[2a00:bbe0:0:42:222:64ff:fe9a:e206]:8333 +[2a00:c98:2050:a020:3::110]:8333 +[2a00:dcc0:eda:98:183:193:1d24:b53a]: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: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 +[2a00:f90:ff0:c100:53c4:97a7:8b59:796a]:8333 +[2a01:238:435c:de00:b110:38cf:192d:b2c]:28333 +[2a01:348:6:7cf::2]:8333 +[2a01:368:e012:8888:216:3eff:fe24:1162]:8333 +[2a01:488:66:1000:53a9:22b:0:1]:8333 +[2a01:488:67:1000:523:ffa7:0:1]:8333 +[2a01:488:67:1000:b01c:3379:0:1]: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:110:5105::2]:8333 -[2a01:4f8:110:516c::2]:8333 +[2a01:4f8:10a:2e4::2]:8333 +[2a01:4f8:10a:34e::2]:8333 +[2a01:4f8:10a:51d::2]:8333 +[2a01:4f8:10a:622::2]:8333 +[2a01:4f8:10a:85f::2]:8333 +[2a01:4f8:10a:864::2]:8333 +[2a01:4f8:10a:d04::2]:8333 +[2a01:4f8:110:334c::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:8203::2]:8333 -[2a01:4f8:121:234d::2]:8333 -[2a01:4f8:121:261::2]:8333 -[2a01:4f8:130:11ea::2]:8333 +[2a01:4f8:121:4346::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:934f::2]:8333 +[2a01:4f8:131:33ad::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:31b0::2]:8333 +[2a01:4f8:140:4088::2]:8333 +[2a01:4f8:140:931a::2]:8333 [2a01:4f8:140:93b0::2]:8333 -[2a01:4f8:141:1167::2]:8333 +[2a01:4f8:141:13ad::c451]:8333 [2a01:4f8:141:186::2]: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:21ca::2]:8333 -[2a01:4f8:151:41c2:0:5404:a67e:f250]:8333 -[2a01:4f8:151:5128::2]:8333 +[2a01:4f8:141:22ae::2]:8333 +[2a01:4f8:141:322c::2]:8333 +[2a01:4f8:150:11d4::2]:8333 +[2a01:4f8:150:440f::2]:8333 +[2a01:4f8:150:61ee::2]:8333 +[2a01:4f8:150:726b::2]:8333 +[2a01:4f8:151:30c9::2]:15000 +[2a01:4f8:151:41a2::2]:8333 +[2a01:4f8:151:41cc::2]:8333 [2a01:4f8:151:52c6::154]:8333 -[2a01:4f8:151:6347::2]:9001 -[2a01:4f8:160:5136::2]:8333 -[2a01:4f8:160:72c5::2858:e1c5]:8333 -[2a01:4f8:160:72c5::593b:60d5]:8333 +[2a01:4f8:151:600b::1:1]:8333 +[2a01:4f8:151:7175::2]:8333 +[2a01:4f8:160:41f0::1:33]:8333 +[2a01:4f8:160:5328::27f0:187a]: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:21ad::333:30]: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:162:4110::2]:8333 +[2a01:4f8:162:4348::2]:8333 +[2a01:4f8:171:1c1b::2]:8333 +[2a01:4f8:171:1c3::2]:8333 +[2a01:4f8:171:2258::2]:8333 +[2a01:4f8:171:2a70::2]:8333 +[2a01:4f8:171:2e1b::2]:8333 +[2a01:4f8:171:2f28::2]:8333 +[2a01:4f8:171:3248::2]:8333 +[2a01:4f8:171:380c::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:171:d0a::2]:8333 +[2a01:4f8:172:116c::2]:8333 +[2a01:4f8:172:1287::2]:8333 +[2a01:4f8:172:17a9::2]:8333 +[2a01:4f8:172:1ca7::2]:8333 +[2a01:4f8:172:2159::2]:8333 +[2a01:4f8:172:3a41::2]:8333 +[2a01:4f8:172:3b42::2]:8333 +[2a01:4f8:172:3ec1::2]:8333 +[2a01:4f8:172:3ec2::2]:8333 +[2a01:4f8:172:aeb::2]:8333 +[2a01:4f8:172:aec::2]:8333 +[2a01:4f8:173:10ab::2]:8333 +[2a01:4f8:173:1551::2]:8333 +[2a01:4f8:173:1bca::2]:8333 +[2a01:4f8:173:1e2e::2]:8333 +[2a01:4f8:173:2162::2]:8333 +[2a01:4f8:173:21e6::2]:8333 +[2a01:4f8:173:42::2]:8333 +[2a01:4f8:173:cc1::2]:8333 +[2a01:4f8:190:1253::2]:8333 +[2a01:4f8:190:24eb::2]:8333 +[2a01:4f8:190:34f0::2]:8333 +[2a01:4f8:190:528d::2]:8333 [2a01:4f8:190:91ce::2]:8333 [2a01:4f8:191:2194::83]: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:192:11b2::2]:8333 +[2a01:4f8:191:8165::2]:22556 +[2a01:4f8:191:81b7::2]:8333 +[2a01:4f8:191:8328::3]:8333 +[2a01:4f8:192:11b2::2]:8343 [2a01:4f8:192:216c::2]:8333 -[2a01:4f8:192:22b3::2]:8333 +[2a01:4f8:192:22af::2]:8333 +[2a01:4f8:192:2422::2]:8333 +[2a01:4f8:192:34d0::2]:8333 [2a01:4f8:192:440b::2]:8333 +[2a01:4f8:192:5230::2]:8333 [2a01:4f8:192:db::2]:8333 [2a01:4f8:200:1012::2]: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:214c::2]:8333 -[2a01:4f8:201:233:1::3]:8333 -[2a01:4f8:201:3e3::2]:8333 +[2a01:4f8:200:414e::2]:8333 +[2a01:4f8:200:416a::2]:8333 +[2a01:4f8:201:21a7::2]:8333 +[2a01:4f8:201:4017::11]: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:12d6::2]:8333 [2a01:4f8:202:31e3::2]:8333 -[2a01:4f8:202:31ef::2]:8333 -[2a01:4f8:202:3392::2]:8333 +[2a01:4f8:202:32c6::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:211:14cf::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: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:4f8:211:1ec5::2]:8333 +[2a01:4f8:211:483::2]:8333 +[2a01:4f8:211:d99::8]:8333 +[2a01:4f8:212:1826::2]:8333 +[2a01:4f8:212:27a8::2]:8333 +[2a01:4f8:221:801::2]:8333 +[2a01:4f8:a0:12cc::2]:8333 +[2a01:4f8:a0:746a:101:1:1:2]:8333 +[2a01:4f8:a0:828a::2]:8333 +[2a01:4f8:c17:2eef::2]:8333 +[2a01:4f8:c17:2f3c::2]:3333 +[2a01:4f8:c17:3b02::2]:8333 +[2a01:4f8:c17:4245::2]:8333 +[2a01:4f8:c17:464f::2]:8333 +[2a01:4f8:c17:4a1c::2]:8333 +[2a01:4f8:c17:4c5d::2]:8333 +[2a01:4f8:c17:67f8::2]:8333 +[2a01:4f8:c17:6dd0::2]:8333 +[2a01:4f8:c17:710b::2]:8333 +[2a01:4f8:c17:714::2]:8333 +[2a01:4f8:c17:72c6::2]:8333 [2a01:608:ffff:a009:8bf5:879d:e51a:f837]: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:680:10:10::1]:8333 +[2a01:6f0:ffff:120::8dcb]:8333 +[2a01:79c:cebc:857c:98c1:88ff:fef5:90de]:8333 +[2a01:79d:7377:2629:7e57:7e57:1:1]: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:3942]:8333 +[2a01:7c8:aab5:3e6:5054:ff:fed7:4e54]:8333 +[2a01:7c8:aabd:3d5:5054:ff:fe95:f586]:8333 +[2a01:7c8:aac1:453:d0d2:af96:fa88:5d0e]:8333 +[2a01:7c8:aac3:663:5054:ff:fe25:8c69]:8333 +[2a01:7c8:aac3:97:5054:ff:fea7:3780]:8333 +[2a01:7c8:aac4:567:5054:ff:fedc:518a]: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:fe50:94b8]:8333 +[2a01:7e00::f03c:91ff:fe55:2c]:8333 [2a01:7e00::f03c:91ff:fe89:1143]:8333 -[2a01:7e00::f03c:91ff:fe98:2505]:8333 -[2a01:7e00::f03c:91ff:fedb:352e]: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:7e00::f03c:91ff:fe89:53fd]:8333 +[2a01:7e00::f03c:91ff:fedf:b70f]:8333 +[2a01:b000::4166:515b:ef9e:b3]:8333 +[2a01:b2e0:2::40]:8333 +[2a01:e34:ec29:24c0:f3:ddaf:9f59:586f]:8333 +[2a01:e34:eed7:6670:ec1b:bf7c:b012:6069]:8333 [2a01:e35:2ee5:610:21f:d0ff:fe4e:7460]:8333 [2a01:e35:8a3f:47c0:c617:feff:fe3c:9fbd]: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:fa:1a56:216:44ff:fe6a:d112]:8333 -[2a02:27f8:2012:0:e9f7:268f:c441:6129]:8333 +[2a01:e35:8bff:70b0:1e1b:dff:fe0b:236d]:8333 +[2a02:1205:34c3:a4e0:d63d:7eff:fe98:10c8]:8333 +[2a02:1205:34da:aa00:5882:249d:ddbf:bc43]:8333 +[2a02:1205:5051:a640:d6ae:52ff:fea3:ac]:8333 +[2a02:1205:c689:d980:baae:edff:feea:9445]:8333 +[2a02:120b:2c2a:5ec0:10dd:31ff:fe42:5079]:8333 +[2a02:120b:2c35:69d0:219:99ff:fe6b:4ec3]:8333 +[2a02:120b:c3c2:ff60:21f:5bff:fec3:a7ad]:24312 +[2a02:13b8:4000:1000:216:e6ff:fe92:8619]:8333 +[2a02:13b8:4000:1000::27]:8333 +[2a02:17d0:2a:4400:40f:3dd4:b053:47ad]:8333 +[2a02:180:1:1::517:afb]:8333 +[2a02:180:6:1::18]:8333 +[2a02:1810:1d11:f900:6872:f28e:8126:f635]:8333 +[2a02:27a8:0:1:52e5:49ff:fee3:3b49]:8333 [2a02:348:86:3011::1]:8333 -[2a02:4780:1:1::1:8a01]:8333 -[2a02:578:5002:116::2]:8333 +[2a02:390:9000:0:218:7dff:fe10:be33]:8333 +[2a02:582:78c1:7600:2d49:6212:29d3:abb]:8333 [2a02:6080::1:190b:69e3]:8333 -[2a02:6080::1:e893:d9d6]:8333 -[2a02:770:4000::139]:8333 +[2a02:750:7:3305::575]:8333 +[2a02:752:100:3::53]:8333 +[2a02:7aa0:1201::7501:d950]: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 +[2a02:7aa0:1619::a037:69a6]:8333 +[2a02:810d:14c0:8694:d250:99ff:fe81:23d9]:8333 +[2a02:a50::dacb:8aff:fe36:8d2d]:8333 +[2a02:c200:0:10:3:0:2591:1]:8333 +[2a02:c200:1:10:2:5:9982:1]:8333 +[2a02:c200:1:10:3:0:9290:1]:8333 +[2a02:c205:3000:7158::1]:8333 +[2a02:c205:3001:4522::1]:8333 +[2a02:c205:3001:6549::1]:8333 +[2a02:c207:2008:3772::1]:8333 +[2a02:c207:2008:6519::1]:8333 +[2a02:c207:2009:213::1]:8333 +[2a02:c207:2009:7858::1]:8333 +[2a02:c207:2010:302::1]:8333 +[2a02:c207:3001:5824::1]:8333 +[2a02:ce80:0:20::1]:8333 [2a03:4000:2:496::8]:8333 +[2a03:4000:6:416c::53]: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:4000:9:8e::1]:8333 +[2a03:7380:2140:17:51fe:3519:b571:4a13]:8333 +[2a03:b0c0:0:1010::7a3:1001]:8333 +[2a03:b0c0:0:1010::7aa:4001]:8333 +[2a03:b0c0:3:d0::1b99:c001]:8333 +[2a03:b0c0:3:d0::1b99:e001]:8333 +[2a03:b0c0:3:d0::1b9a:3001]:8333 +[2a03:b0c0:3:d0::2208:6001]:8333 +[2a03:b0c0:3:d0::23f7:1001]:8333 +[2a03:b0c0:3:d0::23f7:9001]:8333 +[2a03:b0c0:3:d0::23fb:2001]:8333 +[2a03:b0c0:3:d0::23fb:3001]:8333 +[2a03:b0c0:3:d0::23fb:5001]:8333 +[2a03:b0c0:3:d0::23fb:7001]:8333 +[2a03:b0c0:3:d0::2400:1]:8333 +[2a03:b0c0:3:d0::2400:3001]:8333 +[2a03:b0c0:3:d0::2400:e001]:8333 +[2a03:b0c0:3:d0::2401:e001]:8333 +[2a03:b0c0:3:d0::2402:2001]:8333 +[2a03:b0c0:3:d0::2402:8001]:8333 +[2a03:b0c0:3:d0::2402:9001]:8333 +[2a03:b0c0:3:d0::2402:b001]:8333 +[2a03:b0c0:3:d0::2402:d001]:8333 +[2a03:b0c0:3:d0::2403:1001]:8333 +[2a03:b0c0:3:d0::2403:2001]:8333 +[2a03:b0c0:3:d0::2403:4001]:8333 +[2a03:b0c0:3:d0::2403:6001]:8333 +[2a03:b0c0:3:d0::2403:a001]:8333 +[2a03:b0c0:3:d0::2403:b001]:8333 +[2a03:b0c0:3:d0::2403:f001]:8333 +[2a03:b0c0:3:d0::2404:6001]:8333 +[2a03:b0c0:3:d0::2404:b001]: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 +[2a04:1980:3100:1aac:e61d:2dff:fe29:f241]:8333 +[2a04:1980:3100:1aac:e61d:2dff:fe29:f251]:8333 +[2a04:2180:0:1::5a49:3c06]:8333 +[2a04:2180:1:7::3]:8333 +[2a04:2e00:5:2e:9a4b:e1ff:fe62:6dc0]:8333 +[2a04:3542:1000:910:8492:b8ff:fe91:711d]:8333 +[2a04:dbc3:fffe:0:e61f:13ff:fe95:8401]:8333 +[2a06:9fc0:2a06:9fc0:2a06:9fc1:67c:e706]:8333 +[2c0f:f738:2004:82::]:8333 +2hryb3uh3tzwgnya.onion:8333 3nmbbakinewlgdln.onion:8333 -4j77gihpokxu2kj4.onion:8333 -546esc6botbjfbxb.onion:8333 -5at7sq5nm76xijkd.onion:8333 -77mx2jsxaoyesz2p.onion:8333 -7g7j54btiaxhtsiy.onion:8333 -a6obdgzn67l7exu3.onion:8333 -ab64h7olpl7qpxci.onion:8333 -am2a4rahltfuxz6l.onion:8333 -azuxls4ihrr2mep7.onion:8333 -bitcoin7bi4op7wb.onion:8333 -bitcoinostk4e4re.onion:8333 +3qeri3tmhzmpegyv.onion:8333 +4wdknmecghcmclq5.onion:8333 +53tsjt6zq3iasv5q.onion:8333 +5cg7qeywvwo6vxpt.onion:8333 +5gbcrgqxcbxj253s.onion:8333 +6cn4ilbwkrkh7gwo.onion:8333 +6e4jrnn7igeqxmlf.onion:8333 +6ymgbvnn6d5nfmv4.onion:8333 +6zsh3bfduhpo7ldl.onion:8333 +72fq6phv4fg4rhvh.onion:8333 +7gdqp6npusk4lfwk.onion:8333 +a7emxol55e623lqc.onion:8333 +assbiydziq77zaki.onion:8333 +bafk5ioatlgt7dgl.onion:8333 bk7yp6epnmcllq72.onion:8333 -bmutjfrj5btseddb.onion:8333 -ceeji4qpfs3ms3zc.onion:8333 -clexmzqio7yhdao4.onion:8333 +brwqezn6le54w2bb.onion:8333 +bs4bq6s6qkvt5hpi.onion:8333 +bup5n5e3kurvjzf3.onion:8333 +c2tpqkaz4ihjzwgb.onion:8333 +cernrmrk5zomzozn.onion:8333 +cfyegj64ht3jpodr.onion:8333 +cg5vg54cazzpvoug.onion:8333 +cgk4u2lxrvml4jvb.onion:8333 +cjygd7pu5lqkky5j.onion:8333 +d6wubsdtr46dd5ki.onion:8333 +dfq6yjc3aelplwr4.onion:8333 +dqpxwlpnv3z3hznl.onion:8333 +eamfospuveabaimd.onion:8333 +ep2mjzox3kvb6ax4.onion:8333 +fpbxb4wjudiw2w5a.onion:8333 +fu5hfsbbf5jwsvhv.onion:8333 +g4freoibsczujle3.onion:8333 gb5ypqt63du3wfhn.onion:8333 -h2vlpudzphzqxutd.onion:8333 -n42h7r6oumcfsbrs.onion:4176 -ncwk3lutemffcpc4.onion:8333 +ggdy2pb2avlbtjwq.onion:8333 +gh2aiddzxmvyrnue.onion:8333 +gnxgylbgzvaazkq7.onion:8333 +hnizdxnejel64ubk.onion:8333 +htvdcmlc3abji2ab.onion:8443 +hwuboois4gslupgx.onion:8333 +hxz6gowludlj6d5a.onion:8333 +j6umo4bnsztpsonc.onion:8333 +jdunmaocwbbnw565.onion:8333 +ktv3qlxl7xvmdlf4.onion:8333 +kvd44sw7skb5folw.onion:8333 +kwimnzm6vd4zakvl.onion:8333 +la5xhk3lprxzxmz2.onion:8333 +lc7cx67end26uutp.onion:8352 +mwu5og2agcspmgkx.onion:8333 +mzxkipiyekaoh7my.onion:8333 +n6rwlrtwpqc7qwo7.onion:8333 +nj36424yccqph62z.onion:8333 +o256w7t3vcgktmxk.onion:8333 +o4sl5na6jeqgi3l6.onion:8333 okdzjarwekbshnof.onion:8333 -pjghcivzkoersesd.onion:8333 -rw7ocjltix26mefn.onion:8333 -uws7itep7o3yinxo.onion:8333 -vk3qjdehyy4dwcxw.onion:8333 +oyebydl2pacx6v26.onion:8333 +p5mx2imj75dpmime.onion:8333 +psco6bxjewljrczx.onion:8333 +pxtgswet6tlgrbwj.onion:8333 +rb4v3fhgx2zr4rre.onion:8333 +rjlnp3hwvrsmap6e.onion:8333 +rlafimkctvz63llg.onion:8333 +rxjvy5eyttep5tts.onion:8333 +seoskudzk6vn6mqz.onion:8333 +tpgdufxxsw3jkrdf.onion:8333 +tuiyvqgi3o675pjb.onion:8333 +tx4zd7d5exonnblh.onion:8333 +uokg6avfgbhofls3.onion:8333 +v3gjphgqy5hygcml.onion:8333 +vhdoxqq63xr53ol7.onion:8333 +visevrizz3quyagj.onion:8333 vqpye2k5rcqvj5mq.onion:8333 -wpi7rpvhnndl52ee.onion:8333 +wfsx2gi7djhy22hk.onion:8333 +wg6vwmbrzyyzapun.onion:8333 +xub4w3w4wwk56xiq.onion:8333 +ycivnom44dmxx4ob.onion:8333 +ywskufc62bf2fum4.onion:8333 +z4fax2vxg23t2ddf.onion:8333 +zo5dklwelmdrpo5n.onion:8333 diff --git a/contrib/testgen/base58.py b/contrib/testgen/base58.py index bb0aeaff05..0d09692b36 100644 --- a/contrib/testgen/base58.py +++ b/contrib/testgen/base58.py @@ -84,7 +84,6 @@ def b58decode_chk(v): result = b58decode(v) if result is None: return None - h3 = checksum(result[:-4]) if result[-4:] == checksum(result[:-4]): return result[:-4] else: diff --git a/contrib/testgen/gen_base58_test_vectors.py b/contrib/testgen/gen_base58_test_vectors.py index 7e475b7a36..ac0701e6be 100755 --- a/contrib/testgen/gen_base58_test_vectors.py +++ b/contrib/testgen/gen_base58_test_vectors.py @@ -45,7 +45,6 @@ def is_valid(v): result = b58decode_chk(v) if result is None: return False - valid = False for template in templates: prefix = str(bytearray(template[0])) suffix = str(bytearray(template[2])) diff --git a/contrib/verify-commits/allow-revsig-commits b/contrib/verify-commits/allow-revsig-commits index e69de29bb2..f0088cdca4 100644 --- a/contrib/verify-commits/allow-revsig-commits +++ b/contrib/verify-commits/allow-revsig-commits @@ -0,0 +1,104 @@ +a06ede9a138d0fb86b0de17c42b936d9fe6e2158 +923dc447eaa8e017985b2afbbb12dd1283fbea0e +71148b8947fe8b4d756822420a7f31c380159425 +6696b4635ceb9b47aaa63244bff9032fa7b08354 +812714fd80e96e28cd288c553c83838cecbfc2d9 +8a445c5651edb9a1f51497055b7ddf4402be9188 +e126d0c12ca66278d9e7b12187c5ff4fc02a7e6c +3908fc4728059719bed0e1c7b1c8b388c2d4a8da +8b66bf74e2a349e71eaa183af81fa63eaee76ad2 +05950427d310654774031764a7141a1a4fd9c6e4 +07fd147b9f12e9205afd66a624edce357977d615 +12e31127948fa4bb01c3bddc1b8c85b432f7465b +8c87f175d335e9d9e93f987d871ae9f05f6a10a7 +46b249e578e8a3dfbe85bc7253a12e82ef4b658b +a55716abe5662ec74c2f8af93023f1e7cca901fc +f646275b90b1de93bc62b4c4d045d75ac0b96eee +c252685aa5867631e9a5ef07ccae7c7c25cae8ff +a7d55c93385359952d85decd5037843ac70ba3d4 +7dac1e5e9e887f5f6ff146e812a05bd3bf281eae +2a524b8e8fe69ef487fd8ea1b4f7a03f473ed201 +ce5c1f4acae43477989cdf9a82ed33703919cda2 +2db4cbcc437f51f5dac82cc4de46f383b92e6f11 +7aa700424cbda387536373d8dfec88aee43f950e +b99a093afed880f23fb279c443cc6ae5e379cc43 +b83264d9c7a8ddb79f64bd9540caddc8632ef31f +57e337d40e94ba33d8cd265c134d6ef857b32b59 +a1dcf2e1087beaf3981739fd2bb74f35ecad630a +d38b0d7a6b6056cba26999b702815775e2437d87 +815640ec6af9a38d6a2da4a4400056e2f4105080 +09c4fd157c5b88df2d97fad4826c79b094db90c9 +2efcfa5acfacb958973d9e8125e1d81f102e2dfd +dc6dee41f7cf2ba93fcd0fea7c157e4b2775d439 +ad826b3df9f763b49f1e3e3d50c4efdd438c7547 +c1a52276848d8caa9a9789dff176408c1aa6b1ed +3bf06e9bac57b5b5a746677b75e297a7b154bdbd +72ae6f8cf0224370e8121d6769b21e612ca15d6f +a143b88dbd4971ecfdd1d39a494489c8f2db0344 +76fec09d878d6dbf214bdb6228d480bd9195db4c +93566e0c37c5ae104095474fea89f00dcb40f551 +407d9232ef5cb1ebf6cff21f3d13e07ea4158eeb +9346f8429957e356d21c665bab59fe45bcf1f74e +6eeac6e30d65f9a972067c1ea8c49978c8e631ac +dc6b9406bdfab2af8c86cb080cb3e6cf8f2385d8 +9f554e03ebe5701c1b75ff03b3d6152095c0cad3 +05009935f9ac070197113954d680bc2c9150b9b3 +508404de98a8a5435f52916cef8f328e82651961 +ed0cc50afed146c27f6d8129c683c225fb940093 +6429cfa8a70308241c576aeb92ffe3db5203b2ef +6898213409811b140843c3d89af43328c3b22fad +5b2ea29cf4fd298346437bb16a54407f8c1f9dca +e2a1a1ee895149c544d4ae295466611f0cec3094 +e82fb872ff5cc8fd22d43327c1ee3e755f61c562 +19b0f33de0efd9da788e8e4f3fdc2a9e159abdb1 +89de1538ce1f8c00f80e8d11f43e1b77e24d7dea +de07fdcf77e97b8613091285e4d0a734f5de7492 +01680195f8aa586c55c44767397380def3a23b54 +05e1c85fb687c82ae477c72d4a7e2d6b0c692167 +c072b8fd95cd4fa84f08189a0cd8b173ea2dbb8e +9a0ed08b40b15ae2b791aa8549b53e69934b4ea7 +53f8f226bd1d627c4a6dec5862a1d4ea5a933e45 +9d0f43b7ca7241d8a018fd35dd3bc01555235ec6 +f12d2b5a8ac397e4bcaefcc19898f8ff5705dea5 +8250de13587ed05ca45df3e12c5dc9bcb1500e2c +d727f77e390426e9e463336bda08d50c451c7086 +484312bda2d43e3ea60047be076332299463adf8 +c7e05b35ab0a791c7a8e2d863e716fdec6f3f671 +b9c1cd81848da9de1baf9c2f29c19c50e549de13 +8ea7d31e384975019733b5778feabbd9955c79d8 +f798b891bcecea9548eedacae70eeb9906c1ddbf +ebefe7a00b46579cdd1e033a8c7fd8ce9aa578e4 +ad087638ee4864d6244ec9381ff764bfa6ee5086 +66db2d62d59817320c9182fc18e75a93b76828ea +7ce9ac5c83b1844a518ef2e12e87aae3cacdfe58 +4286f43025149cf44207c3ad98e4a1f068520ada +cd0c5135ab2291aaa5410ac919bad3fc87249a4a +66ed450d771a8fc01c159a8402648ebd1c35eb4c +a82f03393a32842d49236e8666ee57805ca701f8 +f972b04d63eb8af79ff3cec1dc561ed13dfa6053 +ec45cc5e27668171b55271b0c735194c70e7da41 +715e9fd7454f7a48d7adba7d42f662c20a3e3367 +2e0a99037dcc35bc63ba0d54371bc678af737c8e +7fa8d758598407f3bf0beb0118dc122ea5340736 +6a22373771edbc3c7513cacb9355f880c73c2cbf +b89ef131147f71a96152a7b5c4374266cdf539b2 +01d8359983e2f77b5118fede3ffa947072c666c8 +58f0c929a3d70a4bff79cc200f1c186f71ef1675 +950be19727a581970591d8f8138dfe4725750382 +425278d17bd0edf8a3a7cc81e55016f7fd8e7726 +c028c7b7557da2baff7af8840108e8be4db8e0c6 +47a7cfb0aa2498f6801026d258a59f9de48f60b0 +f6b7df3155ddb4cedfbcf5d3eb3383d4614b3a85 +d72098038f3b55a714ed8adb34fab547b15eb0d5 +c49c825bd9f4764536b45df5a684d97173673fc7 +33799afe83eec4200ff140e9bf5eae83701a4d7f +5c3f8ddcaa1164079105c452429fccf8127b01b6 +1f01443567b03ac75a91c810f1733f5c21b5699d +b3e42b6d02e8d19658a9135e427ebceab5367779 +69b3a6dd9d9a0adf5506c8b9fde42187356bd4a8 +bafd075c5e6a1088ef0f1aa0b0b224e026a3d3e0 +7daa3adb242d9c8728fdb15c6af6596aaad5502f +514993554c370f4cf30a109ac28d5d64893dbf0a +c8d2473e6cb042e7275a10c49d3f6a4a91bf0166 +386f4385ab04b0b2c3d47bddc0dc0f2de7354964 +9f33dba05c01ecc5c56eb1284ab7d64d42f55171 diff --git a/contrib/verify-commits/verify-commits.sh b/contrib/verify-commits/verify-commits.sh index cfe4f11a0b..b2cebdf1a0 100755 --- a/contrib/verify-commits/verify-commits.sh +++ b/contrib/verify-commits/verify-commits.sh @@ -28,9 +28,10 @@ IS_SIGNED () { local PARENTS PARENTS=$(git show -s --format=format:%P $1) for PARENT in $PARENTS; do - if IS_SIGNED $PARENT > /dev/null; then + if IS_SIGNED $PARENT; then return 0; fi + break done if ! "$HAVE_FAILED"; then echo "No parent of $1 was signed with a trusted key!" > /dev/stderr diff --git a/contrib/zmq/zmq_sub.py b/contrib/zmq/zmq_sub.py index 5707188f23..ea398a27ea 100755 --- a/contrib/zmq/zmq_sub.py +++ b/contrib/zmq/zmq_sub.py @@ -1,43 +1,84 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python3 # Copyright (c) 2014-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. +""" + ZMQ example using python3's asyncio + + Bitcoin should be started with the command line arguments: + bitcoind -testnet -daemon \ + -zmqpubhashblock=tcp://127.0.0.1:28332 \ + -zmqpubrawtx=tcp://127.0.0.1:28332 \ + -zmqpubhashtx=tcp://127.0.0.1:28332 \ + -zmqpubhashblock=tcp://127.0.0.1:28332 + + We use the asyncio library here. `self.handle()` installs itself as a + future at the end of the function. Since it never returns with the event + loop having an empty stack of futures, this creates an infinite loop. An + alternative is to wrap the contents of `handle` inside `while True`. + + A blocking example using python 2.7 can be obtained from the git history: + https://github.com/bitcoin/bitcoin/blob/37a7fe9e440b83e2364d5498931253937abe9294/contrib/zmq/zmq_sub.py +""" + import binascii +import asyncio import zmq +import zmq.asyncio +import signal import struct +import sys + +if not (sys.version_info.major >= 3 and sys.version_info.minor >= 5): + print("This example only works with Python 3.5 and greater") + exit(1) port = 28332 -zmqContext = zmq.Context() -zmqSubSocket = zmqContext.socket(zmq.SUB) -zmqSubSocket.setsockopt(zmq.SUBSCRIBE, "hashblock") -zmqSubSocket.setsockopt(zmq.SUBSCRIBE, "hashtx") -zmqSubSocket.setsockopt(zmq.SUBSCRIBE, "rawblock") -zmqSubSocket.setsockopt(zmq.SUBSCRIBE, "rawtx") -zmqSubSocket.connect("tcp://127.0.0.1:%i" % port) - -try: - while True: - msg = zmqSubSocket.recv_multipart() - topic = str(msg[0]) +class ZMQHandler(): + def __init__(self): + self.loop = zmq.asyncio.install() + self.zmqContext = zmq.asyncio.Context() + + self.zmqSubSocket = self.zmqContext.socket(zmq.SUB) + self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "hashblock") + self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "hashtx") + self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "rawblock") + self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "rawtx") + self.zmqSubSocket.connect("tcp://127.0.0.1:%i" % port) + + async def handle(self) : + msg = await self.zmqSubSocket.recv_multipart() + topic = msg[0] body = msg[1] sequence = "Unknown" if len(msg[-1]) == 4: msgSequence = struct.unpack('<I', msg[-1])[-1] sequence = str(msgSequence) - if topic == "hashblock": - print '- HASH BLOCK ('+sequence+') -' - print binascii.hexlify(body) - elif topic == "hashtx": - print '- HASH TX ('+sequence+') -' - print binascii.hexlify(body) - elif topic == "rawblock": - print '- RAW BLOCK HEADER ('+sequence+') -' - print binascii.hexlify(body[:80]) - elif topic == "rawtx": - print '- RAW TX ('+sequence+') -' - print binascii.hexlify(body) - -except KeyboardInterrupt: - zmqContext.destroy() + if topic == b"hashblock": + print('- HASH BLOCK ('+sequence+') -') + print(binascii.hexlify(body)) + elif topic == b"hashtx": + print('- HASH TX ('+sequence+') -') + print(binascii.hexlify(body)) + elif topic == b"rawblock": + print('- RAW BLOCK HEADER ('+sequence+') -') + print(binascii.hexlify(body[:80])) + elif topic == b"rawtx": + print('- RAW TX ('+sequence+') -') + print(binascii.hexlify(body)) + # schedule ourselves to receive the next message + asyncio.ensure_future(self.handle()) + + def start(self): + self.loop.add_signal_handler(signal.SIGINT, self.stop) + self.loop.create_task(self.handle()) + self.loop.run_forever() + + def stop(self): + self.loop.stop() + self.zmqContext.destroy() + +daemon = ZMQHandler() +daemon.start() diff --git a/contrib/zmq/zmq_sub3.4.py b/contrib/zmq/zmq_sub3.4.py new file mode 100755 index 0000000000..a2ff64b29b --- /dev/null +++ b/contrib/zmq/zmq_sub3.4.py @@ -0,0 +1,89 @@ +#!/usr/bin/env python3 +# Copyright (c) 2014-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. + +""" + ZMQ example using python3's asyncio + + Bitcoin should be started with the command line arguments: + bitcoind -testnet -daemon \ + -zmqpubhashblock=tcp://127.0.0.1:28332 \ + -zmqpubrawtx=tcp://127.0.0.1:28332 \ + -zmqpubhashtx=tcp://127.0.0.1:28332 \ + -zmqpubhashblock=tcp://127.0.0.1:28332 + + We use the asyncio library here. `self.handle()` installs itself as a + future at the end of the function. Since it never returns with the event + loop having an empty stack of futures, this creates an infinite loop. An + alternative is to wrap the contents of `handle` inside `while True`. + + The `@asyncio.coroutine` decorator and the `yield from` syntax found here + was introduced in python 3.4 and has been deprecated in favor of the `async` + and `await` keywords respectively. + + A blocking example using python 2.7 can be obtained from the git history: + https://github.com/bitcoin/bitcoin/blob/37a7fe9e440b83e2364d5498931253937abe9294/contrib/zmq/zmq_sub.py +""" + +import binascii +import asyncio +import zmq +import zmq.asyncio +import signal +import struct +import sys + +if not (sys.version_info.major >= 3 and sys.version_info.minor >= 4): + print("This example only works with Python 3.4 and greater") + exit(1) + +port = 28332 + +class ZMQHandler(): + def __init__(self): + self.loop = zmq.asyncio.install() + self.zmqContext = zmq.asyncio.Context() + + self.zmqSubSocket = self.zmqContext.socket(zmq.SUB) + self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "hashblock") + self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "hashtx") + self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "rawblock") + self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "rawtx") + self.zmqSubSocket.connect("tcp://127.0.0.1:%i" % port) + + @asyncio.coroutine + def handle(self) : + msg = yield from self.zmqSubSocket.recv_multipart() + topic = msg[0] + body = msg[1] + sequence = "Unknown"; + if len(msg[-1]) == 4: + msgSequence = struct.unpack('<I', msg[-1])[-1] + sequence = str(msgSequence) + if topic == b"hashblock": + print('- HASH BLOCK ('+sequence+') -') + print(binascii.hexlify(body)) + elif topic == b"hashtx": + print('- HASH TX ('+sequence+') -') + print(binascii.hexlify(body)) + elif topic == b"rawblock": + print('- RAW BLOCK HEADER ('+sequence+') -') + print(binascii.hexlify(body[:80])) + elif topic == b"rawtx": + print('- RAW TX ('+sequence+') -') + print(binascii.hexlify(body)) + # schedule ourselves to receive the next message + asyncio.ensure_future(self.handle()) + + def start(self): + self.loop.add_signal_handler(signal.SIGINT, self.stop) + self.loop.create_task(self.handle()) + self.loop.run_forever() + + def stop(self): + self.loop.stop() + self.zmqContext.destroy() + +daemon = ZMQHandler() +daemon.start() diff --git a/depends/packages/native_cctools.mk b/depends/packages/native_cctools.mk index 797480c25e..44d238cc4c 100644 --- a/depends/packages/native_cctools.mk +++ b/depends/packages/native_cctools.mk @@ -38,7 +38,8 @@ $(package)_cxx=$($(package)_extract_dir)/toolchain/bin/clang++ endef define $(package)_preprocess_cmds - cd $($(package)_build_subdir); ./autogen.sh + cd $($(package)_build_subdir); ./autogen.sh && \ + sed -i.old "/define HAVE_PTHREADS/d" ld64/src/ld/InputFiles.h endef define $(package)_config_cmds diff --git a/depends/packages/packages.mk b/depends/packages/packages.mk index 4cf44385b8..088723ebd0 100644 --- a/depends/packages/packages.mk +++ b/depends/packages/packages.mk @@ -2,7 +2,7 @@ packages:=boost openssl libevent zeromq native_packages := native_ccache qt_native_packages = native_protobuf -qt_packages = qrencode protobuf +qt_packages = qrencode protobuf zlib qt_x86_64_linux_packages:=qt expat dbus libxcb xcb_proto libXau xproto freetype fontconfig libX11 xextproto libXext xtrans qt_i686_linux_packages:=$(qt_x86_64_linux_packages) diff --git a/depends/packages/qrencode.mk b/depends/packages/qrencode.mk index 7b21247133..44fdf1c295 100644 --- a/depends/packages/qrencode.mk +++ b/depends/packages/qrencode.mk @@ -1,7 +1,7 @@ package=qrencode $(package)_version=3.4.4 $(package)_download_path=https://fukuchi.org/works/qrencode/ -$(package)_file_name=qrencode-$(qrencode_version).tar.bz2 +$(package)_file_name=$(package)-$($(package)_version).tar.bz2 $(package)_sha256_hash=efe5188b1ddbcbf98763b819b146be6a90481aac30cfc8d858ab78a19cde1fa5 define $(package)_set_vars diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index 383ef2dae6..bbfdb766ed 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -4,7 +4,7 @@ $(package)_download_path=http://download.qt.io/official_releases/qt/5.7/$($(pack $(package)_suffix=opensource-src-$($(package)_version).tar.gz $(package)_file_name=qtbase-$($(package)_suffix) $(package)_sha256_hash=95f83e532d23b3ddbde7973f380ecae1bac13230340557276f75f2e37984e410 -$(package)_dependencies=openssl +$(package)_dependencies=openssl zlib $(package)_linux_dependencies=freetype fontconfig libxcb libX11 xproto libXext $(package)_build_subdir=qtbase $(package)_qt_libs=corelib network widgets gui plugins testlib @@ -73,11 +73,13 @@ $(package)_config_opts += -prefix $(host_prefix) $(package)_config_opts += -qt-libpng $(package)_config_opts += -qt-libjpeg $(package)_config_opts += -qt-pcre -$(package)_config_opts += -qt-zlib +$(package)_config_opts += -system-zlib $(package)_config_opts += -reduce-exports $(package)_config_opts += -static $(package)_config_opts += -silent $(package)_config_opts += -v +$(package)_config_opts += -no-feature-printer +$(package)_config_opts += -no-feature-printdialog ifneq ($(build_os),darwin) $(package)_config_opts_darwin = -xplatform macx-clang-linux @@ -138,12 +140,13 @@ define $(package)_preprocess_cmds patch -p1 < $($(package)_patch_dir)/pidlist_absolute.patch && \ patch -p1 < $($(package)_patch_dir)/fix-xcb-include-order.patch && \ patch -p1 < $($(package)_patch_dir)/fix_qt_pkgconfig.patch && \ - echo "QMAKE_CFLAGS += $($(package)_cflags) $($(package)_cppflags)" >> qtbase/mkspecs/common/gcc-base.conf && \ - echo "QMAKE_CXXFLAGS += $($(package)_cxxflags) $($(package)_cppflags)" >> qtbase/mkspecs/common/gcc-base.conf && \ - echo "QMAKE_LFLAGS += $($(package)_ldflags)" >> qtbase/mkspecs/common/gcc-base.conf && \ - sed -i.old "s|QMAKE_CFLAGS = |QMAKE_CFLAGS = $($(package)_cflags) $($(package)_cppflags) |" qtbase/mkspecs/win32-g++/qmake.conf && \ - sed -i.old "s|QMAKE_LFLAGS = |QMAKE_LFLAGS = $($(package)_ldflags) |" qtbase/mkspecs/win32-g++/qmake.conf && \ - sed -i.old "s|QMAKE_CXXFLAGS = |QMAKE_CXXFLAGS = $($(package)_cxxflags) $($(package)_cppflags) |" qtbase/mkspecs/win32-g++/qmake.conf + echo "!host_build: QMAKE_CFLAGS += $($(package)_cflags) $($(package)_cppflags)" >> qtbase/mkspecs/common/gcc-base.conf && \ + echo "!host_build: QMAKE_CXXFLAGS += $($(package)_cxxflags) $($(package)_cppflags)" >> qtbase/mkspecs/common/gcc-base.conf && \ + echo "!host_build: QMAKE_LFLAGS += $($(package)_ldflags)" >> qtbase/mkspecs/common/gcc-base.conf && \ + sed -i.old "s|QMAKE_CFLAGS = |!host_build: QMAKE_CFLAGS = $($(package)_cflags) $($(package)_cppflags) |" qtbase/mkspecs/win32-g++/qmake.conf && \ + sed -i.old "s|QMAKE_LFLAGS = |!host_build: QMAKE_LFLAGS = $($(package)_ldflags) |" qtbase/mkspecs/win32-g++/qmake.conf && \ + sed -i.old "s|QMAKE_CXXFLAGS = |!host_build: QMAKE_CXXFLAGS = $($(package)_cxxflags) $($(package)_cppflags) |" qtbase/mkspecs/win32-g++/qmake.conf + endef define $(package)_config_cmds @@ -151,6 +154,8 @@ define $(package)_config_cmds export PKG_CONFIG_LIBDIR=$(host_prefix)/lib/pkgconfig && \ export PKG_CONFIG_PATH=$(host_prefix)/share/pkgconfig && \ ./configure $($(package)_config_opts) && \ + echo "host_build: QT_CONFIG ~= s/system-zlib/zlib" >> mkspecs/qconfig.pri && \ + echo "CONFIG += force_bootstrap" >> mkspecs/qconfig.pri && \ $(MAKE) sub-src-clean && \ cd ../qttranslations && ../qtbase/bin/qmake qttranslations.pro -o Makefile && \ cd translations && ../../qtbase/bin/qmake translations.pro -o Makefile && cd ../.. &&\ diff --git a/depends/packages/zlib.mk b/depends/packages/zlib.mk new file mode 100644 index 0000000000..7ff5d00bbd --- /dev/null +++ b/depends/packages/zlib.mk @@ -0,0 +1,25 @@ +package=zlib +$(package)_version=1.2.11 +$(package)_download_path=http://www.zlib.net +$(package)_file_name=$(package)-$($(package)_version).tar.gz +$(package)_sha256_hash=c3e5e9fdd5004dcb542feda5ee4f0ff0744628baf8ed2dd5d66f8ca1197cb1a1 + +define $(package)_set_vars +$(package)_build_opts= CC="$($(package)_cc)" +$(package)_build_opts+=CFLAGS="$($(package)_cflags) $($(package)_cppflags) -fPIC" +$(package)_build_opts+=AR="$($(package)_ar)" +$(package)_build_opts+=RANLIB="$($(package)_ranlib)" +endef + +define $(package)_config_cmds + ./configure --static --prefix=$(host_prefix) +endef + +define $(package)_build_cmds + $(MAKE) $($(package)_build_opts) libz.a +endef + +define $(package)_stage_cmds + $(MAKE) DESTDIR=$($(package)_staging_dir) install $($(package)_build_opts) +endef + diff --git a/depends/patches/qt/mac-qmake.conf b/depends/patches/qt/mac-qmake.conf index 402e0555b0..ca70d30b15 100644 --- a/depends/patches/qt/mac-qmake.conf +++ b/depends/patches/qt/mac-qmake.conf @@ -1,6 +1,5 @@ MAKEFILE_GENERATOR = UNIX CONFIG += app_bundle incremental global_init_link_order lib_version_first plugin_no_soname absolute_library_soname -DEFINES += QT_NO_PRINTER QT_NO_PRINTDIALOG QMAKE_INCREMENTAL_STYLE = sublib include(../common/macx.conf) include(../common/gcc-base-mac.conf) @@ -15,10 +14,10 @@ QMAKE_MAC_SDK.macosx.Path = $${MAC_SDK_PATH} QMAKE_MAC_SDK.macosx.platform_name = macosx QMAKE_MAC_SDK.macosx.SDKVersion = $${MAC_SDK_VERSION} QMAKE_MAC_SDK.macosx.PlatformPath = /phony -QMAKE_CFLAGS += -target $${MAC_TARGET} -QMAKE_OBJECTIVE_CFLAGS += $$QMAKE_CFLAGS -QMAKE_CXXFLAGS += $$QMAKE_CFLAGS -QMAKE_LFLAGS += -target $${MAC_TARGET} -mlinker-version=$${MAC_LD64_VERSION} +!host_build: QMAKE_CFLAGS += -target $${MAC_TARGET} +!host_build: QMAKE_OBJECTIVE_CFLAGS += $$QMAKE_CFLAGS +!host_build: QMAKE_CXXFLAGS += $$QMAKE_CFLAGS +!host_build: QMAKE_LFLAGS += -target $${MAC_TARGET} -mlinker-version=$${MAC_LD64_VERSION} QMAKE_AR = $${CROSS_COMPILE}ar cq QMAKE_RANLIB=$${CROSS_COMPILE}ranlib QMAKE_LIBTOOL=$${CROSS_COMPILE}libtool diff --git a/doc/Doxyfile b/doc/Doxyfile index ef55acdbc3..45436a6b15 100644 --- a/doc/Doxyfile +++ b/doc/Doxyfile @@ -38,7 +38,7 @@ PROJECT_NAME = "Bitcoin Core" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 0.13.99 +PROJECT_NUMBER = 0.14.99 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/doc/README.md b/doc/README.md index 36684e5401..09f32bc09e 100644 --- a/doc/README.md +++ b/doc/README.md @@ -1,4 +1,4 @@ -Bitcoin Core 0.13.99 +Bitcoin Core 0.14.99 ===================== Setup diff --git a/doc/README_windows.txt b/doc/README_windows.txt index 74a05138a4..0e4c9ce04f 100644 --- a/doc/README_windows.txt +++ b/doc/README_windows.txt @@ -1,4 +1,4 @@ -Bitcoin Core 0.13.99
+Bitcoin Core 0.14.99
=====================
Intro
diff --git a/doc/bips.md b/doc/bips.md index 4f41610089..bc8dcb6fb3 100644 --- a/doc/bips.md +++ b/doc/bips.md @@ -20,6 +20,7 @@ BIPs that are implemented by Bitcoin Core (up-to-date up to **v0.13.0**): * [`BIP 66`](https://github.com/bitcoin/bips/blob/master/bip-0066.mediawiki): The strict DER rules and associated version 3 blocks have been implemented since **v0.10.0** ([PR #5713](https://github.com/bitcoin/bitcoin/pull/5713)). * [`BIP 68`](https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki): Sequence locks have been implemented as of **v0.12.1** ([PR #7184](https://github.com/bitcoin/bitcoin/pull/7184)), and have been activated since *block 419328*. * [`BIP 70`](https://github.com/bitcoin/bips/blob/master/bip-0070.mediawiki) [`71`](https://github.com/bitcoin/bips/blob/master/bip-0071.mediawiki) [`72`](https://github.com/bitcoin/bips/blob/master/bip-0072.mediawiki): Payment Protocol support has been available in Bitcoin Core GUI since **v0.9.0** ([PR #5216](https://github.com/bitcoin/bitcoin/pull/5216)). +* [`BIP 90`](https://github.com/bitcoin/bips/blob/master/bip-0090.mediawiki): Trigger mechanism for activation of BIPs 34, 65, and 66 has been simplified to block height checks since **v0.14.0** ([PR #8391](https://github.com/bitcoin/bitcoin/pull/8391)). * [`BIP 111`](https://github.com/bitcoin/bips/blob/master/bip-0111.mediawiki): `NODE_BLOOM` service bit added, and enforced for all peer versions as of **v0.13.0** ([PR #6579](https://github.com/bitcoin/bitcoin/pull/6579) and [PR #6641](https://github.com/bitcoin/bitcoin/pull/6641)). * [`BIP 112`](https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki): The CHECKSEQUENCEVERIFY opcode has been implemented since **v0.12.1** ([PR #7524](https://github.com/bitcoin/bitcoin/pull/7524)) and has been activated since *block 419328*. * [`BIP 113`](https://github.com/bitcoin/bips/blob/master/bip-0113.mediawiki): Median time past lock-time calculations have been implemented since **v0.12.1** ([PR #6566](https://github.com/bitcoin/bitcoin/pull/6566)) and have been activated since *block 419328*. diff --git a/doc/build-openbsd.md b/doc/build-openbsd.md index 55283d6dce..f4a9826d80 100644 --- a/doc/build-openbsd.md +++ b/doc/build-openbsd.md @@ -1,6 +1,6 @@ OpenBSD build guide ====================== -(updated for OpenBSD 5.9) +(updated for OpenBSD 6.0) This guide describes how to build bitcoind and command-line utilities on OpenBSD. @@ -124,7 +124,7 @@ To configure with wallet: ```bash ./configure --with-gui=no --with-boost=$BOOST_PREFIX \ CC=egcc CXX=eg++ CPP=ecpp \ - LDFLAGS="-L${BDB_PREFIX}/lib/" CPPFLAGS="-I${BDB_PREFIX}/include/" + BDB_LIBS="-L${BDB_PREFIX}/lib -ldb_cxx-4.8" BDB_CFLAGS="-I${BDB_PREFIX}/include" ``` To configure without wallet: @@ -142,6 +142,8 @@ gmake check Clang (not currently working) ------------------------------ +WARNING: This is outdated, needs to be updated for OpenBSD 6.0 and re-tried. + Using a newer g++ results in linking the new code to a new libstdc++. Libraries built with the old g++, will still import the old library. This gives conflicts, necessitating rebuild of all C++ dependencies of the application. diff --git a/doc/build-unix.md b/doc/build-unix.md index 5b0a38457e..31a88a1b18 100644 --- a/doc/build-unix.md +++ b/doc/build-unix.md @@ -315,7 +315,7 @@ For further documentation on the depends system see [README.md](../depends/READM Building on FreeBSD -------------------- -(Updated as of FreeBSD 10.3) +(Updated as of FreeBSD 11.0) Clang is installed by default as `cc` compiler, this makes it easier to get started than on [OpenBSD](build-openbsd.md). Installing dependencies: @@ -337,7 +337,7 @@ with 4.8-built Bitcoin Core is needed follow the steps under "Berkeley DB" above Then build using: ./autogen.sh - ./configure --with-incompatible-bdb CPPFLAGS=-I/usr/local/include/db5 LDFLAGS=-L/usr/local/lib/db5 + ./configure --with-incompatible-bdb BDB_CFLAGS="-I/usr/local/include/db5" BDB_LIBS="-L/usr/local/lib -ldb_cxx-5" make *Note on debugging*: The version of `gdb` installed by default is [ancient and considered harmful](https://wiki.freebsd.org/GdbRetirement). diff --git a/doc/developer-notes.md b/doc/developer-notes.md index f8c34e060f..3a7e4f73b3 100644 --- a/doc/developer-notes.md +++ b/doc/developer-notes.md @@ -4,10 +4,11 @@ Developer Notes Various coding styles have been used during the history of the codebase, and the result is not very consistent. However, we're now trying to converge to a single style, so please use it in new code. Old code will be converted -gradually. +gradually and you are encouraged to use the provided +[clang-format-diff script](/contrib/devtools/README.md#clang-format-diffpy) +to clean up the patch automatically before submitting a pull request. + - Basic rules specified in [src/.clang-format](/src/.clang-format). - Use a recent clang-format to format automatically using one of the [dev scripts] - (/contrib/devtools/README.md#clang-formatpy). - Braces on new lines for namespaces, classes, functions, methods. - Braces on the same line for everything else. - 4 space indentation (no tabs) for every block except namespaces. @@ -447,7 +448,7 @@ Current subtrees include: - Upstream at https://github.com/jgarzik/univalue ; report important PRs to Core to avoid delay. -Git and github tips +Git and GitHub tips --------------------- - For resolving merge/rebase conflicts, it can be useful to enable diff3 style using diff --git a/doc/man/Makefile.am b/doc/man/Makefile.am index 5252ef4a19..08ff4d6ac1 100644 --- a/doc/man/Makefile.am +++ b/doc/man/Makefile.am @@ -1 +1,13 @@ -dist_man1_MANS=bitcoind.1 bitcoin-qt.1 bitcoin-cli.1 bitcoin-tx.1 +dist_man1_MANS= + +if BUILD_BITCOIND + dist_man1_MANS+=bitcoind.1 +endif + +if ENABLE_QT + dist_man1_MANS+=bitcoin-qt.1 +endif + +if BUILD_BITCOIN_UTILS + dist_man1_MANS+=bitcoin-cli.1 bitcoin-tx.1 +endif diff --git a/doc/man/bitcoin-cli.1 b/doc/man/bitcoin-cli.1 index 11b690cf85..0493241b1e 100644 --- a/doc/man/bitcoin-cli.1 +++ b/doc/man/bitcoin-cli.1 @@ -1,19 +1,17 @@ -.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.46.5. -.TH BITCOIN-CLI "1" "September 2016" "bitcoin-cli v0.13.0.0" "User Commands" +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4. +.TH BITCOIN-CLI "1" "February 2017" "bitcoin-cli v0.14.99.0" "User Commands" .SH NAME -bitcoin-cli \- manual page for bitcoin-cli v0.13.0.0 +bitcoin-cli \- manual page for bitcoin-cli v0.14.99.0 .SH DESCRIPTION -Bitcoin Core RPC client version v0.13.0.0 +Bitcoin Core RPC client version v0.14.99.0 .SS "Usage:" .TP bitcoin\-cli [options] <command> [params] Send command to Bitcoin Core -.TP -bitcoin\-cli [options] help -List commands -.TP -bitcoin\-cli [options] help <command> -Get help for a command +.IP +bitcoin\-cli [options] \fB\-named\fR <command> [name=value] ... Send command to Bitcoin Core (with named arguments) +bitcoin\-cli [options] help List commands +bitcoin\-cli [options] help <command> Get help for a command .SH OPTIONS .HP \-? @@ -40,6 +38,10 @@ Enter regression test mode, which uses a special chain in which blocks can be solved instantly. This is intended for regression testing tools and app development. .HP +\fB\-named\fR +.IP +Pass named instead of positional arguments (default: false) +.HP \fB\-rpcconnect=\fR<ip> .IP Send commands to node running on <ip> (default: 127.0.0.1) @@ -69,7 +71,7 @@ Timeout during HTTP requests (default: 900) Read extra arguments from standard input, one per line until EOF/Ctrl\-D (recommended for sensitive information such as passphrases) .SH COPYRIGHT -Copyright (C) 2009-2016 The Bitcoin Core developers +Copyright (C) 2009-2017 The Bitcoin Core developers Please contribute if you find Bitcoin Core useful. Visit <https://bitcoincore.org> for further information about the software. @@ -77,8 +79,8 @@ The source code is available from <https://github.com/bitcoin/bitcoin>. This is experimental software. Distributed under the MIT software license, see the accompanying file COPYING -or <http://www.opensource.org/licenses/mit-license.php>. +or <https://opensource.org/licenses/MIT> 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. +OpenSSL Toolkit <https://www.openssl.org> and cryptographic software written by +Eric Young and UPnP software written by Thomas Bernard. diff --git a/doc/man/bitcoin-qt.1 b/doc/man/bitcoin-qt.1 index 2129a151e2..ce252612e5 100644 --- a/doc/man/bitcoin-qt.1 +++ b/doc/man/bitcoin-qt.1 @@ -1,9 +1,9 @@ -.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.46.5. -.TH BITCOIN-QT "1" "September 2016" "bitcoin-qt v0.13.0.0" "User Commands" +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4. +.TH BITCOIN-QT "1" "February 2017" "bitcoin-qt v0.14.99.0" "User Commands" .SH NAME -bitcoin-qt \- manual page for bitcoin-qt v0.13.0.0 +bitcoin-qt \- manual page for bitcoin-qt v0.14.99.0 .SH DESCRIPTION -Bitcoin Core version v0.13.0.0 (64\-bit) +Bitcoin Core version v0.14.99.0 (64\-bit) Usage: .IP bitcoin\-qt [command\-line options] @@ -27,13 +27,14 @@ long fork (%s in cmd is replaced by message) Execute command when the best block changes (%s in cmd is replaced by block hash) .HP -\fB\-checkblocks=\fR<n> +\fB\-assumevalid=\fR<hex> .IP -How many blocks to check at startup (default: 288, 0 = all) -.HP -\fB\-checklevel=\fR<n> -.IP -How thorough the block verification of \fB\-checkblocks\fR is (0\-4, default: 3) +If this block is in the chain assume that it and its ancestors are valid +and potentially skip their script verification (0 to verify all, +default: +00000000000000000013176bf8d7dfeab4e1db31dc93bc311b436e82ab226b90, +testnet: +00000000000128796ee387cf110ccb9d2f36cffaf7f73079c995377c65ac0dcc) .HP \fB\-conf=\fR<file> .IP @@ -62,11 +63,16 @@ Keep the transaction memory pool below <n> megabytes (default: 300) \fB\-mempoolexpiry=\fR<n> .IP Do not keep transactions in the mempool longer than <n> hours (default: -72) +336) +.HP +\fB\-blockreconstructionextratxn=\fR<n> +.IP +Extra transactions to keep in memory for compact block reconstructions +(default: 100) .HP \fB\-par=\fR<n> .IP -Set the number of script verification threads (\fB\-4\fR to 16, 0 = auto, <0 = +Set the number of script verification threads (\fB\-2\fR to 16, 0 = auto, <0 = leave that many cores free, default: 0) .HP \fB\-pid=\fR<file> @@ -75,13 +81,15 @@ Specify pid file (default: bitcoind.pid) .HP \fB\-prune=\fR<n> .IP -Reduce storage requirements by enabling pruning (deleting) of old blocks. -This allows the pruneblockchain RPC to be called to delete specific blocks, -and enables automatic pruning of old blocks if a target size in MiB is -provided. This mode is incompatible with \fB\-txindex\fR and \fB\-rescan\fR. -Warning: Reverting this setting requires re\-downloading the entire blockchain. -(default: 0 = disable pruning blocks, 1 = allow manual pruning via RPC, >550 = -automatically prune block files to stay under the specified target size in MiB) +Reduce storage requirements by enabling pruning (deleting) of old +blocks. This allows the pruneblockchain RPC to be called to +delete specific blocks, and enables automatic pruning of old +blocks if a target size in MiB is provided. This mode is +incompatible with \fB\-txindex\fR and \fB\-rescan\fR. Warning: Reverting this +setting requires re\-downloading the entire blockchain. (default: +0 = disable pruning blocks, 1 = allow manual pruning via RPC, +>550 = automatically prune block files to stay under the +specified target size in MiB) .HP \fB\-reindex\-chainstate\fR .IP @@ -123,7 +131,8 @@ for IPv6 .HP \fB\-connect=\fR<ip> .IP -Connect only to the specified node(s) +Connect only to the specified node(s); \fB\-noconnect\fR or \fB\-connect\fR=\fI\,0\/\fR alone to +disable automatic connections .HP \fB\-discover\fR .IP @@ -137,7 +146,7 @@ Allow DNS lookups for \fB\-addnode\fR, \fB\-seednode\fR and \fB\-connect\fR (def \fB\-dnsseed\fR .IP Query for peer addresses via DNS lookup, if low on addresses (default: 1 -unless \fB\-connect\fR) +unless \fB\-connect\fR/\-noconnect) .HP \fB\-externalip=\fR<ip> .IP @@ -149,7 +158,8 @@ Always query for peer addresses via DNS lookup (default: 0) .HP \fB\-listen\fR .IP -Accept connections from outside (default: 1 if no \fB\-proxy\fR or \fB\-connect\fR) +Accept connections from outside (default: 1 if no \fB\-proxy\fR or +\fB\-connect\fR/\-noconnect) .HP \fB\-listenonion\fR .IP @@ -204,6 +214,11 @@ Connect through SOCKS5 proxy Randomize credentials for every proxy connection. This enables Tor stream isolation (default: 1) .HP +\fB\-rpcserialversion\fR +.IP +Sets the serialization of raw transaction or block hex returned in +non\-verbose mode, non\-segwit(0) or segwit(1) (default: 1) +.HP \fB\-seednode=\fR<ip> .IP Connect to a node to retrieve peer addresses, and disconnect @@ -221,17 +236,22 @@ Tor control port to use if onion listening enabled (default: .IP Tor control port password (default: empty) .HP +\fB\-upnp\fR +.IP +Use UPnP to map the listening port (default: 0) +.HP \fB\-whitebind=\fR<addr> .IP Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6 .HP -\fB\-whitelist=\fR<netmask> +\fB\-whitelist=\fR<IP address or network> .IP -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 +Whitelist peers connecting from the given IP address (e.g. 1.2.3.4) or +CIDR notated network (e.g. 1.2.3.0/24). 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 .HP \fB\-whitelistrelay\fR .IP @@ -240,7 +260,7 @@ not relaying transactions (default: 1) .HP \fB\-whitelistforcerelay\fR .IP -Force relay of transactions from whitelisted peers even they violate +Force relay of transactions from whitelisted peers even if they violate local relay policy (default: 1) .HP \fB\-maxuploadtarget=\fR<n> @@ -287,13 +307,17 @@ Spend unconfirmed change when sending transactions (default: 1) \fB\-txconfirmtarget=\fR<n> .IP If paytxfee is not set, include enough fee so transactions begin -confirmation on average within n blocks (default: 2) +confirmation on average within n blocks (default: 6) .HP \fB\-usehd\fR .IP Use hierarchical deterministic key generation (HD) after BIP32. Only has effect during wallet creation/first start (default: 1) .HP +\fB\-walletrbf\fR +.IP +Send transactions with full\-RBF opt\-in enabled (default: 0) +.HP \fB\-upgradewallet\fR .IP Upgrade wallet to latest format on startup @@ -347,9 +371,9 @@ Append comment to the user agent string Output debugging information (default: 0, supplying <category> is optional). If <category> is not supplied or if <category> = 1, output all debugging information.<category> can be: addrman, -alert, bench, coindb, db, http, libevent, lock, mempool, -mempoolrej, net, proxy, prune, rand, reindex, rpc, selectcoins, -tor, zmq, qt. +alert, bench, cmpctblock, coindb, db, http, libevent, lock, +mempool, mempoolrej, net, proxy, prune, rand, reindex, rpc, +selectcoins, tor, zmq, qt. .HP \fB\-help\-debug\fR .IP @@ -422,6 +446,11 @@ Set maximum block size in bytes (default: 750000) .IP Set maximum size of high\-priority/low\-fee transactions in bytes (default: 0) +.HP +\fB\-blockmintxfee=\fR<amt> +.IP +Set lowest fee rate (in BTC/kB) for transactions to be included in block +creation. (default: 0.00001) .PP RPC server options: .HP @@ -455,8 +484,10 @@ Password for JSON\-RPC connections .IP 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 +canonical python script is included in share/rpcuser. The client +then connects normally using the +rpcuser=<USERNAME>/rpcpassword=<PASSWORD> pair of arguments. This +option can be specified multiple times .HP \fB\-rpcport=\fR<port> .IP @@ -500,7 +531,7 @@ Show splash screen on startup (default: 1) .IP Reset all settings changed in the GUI .SH COPYRIGHT -Copyright (C) 2009-2016 The Bitcoin Core developers +Copyright (C) 2009-2017 The Bitcoin Core developers Please contribute if you find Bitcoin Core useful. Visit <https://bitcoincore.org> for further information about the software. @@ -508,8 +539,8 @@ The source code is available from <https://github.com/bitcoin/bitcoin>. This is experimental software. Distributed under the MIT software license, see the accompanying file COPYING -or <http://www.opensource.org/licenses/mit-license.php>. +or <https://opensource.org/licenses/MIT> 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. +OpenSSL Toolkit <https://www.openssl.org> and cryptographic software written by +Eric Young and UPnP software written by Thomas Bernard. diff --git a/doc/man/bitcoin-tx.1 b/doc/man/bitcoin-tx.1 index 5c4e31e7f7..98adf2f5b1 100644 --- a/doc/man/bitcoin-tx.1 +++ b/doc/man/bitcoin-tx.1 @@ -1,9 +1,9 @@ -.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.46.5. -.TH BITCOIN-TX "1" "September 2016" "bitcoin-tx v0.13.0.0" "User Commands" +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4. +.TH BITCOIN-TX "1" "February 2017" "bitcoin-tx v0.14.99.0" "User Commands" .SH NAME -bitcoin-tx \- manual page for bitcoin-tx v0.13.0.0 +bitcoin-tx \- manual page for bitcoin-tx v0.14.99.0 .SH DESCRIPTION -Bitcoin Core bitcoin\-tx utility version v0.13.0.0 +Bitcoin Core bitcoin\-tx utility version v0.14.99.0 .SS "Usage:" .TP bitcoin\-tx [options] <hex\-tx> [commands] @@ -67,13 +67,28 @@ outaddr=VALUE:ADDRESS .IP Add address\-based output to TX .IP +outpubkey=VALUE:PUBKEY[:FLAGS] +.IP +Add pay\-to\-pubkey output to TX. Optionally add the "W" flag to produce a +pay\-to\-witness\-pubkey\-hash output. Optionally add the "S" flag to +wrap the output in a pay\-to\-script\-hash. +.IP outdata=[VALUE:]DATA .IP Add data\-based output to TX .IP -outscript=VALUE:SCRIPT +outscript=VALUE:SCRIPT[:FLAGS] +.IP +Add raw script output to TX. Optionally add the "W" flag to produce a +pay\-to\-witness\-script\-hash output. Optionally add the "S" flag to +wrap the output in a pay\-to\-script\-hash. +.IP +outmultisig=VALUE:REQUIRED:PUBKEYS:PUBKEY1:PUBKEY2:....[:FLAGS] .IP -Add raw script output to TX +Add Pay To n\-of\-m Multi\-sig output to TX. n = REQUIRED, m = PUBKEYS. +Optionally add the "W" flag to produce a +pay\-to\-witness\-script\-hash output. Optionally add the "S" flag to +wrap the output in a pay\-to\-script\-hash. .IP sign=SIGHASH\-FLAGS .IP @@ -92,7 +107,7 @@ set=NAME:JSON\-STRING .IP Set register NAME to given JSON\-STRING .SH COPYRIGHT -Copyright (C) 2009-2016 The Bitcoin Core developers +Copyright (C) 2009-2017 The Bitcoin Core developers Please contribute if you find Bitcoin Core useful. Visit <https://bitcoincore.org> for further information about the software. @@ -100,8 +115,8 @@ The source code is available from <https://github.com/bitcoin/bitcoin>. This is experimental software. Distributed under the MIT software license, see the accompanying file COPYING -or <http://www.opensource.org/licenses/mit-license.php>. +or <https://opensource.org/licenses/MIT> 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. +OpenSSL Toolkit <https://www.openssl.org> and cryptographic software written by +Eric Young and UPnP software written by Thomas Bernard. diff --git a/doc/man/bitcoind.1 b/doc/man/bitcoind.1 index 47539d8131..fb066e0c6f 100644 --- a/doc/man/bitcoind.1 +++ b/doc/man/bitcoind.1 @@ -1,9 +1,9 @@ -.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.46.5. -.TH BITCOIND "1" "September 2016" "bitcoind v0.13.0.0" "User Commands" +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4. +.TH BITCOIND "1" "February 2017" "bitcoind v0.14.99.0" "User Commands" .SH NAME -bitcoind \- manual page for bitcoind v0.13.0.0 +bitcoind \- manual page for bitcoind v0.14.99.0 .SH DESCRIPTION -Bitcoin Core Daemon version v0.13.0.0 +Bitcoin Core Daemon version v0.14.99.0 .SS "Usage:" .TP bitcoind [options] @@ -28,13 +28,14 @@ long fork (%s in cmd is replaced by message) Execute command when the best block changes (%s in cmd is replaced by block hash) .HP -\fB\-checkblocks=\fR<n> +\fB\-assumevalid=\fR<hex> .IP -How many blocks to check at startup (default: 288, 0 = all) -.HP -\fB\-checklevel=\fR<n> -.IP -How thorough the block verification of \fB\-checkblocks\fR is (0\-4, default: 3) +If this block is in the chain assume that it and its ancestors are valid +and potentially skip their script verification (0 to verify all, +default: +00000000000000000013176bf8d7dfeab4e1db31dc93bc311b436e82ab226b90, +testnet: +00000000000128796ee387cf110ccb9d2f36cffaf7f73079c995377c65ac0dcc) .HP \fB\-conf=\fR<file> .IP @@ -67,11 +68,16 @@ Keep the transaction memory pool below <n> megabytes (default: 300) \fB\-mempoolexpiry=\fR<n> .IP Do not keep transactions in the mempool longer than <n> hours (default: -72) +336) +.HP +\fB\-blockreconstructionextratxn=\fR<n> +.IP +Extra transactions to keep in memory for compact block reconstructions +(default: 100) .HP \fB\-par=\fR<n> .IP -Set the number of script verification threads (\fB\-4\fR to 16, 0 = auto, <0 = +Set the number of script verification threads (\fB\-2\fR to 16, 0 = auto, <0 = leave that many cores free, default: 0) .HP \fB\-pid=\fR<file> @@ -80,13 +86,15 @@ Specify pid file (default: bitcoind.pid) .HP \fB\-prune=\fR<n> .IP -Reduce storage requirements by enabling pruning (deleting) of old blocks. -This allows the pruneblockchain RPC to be called to delete specific blocks, -and enables automatic pruning of old blocks if a target size in MiB is -provided. This mode is incompatible with \fB\-txindex\fR and \fB\-rescan\fR. -Warning: Reverting this setting requires re\-downloading the entire blockchain. -(default: 0 = disable pruning blocks, 1 = allow manual pruning via RPC, >550 = -automatically prune block files to stay under the specified target size in MiB) +Reduce storage requirements by enabling pruning (deleting) of old +blocks. This allows the pruneblockchain RPC to be called to +delete specific blocks, and enables automatic pruning of old +blocks if a target size in MiB is provided. This mode is +incompatible with \fB\-txindex\fR and \fB\-rescan\fR. Warning: Reverting this +setting requires re\-downloading the entire blockchain. (default: +0 = disable pruning blocks, 1 = allow manual pruning via RPC, +>550 = automatically prune block files to stay under the +specified target size in MiB) .HP \fB\-reindex\-chainstate\fR .IP @@ -128,7 +136,8 @@ for IPv6 .HP \fB\-connect=\fR<ip> .IP -Connect only to the specified node(s) +Connect only to the specified node(s); \fB\-noconnect\fR or \fB\-connect\fR=\fI\,0\/\fR alone to +disable automatic connections .HP \fB\-discover\fR .IP @@ -142,7 +151,7 @@ Allow DNS lookups for \fB\-addnode\fR, \fB\-seednode\fR and \fB\-connect\fR (def \fB\-dnsseed\fR .IP Query for peer addresses via DNS lookup, if low on addresses (default: 1 -unless \fB\-connect\fR) +unless \fB\-connect\fR/\-noconnect) .HP \fB\-externalip=\fR<ip> .IP @@ -154,7 +163,8 @@ Always query for peer addresses via DNS lookup (default: 0) .HP \fB\-listen\fR .IP -Accept connections from outside (default: 1 if no \fB\-proxy\fR or \fB\-connect\fR) +Accept connections from outside (default: 1 if no \fB\-proxy\fR or +\fB\-connect\fR/\-noconnect) .HP \fB\-listenonion\fR .IP @@ -209,6 +219,11 @@ Connect through SOCKS5 proxy Randomize credentials for every proxy connection. This enables Tor stream isolation (default: 1) .HP +\fB\-rpcserialversion\fR +.IP +Sets the serialization of raw transaction or block hex returned in +non\-verbose mode, non\-segwit(0) or segwit(1) (default: 1) +.HP \fB\-seednode=\fR<ip> .IP Connect to a node to retrieve peer addresses, and disconnect @@ -226,17 +241,22 @@ Tor control port to use if onion listening enabled (default: .IP Tor control port password (default: empty) .HP +\fB\-upnp\fR +.IP +Use UPnP to map the listening port (default: 0) +.HP \fB\-whitebind=\fR<addr> .IP Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6 .HP -\fB\-whitelist=\fR<netmask> +\fB\-whitelist=\fR<IP address or network> .IP -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 +Whitelist peers connecting from the given IP address (e.g. 1.2.3.4) or +CIDR notated network (e.g. 1.2.3.0/24). 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 .HP \fB\-whitelistrelay\fR .IP @@ -245,7 +265,7 @@ not relaying transactions (default: 1) .HP \fB\-whitelistforcerelay\fR .IP -Force relay of transactions from whitelisted peers even they violate +Force relay of transactions from whitelisted peers even if they violate local relay policy (default: 1) .HP \fB\-maxuploadtarget=\fR<n> @@ -292,13 +312,17 @@ Spend unconfirmed change when sending transactions (default: 1) \fB\-txconfirmtarget=\fR<n> .IP If paytxfee is not set, include enough fee so transactions begin -confirmation on average within n blocks (default: 2) +confirmation on average within n blocks (default: 6) .HP \fB\-usehd\fR .IP Use hierarchical deterministic key generation (HD) after BIP32. Only has effect during wallet creation/first start (default: 1) .HP +\fB\-walletrbf\fR +.IP +Send transactions with full\-RBF opt\-in enabled (default: 0) +.HP \fB\-upgradewallet\fR .IP Upgrade wallet to latest format on startup @@ -352,9 +376,9 @@ Append comment to the user agent string Output debugging information (default: 0, supplying <category> is optional). If <category> is not supplied or if <category> = 1, output all debugging information.<category> can be: addrman, -alert, bench, coindb, db, http, libevent, lock, mempool, -mempoolrej, net, proxy, prune, rand, reindex, rpc, selectcoins, -tor, zmq. +alert, bench, cmpctblock, coindb, db, http, libevent, lock, +mempool, mempoolrej, net, proxy, prune, rand, reindex, rpc, +selectcoins, tor, zmq. .HP \fB\-help\-debug\fR .IP @@ -427,6 +451,11 @@ Set maximum block size in bytes (default: 750000) .IP Set maximum size of high\-priority/low\-fee transactions in bytes (default: 0) +.HP +\fB\-blockmintxfee=\fR<amt> +.IP +Set lowest fee rate (in BTC/kB) for transactions to be included in block +creation. (default: 0.00001) .PP RPC server options: .HP @@ -460,8 +489,10 @@ Password for JSON\-RPC connections .IP 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 +canonical python script is included in share/rpcuser. The client +then connects normally using the +rpcuser=<USERNAME>/rpcpassword=<PASSWORD> pair of arguments. This +option can be specified multiple times .HP \fB\-rpcport=\fR<port> .IP @@ -479,7 +510,7 @@ option can be specified multiple times .IP Set the number of threads to service RPC calls (default: 4) .SH COPYRIGHT -Copyright (C) 2009-2016 The Bitcoin Core developers +Copyright (C) 2009-2017 The Bitcoin Core developers Please contribute if you find Bitcoin Core useful. Visit <https://bitcoincore.org> for further information about the software. @@ -487,8 +518,8 @@ The source code is available from <https://github.com/bitcoin/bitcoin>. This is experimental software. Distributed under the MIT software license, see the accompanying file COPYING -or <http://www.opensource.org/licenses/mit-license.php>. +or <https://opensource.org/licenses/MIT> 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. +OpenSSL Toolkit <https://www.openssl.org> and cryptographic software written by +Eric Young and UPnP software written by Thomas Bernard. diff --git a/doc/release-notes.md b/doc/release-notes.md index 0ea9e1949e..eaa0b330eb 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -33,117 +33,6 @@ frequently tested on them. Notable changes =============== -Low-level RPC changes ----------------------- - -- `importprunedfunds` only accepts two required arguments. Some versions accept - an optional third arg, which was always ignored. Make sure to never pass more - than two arguments. - -Fee Estimation Changes ----------------------- - -- Since 0.13.2 fee estimation for a confirmation target of 1 block has been - disabled. This is only a minor behavior change as there was often insufficient - data for this target anyway. `estimatefee 1` will now always return -1 and - `estimatesmartfee 1` will start searching at a target of 2. - -- The default target for fee estimation is changed to 6 blocks in both the GUI - (previously 25) and for RPC calls (previously 2). - -Removal of Priority Estimation -------------------------------- - -- Estimation of "priority" needed for a transaction to be included within a target - number of blocks has been removed. The rpc calls are deprecated and will either - return -1 or 1e24 appropriately. The format for `fee_estimates.dat` has also - changed to no longer save these priority estimates. It will automatically be - converted to the new format which is not readable by prior versions of the - software. - -- The concept of "priority" (coin age) transactions is planned to be removed in - the next major version. To prepare for this, the default for the rate limit of - priority transactions (`-limitfreerelay`) has been set to `0` kB/minute. This - is not to be confused with the `prioritisetransaction` RPC which will remain - supported for adding fee deltas to transactions. - -P2P connection management --------------------------- - -- Peers manually added through the addnode option or addnode RPC now have their own - limit of eight connections which does not compete with other inbound or outbound - connection usage and is not subject to the maxconnections limitation. - -- New connections to manually added peers are much faster. - -Introduction of assumed-valid blocks -------------------------------------- - -- A significant portion of the initial block download time is spent verifying - scripts/signatures. Although the verification must pass to ensure the security - of the system, no other result from this verification is needed: If the node - knew the history of a given block were valid it could skip checking scripts - for its ancestors. - -- A new configuration option 'assumevalid' is provided to express this knowledge - to the software. Unlike the 'checkpoints' in the past this setting does not - force the use of a particular chain: chains that are consistent with it are - processed quicker, but other chains are still accepted if they'd otherwise - be chosen as best. Also unlike 'checkpoints' the user can configure which - block history is assumed true, this means that even outdated software can - sync more quickly if the setting is updated by the user. - -- Because the validity of a chain history is a simple objective fact it is much - easier to review this setting. As a result the software ships with a default - value adjusted to match the current chain shortly before release. The use - of this default value can be disabled by setting -assumevalid=0 - -0.14.0 Change log -================= - -Detailed release notes follow. This overview includes changes that affect -behavior, not code moves, refactors and string updates. For convenience in locating -the code changes and accompanying discussion, both the pull request and -git merge commit are mentioned. - -### RPC and REST - -UTXO set query (`GET /rest/getutxos/<checkmempool>/<txid>-<n>/<txid>-<n>/.../<txid>-<n>.<bin|hex|json>`) responses -were changed to return status code HTTP_BAD_REQUEST (400) instead of HTTP_INTERNAL_SERVER_ERROR (500) when requests -contain invalid parameters. - -The first boolean argument to `getaddednodeinfo` has been removed. This is an incompatible change. - -Call "getmininginfo" loses the "testnet" field in favor of the more generic "chain" (which has been present for years). - -### Configuration and command-line options - -### Block and transaction handling - -### P2P protocol and network code - -### Validation - -### Build system - -### Wallet - -0.14.0 Fundrawtransaction change address reuse -============================================== - -Before 0.14, `fundrawtransaction` was by default wallet stateless. In almost all cases `fundrawtransaction` does add a change-output to the outputs of the funded transaction. Before 0.14, the used keypool key was never marked as change-address key and directly returned to the keypool (leading to address reuse). -Before 0.14, calling `getnewaddress` directly after `fundrawtransaction` did generate the same address as the change-output address. - -Since 0.14, fundrawtransaction does reserve the change-output-key from the keypool by default (optional by setting `reserveChangeKey`, default = `true`) - -Users should also consider using `getrawchangeaddress()` in conjunction with `fundrawtransaction`'s `changeAddress` option. - -### GUI - -### Tests - -### Miscellaneous - Credits ======= diff --git a/doc/translation_process.md b/doc/translation_process.md index 9e9ced2457..1702637d53 100644 --- a/doc/translation_process.md +++ b/doc/translation_process.md @@ -4,7 +4,7 @@ Translations The Bitcoin-Core project has been designed to support multiple localisations. This makes adding new phrases, and completely new languages easily achievable. For managing all application translations, Bitcoin-Core makes use of the Transifex online translation management tool. ### Helping to translate (using Transifex) -Transifex is setup to monitor the Github repo for updates, and when code containing new translations is found, Transifex will process any changes. It may take several hours after a pull-request has been merged, to appear in the Transifex web interface. +Transifex is setup to monitor the GitHub repo for updates, and when code containing new translations is found, Transifex will process any changes. It may take several hours after a pull-request has been merged, to appear in the Transifex web interface. Multiple language support is critical in assisting Bitcoin’s global adoption, and growth. One of Bitcoin’s greatest strengths is cross-border money transfers, any help making that easier is greatly appreciated. @@ -32,7 +32,7 @@ QToolBar *toolbar = addToolBar(tr("Tabs toolbar")); ### Creating a pull-request For general PRs, you shouldn’t include any updates to the translation source files. They will be updated periodically, primarily around pre-releases, allowing time for any new phrases to be translated before public releases. This is also important in avoiding translation related merge conflicts. -When an updated source file is merged into the Github repo, Transifex will automatically detect it (although it can take several hours). Once processed, the new strings will show up as "Remaining" in the Transifex web interface and are ready for translators. +When an updated source file is merged into the GitHub repo, Transifex will automatically detect it (although it can take several hours). Once processed, the new strings will show up as "Remaining" in the Transifex web interface and are ready for translators. To create the pull-request, use the following commands: ``` diff --git a/doc/zmq.md b/doc/zmq.md index 6079e3254f..1019ff6653 100644 --- a/doc/zmq.md +++ b/doc/zmq.md @@ -1,4 +1,4 @@ -# Block and Transaction Broadcasting With ZeroMQ +# Block and Transaction Broadcasting with ZeroMQ [ZeroMQ](http://zeromq.org/) is a lightweight wrapper around TCP connections, inter-process communication, and shared-memory, @@ -50,7 +50,7 @@ during the *configure* step of building bitcoind: $ ./configure --disable-zmq (other options) To actually enable operation, one must set the appropriate options on -the commandline or in the configuration file. +the command line or in the configuration file. ## Usage diff --git a/qa/README.md b/qa/README.md index 225207cc1c..f4dce7af5c 100644 --- a/qa/README.md +++ b/qa/README.md @@ -39,12 +39,12 @@ Run the regression test suite with Run all possible tests with - qa/pull-tester/rpc-tests.py -extended + qa/pull-tester/rpc-tests.py --extended By default, tests will be run in parallel. To specify how many jobs to run, -append `-parallel=n` (default n=4). +append `--jobs=n` (default n=4). -If you want to create a basic coverage report for the rpc test suite, append `--coverage`. +If you want to create a basic coverage report for the RPC test suite, append `--coverage`. Possible options, which apply to each individual test run: @@ -83,5 +83,5 @@ killall bitcoind Writing tests ============= You are encouraged to write tests for new or existing features. -Further information about the test framework and individual rpc +Further information about the test framework and individual RPC tests is found in [qa/rpc-tests](/qa/rpc-tests). diff --git a/qa/pull-tester/rpc-tests.py b/qa/pull-tester/rpc-tests.py index 26bc6a73df..68e11b4c2b 100755 --- a/qa/pull-tester/rpc-tests.py +++ b/qa/pull-tester/rpc-tests.py @@ -2,25 +2,21 @@ # Copyright (c) 2014-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. - """ -Run Regression Test Suite +rpc-tests.py - run regression test suite This module calls down into individual test cases via subprocess. It will -forward all unrecognized arguments onto the individual test scripts, other -than: +forward all unrecognized arguments onto the individual test scripts. - - `-extended`: run the "extended" test suite in addition to the basic one. - - `-win`: signal that this is running in a Windows environment, and we - should run the tests. - - `--coverage`: this generates a basic coverage report for the RPC - interface. +RPC tests are disabled on Windows by default. Use --force to run them anyway. For a description of arguments recognized by test scripts, see `qa/pull-tester/test_framework/test_framework.py:BitcoinTestFramework.main`. """ +import argparse +import configparser import os import time import shutil @@ -29,77 +25,9 @@ import subprocess import tempfile import re -sys.path.append("qa/pull-tester/") -from tests_config import * - -BOLD = ("","") -if os.name == 'posix': - # primitive formatting on supported - # terminal via ANSI escape sequences: - BOLD = ('\033[0m', '\033[1m') - -RPC_TESTS_DIR = SRCDIR + '/qa/rpc-tests/' - -#If imported values are not defined then set to zero (or disabled) -if 'ENABLE_WALLET' not in vars(): - ENABLE_WALLET=0 -if 'ENABLE_BITCOIND' not in vars(): - ENABLE_BITCOIND=0 -if 'ENABLE_UTILS' not in vars(): - ENABLE_UTILS=0 -if 'ENABLE_ZMQ' not in vars(): - ENABLE_ZMQ=0 - -ENABLE_COVERAGE=0 - -#Create a set to store arguments and create the passon string -opts = set() -passon_args = [] -PASSON_REGEX = re.compile("^--") -PARALLEL_REGEX = re.compile('^-parallel=') - -print_help = False -run_parallel = 4 - -for arg in sys.argv[1:]: - if arg == "--help" or arg == "-h" or arg == "-?": - print_help = True - break - if arg == '--coverage': - ENABLE_COVERAGE = 1 - elif PASSON_REGEX.match(arg): - passon_args.append(arg) - elif PARALLEL_REGEX.match(arg): - run_parallel = int(arg.split(sep='=', maxsplit=1)[1]) - else: - opts.add(arg) - -#Set env vars -if "BITCOIND" not in os.environ: - os.environ["BITCOIND"] = BUILDDIR + '/src/bitcoind' + EXEEXT - -if EXEEXT == ".exe" and "-win" not in opts: - # https://github.com/bitcoin/bitcoin/commit/d52802551752140cf41f0d9a225a43e84404d3e9 - # https://github.com/bitcoin/bitcoin/pull/5677#issuecomment-136646964 - print("Win tests currently disabled by default. Use -win option to enable") - sys.exit(0) - -if not (ENABLE_WALLET == 1 and ENABLE_UTILS == 1 and ENABLE_BITCOIND == 1): - print("No rpc tests to run. Wallet, utils, and bitcoind must all be enabled") - sys.exit(0) - -# python3-zmq may not be installed. Handle this gracefully and with some helpful info -if ENABLE_ZMQ: - try: - import zmq - except ImportError: - print("ERROR: \"import zmq\" failed. Set ENABLE_ZMQ=0 or " - "to run zmq tests, see dependency info in /qa/README.md.") - # ENABLE_ZMQ=0 - raise - -testScripts = [ - # longest test should go first, to favor running tests in parallel +BASE_SCRIPTS= [ + # Scripts that are run by the travis build process. + # Longest test should go first, to favor running tests in parallel 'wallet-hd.py', 'walletbackup.py', # vv Tests less than 5m vv @@ -154,11 +82,17 @@ testScripts = [ 'bumpfee.py', 'rpcnamedargs.py', 'listsinceblock.py', + 'p2p-leaktests.py', ] -if ENABLE_ZMQ: - testScripts.append('zmq_test.py') -testScriptsExt = [ +ZMQ_SCRIPTS = [ + # ZMQ test can only be run if bitcoin was built with zmq-enabled. + # call rpc_tests.py with -nozmq to explicitly exclude these tests. + "zmq_test.py"] + +EXTENDED_SCRIPTS = [ + # These tests are not run by the travis build process. + # Longest test should go first, to favor running tests in parallel 'pruning.py', # vv Tests less than 20m vv 'smartfees.py', @@ -168,6 +102,7 @@ testScriptsExt = [ # vv Tests less than 2m vv 'bip68-sequence.py', 'getblocktemplate_longpoll.py', + 'p2p-timeouts.py', # vv Tests less than 60s vv 'bip9-softforks.py', 'p2p-feefilter.py', @@ -187,44 +122,131 @@ testScriptsExt = [ 'replace-by-fee.py', ] +ALL_SCRIPTS = BASE_SCRIPTS + ZMQ_SCRIPTS + EXTENDED_SCRIPTS + +def main(): + # Parse arguments and pass through unrecognised args + parser = argparse.ArgumentParser(add_help=False, + usage='%(prog)s [rpc-test.py options] [script options] [scripts]', + description=__doc__, + epilog=''' + Help text and arguments for individual test script:''', + formatter_class=argparse.RawTextHelpFormatter) + parser.add_argument('--coverage', action='store_true', help='generate a basic coverage report for the RPC interface') + parser.add_argument('--exclude', '-x', help='specify a comma-seperated-list of scripts to exclude. Do not include the .py extension in the name.') + parser.add_argument('--extended', action='store_true', help='run the extended test suite in addition to the basic tests') + parser.add_argument('--force', '-f', action='store_true', help='run tests even on platforms where they are disabled by default (e.g. windows).') + parser.add_argument('--help', '-h', '-?', action='store_true', help='print help text and exit') + parser.add_argument('--jobs', '-j', type=int, default=4, help='how many test scripts to run in parallel. Default=4.') + parser.add_argument('--nozmq', action='store_true', help='do not run the zmq tests') + args, unknown_args = parser.parse_known_args() + + # Create a set to store arguments and create the passon string + tests = set(arg for arg in unknown_args if arg[:2] != "--") + passon_args = [arg for arg in unknown_args if arg[:2] == "--"] + + # Read config generated by configure. + config = configparser.ConfigParser() + config.read_file(open(os.path.dirname(__file__) + "/tests_config.ini")) + + enable_wallet = config["components"].getboolean("ENABLE_WALLET") + enable_utils = config["components"].getboolean("ENABLE_UTILS") + enable_bitcoind = config["components"].getboolean("ENABLE_BITCOIND") + enable_zmq = config["components"].getboolean("ENABLE_ZMQ") and not args.nozmq + + if config["environment"]["EXEEXT"] == ".exe" and not args.force: + # https://github.com/bitcoin/bitcoin/commit/d52802551752140cf41f0d9a225a43e84404d3e9 + # https://github.com/bitcoin/bitcoin/pull/5677#issuecomment-136646964 + print("Tests currently disabled on Windows by default. Use --force option to enable") + sys.exit(0) -def runtests(): - test_list = [] - if '-extended' in opts: - test_list = testScripts + testScriptsExt - elif len(opts) == 0 or (len(opts) == 1 and "-win" in opts): - test_list = testScripts + if not (enable_wallet and enable_utils and enable_bitcoind): + print("No rpc tests to run. Wallet, utils, and bitcoind must all be enabled") + print("Rerun `configure` with -enable-wallet, -with-utils and -with-daemon and rerun make") + sys.exit(0) + + # python3-zmq may not be installed. Handle this gracefully and with some helpful info + if enable_zmq: + try: + import zmq + except ImportError: + print("ERROR: \"import zmq\" failed. Use -nozmq to run without the ZMQ tests." + "To run zmq tests, see dependency info in /qa/README.md.") + raise + + # Build list of tests + if tests: + # Individual tests have been specified. Run specified tests that exist + # in the ALL_SCRIPTS list. Accept the name with or without .py extension. + test_list = [t for t in ALL_SCRIPTS if + (t in tests or re.sub(".py$", "", t) in tests)] else: - for t in testScripts + testScriptsExt: - if t in opts or re.sub(".py$", "", t) in opts: - test_list.append(t) + # No individual tests have been specified. Run base tests, and + # optionally ZMQ tests and extended tests. + test_list = BASE_SCRIPTS + if enable_zmq: + test_list += ZMQ_SCRIPTS + if args.extended: + test_list += EXTENDED_SCRIPTS + # TODO: BASE_SCRIPTS and EXTENDED_SCRIPTS are sorted by runtime + # (for parallel running efficiency). This combined list will is no + # longer sorted. + + # Remove the test cases that the user has explicitly asked to exclude. + if args.exclude: + for exclude_test in args.exclude.split(','): + if exclude_test + ".py" in test_list: + test_list.remove(exclude_test + ".py") + + if not test_list: + print("No valid test scripts specified. Check that your test is in one " + "of the test lists in rpc-tests.py, or run rpc-tests.py with no arguments to run all tests") + sys.exit(0) - if print_help: - # Only print help of the first script and exit - subprocess.check_call((RPC_TESTS_DIR + test_list[0]).split() + ['-h']) + if args.help: + # Print help for rpc-tests.py, then print help of the first script and exit. + parser.print_help() + subprocess.check_call((config["environment"]["SRCDIR"] + '/qa/rpc-tests/' + test_list[0]).split() + ['-h']) sys.exit(0) - coverage = None + run_tests(test_list, config["environment"]["SRCDIR"], config["environment"]["BUILDDIR"], config["environment"]["EXEEXT"], args.jobs, args.coverage, passon_args) - if ENABLE_COVERAGE: +def run_tests(test_list, src_dir, build_dir, exeext, jobs=1, enable_coverage=False, args=[]): + BOLD = ("","") + if os.name == 'posix': + # primitive formatting on supported + # terminal via ANSI escape sequences: + BOLD = ('\033[0m', '\033[1m') + + #Set env vars + if "BITCOIND" not in os.environ: + os.environ["BITCOIND"] = build_dir + '/src/bitcoind' + exeext + + tests_dir = src_dir + '/qa/rpc-tests/' + + flags = ["--srcdir={}/src".format(build_dir)] + args + flags.append("--cachedir=%s/qa/cache" % build_dir) + + if enable_coverage: coverage = RPCCoverage() - print("Initializing coverage directory at %s\n" % coverage.dir) - flags = ["--srcdir=%s/src" % BUILDDIR] + passon_args - flags.append("--cachedir=%s/qa/cache" % BUILDDIR) - if coverage: flags.append(coverage.flag) + print("Initializing coverage directory at %s\n" % coverage.dir) + else: + coverage = None - if len(test_list) > 1 and run_parallel > 1: + if len(test_list) > 1 and jobs > 1: # Populate cache - subprocess.check_output([RPC_TESTS_DIR + 'create_cache.py'] + flags) + subprocess.check_output([tests_dir + 'create_cache.py'] + flags) #Run Tests - max_len_name = len(max(test_list, key=len)) + all_passed = True time_sum = 0 time0 = time.time() - job_queue = RPCTestHandler(run_parallel, test_list, flags) + + job_queue = RPCTestHandler(jobs, tests_dir, test_list, flags) + + max_len_name = len(max(test_list, key=len)) results = BOLD[1] + "%s | %s | %s\n\n" % ("TEST".ljust(max_len_name), "PASSED", "DURATION") + BOLD[0] - all_passed = True for _ in range(len(test_list)): (name, stdout, stderr, passed, duration) = job_queue.get_next() all_passed = all_passed and passed @@ -233,8 +255,10 @@ def runtests(): print('\n' + BOLD[1] + name + BOLD[0] + ":") print('' if passed else stdout + '\n', end='') print('' if stderr == '' else 'stderr:\n' + stderr + '\n', end='') - results += "%s | %s | %s s\n" % (name.ljust(max_len_name), str(passed).ljust(6), duration) print("Pass: %s%s%s, Duration: %s s\n" % (BOLD[1], passed, BOLD[0], duration)) + + results += "%s | %s | %s s\n" % (name.ljust(max_len_name), str(passed).ljust(6), duration) + results += BOLD[1] + "\n%s | %s | %s s (accumulated)" % ("ALL".ljust(max_len_name), str(all_passed).ljust(6), time_sum) + BOLD[0] print(results) print("\nRuntime: %s s" % (int(time.time() - time0))) @@ -247,15 +271,15 @@ def runtests(): sys.exit(not all_passed) - class RPCTestHandler: """ Trigger the testscrips passed in via the list. """ - def __init__(self, num_tests_parallel, test_list=None, flags=None): + def __init__(self, num_tests_parallel, tests_dir, test_list=None, flags=None): assert(num_tests_parallel >= 1) self.num_jobs = num_tests_parallel + self.tests_dir = tests_dir self.test_list = test_list self.flags = flags self.num_running = 0 @@ -275,7 +299,7 @@ class RPCTestHandler: log_stderr = tempfile.SpooledTemporaryFile(max_size=2**16) self.jobs.append((t, time.time(), - subprocess.Popen((RPC_TESTS_DIR + t).split() + self.flags + port_seed, + subprocess.Popen((self.tests_dir + t).split() + self.flags + port_seed, universal_newlines=True, stdout=log_stdout, stderr=log_stderr), @@ -340,10 +364,10 @@ class RPCCoverage(object): """ # This is shared from `qa/rpc-tests/test-framework/coverage.py` - REFERENCE_FILENAME = 'rpc_interface.txt' - COVERAGE_FILE_PREFIX = 'coverage.' + reference_filename = 'rpc_interface.txt' + coverage_file_prefix = 'coverage.' - coverage_ref_filename = os.path.join(self.dir, REFERENCE_FILENAME) + coverage_ref_filename = os.path.join(self.dir, reference_filename) coverage_filenames = set() all_cmds = set() covered_cmds = set() @@ -356,7 +380,7 @@ class RPCCoverage(object): for root, dirs, files in os.walk(self.dir): for filename in files: - if filename.startswith(COVERAGE_FILE_PREFIX): + if filename.startswith(coverage_file_prefix): coverage_filenames.add(os.path.join(root, filename)) for filename in coverage_filenames: @@ -367,4 +391,4 @@ class RPCCoverage(object): if __name__ == '__main__': - runtests() + main() diff --git a/qa/pull-tester/tests_config.ini.in b/qa/pull-tester/tests_config.ini.in new file mode 100644 index 0000000000..e3e457d0b1 --- /dev/null +++ b/qa/pull-tester/tests_config.ini.in @@ -0,0 +1,18 @@ +# Copyright (c) 2013-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. + +# These environment variables are set by the build process and read by +# rpc-tests.py + +[environment] +SRCDIR=@abs_top_srcdir@ +BUILDDIR=@abs_top_builddir@ +EXEEXT=@EXEEXT@ + +[components] +# Which components are enabled. These are commented out by `configure` if they were disabled when running config. +@ENABLE_WALLET_TRUE@ENABLE_WALLET=true +@BUILD_BITCOIN_UTILS_TRUE@ENABLE_UTILS=true +@BUILD_BITCOIND_TRUE@ENABLE_BITCOIND=true +@ENABLE_ZMQ_TRUE@ENABLE_ZMQ=true diff --git a/qa/pull-tester/tests_config.py.in b/qa/pull-tester/tests_config.py.in deleted file mode 100644 index a0d0a3d98a..0000000000 --- a/qa/pull-tester/tests_config.py.in +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env python3 -# Copyright (c) 2013-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. - -SRCDIR="@abs_top_srcdir@" -BUILDDIR="@abs_top_builddir@" -EXEEXT="@EXEEXT@" - -# These will turn into comments if they were disabled when configuring. -@ENABLE_WALLET_TRUE@ENABLE_WALLET=1 -@BUILD_BITCOIN_UTILS_TRUE@ENABLE_UTILS=1 -@BUILD_BITCOIND_TRUE@ENABLE_BITCOIND=1 -@ENABLE_ZMQ_TRUE@ENABLE_ZMQ=1 diff --git a/qa/rpc-tests/abandonconflict.py b/qa/rpc-tests/abandonconflict.py index 874df48777..b32d4e2ce0 100755 --- a/qa/rpc-tests/abandonconflict.py +++ b/qa/rpc-tests/abandonconflict.py @@ -2,7 +2,14 @@ # Copyright (c) 2014-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. - +"""Test the abandontransaction RPC. + + The abandontransaction RPC marks a transaction and all its in-wallet + descendants as abandoned which allows their inputs to be respent. It can be + used to replace "stuck" or evicted transactions. It only works on transactions + which are not included in a block and are not currently in the mempool. It has + no effect on transactions which are already conflicted or abandoned. +""" from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * diff --git a/qa/rpc-tests/assumevalid.py b/qa/rpc-tests/assumevalid.py index e4bc22951b..b8dafff161 100755 --- a/qa/rpc-tests/assumevalid.py +++ b/qa/rpc-tests/assumevalid.py @@ -2,8 +2,7 @@ # Copyright (c) 2014-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. -''' -assumevalid.py +"""Test logic for skipping signature validation on old blocks. Test logic for skipping signature validation on blocks which we've assumed valid (https://github.com/bitcoin/bitcoin/pull/9484) @@ -29,7 +28,7 @@ Start three nodes: - node2 has -assumevalid set to the hash of block 102. Try to sync to block 200. node2 will reject block 102 since it's assumed valid, but it isn't buried by at least two weeks' work. -''' +""" from test_framework.mininode import * from test_framework.test_framework import BitcoinTestFramework diff --git a/qa/rpc-tests/bip65-cltv-p2p.py b/qa/rpc-tests/bip65-cltv-p2p.py index e903b2fbf0..ea9c3d73ab 100755 --- a/qa/rpc-tests/bip65-cltv-p2p.py +++ b/qa/rpc-tests/bip65-cltv-p2p.py @@ -2,6 +2,19 @@ # Copyright (c) 2015-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. +"""Test BIP65 (CHECKLOCKTIMEVERIFY). + +Connect to a single node. +Mine 2 (version 3) blocks (save the coinbases for later). +Generate 98 more version 3 blocks, verify the node accepts. +Mine 749 version 4 blocks, verify the node accepts. +Check that the new CLTV rules are not enforced on the 750th version 4 block. +Check that the new CLTV rules are enforced on the 751st version 4 block. +Mine 199 new version blocks. +Mine 1 old-version block. +Mine 1 new version block. +Mine 1 old version block, see that the node rejects. +""" from test_framework.test_framework import ComparisonTestFramework from test_framework.util import * @@ -20,19 +33,6 @@ def cltv_invalidate(tx): tx.vin[0].scriptSig = CScript([OP_1NEGATE, OP_CHECKLOCKTIMEVERIFY, OP_DROP] + list(CScript(tx.vin[0].scriptSig))) -''' -This test is meant to exercise BIP65 (CHECKLOCKTIMEVERIFY) -Connect to a single node. -Mine 2 (version 3) blocks (save the coinbases for later). -Generate 98 more version 3 blocks, verify the node accepts. -Mine 749 version 4 blocks, verify the node accepts. -Check that the new CLTV rules are not enforced on the 750th version 4 block. -Check that the new CLTV rules are enforced on the 751st version 4 block. -Mine 199 new version blocks. -Mine 1 old-version block. -Mine 1 new version block. -Mine 1 old version block, see that the node rejects. -''' class BIP65Test(ComparisonTestFramework): diff --git a/qa/rpc-tests/bip65-cltv.py b/qa/rpc-tests/bip65-cltv.py index baa77b92a0..c9d02a98f3 100755 --- a/qa/rpc-tests/bip65-cltv.py +++ b/qa/rpc-tests/bip65-cltv.py @@ -2,10 +2,7 @@ # Copyright (c) 2015-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. - -# -# Test the CHECKLOCKTIMEVERIFY (BIP65) soft-fork logic -# +"""Test the CHECKLOCKTIMEVERIFY (BIP65) soft-fork logic.""" from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * diff --git a/qa/rpc-tests/bip68-112-113-p2p.py b/qa/rpc-tests/bip68-112-113-p2p.py index c96b746c9d..836267ea7f 100755 --- a/qa/rpc-tests/bip68-112-113-p2p.py +++ b/qa/rpc-tests/bip68-112-113-p2p.py @@ -2,18 +2,8 @@ # Copyright (c) 2015-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. +"""Test activation of the first version bits soft fork. -from test_framework.test_framework import ComparisonTestFramework -from test_framework.util import * -from test_framework.mininode import ToHex, CTransaction, NetworkThread -from test_framework.blocktools import create_coinbase, create_block -from test_framework.comptool import TestInstance, TestManager -from test_framework.script import * -from io import BytesIO -import time - -''' -This test is meant to exercise activation of the first version bits soft fork This soft fork will activate the following BIPS: BIP 68 - nSequence relative lock times BIP 112 - CHECKSEQUENCEVERIFY @@ -51,7 +41,16 @@ bip112txs_vary_nSequence_9 - 16 txs with nSequence relative_locktimes of 9 evalu bip112txs_vary_OP_CSV - 16 txs with nSequence = 10 evaluated against varying {relative_locktimes of 10} OP_CSV OP_DROP bip112txs_vary_OP_CSV_9 - 16 txs with nSequence = 9 evaluated against varying {relative_locktimes of 10} OP_CSV OP_DROP bip112tx_special - test negative argument to OP_CSV -''' +""" + +from test_framework.test_framework import ComparisonTestFramework +from test_framework.util import * +from test_framework.mininode import ToHex, CTransaction, NetworkThread +from test_framework.blocktools import create_coinbase, create_block +from test_framework.comptool import TestInstance, TestManager +from test_framework.script import * +from io import BytesIO +import time base_relative_locktime = 10 seq_disable_flag = 1<<31 diff --git a/qa/rpc-tests/bip68-sequence.py b/qa/rpc-tests/bip68-sequence.py index a12bf10ebd..74ac393fe9 100755 --- a/qa/rpc-tests/bip68-sequence.py +++ b/qa/rpc-tests/bip68-sequence.py @@ -2,15 +2,10 @@ # Copyright (c) 2014-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. - -# -# Test BIP68 implementation -# +"""Test BIP68 implementation.""" from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * -from test_framework.script import * -from test_framework.mininode import * from test_framework.blocktools import * SEQUENCE_LOCKTIME_DISABLE_FLAG = (1<<31) diff --git a/qa/rpc-tests/bip9-softforks.py b/qa/rpc-tests/bip9-softforks.py index 69a10cc8b4..70d4be3f69 100755 --- a/qa/rpc-tests/bip9-softforks.py +++ b/qa/rpc-tests/bip9-softforks.py @@ -2,20 +2,8 @@ # Copyright (c) 2015-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. +"""Test BIP 9 soft forks. -from test_framework.blockstore import BlockStore -from test_framework.test_framework import ComparisonTestFramework -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_CHECKSEQUENCEVERIFY, OP_DROP -from io import BytesIO -import time -import itertools - -''' -This test is meant to exercise BIP forks Connect to a single node. regtest lock-in with 108/144 block signalling activation after a further 144 blocks @@ -26,8 +14,18 @@ mine 108 blocks signalling readiness and 36 blocks not signalling readiness (STA mine a further 143 blocks (LOCKED_IN) test that enforcement has not triggered (which triggers ACTIVE) test that enforcement has triggered -''' +""" +from test_framework.blockstore import BlockStore +from test_framework.test_framework import ComparisonTestFramework +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_CHECKSEQUENCEVERIFY, OP_DROP +from io import BytesIO +import time +import itertools class BIP9SoftForksTest(ComparisonTestFramework): @@ -225,21 +223,21 @@ class BIP9SoftForksTest(ComparisonTestFramework): return def csv_invalidate(self, tx): - '''Modify the signature in vin 0 of the tx to fail CSV + """Modify the signature in vin 0 of the tx to fail CSV Prepends -1 CSV DROP in the scriptSig itself. - ''' + """ tx.vin[0].scriptSig = CScript([OP_1NEGATE, OP_CHECKSEQUENCEVERIFY, OP_DROP] + list(CScript(tx.vin[0].scriptSig))) def sequence_lock_invalidate(self, tx): - '''Modify the nSequence to make it fails once sequence lock rule is activated (high timespan) - ''' + """Modify the nSequence to make it fails once sequence lock rule is + activated (high timespan). + """ tx.vin[0].nSequence = 0x00FFFFFF tx.nLockTime = 0 def mtp_invalidate(self, tx): - '''Modify the nLockTime to make it fails once MTP rule is activated - ''' + """Modify the nLockTime to make it fails once MTP rule is activated.""" # Disable Sequence lock, Activate nLockTime tx.vin[0].nSequence = 0x90FFFFFF tx.nLockTime = self.last_block_time diff --git a/qa/rpc-tests/bipdersig-p2p.py b/qa/rpc-tests/bipdersig-p2p.py index 3bad5af5e6..b82ef89395 100755 --- a/qa/rpc-tests/bipdersig-p2p.py +++ b/qa/rpc-tests/bipdersig-p2p.py @@ -2,6 +2,19 @@ # Copyright (c) 2015-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. +"""Test BIP66 (DER SIG). + +Connect to a single node. +Mine 2 (version 2) blocks (save the coinbases for later). +Generate 98 more version 2 blocks, verify the node accepts. +Mine 749 version 3 blocks, verify the node accepts. +Check that the new DERSIG rules are not enforced on the 750th version 3 block. +Check that the new DERSIG rules are enforced on the 751st version 3 block. +Mine 199 new version blocks. +Mine 1 old-version block. +Mine 1 new version block. +Mine 1 old version block, see that the node rejects. +""" from test_framework.test_framework import ComparisonTestFramework from test_framework.util import * @@ -15,10 +28,10 @@ import time # A canonical signature consists of: # <30> <total len> <02> <len R> <R> <02> <len S> <S> <hashtype> def unDERify(tx): - ''' + """ Make the signature in vin 0 of a tx non-DER-compliant, by adding padding after the S-value. - ''' + """ scriptSig = CScript(tx.vin[0].scriptSig) newscript = [] for i in scriptSig: @@ -27,20 +40,6 @@ def unDERify(tx): else: newscript.append(i) tx.vin[0].scriptSig = CScript(newscript) - -''' -This test is meant to exercise BIP66 (DER SIG). -Connect to a single node. -Mine 2 (version 2) blocks (save the coinbases for later). -Generate 98 more version 2 blocks, verify the node accepts. -Mine 749 version 3 blocks, verify the node accepts. -Check that the new DERSIG rules are not enforced on the 750th version 3 block. -Check that the new DERSIG rules are enforced on the 751st version 3 block. -Mine 199 new version blocks. -Mine 1 old-version block. -Mine 1 new version block. -Mine 1 old version block, see that the node rejects. -''' class BIP66Test(ComparisonTestFramework): diff --git a/qa/rpc-tests/bipdersig.py b/qa/rpc-tests/bipdersig.py index 17c2ced79a..fa54bc2749 100755 --- a/qa/rpc-tests/bipdersig.py +++ b/qa/rpc-tests/bipdersig.py @@ -2,10 +2,7 @@ # Copyright (c) 2014-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. - -# -# Test the BIP66 changeover logic -# +"""Test the BIP66 changeover logic.""" from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * diff --git a/qa/rpc-tests/blockchain.py b/qa/rpc-tests/blockchain.py index 410b85d15e..67b5826840 100755 --- a/qa/rpc-tests/blockchain.py +++ b/qa/rpc-tests/blockchain.py @@ -2,11 +2,14 @@ # Copyright (c) 2014-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. +"""Test RPCs related to blockchainstate. -# -# Test RPC calls related to blockchain state. Tests correspond to code in -# rpc/blockchain.cpp. -# +Test the following RPCs: + - gettxoutsetinfo + - verifychain + +Tests correspond to code in rpc/blockchain.cpp. +""" from decimal import Decimal @@ -23,13 +26,6 @@ from test_framework.util import ( class BlockchainTest(BitcoinTestFramework): - """ - Test blockchain-related RPC calls: - - - gettxoutsetinfo - - verifychain - - """ def __init__(self): super().__init__() diff --git a/qa/rpc-tests/bumpfee.py b/qa/rpc-tests/bumpfee.py index 0ebd79f7f3..cc897a32c7 100755 --- a/qa/rpc-tests/bumpfee.py +++ b/qa/rpc-tests/bumpfee.py @@ -2,16 +2,15 @@ # 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. +"""Test the bumpfee RPC.""" from segwit import send_to_witness from test_framework.test_framework import BitcoinTestFramework from test_framework import blocktools from test_framework.mininode import CTransaction from test_framework.util import * -from test_framework.util import * import io -import time # Sequence number that is BIP 125 opt-in and BIP 68-compliant BIP125_SEQUENCE_NUMBER = 0xfffffffd @@ -69,6 +68,7 @@ class BumpFeeTest(BitcoinTestFramework): test_rebumping(rbf_node, dest_address) test_rebumping_not_replaceable(rbf_node, dest_address) test_unconfirmed_not_spendable(rbf_node, rbf_node_address) + test_bumpfee_metadata(rbf_node, dest_address) test_locked_wallet_fails(rbf_node, dest_address) print("Success") @@ -257,6 +257,14 @@ def test_unconfirmed_not_spendable(rbf_node, rbf_node_address): if t["txid"] == rbfid and t["address"] == rbf_node_address and t["spendable"]), 1) +def test_bumpfee_metadata(rbf_node, dest_address): + rbfid = rbf_node.sendtoaddress(dest_address, 0.00090000, "comment value", "to value") + bumped_tx = rbf_node.bumpfee(rbfid) + bumped_wtx = rbf_node.gettransaction(bumped_tx["txid"]) + assert_equal(bumped_wtx["comment"], "comment value") + assert_equal(bumped_wtx["to"], "to value") + + def test_locked_wallet_fails(rbf_node, dest_address): rbfid = create_fund_sign_send(rbf_node, {dest_address: 0.00090000}) rbf_node.walletlock() diff --git a/qa/rpc-tests/create_cache.py b/qa/rpc-tests/create_cache.py index 1ace6310d0..13eac92bbc 100755 --- a/qa/rpc-tests/create_cache.py +++ b/qa/rpc-tests/create_cache.py @@ -2,11 +2,12 @@ # 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. +"""Create a blockchain cache. -# -# Helper script to create the cache -# (see BitcoinTestFramework.setup_chain) -# +Creating a cache of the blockchain speeds up test execution when running +multiple qa tests. This helper script is executed by rpc-tests when multiple +tests are being run in parallel. +""" from test_framework.test_framework import BitcoinTestFramework diff --git a/qa/rpc-tests/decodescript.py b/qa/rpc-tests/decodescript.py index 24768c2655..5555e96c44 100755 --- a/qa/rpc-tests/decodescript.py +++ b/qa/rpc-tests/decodescript.py @@ -2,6 +2,7 @@ # Copyright (c) 2015-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. +"""Test decoding scripts via decodescript RPC command.""" from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * @@ -9,7 +10,6 @@ from test_framework.mininode import * from io import BytesIO class DecodeScriptTest(BitcoinTestFramework): - """Tests decoding scripts via RPC command "decodescript".""" def __init__(self): super().__init__() @@ -111,7 +111,7 @@ class DecodeScriptTest(BitcoinTestFramework): 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". + """Test decoding scripts via RPC command "decoderawtransaction". This test is in with the "decodescript" tests because they are testing the same "asm" script decodes. """ diff --git a/qa/rpc-tests/disablewallet.py b/qa/rpc-tests/disablewallet.py index 36c147edad..ff7121659b 100755 --- a/qa/rpc-tests/disablewallet.py +++ b/qa/rpc-tests/disablewallet.py @@ -2,10 +2,11 @@ # Copyright (c) 2015-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. +"""Test a node with the -disablewallet option. -# -# Exercise API with -disablewallet. -# +- Test that validateaddress RPC works when running with -disablewallet +- Test that it is not possible to mine to an invalid address. +""" from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * @@ -24,7 +25,6 @@ class DisableWalletTest (BitcoinTestFramework): self.sync_all() def run_test (self): - # Check regression: https://github.com/bitcoin/bitcoin/issues/6963#issuecomment-154548880 x = self.nodes[0].validateaddress('3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLy') assert(x['isvalid'] == False) x = self.nodes[0].validateaddress('mneYUmWYsuk7kySiURxCi3AGxrAqZxLgPZ') diff --git a/qa/rpc-tests/forknotify.py b/qa/rpc-tests/forknotify.py index a1901aedab..c2724ba5df 100755 --- a/qa/rpc-tests/forknotify.py +++ b/qa/rpc-tests/forknotify.py @@ -2,10 +2,7 @@ # Copyright (c) 2014-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. - -# -# Test -alertnotify -# +"""Test the -alertnotify option.""" from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * @@ -22,7 +19,7 @@ class ForkNotifyTest(BitcoinTestFramework): def setup_network(self): self.nodes = [] self.alert_filename = os.path.join(self.options.tmpdir, "alert.txt") - with open(self.alert_filename, 'w', encoding='utf8') as f: + with open(self.alert_filename, 'w', encoding='utf8'): pass # Just open then close to create zero-length file self.nodes.append(start_node(0, self.options.tmpdir, ["-blockversion=2", "-alertnotify=echo %s >> \"" + self.alert_filename + "\""])) diff --git a/qa/rpc-tests/fundrawtransaction.py b/qa/rpc-tests/fundrawtransaction.py index 7396ba46a4..7892e85e22 100755 --- a/qa/rpc-tests/fundrawtransaction.py +++ b/qa/rpc-tests/fundrawtransaction.py @@ -2,6 +2,7 @@ # Copyright (c) 2014-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. +"""Test the fundrawtransaction RPC.""" from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * @@ -469,7 +470,9 @@ class RawTransactionsTest(BitcoinTestFramework): # locked wallet test self.nodes[1].encryptwallet("test") self.nodes.pop(1) - stop_nodes(self.nodes) + stop_node(self.nodes[0], 0) + stop_node(self.nodes[1], 2) + stop_node(self.nodes[2], 3) self.nodes = start_nodes(self.num_nodes, self.options.tmpdir) # This test is not meant to test fee estimation and we'd like diff --git a/qa/rpc-tests/getblocktemplate_longpoll.py b/qa/rpc-tests/getblocktemplate_longpoll.py index 3cddf4046a..b73fea0695 100755 --- a/qa/rpc-tests/getblocktemplate_longpoll.py +++ b/qa/rpc-tests/getblocktemplate_longpoll.py @@ -2,6 +2,7 @@ # Copyright (c) 2014-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. +"""Test longpolling with getblocktemplate.""" from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * @@ -22,10 +23,6 @@ class LongpollThread(threading.Thread): self.node.getblocktemplate({'longpollid':self.longpollid}) class GetBlockTemplateLPTest(BitcoinTestFramework): - ''' - Test longpolling with getblocktemplate. - ''' - def __init__(self): super().__init__() self.num_nodes = 4 diff --git a/qa/rpc-tests/getblocktemplate_proposals.py b/qa/rpc-tests/getblocktemplate_proposals.py index 7a4f8f8fdc..3b17dfcfb5 100755 --- a/qa/rpc-tests/getblocktemplate_proposals.py +++ b/qa/rpc-tests/getblocktemplate_proposals.py @@ -2,6 +2,7 @@ # Copyright (c) 2014-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. +"""Test block proposals with getblocktemplate.""" from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * @@ -66,9 +67,6 @@ def assert_template(node, tmpl, txlist, expect): raise AssertionError('unexpected: %s' % (rsp,)) class GetBlockTemplateProposalTest(BitcoinTestFramework): - ''' - Test block proposals with getblocktemplate. - ''' def __init__(self): super().__init__() diff --git a/qa/rpc-tests/getchaintips.py b/qa/rpc-tests/getchaintips.py index 1c66b8c289..14222334a6 100755 --- a/qa/rpc-tests/getchaintips.py +++ b/qa/rpc-tests/getchaintips.py @@ -2,10 +2,13 @@ # Copyright (c) 2014-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. +"""Test the getchaintips RPC. -# Exercise the getchaintips API. We introduce a network split, work -# on chains of different lengths, and join the network together again. -# This gives us two tips, verify that it works. +- introduce a network split +- work on chains of different lengths +- join the network together again +- verify that getchaintips now returns two chain tips. +""" from test_framework.test_framework import BitcoinTestFramework from test_framework.util import assert_equal diff --git a/qa/rpc-tests/httpbasics.py b/qa/rpc-tests/httpbasics.py index 10bc927e1a..8f35f0ab87 100755 --- a/qa/rpc-tests/httpbasics.py +++ b/qa/rpc-tests/httpbasics.py @@ -2,10 +2,7 @@ # Copyright (c) 2014-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. - -# -# Test rpc http basics -# +"""Test the RPC HTTP basics.""" from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * diff --git a/qa/rpc-tests/import-rescan.py b/qa/rpc-tests/import-rescan.py index e683df26db..7ca61824c9 100755 --- a/qa/rpc-tests/import-rescan.py +++ b/qa/rpc-tests/import-rescan.py @@ -2,63 +2,126 @@ # Copyright (c) 2014-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. +"""Test wallet import RPCs. +Test rescan behavior of importaddress, importpubkey, importprivkey, and +importmulti RPCs with different types of keys and rescan options. + +In the first part of the test, node 1 creates an address for each type of +import RPC call and node 0 sends BTC to it. Then other nodes import the +addresses, and the test makes listtransactions and getbalance calls to confirm +that the importing node either did or did not execute rescans picking up the +send transactions. + +In the second part of the test, node 0 sends more BTC to each address, and the +test makes more listtransactions and getbalance calls to confirm that the +importing nodes pick up the new transactions regardless of whether rescans +happened previously. +""" + +from test_framework.authproxy import JSONRPCException from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import (start_nodes, connect_nodes, sync_blocks, assert_equal) +from test_framework.util import (start_nodes, connect_nodes, sync_blocks, assert_equal, set_node_times) from decimal import Decimal import collections import enum import itertools -import functools Call = enum.Enum("Call", "single multi") Data = enum.Enum("Data", "address pub priv") -ImportNode = collections.namedtuple("ImportNode", "rescan") - - -def call_import_rpc(call, data, address, scriptPubKey, pubkey, key, label, node, rescan): - """Helper that calls a wallet import RPC on a bitcoin node.""" - watchonly = data != Data.priv - if call == Call.single: - if data == Data.address: - response = node.importaddress(address, label, rescan) - elif data == Data.pub: - response = node.importpubkey(pubkey, label, rescan) - elif data == Data.priv: - response = node.importprivkey(key, label, rescan) - assert_equal(response, None) - elif call == Call.multi: - response = node.importmulti([{ - "scriptPubKey": { - "address": address - }, - "pubkeys": [pubkey] if data == Data.pub else [], - "keys": [key] if data == Data.priv else [], - "label": label, - "watchonly": watchonly - }], {"rescan": rescan}) - assert_equal(response, [{"success": True}]) - return watchonly - - -# List of RPCs that import a wallet key or address in various ways. -IMPORT_RPCS = [functools.partial(call_import_rpc, call, data) for call, data in itertools.product(Call, Data)] - -# List of bitcoind nodes that will import keys. -IMPORT_NODES = [ - ImportNode(rescan=True), - ImportNode(rescan=False), -] +Rescan = enum.Enum("Rescan", "no yes late_timestamp") + + +class Variant(collections.namedtuple("Variant", "call data rescan prune")): + """Helper for importing one key and verifying scanned transactions.""" + + def do_import(self, timestamp): + """Call one key import RPC.""" + + if self.call == Call.single: + if self.data == Data.address: + response, error = try_rpc(self.node.importaddress, self.address["address"], self.label, + self.rescan == Rescan.yes) + elif self.data == Data.pub: + response, error = try_rpc(self.node.importpubkey, self.address["pubkey"], self.label, + self.rescan == Rescan.yes) + elif self.data == Data.priv: + response, error = try_rpc(self.node.importprivkey, self.key, self.label, self.rescan == Rescan.yes) + assert_equal(response, None) + assert_equal(error, {'message': 'Rescan is disabled in pruned mode', + 'code': -4} if self.expect_disabled else None) + elif self.call == Call.multi: + response = self.node.importmulti([{ + "scriptPubKey": { + "address": self.address["address"] + }, + "timestamp": timestamp + RESCAN_WINDOW + (1 if self.rescan == Rescan.late_timestamp else 0), + "pubkeys": [self.address["pubkey"]] if self.data == Data.pub else [], + "keys": [self.key] if self.data == Data.priv else [], + "label": self.label, + "watchonly": self.data != Data.priv + }], {"rescan": self.rescan in (Rescan.yes, Rescan.late_timestamp)}) + assert_equal(response, [{"success": True}]) + + def check(self, txid=None, amount=None, confirmations=None): + """Verify that getbalance/listtransactions return expected values.""" + + balance = self.node.getbalance(self.label, 0, True) + assert_equal(balance, self.expected_balance) + + txs = self.node.listtransactions(self.label, 10000, 0, True) + assert_equal(len(txs), self.expected_txs) + + if txid is not None: + tx, = [tx for tx in txs if tx["txid"] == txid] + assert_equal(tx["account"], self.label) + assert_equal(tx["address"], self.address["address"]) + assert_equal(tx["amount"], amount) + assert_equal(tx["category"], "receive") + assert_equal(tx["label"], self.label) + assert_equal(tx["txid"], txid) + assert_equal(tx["confirmations"], confirmations) + assert_equal("trusted" not in tx, True) + # Verify the transaction is correctly marked watchonly depending on + # whether the transaction pays to an imported public key or + # imported private key. The test setup ensures that transaction + # inputs will not be from watchonly keys (important because + # involvesWatchonly will be true if either the transaction output + # or inputs are watchonly). + if self.data != Data.priv: + assert_equal(tx["involvesWatchonly"], True) + else: + assert_equal("involvesWatchonly" not in tx, True) + + +# List of Variants for each way a key or address could be imported. +IMPORT_VARIANTS = [Variant(*variants) for variants in itertools.product(Call, Data, Rescan, (False, True))] + +# List of nodes to import keys to. Half the nodes will have pruning disabled, +# half will have it enabled. Different nodes will be used for imports that are +# expected to cause rescans, and imports that are not expected to cause +# rescans, in order to prevent rescans during later imports picking up +# transactions associated with earlier imports. This makes it easier to keep +# track of expected balances and transactions. +ImportNode = collections.namedtuple("ImportNode", "prune rescan") +IMPORT_NODES = [ImportNode(*fields) for fields in itertools.product((False, True), repeat=2)] + +# Rescans start at the earliest block up to 2 hours before the key timestamp. +RESCAN_WINDOW = 2 * 60 * 60 class ImportRescanTest(BitcoinTestFramework): def __init__(self): super().__init__() - self.num_nodes = 1 + len(IMPORT_NODES) + self.num_nodes = 2 + len(IMPORT_NODES) def setup_network(self): extra_args = [["-debug=1"] for _ in range(self.num_nodes)] + for i, import_node in enumerate(IMPORT_NODES, 2): + if import_node.prune: + extra_args[i] += ["-prune=1"] + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, extra_args) for i in range(1, self.num_nodes): connect_nodes(self.nodes[i], 0) @@ -66,89 +129,64 @@ class ImportRescanTest(BitcoinTestFramework): def run_test(self): # Create one transaction on node 0 with a unique amount and label for # each possible type of wallet import RPC. - import_rpc_variants = [] - for i, import_rpc in enumerate(IMPORT_RPCS): - label = "label{}".format(i) - addr = self.nodes[0].validateaddress(self.nodes[0].getnewaddress(label)) - key = self.nodes[0].dumpprivkey(addr["address"]) - amount = 24.9375 - i * .0625 - txid = self.nodes[0].sendtoaddress(addr["address"], amount) - import_rpc = functools.partial(import_rpc, addr["address"], addr["scriptPubKey"], addr["pubkey"], key, - label) - import_rpc_variants.append((import_rpc, label, amount, txid, addr)) - + for i, variant in enumerate(IMPORT_VARIANTS): + variant.label = "label {} {}".format(i, variant) + variant.address = self.nodes[1].validateaddress(self.nodes[1].getnewaddress(variant.label)) + variant.key = self.nodes[1].dumpprivkey(variant.address["address"]) + variant.initial_amount = 10 - (i + 1) / 4.0 + variant.initial_txid = self.nodes[0].sendtoaddress(variant.address["address"], variant.initial_amount) + + # Generate a block containing the initial transactions, then another + # block further in the future (past the rescan window). self.nodes[0].generate(1) assert_equal(self.nodes[0].getrawmempool(), []) + timestamp = self.nodes[0].getblockheader(self.nodes[0].getbestblockhash())["time"] + set_node_times(self.nodes, timestamp + RESCAN_WINDOW + 1) + self.nodes[0].generate(1) sync_blocks(self.nodes) - # For each importing node and variation of wallet import RPC, invoke - # the RPC and check the results from getbalance and listtransactions. - for node, import_node in zip(self.nodes[1:], IMPORT_NODES): - for import_rpc, label, amount, txid, addr in import_rpc_variants: - watchonly = import_rpc(node, import_node.rescan) - - balance = node.getbalance(label, 0, True) - if import_node.rescan: - assert_equal(balance, amount) - else: - assert_equal(balance, 0) - - txs = node.listtransactions(label, 10000, 0, True) - if import_node.rescan: - assert_equal(len(txs), 1) - assert_equal(txs[0]["account"], label) - assert_equal(txs[0]["address"], addr["address"]) - assert_equal(txs[0]["amount"], amount) - assert_equal(txs[0]["category"], "receive") - assert_equal(txs[0]["label"], label) - assert_equal(txs[0]["txid"], txid) - assert_equal(txs[0]["confirmations"], 1) - assert_equal("trusted" not in txs[0], True) - if watchonly: - assert_equal(txs[0]["involvesWatchonly"], True) - else: - assert_equal("involvesWatchonly" not in txs[0], True) - else: - assert_equal(len(txs), 0) - - # Create spends for all the imported addresses. - spend_txids = [] + # For each variation of wallet key import, invoke the import RPC and + # check the results from getbalance and listtransactions. + for variant in IMPORT_VARIANTS: + variant.expect_disabled = variant.rescan == Rescan.yes and variant.prune and variant.call == Call.single + expect_rescan = variant.rescan == Rescan.yes and not variant.expect_disabled + variant.node = self.nodes[2 + IMPORT_NODES.index(ImportNode(variant.prune, expect_rescan))] + variant.do_import(timestamp) + if expect_rescan: + variant.expected_balance = variant.initial_amount + variant.expected_txs = 1 + variant.check(variant.initial_txid, variant.initial_amount, 2) + else: + variant.expected_balance = 0 + variant.expected_txs = 0 + variant.check() + + # Create new transactions sending to each address. fee = self.nodes[0].getnetworkinfo()["relayfee"] - for import_rpc, label, amount, txid, addr in import_rpc_variants: - raw_tx = self.nodes[0].getrawtransaction(txid) - decoded_tx = self.nodes[0].decoderawtransaction(raw_tx) - input_vout = next(out["n"] for out in decoded_tx["vout"] - if out["scriptPubKey"]["addresses"] == [addr["address"]]) - inputs = [{"txid": txid, "vout": input_vout}] - outputs = {self.nodes[0].getnewaddress(): Decimal(amount) - fee} - raw_spend_tx = self.nodes[0].createrawtransaction(inputs, outputs) - signed_spend_tx = self.nodes[0].signrawtransaction(raw_spend_tx) - spend_txid = self.nodes[0].sendrawtransaction(signed_spend_tx["hex"]) - spend_txids.append(spend_txid) + for i, variant in enumerate(IMPORT_VARIANTS): + variant.sent_amount = 10 - (2 * i + 1) / 8.0 + variant.sent_txid = self.nodes[0].sendtoaddress(variant.address["address"], variant.sent_amount) + # Generate a block containing the new transactions. self.nodes[0].generate(1) assert_equal(self.nodes[0].getrawmempool(), []) sync_blocks(self.nodes) - # Check the results from getbalance and listtransactions after the spends. - for node, import_node in zip(self.nodes[1:], IMPORT_NODES): - txs = node.listtransactions("*", 10000, 0, True) - for (import_rpc, label, amount, txid, addr), spend_txid in zip(import_rpc_variants, spend_txids): - balance = node.getbalance(label, 0, True) - spend_tx = [tx for tx in txs if tx["txid"] == spend_txid] - if import_node.rescan: - assert_equal(balance, amount) - assert_equal(len(spend_tx), 1) - assert_equal(spend_tx[0]["account"], "") - assert_equal(spend_tx[0]["amount"] + spend_tx[0]["fee"], -amount) - assert_equal(spend_tx[0]["category"], "send") - assert_equal("label" not in spend_tx[0], True) - assert_equal(spend_tx[0]["confirmations"], 1) - assert_equal("trusted" not in spend_tx[0], True) - assert_equal("involvesWatchonly" not in txs[0], True) - else: - assert_equal(balance, 0) - assert_equal(spend_tx, []) + # Check the latest results from getbalance and listtransactions. + for variant in IMPORT_VARIANTS: + if not variant.expect_disabled: + variant.expected_balance += variant.sent_amount + variant.expected_txs += 1 + variant.check(variant.sent_txid, variant.sent_amount, 1) + else: + variant.check() + + +def try_rpc(func, *args, **kwargs): + try: + return func(*args, **kwargs), None + except JSONRPCException as e: + return None, e.error if __name__ == "__main__": diff --git a/qa/rpc-tests/importmulti.py b/qa/rpc-tests/importmulti.py index e100a3af9d..015336effe 100755 --- a/qa/rpc-tests/importmulti.py +++ b/qa/rpc-tests/importmulti.py @@ -2,7 +2,7 @@ # Copyright (c) 2014-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. - +"""Test the importmulti RPC.""" from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * @@ -20,6 +20,7 @@ class ImportMultiTest (BitcoinTestFramework): print ("Mining blocks...") self.nodes[0].generate(1) self.nodes[1].generate(1) + timestamp = self.nodes[1].getblock(self.nodes[1].getbestblockhash())['mediantime'] # keyword definition PRIV_KEY = 'privkey' @@ -52,31 +53,48 @@ class ImportMultiTest (BitcoinTestFramework): result = self.nodes[1].importmulti([{ "scriptPubKey": { "address": address['address'] - } + }, + "timestamp": "now", }]) assert_equal(result[0]['success'], True) address_assert = self.nodes[1].validateaddress(address['address']) assert_equal(address_assert['iswatchonly'], True) assert_equal(address_assert['ismine'], False) + assert_equal(address_assert['timestamp'], timestamp) + watchonly_address = address['address'] + watchonly_timestamp = timestamp + print("Should not import an invalid address") + result = self.nodes[1].importmulti([{ + "scriptPubKey": { + "address": "not valid address", + }, + "timestamp": "now", + }]) + assert_equal(result[0]['success'], False) + assert_equal(result[0]['error']['code'], -5) + assert_equal(result[0]['error']['message'], 'Invalid address') # ScriptPubKey + internal print("Should import a scriptPubKey with internal flag") address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress()) result = self.nodes[1].importmulti([{ "scriptPubKey": address['scriptPubKey'], + "timestamp": "now", "internal": True }]) assert_equal(result[0]['success'], True) address_assert = self.nodes[1].validateaddress(address['address']) assert_equal(address_assert['iswatchonly'], True) assert_equal(address_assert['ismine'], False) + assert_equal(address_assert['timestamp'], timestamp) # ScriptPubKey + !internal print("Should not import a scriptPubKey without internal flag") address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress()) result = self.nodes[1].importmulti([{ - "scriptPubKey": address['scriptPubKey'] + "scriptPubKey": address['scriptPubKey'], + "timestamp": "now", }]) assert_equal(result[0]['success'], False) assert_equal(result[0]['error']['code'], -8) @@ -84,6 +102,7 @@ class ImportMultiTest (BitcoinTestFramework): address_assert = self.nodes[1].validateaddress(address['address']) assert_equal(address_assert['iswatchonly'], False) assert_equal(address_assert['ismine'], False) + assert_equal('timestamp' in address_assert, False) # Address + Public key + !Internal @@ -93,12 +112,14 @@ class ImportMultiTest (BitcoinTestFramework): "scriptPubKey": { "address": address['address'] }, + "timestamp": "now", "pubkeys": [ address['pubkey'] ] }]) assert_equal(result[0]['success'], True) address_assert = self.nodes[1].validateaddress(address['address']) assert_equal(address_assert['iswatchonly'], True) assert_equal(address_assert['ismine'], False) + assert_equal(address_assert['timestamp'], timestamp) # ScriptPubKey + Public key + internal @@ -106,6 +127,7 @@ class ImportMultiTest (BitcoinTestFramework): address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress()) request = [{ "scriptPubKey": address['scriptPubKey'], + "timestamp": "now", "pubkeys": [ address['pubkey'] ], "internal": True }] @@ -114,12 +136,14 @@ class ImportMultiTest (BitcoinTestFramework): address_assert = self.nodes[1].validateaddress(address['address']) assert_equal(address_assert['iswatchonly'], True) assert_equal(address_assert['ismine'], False) + assert_equal(address_assert['timestamp'], timestamp) # ScriptPubKey + Public key + !internal print("Should not import a scriptPubKey without internal and with public key") address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress()) request = [{ "scriptPubKey": address['scriptPubKey'], + "timestamp": "now", "pubkeys": [ address['pubkey'] ] }] result = self.nodes[1].importmulti(request) @@ -129,6 +153,7 @@ class ImportMultiTest (BitcoinTestFramework): address_assert = self.nodes[1].validateaddress(address['address']) assert_equal(address_assert['iswatchonly'], False) assert_equal(address_assert['ismine'], False) + assert_equal('timestamp' in address_assert, False) # Address + Private key + !watchonly print("Should import an address with private key") @@ -137,12 +162,14 @@ class ImportMultiTest (BitcoinTestFramework): "scriptPubKey": { "address": address['address'] }, + "timestamp": "now", "keys": [ self.nodes[0].dumpprivkey(address['address']) ] }]) assert_equal(result[0]['success'], True) address_assert = self.nodes[1].validateaddress(address['address']) assert_equal(address_assert['iswatchonly'], False) assert_equal(address_assert['ismine'], True) + assert_equal(address_assert['timestamp'], timestamp) # Address + Private key + watchonly print("Should not import an address with private key and with watchonly") @@ -151,6 +178,7 @@ class ImportMultiTest (BitcoinTestFramework): "scriptPubKey": { "address": address['address'] }, + "timestamp": "now", "keys": [ self.nodes[0].dumpprivkey(address['address']) ], "watchonly": True }]) @@ -160,12 +188,14 @@ class ImportMultiTest (BitcoinTestFramework): address_assert = self.nodes[1].validateaddress(address['address']) assert_equal(address_assert['iswatchonly'], False) assert_equal(address_assert['ismine'], False) + assert_equal('timestamp' in address_assert, False) # ScriptPubKey + Private key + internal print("Should import a scriptPubKey with internal and with private key") address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress()) result = self.nodes[1].importmulti([{ "scriptPubKey": address['scriptPubKey'], + "timestamp": "now", "keys": [ self.nodes[0].dumpprivkey(address['address']) ], "internal": True }]) @@ -173,12 +203,14 @@ class ImportMultiTest (BitcoinTestFramework): address_assert = self.nodes[1].validateaddress(address['address']) assert_equal(address_assert['iswatchonly'], False) assert_equal(address_assert['ismine'], True) + assert_equal(address_assert['timestamp'], timestamp) # ScriptPubKey + Private key + !internal print("Should not import a scriptPubKey without internal and with private key") address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress()) result = self.nodes[1].importmulti([{ "scriptPubKey": address['scriptPubKey'], + "timestamp": "now", "keys": [ self.nodes[0].dumpprivkey(address['address']) ] }]) assert_equal(result[0]['success'], False) @@ -187,6 +219,7 @@ class ImportMultiTest (BitcoinTestFramework): address_assert = self.nodes[1].validateaddress(address['address']) assert_equal(address_assert['iswatchonly'], False) assert_equal(address_assert['ismine'], False) + assert_equal('timestamp' in address_assert, False) # P2SH address @@ -197,18 +230,21 @@ class ImportMultiTest (BitcoinTestFramework): self.nodes[1].generate(100) transactionid = self.nodes[1].sendtoaddress(multi_sig_script['address'], 10.00) self.nodes[1].generate(1) + timestamp = self.nodes[1].getblock(self.nodes[1].getbestblockhash())['mediantime'] transaction = self.nodes[1].gettransaction(transactionid) print("Should import a p2sh") result = self.nodes[1].importmulti([{ "scriptPubKey": { "address": multi_sig_script['address'] - } + }, + "timestamp": "now", }]) assert_equal(result[0]['success'], True) address_assert = self.nodes[1].validateaddress(multi_sig_script['address']) assert_equal(address_assert['isscript'], True) assert_equal(address_assert['iswatchonly'], True) + assert_equal(address_assert['timestamp'], timestamp) p2shunspent = self.nodes[1].listunspent(0,999999, [multi_sig_script['address']])[0] assert_equal(p2shunspent['spendable'], False) assert_equal(p2shunspent['solvable'], False) @@ -222,6 +258,7 @@ class ImportMultiTest (BitcoinTestFramework): self.nodes[1].generate(100) transactionid = self.nodes[1].sendtoaddress(multi_sig_script['address'], 10.00) self.nodes[1].generate(1) + timestamp = self.nodes[1].getblock(self.nodes[1].getbestblockhash())['mediantime'] transaction = self.nodes[1].gettransaction(transactionid) print("Should import a p2sh with respective redeem script") @@ -229,9 +266,12 @@ class ImportMultiTest (BitcoinTestFramework): "scriptPubKey": { "address": multi_sig_script['address'] }, + "timestamp": "now", "redeemscript": multi_sig_script['redeemScript'] }]) assert_equal(result[0]['success'], True) + address_assert = self.nodes[1].validateaddress(multi_sig_script['address']) + assert_equal(address_assert['timestamp'], timestamp) p2shunspent = self.nodes[1].listunspent(0,999999, [multi_sig_script['address']])[0] assert_equal(p2shunspent['spendable'], False) @@ -246,6 +286,7 @@ class ImportMultiTest (BitcoinTestFramework): self.nodes[1].generate(100) transactionid = self.nodes[1].sendtoaddress(multi_sig_script['address'], 10.00) self.nodes[1].generate(1) + timestamp = self.nodes[1].getblock(self.nodes[1].getbestblockhash())['mediantime'] transaction = self.nodes[1].gettransaction(transactionid) print("Should import a p2sh with respective redeem script and private keys") @@ -253,10 +294,13 @@ class ImportMultiTest (BitcoinTestFramework): "scriptPubKey": { "address": multi_sig_script['address'] }, + "timestamp": "now", "redeemscript": multi_sig_script['redeemScript'], "keys": [ self.nodes[0].dumpprivkey(sig_address_1['address']), self.nodes[0].dumpprivkey(sig_address_2['address'])] }]) assert_equal(result[0]['success'], True) + address_assert = self.nodes[1].validateaddress(multi_sig_script['address']) + assert_equal(address_assert['timestamp'], timestamp) p2shunspent = self.nodes[1].listunspent(0,999999, [multi_sig_script['address']])[0] assert_equal(p2shunspent['spendable'], False) @@ -277,6 +321,7 @@ class ImportMultiTest (BitcoinTestFramework): "scriptPubKey": { "address": multi_sig_script['address'] }, + "timestamp": "now", "redeemscript": multi_sig_script['redeemScript'], "keys": [ self.nodes[0].dumpprivkey(sig_address_1['address']), self.nodes[0].dumpprivkey(sig_address_2['address'])], "watchonly": True @@ -294,6 +339,7 @@ class ImportMultiTest (BitcoinTestFramework): "scriptPubKey": { "address": address['address'] }, + "timestamp": "now", "pubkeys": [ address2['pubkey'] ] }]) assert_equal(result[0]['success'], False) @@ -302,6 +348,7 @@ class ImportMultiTest (BitcoinTestFramework): address_assert = self.nodes[1].validateaddress(address['address']) assert_equal(address_assert['iswatchonly'], False) assert_equal(address_assert['ismine'], False) + assert_equal('timestamp' in address_assert, False) # ScriptPubKey + Public key + internal + Wrong pubkey @@ -310,6 +357,7 @@ class ImportMultiTest (BitcoinTestFramework): address2 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress()) request = [{ "scriptPubKey": address['scriptPubKey'], + "timestamp": "now", "pubkeys": [ address2['pubkey'] ], "internal": True }] @@ -320,6 +368,7 @@ class ImportMultiTest (BitcoinTestFramework): address_assert = self.nodes[1].validateaddress(address['address']) assert_equal(address_assert['iswatchonly'], False) assert_equal(address_assert['ismine'], False) + assert_equal('timestamp' in address_assert, False) # Address + Private key + !watchonly + Wrong private key @@ -330,6 +379,7 @@ class ImportMultiTest (BitcoinTestFramework): "scriptPubKey": { "address": address['address'] }, + "timestamp": "now", "keys": [ self.nodes[0].dumpprivkey(address2['address']) ] }]) assert_equal(result[0]['success'], False) @@ -338,6 +388,7 @@ class ImportMultiTest (BitcoinTestFramework): address_assert = self.nodes[1].validateaddress(address['address']) assert_equal(address_assert['iswatchonly'], False) assert_equal(address_assert['ismine'], False) + assert_equal('timestamp' in address_assert, False) # ScriptPubKey + Private key + internal + Wrong private key @@ -346,6 +397,7 @@ class ImportMultiTest (BitcoinTestFramework): address2 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress()) result = self.nodes[1].importmulti([{ "scriptPubKey": address['scriptPubKey'], + "timestamp": "now", "keys": [ self.nodes[0].dumpprivkey(address2['address']) ], "internal": True }]) @@ -355,6 +407,28 @@ class ImportMultiTest (BitcoinTestFramework): address_assert = self.nodes[1].validateaddress(address['address']) assert_equal(address_assert['iswatchonly'], False) assert_equal(address_assert['ismine'], False) + assert_equal('timestamp' in address_assert, False) + + # restart nodes to check for proper serialization/deserialization of watch only address + stop_nodes(self.nodes) + self.nodes = start_nodes(2, self.options.tmpdir) + address_assert = self.nodes[1].validateaddress(watchonly_address) + assert_equal(address_assert['iswatchonly'], True) + assert_equal(address_assert['ismine'], False) + assert_equal(address_assert['timestamp'], watchonly_timestamp); + + # Bad or missing timestamps + print("Should throw on invalid or missing timestamp values") + assert_raises_message(JSONRPCException, 'Missing required timestamp field for key', + self.nodes[1].importmulti, [{ + "scriptPubKey": address['scriptPubKey'], + }]) + assert_raises_message(JSONRPCException, 'Expected number or "now" timestamp value for key. got type string', + self.nodes[1].importmulti, [{ + "scriptPubKey": address['scriptPubKey'], + "timestamp": "", + }]) + if __name__ == '__main__': ImportMultiTest ().main () diff --git a/qa/rpc-tests/importprunedfunds.py b/qa/rpc-tests/importprunedfunds.py index 0dee8ad4ec..a941124656 100755 --- a/qa/rpc-tests/importprunedfunds.py +++ b/qa/rpc-tests/importprunedfunds.py @@ -2,7 +2,7 @@ # Copyright (c) 2014-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. - +"""Test the importprunedfunds and removeprunedfunds RPCs.""" from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * diff --git a/qa/rpc-tests/invalidateblock.py b/qa/rpc-tests/invalidateblock.py index 0faadd33ab..92e65927d5 100755 --- a/qa/rpc-tests/invalidateblock.py +++ b/qa/rpc-tests/invalidateblock.py @@ -2,10 +2,7 @@ # Copyright (c) 2014-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. - -# -# Test InvalidateBlock code -# +"""Test the invalidateblock RPC.""" from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * diff --git a/qa/rpc-tests/invalidblockrequest.py b/qa/rpc-tests/invalidblockrequest.py index 3d8107a76c..eabc0db8df 100755 --- a/qa/rpc-tests/invalidblockrequest.py +++ b/qa/rpc-tests/invalidblockrequest.py @@ -2,6 +2,14 @@ # Copyright (c) 2015-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. +"""Test node responses to invalid blocks. + +In this test we connect to one node over p2p, and test block requests: +1) Valid blocks should be requested and become chain tip. +2) Invalid block with duplicated transaction should be re-requested. +3) Invalid block with bad coinbase value should be rejected and not +re-requested. +""" from test_framework.test_framework import ComparisonTestFramework from test_framework.util import * @@ -10,15 +18,6 @@ from test_framework.blocktools import * import copy import time - -''' -In this test we connect to one node over p2p, and test block requests: -1) Valid blocks should be requested and become chain tip. -2) Invalid block with duplicated transaction should be re-requested. -3) Invalid block with bad coinbase value should be rejected and not -re-requested. -''' - # Use the ComparisonTestFramework with 1 node: only use --testbinary. class InvalidBlockRequestTest(ComparisonTestFramework): diff --git a/qa/rpc-tests/invalidtxrequest.py b/qa/rpc-tests/invalidtxrequest.py index 93205d79de..a9ac231f09 100755 --- a/qa/rpc-tests/invalidtxrequest.py +++ b/qa/rpc-tests/invalidtxrequest.py @@ -2,6 +2,10 @@ # Copyright (c) 2015-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. +"""Test node responses to invalid transactions. + +In this test we connect to one node over p2p, and test tx requests. +""" from test_framework.test_framework import ComparisonTestFramework from test_framework.comptool import TestManager, TestInstance, RejectResult @@ -9,9 +13,6 @@ 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): diff --git a/qa/rpc-tests/keypool.py b/qa/rpc-tests/keypool.py index fa39476568..4b9936a1fd 100755 --- a/qa/rpc-tests/keypool.py +++ b/qa/rpc-tests/keypool.py @@ -2,8 +2,7 @@ # Copyright (c) 2014-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. - -# Exercise the wallet keypool, and interaction with wallet encryption/locking +"""Test the wallet keypool and interaction with wallet encryption/locking.""" from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * diff --git a/qa/rpc-tests/listsinceblock.py b/qa/rpc-tests/listsinceblock.py index ca67b8eceb..88304af5b0 100755 --- a/qa/rpc-tests/listsinceblock.py +++ b/qa/rpc-tests/listsinceblock.py @@ -2,6 +2,7 @@ # Copyright (c) 2017 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 the listsincelast RPC.""" from test_framework.test_framework import BitcoinTestFramework from test_framework.util import assert_equal diff --git a/qa/rpc-tests/listtransactions.py b/qa/rpc-tests/listtransactions.py index 5ec6ce17e0..92fb96c809 100755 --- a/qa/rpc-tests/listtransactions.py +++ b/qa/rpc-tests/listtransactions.py @@ -2,8 +2,7 @@ # Copyright (c) 2014-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. - -# Exercise the listtransactions API +"""Test the listtransactions API.""" from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * diff --git a/qa/rpc-tests/maxblocksinflight.py b/qa/rpc-tests/maxblocksinflight.py index 1df1c484be..8ea405b4d5 100755 --- a/qa/rpc-tests/maxblocksinflight.py +++ b/qa/rpc-tests/maxblocksinflight.py @@ -2,18 +2,19 @@ # Copyright (c) 2015-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. +"""Test nodes responses to having many blocks in flight. + +In this test we connect to one node over p2p, send it numerous inv's, and +compare the resulting number of getdata requests to a max allowed value. We +test for exceeding 128 blocks in flight, which was the limit an 0.9 client will +reach. [0.10 clients shouldn't request more than 16 from a single peer.] +""" from test_framework.mininode import * from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * import logging -''' -In this test we connect to one node over p2p, send it numerous inv's, and -compare the resulting number of getdata requests to a max allowed value. We -test for exceeding 128 blocks in flight, which was the limit an 0.9 client will -reach. [0.10 clients shouldn't request more than 16 from a single peer.] -''' MAX_REQUESTS = 128 class TestManager(NodeConnCB): diff --git a/qa/rpc-tests/maxuploadtarget.py b/qa/rpc-tests/maxuploadtarget.py index 9340e899eb..757aa60afd 100755 --- a/qa/rpc-tests/maxuploadtarget.py +++ b/qa/rpc-tests/maxuploadtarget.py @@ -2,21 +2,19 @@ # Copyright (c) 2015-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. - -from test_framework.mininode import * -from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import * -import time - -''' -Test behavior of -maxuploadtarget. +"""Test behavior of -maxuploadtarget. * Verify that getdata requests for old blocks (>1week) are dropped if uploadtarget has been reached. * Verify that getdata requests for recent blocks are respecteved even if uploadtarget has been reached. * Verify that the upload counters are reset after 24 hours. -''' +""" + +from test_framework.mininode import * +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import * +import time # TestNode: bare-bones "peer". Used mostly as a conduit for a test to sending # p2p messages to a node, generating the messages in the main testing logic. diff --git a/qa/rpc-tests/mempool_limit.py b/qa/rpc-tests/mempool_limit.py index 154ae59c26..8fae92ad2b 100755 --- a/qa/rpc-tests/mempool_limit.py +++ b/qa/rpc-tests/mempool_limit.py @@ -2,8 +2,7 @@ # Copyright (c) 2014-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. - -# Test mempool limiting together/eviction with the wallet +"""Test mempool limiting together/eviction with the wallet.""" from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * diff --git a/qa/rpc-tests/mempool_packages.py b/qa/rpc-tests/mempool_packages.py index f605e7524f..388889d07c 100755 --- a/qa/rpc-tests/mempool_packages.py +++ b/qa/rpc-tests/mempool_packages.py @@ -2,8 +2,7 @@ # Copyright (c) 2014-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. - -# Test descendant package tracking code +"""Test descendant package tracking code.""" from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * diff --git a/qa/rpc-tests/mempool_reorg.py b/qa/rpc-tests/mempool_reorg.py index dd88aae4f2..2cd5573277 100755 --- a/qa/rpc-tests/mempool_reorg.py +++ b/qa/rpc-tests/mempool_reorg.py @@ -2,11 +2,11 @@ # Copyright (c) 2014-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. +"""Test mempool re-org scenarios. -# -# Test re-org scenarios with a mempool that contains transactions -# that spend (directly or indirectly) coinbase transactions. -# +Test re-org scenarios with a mempool that contains transactions +that spend (directly or indirectly) coinbase transactions. +""" from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * diff --git a/qa/rpc-tests/mempool_resurrect_test.py b/qa/rpc-tests/mempool_resurrect_test.py index 3db12cbf76..c7f37aaa44 100755 --- a/qa/rpc-tests/mempool_resurrect_test.py +++ b/qa/rpc-tests/mempool_resurrect_test.py @@ -2,11 +2,7 @@ # Copyright (c) 2014-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. - -# -# Test resurrection of mined transactions when -# the blockchain is re-organized. -# +"""Test resurrection of mined transactions when the blockchain is re-organized.""" from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * diff --git a/qa/rpc-tests/mempool_spendcoinbase.py b/qa/rpc-tests/mempool_spendcoinbase.py index d5e4bf52d2..da8485e2a2 100755 --- a/qa/rpc-tests/mempool_spendcoinbase.py +++ b/qa/rpc-tests/mempool_spendcoinbase.py @@ -2,16 +2,15 @@ # Copyright (c) 2014-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. - -# -# Test spending coinbase transactions. -# The coinbase transaction in block N can appear in block -# N+100... so is valid in the mempool when the best block -# height is N+99. -# This test makes sure coinbase spends that will be mature -# in the next block are accepted into the memory pool, -# but less mature coinbase spends are NOT. -# +"""Test spending coinbase transactions. + +The coinbase transaction in block N can appear in block +N+100... so is valid in the mempool when the best block +height is N+99. +This test makes sure coinbase spends that will be mature +in the next block are accepted into the memory pool, +but less mature coinbase spends are NOT. +""" from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * diff --git a/qa/rpc-tests/merkle_blocks.py b/qa/rpc-tests/merkle_blocks.py index b2155d7fc3..c4b45425d7 100755 --- a/qa/rpc-tests/merkle_blocks.py +++ b/qa/rpc-tests/merkle_blocks.py @@ -2,10 +2,7 @@ # Copyright (c) 2014-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. - -# -# Test merkleblock fetch/validation -# +"""Test gettxoutproof and verifytxoutproof RPCs.""" from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * diff --git a/qa/rpc-tests/multi_rpc.py b/qa/rpc-tests/multi_rpc.py index 95d9090ce2..3b74bf1c46 100755 --- a/qa/rpc-tests/multi_rpc.py +++ b/qa/rpc-tests/multi_rpc.py @@ -2,10 +2,7 @@ # Copyright (c) 2015-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. - -# -# Test multiple rpc user config option rpcauth -# +"""Test multiple RPC users.""" from test_framework.test_framework import BitcoinTestFramework from test_framework.util import str_to_b64str, assert_equal diff --git a/qa/rpc-tests/nodehandling.py b/qa/rpc-tests/nodehandling.py index 7313c79b54..89059d2760 100755 --- a/qa/rpc-tests/nodehandling.py +++ b/qa/rpc-tests/nodehandling.py @@ -2,10 +2,7 @@ # Copyright (c) 2014-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. - -# -# Test node handling -# +"""Test node handling.""" from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * diff --git a/qa/rpc-tests/nulldummy.py b/qa/rpc-tests/nulldummy.py index 54b7eac376..66c4e90f21 100755 --- a/qa/rpc-tests/nulldummy.py +++ b/qa/rpc-tests/nulldummy.py @@ -2,6 +2,16 @@ # 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. +"""Test NULLDUMMY softfork. + +Connect to a single node. +Generate 2 blocks (save the coinbases for later). +Generate 427 more blocks. +[Policy/Consensus] Check that NULLDUMMY compliant transactions are accepted in the 430th block. +[Policy] Check that non-NULLDUMMY transactions are rejected before activation. +[Consensus] Check that the new NULLDUMMY rules are not enforced on the 431st block. +[Policy/Consensus] Check that the new NULLDUMMY rules are enforced on the 432nd block. +""" from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * @@ -25,17 +35,6 @@ def trueDummy(tx): tx.vin[0].scriptSig = CScript(newscript) tx.rehash() -''' -This test is meant to exercise NULLDUMMY softfork. -Connect to a single node. -Generate 2 blocks (save the coinbases for later). -Generate 427 more blocks. -[Policy/Consensus] Check that NULLDUMMY compliant transactions are accepted in the 430th block. -[Policy] Check that non-NULLDUMMY transactions are rejected before activation. -[Consensus] Check that the new NULLDUMMY rules are not enforced on the 431st block. -[Policy/Consensus] Check that the new NULLDUMMY rules are enforced on the 432nd block. -''' - class NULLDUMMYTest(BitcoinTestFramework): def __init__(self): diff --git a/qa/rpc-tests/p2p-acceptblock.py b/qa/rpc-tests/p2p-acceptblock.py index 015ec34eff..2f21fa149a 100755 --- a/qa/rpc-tests/p2p-acceptblock.py +++ b/qa/rpc-tests/p2p-acceptblock.py @@ -2,15 +2,7 @@ # Copyright (c) 2015-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. - -from test_framework.mininode import * -from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import * -import time -from test_framework.blocktools import create_block, create_coinbase - -''' -AcceptBlockTest -- test processing of unrequested blocks. +"""Test processing of unrequested blocks. Since behavior differs when receiving unrequested blocks from whitelisted peers versus non-whitelisted peers, this tests the behavior of both (effectively two @@ -54,7 +46,13 @@ The test: 7. Send Node0 the missing block again. Node0 should process and the tip should advance. -''' +""" + +from test_framework.mininode import * +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import * +import time +from test_framework.blocktools import create_block, create_coinbase # TestNode: bare-bones "peer". Used mostly as a conduit for a test to sending # p2p messages to a node, generating the messages in the main testing logic. diff --git a/qa/rpc-tests/p2p-compactblocks.py b/qa/rpc-tests/p2p-compactblocks.py index 9151ecf5de..79561f35f7 100755 --- a/qa/rpc-tests/p2p-compactblocks.py +++ b/qa/rpc-tests/p2p-compactblocks.py @@ -2,21 +2,18 @@ # 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. +"""Test compact blocks (BIP 152). + +Version 1 compact blocks are pre-segwit (txids) +Version 2 compact blocks are post-segwit (wtxids) +""" 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, add_witness_commitment -from test_framework.siphash import siphash256 from test_framework.script import CScript, OP_TRUE -''' -CompactBlocksTest -- test compact blocks (BIP 152) - -Version 1 compact blocks are pre-segwit (txids) -Version 2 compact blocks are post-segwit (wtxids) -''' - # TestNode: A peer we use to send messages to bitcoind, and store responses. class TestNode(SingleNodeConnCB): def __init__(self): diff --git a/qa/rpc-tests/p2p-feefilter.py b/qa/rpc-tests/p2p-feefilter.py index 86ce0b42e6..1c62961db0 100755 --- a/qa/rpc-tests/p2p-feefilter.py +++ b/qa/rpc-tests/p2p-feefilter.py @@ -2,16 +2,13 @@ # 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. -# +"""Test processing of feefilter messages.""" from test_framework.mininode import * from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * import time -''' -FeeFilterTest -- test processing of feefilter messages -''' def hashToHex(hash): return format(hash, '064x') diff --git a/qa/rpc-tests/p2p-fullblocktest.py b/qa/rpc-tests/p2p-fullblocktest.py index e4b889d761..274dbb8a92 100755 --- a/qa/rpc-tests/p2p-fullblocktest.py +++ b/qa/rpc-tests/p2p-fullblocktest.py @@ -2,6 +2,14 @@ # Copyright (c) 2015-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. +"""Test block processing. + +This reimplements tests from the bitcoinj/FullBlockTestGenerator used +by the pull-tester. + +We use the testing framework in which we expect a particular answer from +each test. +""" from test_framework.test_framework import ComparisonTestFramework from test_framework.util import * @@ -17,14 +25,6 @@ class PreviousSpendableOutput(object): self.tx = tx self.n = n # the output we're spending -''' -This reimplements tests from the bitcoinj/FullBlockTestGenerator used -by the pull-tester. - -We use the testing framework in which we expect a particular answer from -each test. -''' - # Use this class for tests that require behavior other than normal "mininode" behavior. # For now, it is used to serialize a bloated varint (b64). class CBrokenBlock(CBlock): @@ -398,7 +398,7 @@ class FullBlockTest(ComparisonTestFramework): # Extend the b26 chain to make sure bitcoind isn't accepting b26 b27 = block(27, spend=out[7]) - yield rejected(RejectResult(16, b'bad-prevblk')) + yield rejected(RejectResult(0, b'bad-prevblk')) # Now try a too-large-coinbase script tip(15) @@ -410,7 +410,7 @@ class FullBlockTest(ComparisonTestFramework): # Extend the b28 chain to make sure bitcoind isn't accepting b28 b29 = block(29, spend=out[7]) - yield rejected(RejectResult(16, b'bad-prevblk')) + yield rejected(RejectResult(0, b'bad-prevblk')) # b30 has a max-sized coinbase scriptSig. tip(23) diff --git a/qa/rpc-tests/p2p-leaktests.py b/qa/rpc-tests/p2p-leaktests.py new file mode 100755 index 0000000000..bf08ea32f4 --- /dev/null +++ b/qa/rpc-tests/p2p-leaktests.py @@ -0,0 +1,143 @@ +#!/usr/bin/env python3 +# Copyright (c) 2017 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 message sending before handshake completion. + +A node should never send anything other than VERSION/VERACK/REJECT until it's +received a VERACK. + +This test connects to a node and sends it a few messages, trying to intice it +into sending us something it shouldn't. +""" + +from test_framework.mininode import * +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import * + +banscore = 10 + +class CLazyNode(NodeConnCB): + def __init__(self): + self.connection = None + self.unexpected_msg = False + self.connected = False + super().__init__() + + def add_connection(self, conn): + self.connection = conn + + def send_message(self, message): + self.connection.send_message(message) + + def bad_message(self, message): + self.unexpected_msg = True + print("should not have received message: %s" % message.command) + + def on_open(self, conn): + self.connected = True + + def on_version(self, conn, message): self.bad_message(message) + def on_verack(self, conn, message): self.bad_message(message) + def on_reject(self, conn, message): self.bad_message(message) + def on_inv(self, conn, message): self.bad_message(message) + def on_addr(self, conn, message): self.bad_message(message) + def on_alert(self, conn, message): self.bad_message(message) + def on_getdata(self, conn, message): self.bad_message(message) + def on_getblocks(self, conn, message): self.bad_message(message) + def on_tx(self, conn, message): self.bad_message(message) + def on_block(self, conn, message): self.bad_message(message) + def on_getaddr(self, conn, message): self.bad_message(message) + def on_headers(self, conn, message): self.bad_message(message) + def on_getheaders(self, conn, message): self.bad_message(message) + def on_ping(self, conn, message): self.bad_message(message) + def on_mempool(self, conn): self.bad_message(message) + def on_pong(self, conn, message): self.bad_message(message) + def on_feefilter(self, conn, message): self.bad_message(message) + def on_sendheaders(self, conn, message): self.bad_message(message) + def on_sendcmpct(self, conn, message): self.bad_message(message) + def on_cmpctblock(self, conn, message): self.bad_message(message) + def on_getblocktxn(self, conn, message): self.bad_message(message) + def on_blocktxn(self, conn, message): self.bad_message(message) + +# Node that never sends a version. We'll use this to send a bunch of messages +# anyway, and eventually get disconnected. +class CNodeNoVersionBan(CLazyNode): + def __init__(self): + super().__init__() + + # send a bunch of veracks without sending a message. This should get us disconnected. + # NOTE: implementation-specific check here. Remove if bitcoind ban behavior changes + def on_open(self, conn): + super().on_open(conn) + for i in range(banscore): + self.send_message(msg_verack()) + + def on_reject(self, conn, message): pass + +# Node that never sends a version. This one just sits idle and hopes to receive +# any message (it shouldn't!) +class CNodeNoVersionIdle(CLazyNode): + def __init__(self): + super().__init__() + +# Node that sends a version but not a verack. +class CNodeNoVerackIdle(CLazyNode): + def __init__(self): + self.version_received = False + super().__init__() + + def on_reject(self, conn, message): pass + def on_verack(self, conn, message): pass + # When version is received, don't reply with a verack. Instead, see if the + # node will give us a message that it shouldn't. This is not an exhaustive + # list! + def on_version(self, conn, message): + self.version_received = True + conn.send_message(msg_ping()) + conn.send_message(msg_getaddr()) + +class P2PLeakTest(BitcoinTestFramework): + def __init__(self): + super().__init__() + self.num_nodes = 1 + def setup_network(self): + extra_args = [['-debug', '-banscore='+str(banscore)] + for i in range(self.num_nodes)] + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, extra_args) + + def run_test(self): + no_version_bannode = CNodeNoVersionBan() + no_version_idlenode = CNodeNoVersionIdle() + no_verack_idlenode = CNodeNoVerackIdle() + + connections = [] + connections.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], no_version_bannode, send_version=False)) + connections.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], no_version_idlenode, send_version=False)) + connections.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], no_verack_idlenode)) + no_version_bannode.add_connection(connections[0]) + no_version_idlenode.add_connection(connections[1]) + no_verack_idlenode.add_connection(connections[2]) + + NetworkThread().start() # Start up network handling in another thread + + assert(wait_until(lambda: no_version_bannode.connected and no_version_idlenode.connected and no_verack_idlenode.version_received, timeout=10)) + + # Mine a block and make sure that it's not sent to the connected nodes + self.nodes[0].generate(1) + + #Give the node enough time to possibly leak out a message + time.sleep(5) + + #This node should have been banned + assert(no_version_bannode.connection.state == "closed") + + [conn.disconnect_node() for conn in connections] + + # Make sure no unexpected messages came in + assert(no_version_bannode.unexpected_msg == False) + assert(no_version_idlenode.unexpected_msg == False) + assert(no_verack_idlenode.unexpected_msg == False) + +if __name__ == '__main__': + P2PLeakTest().main() diff --git a/qa/rpc-tests/p2p-mempool.py b/qa/rpc-tests/p2p-mempool.py index 1fd125fdcd..c6b1490211 100755 --- a/qa/rpc-tests/p2p-mempool.py +++ b/qa/rpc-tests/p2p-mempool.py @@ -2,6 +2,11 @@ # Copyright (c) 2015-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. +"""Test p2p mempool message. + +Test that nodes are disconnected if they send mempool messages when bloom +filters are not enabled. +""" from test_framework.mininode import * from test_framework.test_framework import BitcoinTestFramework diff --git a/qa/rpc-tests/p2p-segwit.py b/qa/rpc-tests/p2p-segwit.py index a7858ad3d8..470a5398b6 100755 --- a/qa/rpc-tests/p2p-segwit.py +++ b/qa/rpc-tests/p2p-segwit.py @@ -2,6 +2,7 @@ # 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. +"""Test segwit transactions and blocks on P2P network.""" from test_framework.mininode import * from test_framework.test_framework import BitcoinTestFramework @@ -21,9 +22,6 @@ VB_TOP_BITS = 0x20000000 MAX_SIGOP_COST = 80000 -''' -SegWit p2p test. -''' # Calculate the virtual size of a witness block: # (base + witness/4) @@ -951,7 +949,6 @@ class SegWitTest(BitcoinTestFramework): tx.rehash() tx_hash = tx.sha256 - tx_value = tx.vout[0].nValue # Verify that unnecessary witnesses are rejected. self.test_node.announce_tx_and_wait_for_getdata(tx) diff --git a/qa/rpc-tests/p2p-timeouts.py b/qa/rpc-tests/p2p-timeouts.py new file mode 100755 index 0000000000..7f596b6e4b --- /dev/null +++ b/qa/rpc-tests/p2p-timeouts.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python3 +# 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. +"""Test various net timeouts. + +- Create three bitcoind nodes: + + no_verack_node - we never send a verack in response to their version + no_version_node - we never send a version (only a ping) + no_send_node - we never send any P2P message. + +- Start all three nodes +- Wait 1 second +- Assert that we're connected +- Send a ping to no_verack_node and no_version_node +- Wait 30 seconds +- Assert that we're still connected +- Send a ping to no_verack_node and no_version_node +- Wait 31 seconds +- Assert that we're no longer connected (timeout to receive version/verack is 60 seconds) +""" + +from time import sleep + +from test_framework.mininode import * +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import * + +class TestNode(SingleNodeConnCB): + def __init__(self): + SingleNodeConnCB.__init__(self) + self.connected = False + self.received_version = False + + def on_open(self, conn): + self.connected = True + + def on_close(self, conn): + self.connected = False + + def on_version(self, conn, message): + # Don't send a verack in response + self.received_version = True + +class TimeoutsTest(BitcoinTestFramework): + def __init__(self): + super().__init__() + self.setup_clean_chain = True + self.num_nodes = 1 + + def setup_network(self): + self.nodes = [] + + # Start up node0 to be a version 1, pre-segwit node. + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, + [["-debug", "-logtimemicros=1"]]) + + def run_test(self): + # Setup the p2p connections and start up the network thread. + self.no_verack_node = TestNode() # never send verack + self.no_version_node = TestNode() # never send version (just ping) + self.no_send_node = TestNode() # never send anything + + connections = [] + connections.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], self.no_verack_node)) + connections.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], self.no_version_node, send_version=False)) + connections.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], self.no_send_node, send_version=False)) + self.no_verack_node.add_connection(connections[0]) + self.no_version_node.add_connection(connections[1]) + self.no_send_node.add_connection(connections[2]) + + NetworkThread().start() # Start up network handling in another thread + + sleep(1) + + assert(self.no_verack_node.connected) + assert(self.no_version_node.connected) + assert(self.no_send_node.connected) + + ping_msg = msg_ping() + connections[0].send_message(ping_msg) + connections[1].send_message(ping_msg) + + sleep(30) + + assert(self.no_verack_node.received_version) + + assert(self.no_verack_node.connected) + assert(self.no_version_node.connected) + assert(self.no_send_node.connected) + + connections[0].send_message(ping_msg) + connections[1].send_message(ping_msg) + + sleep(31) + + assert(not self.no_verack_node.connected) + assert(not self.no_version_node.connected) + assert(not self.no_send_node.connected) + +if __name__ == '__main__': + TimeoutsTest().main() diff --git a/qa/rpc-tests/p2p-versionbits-warning.py b/qa/rpc-tests/p2p-versionbits-warning.py index fc3eddddee..8e3e361fc1 100755 --- a/qa/rpc-tests/p2p-versionbits-warning.py +++ b/qa/rpc-tests/p2p-versionbits-warning.py @@ -2,6 +2,11 @@ # 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. +"""Test version bits warning system. + +Generate chains with block versions that appear to be signalling unknown +soft-forks, and test that warning alerts are generated. +""" from test_framework.mininode import * from test_framework.test_framework import BitcoinTestFramework @@ -10,13 +15,6 @@ import re import time from test_framework.blocktools import create_block, create_coinbase -''' -Test version bits' warning system. - -Generate chains with block versions that appear to be signalling unknown -soft-forks, and test that warning alerts are generated. -''' - VB_PERIOD = 144 # versionbits period length for regtest VB_THRESHOLD = 108 # versionbits activation threshold for regtest VB_TOP_BITS = 0x20000000 diff --git a/qa/rpc-tests/preciousblock.py b/qa/rpc-tests/preciousblock.py index a806294648..dde164f329 100755 --- a/qa/rpc-tests/preciousblock.py +++ b/qa/rpc-tests/preciousblock.py @@ -2,10 +2,7 @@ # Copyright (c) 2015-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. - -# -# Test PreciousBlock code -# +"""Test the preciousblock RPC.""" from test_framework.test_framework import BitcoinTestFramework from test_framework.util import ( diff --git a/qa/rpc-tests/prioritise_transaction.py b/qa/rpc-tests/prioritise_transaction.py index b7459c80cb..9a63d0838f 100755 --- a/qa/rpc-tests/prioritise_transaction.py +++ b/qa/rpc-tests/prioritise_transaction.py @@ -2,10 +2,7 @@ # Copyright (c) 2015-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. - -# -# Test PrioritiseTransaction code -# +"""Test the prioritisetransaction mining RPC.""" from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * diff --git a/qa/rpc-tests/proxy_test.py b/qa/rpc-tests/proxy_test.py index 9ccc0ffbb0..e4e231f312 100755 --- a/qa/rpc-tests/proxy_test.py +++ b/qa/rpc-tests/proxy_test.py @@ -2,20 +2,8 @@ # Copyright (c) 2015-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. +"""Test bitcoind with different proxy configuration. -import socket -import os - -from test_framework.socks5 import Socks5Configuration, Socks5Command, Socks5Server, AddressType -from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import ( - PORT_MIN, - PORT_RANGE, - start_nodes, - assert_equal, -) -from test_framework.netutil import test_ipv6_local -''' Test plan: - Start bitcoind's with different proxy configurations - Use addnode to initiate connections @@ -37,7 +25,20 @@ addnode connect to IPv4 addnode connect to IPv6 addnode connect to onion addnode connect to generic DNS name -''' +""" + +import socket +import os + +from test_framework.socks5 import Socks5Configuration, Socks5Command, Socks5Server, AddressType +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import ( + PORT_MIN, + PORT_RANGE, + start_nodes, + assert_equal, +) +from test_framework.netutil import test_ipv6_local RANGE_BEGIN = PORT_MIN + 2 * PORT_RANGE # Start after p2p and rpc ports diff --git a/qa/rpc-tests/pruning.py b/qa/rpc-tests/pruning.py index 05e72e6078..ace8ced422 100755 --- a/qa/rpc-tests/pruning.py +++ b/qa/rpc-tests/pruning.py @@ -2,14 +2,12 @@ # Copyright (c) 2014-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. +"""Test the pruning code. -# -# Test pruning code -# ******** -# WARNING: -# This test uses 4GB of disk space. -# This test takes 30 mins or more (up to 2 hours) -# ******** +WARNING: +This test uses 4GB of disk space. +This test takes 30 mins or more (up to 2 hours) +""" from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * @@ -18,6 +16,11 @@ import os MIN_BLOCKS_TO_KEEP = 288 +# Rescans start at the earliest block up to 2 hours before a key timestamp, so +# the manual prune RPC avoids pruning blocks in the same window to be +# compatible with pruning based on key creation time. +RESCAN_WINDOW = 2 * 60 * 60 + 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.) @@ -103,7 +106,7 @@ class PruneTest(BitcoinTestFramework): # Disconnect node 0 so it can mine a longer reorg chain without knowing about node 1's soon-to-be-stale chain # Node 2 stays connected, so it hears about the stale blocks and then reorg's when node0 reconnects # Stopping node 0 also clears its mempool, so it doesn't have node1's transactions to accidentally mine - stop_node(self.nodes[0],0) + self.stop_node(0) self.nodes[0]=start_node(0, self.options.tmpdir, ["-debug","-maxreceivebuffer=20000","-blockmaxsize=999000", "-checkblocks=5"], timewait=900) # Mine 24 blocks in node 1 for i in range(24): @@ -128,7 +131,7 @@ class PruneTest(BitcoinTestFramework): # This will cause Node 2 to do a reorg requiring 288 blocks of undo data to the reorg_test chain # Reboot node 1 to clear its mempool (hopefully make the invalidate faster) # Lower the block max size so we don't keep mining all our big mempool transactions (from disconnected blocks) - stop_node(self.nodes[1],1) + self.stop_node(1) self.nodes[1]=start_node(1, self.options.tmpdir, ["-debug","-maxreceivebuffer=20000","-blockmaxsize=5000", "-checkblocks=5", "-disablesafemode"], timewait=900) height = self.nodes[1].getblockcount() @@ -151,7 +154,7 @@ class PruneTest(BitcoinTestFramework): print("New best height", self.nodes[1].getblockcount()) # Reboot node1 to clear those giant tx's from mempool - stop_node(self.nodes[1],1) + self.stop_node(1) self.nodes[1]=start_node(1, self.options.tmpdir, ["-debug","-maxreceivebuffer=20000","-blockmaxsize=5000", "-checkblocks=5", "-disablesafemode"], timewait=900) print("Generating new longer chain of 300 more blocks") @@ -231,7 +234,7 @@ class PruneTest(BitcoinTestFramework): node = self.nodes[node_number] = start_node(node_number, self.options.tmpdir, ["-debug=0"], timewait=900) assert_equal(node.getblockcount(), 995) assert_raises_message(JSONRPCException, "not in prune mode", node.pruneblockchain, 500) - stop_node(node, node_number) + self.stop_node(node_number) # now re-start in manual pruning mode node = self.nodes[node_number] = start_node(node_number, self.options.tmpdir, ["-debug=0","-prune=1"], timewait=900) @@ -239,7 +242,7 @@ class PruneTest(BitcoinTestFramework): def height(index): if use_timestamp: - return node.getblockheader(node.getblockhash(index))["time"] + return node.getblockheader(node.getblockhash(index))["time"] + RESCAN_WINDOW else: return index @@ -266,25 +269,21 @@ class PruneTest(BitcoinTestFramework): # mine 6 blocks so we are at height 1001 (i.e., above PruneAfterHeight) node.generate(6) + assert_equal(node.getblockchaininfo()["blocks"], 1001) - # negative and zero inputs should raise an exception - try: - node.pruneblockchain(-10) - raise AssertionError("pruneblockchain(-10) should have failed.") - except: - pass - - try: - node.pruneblockchain(0) - raise AssertionError("pruneblockchain(0) should have failed.") - except: - pass + # negative heights should raise an exception + assert_raises_message(JSONRPCException, "Negative", node.pruneblockchain, -10) # height=100 too low to prune first block file so this is a no-op prune(100) if not has_block(0): raise AssertionError("blk00000.dat is missing when should still be there") + # Does nothing + node.pruneblockchain(height(0)) + if not has_block(0): + raise AssertionError("blk00000.dat is missing when should still be there") + # height=500 should prune first file prune(500) if has_block(0): @@ -311,7 +310,7 @@ class PruneTest(BitcoinTestFramework): raise AssertionError("blk00003.dat is still there, should be pruned by now") # stop node, start back up with auto-prune at 550MB, make sure still runs - stop_node(node, node_number) + self.stop_node(node_number) self.nodes[node_number] = start_node(node_number, self.options.tmpdir, ["-debug=0","-prune=550"], timewait=900) print("Success") @@ -320,7 +319,7 @@ class PruneTest(BitcoinTestFramework): # check that the pruning node's wallet is still in good shape print("Stop and start pruning node to trigger wallet rescan") try: - stop_node(self.nodes[2], 2) + self.stop_node(2) start_node(2, self.options.tmpdir, ["-debug=1","-prune=550"]) print("Success") except Exception as detail: @@ -331,9 +330,9 @@ class PruneTest(BitcoinTestFramework): print ("Syncing node 5 to test wallet") connect_nodes(self.nodes[0], 5) nds = [self.nodes[0], self.nodes[5]] - sync_blocks(nds) + sync_blocks(nds, wait=5, timeout=300) try: - stop_node(self.nodes[5],5) #stop and start to trigger rescan + self.stop_node(5) #stop and start to trigger rescan start_node(5, self.options.tmpdir, ["-debug=1","-prune=550"]) print ("Success") except Exception as detail: @@ -353,8 +352,8 @@ class PruneTest(BitcoinTestFramework): # N0=N1=N2 **...*(995) # stop manual-pruning node with 995 blocks - stop_node(self.nodes[3],3) - stop_node(self.nodes[4],4) + self.stop_node(3) + self.stop_node(4) print("Check that we haven't started pruning yet because we're below PruneAfterHeight") self.test_height_min() diff --git a/qa/rpc-tests/rawtransactions.py b/qa/rpc-tests/rawtransactions.py index 33a6f2b0cc..5adef31207 100755 --- a/qa/rpc-tests/rawtransactions.py +++ b/qa/rpc-tests/rawtransactions.py @@ -2,14 +2,14 @@ # Copyright (c) 2014-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. -"""rawtranscation RPCs QA test. - -# Tests the following RPCs: -# - createrawtransaction -# - signrawtransaction -# - sendrawtransaction -# - decoderawtransaction -# - getrawtransaction +"""Test the rawtranscation RPCs. + +Test the following RPCs: + - createrawtransaction + - signrawtransaction + - sendrawtransaction + - decoderawtransaction + - getrawtransaction """ from test_framework.test_framework import BitcoinTestFramework diff --git a/qa/rpc-tests/receivedby.py b/qa/rpc-tests/receivedby.py index 4f17b661cb..248bcdbd68 100755 --- a/qa/rpc-tests/receivedby.py +++ b/qa/rpc-tests/receivedby.py @@ -2,19 +2,16 @@ # Copyright (c) 2014-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. - -# Exercise the listreceivedbyaddress API +"""Test the listreceivedbyaddress RPC.""" from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * - def get_sub_array_from_array(object_array, to_match): ''' Finds and returns a sub array from an array of arrays. to_match should be a unique idetifier of a sub array ''' - num_matched = 0 for item in object_array: all_match = True for key,value in to_match.items(): @@ -104,7 +101,7 @@ class ReceivedByTest(BitcoinTestFramework): received_by_account_json = get_sub_array_from_array(self.nodes[1].listreceivedbyaccount(),{"account":account}) if len(received_by_account_json) == 0: raise AssertionError("No accounts found in node") - balance_by_account = rec_by_accountArr = self.nodes[1].getreceivedbyaccount(account) + balance_by_account = self.nodes[1].getreceivedbyaccount(account) txid = self.nodes[0].sendtoaddress(addr, 0.1) self.sync_all() diff --git a/qa/rpc-tests/reindex.py b/qa/rpc-tests/reindex.py index 25cf4c1679..1b547a920f 100755 --- a/qa/rpc-tests/reindex.py +++ b/qa/rpc-tests/reindex.py @@ -2,10 +2,13 @@ # Copyright (c) 2014-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. +"""Test running bitcoind with -reindex and -reindex-chainstate options. + +- Start a single node and generate 3 blocks. +- Stop the node and restart it with -reindex. Verify that the node has reindexed up to block 3. +- Stop the node and restart it with -reindex-chainstate. Verify that the node has reindexed up to block 3. +""" -# -# Test -reindex and -reindex-chainstate with CheckBlockIndex -# from test_framework.test_framework import BitcoinTestFramework from test_framework.util import ( start_nodes, diff --git a/qa/rpc-tests/replace-by-fee.py b/qa/rpc-tests/replace-by-fee.py index 8aba06c60c..a3c1deddf6 100755 --- a/qa/rpc-tests/replace-by-fee.py +++ b/qa/rpc-tests/replace-by-fee.py @@ -2,10 +2,7 @@ # Copyright (c) 2014-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. - -# -# Test replace by fee code -# +"""Test the RBF code.""" from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * @@ -393,7 +390,6 @@ class ReplaceByFeeTest(BitcoinTestFramework): utxo = make_utxo(self.nodes[0], initial_nValue) fee = int(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): @@ -443,7 +439,7 @@ class ReplaceByFeeTest(BitcoinTestFramework): self.nodes[0].sendrawtransaction(double_tx_hex, True) def test_opt_in(self): - """ Replacing should only work if orig tx opted in """ + """Replacing should only work if orig tx opted in""" tx0_outpoint = make_utxo(self.nodes[0], int(1.1*COIN)) # Create a non-opting in transaction diff --git a/qa/rpc-tests/rest.py b/qa/rpc-tests/rest.py index b769cd71f2..9ca1cc187a 100755 --- a/qa/rpc-tests/rest.py +++ b/qa/rpc-tests/rest.py @@ -2,11 +2,7 @@ # Copyright (c) 2014-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. - -# -# Test REST interface -# - +"""Test the REST API.""" from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * diff --git a/qa/rpc-tests/rpcbind_test.py b/qa/rpc-tests/rpcbind_test.py index d78d0b884e..499fe33679 100755 --- a/qa/rpc-tests/rpcbind_test.py +++ b/qa/rpc-tests/rpcbind_test.py @@ -2,8 +2,7 @@ # Copyright (c) 2014-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. - -# Test for -rpcbind, as well as -rpcallowip and -rpcconnect +"""Test running bitcoind with the -rpcbind and -rpcallowip options.""" from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * @@ -35,11 +34,9 @@ class RPCBindTest(BitcoinTestFramework): base_args += ['-rpcallowip=' + x for x in allow_ips] binds = ['-rpcbind='+addr for addr in addresses] self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, [base_args + binds], connect_to) - try: - pid = bitcoind_processes[0].pid - assert_equal(set(get_bind_addrs(pid)), set(expected)) - finally: - stop_nodes(self.nodes) + pid = bitcoind_processes[0].pid + assert_equal(set(get_bind_addrs(pid)), set(expected)) + stop_nodes(self.nodes) def run_allowip_test(self, allow_ips, rpchost, rpcport): ''' @@ -48,13 +45,10 @@ class RPCBindTest(BitcoinTestFramework): ''' base_args = ['-disablewallet', '-nolisten'] + ['-rpcallowip='+x for x in allow_ips] self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, [base_args]) - try: - # connect to node through non-loopback interface - node = get_rpc_proxy(rpc_url(0, "%s:%d" % (rpchost, rpcport)), 0) - node.getnetworkinfo() - finally: - node = None # make sure connection will be garbage collected and closed - stop_nodes(self.nodes) + # connect to node through non-loopback interface + node = get_rpc_proxy(rpc_url(0, "%s:%d" % (rpchost, rpcport)), 0) + node.getnetworkinfo() + stop_nodes(self.nodes) def run_test(self): # due to OS-specific network stats queries, this test works only on Linux diff --git a/qa/rpc-tests/rpcnamedargs.py b/qa/rpc-tests/rpcnamedargs.py index 0484204668..f6175c8ca7 100755 --- a/qa/rpc-tests/rpcnamedargs.py +++ b/qa/rpc-tests/rpcnamedargs.py @@ -2,18 +2,13 @@ # 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. - -from decimal import Decimal +"""Test using named arguments for RPCs.""" from test_framework.test_framework import BitcoinTestFramework -from test_framework.authproxy import JSONRPCException from test_framework.util import ( assert_equal, assert_raises_jsonrpc, - assert_is_hex_string, - assert_is_hash_string, start_nodes, - connect_nodes_bi, ) @@ -37,7 +32,7 @@ class NamedArgumentTest(BitcoinTestFramework): h = node.help(command='getinfo') assert(h.startswith('getinfo\n')) - assert_raises_jsonrpc(-8, node.help, random='getinfo') + assert_raises_jsonrpc(-8, 'Unknown named parameter', node.help, random='getinfo') h = node.getblockhash(height=0) node.getblock(blockhash=h) diff --git a/qa/rpc-tests/segwit.py b/qa/rpc-tests/segwit.py index 299f5387e7..f475427842 100755 --- a/qa/rpc-tests/segwit.py +++ b/qa/rpc-tests/segwit.py @@ -2,10 +2,7 @@ # 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. - -# -# Test the SegWit changeover logic -# +"""Test the SegWit changeover logic.""" from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * @@ -130,10 +127,14 @@ class SegWitTest(BitcoinTestFramework): print("Verify sigops are counted in GBT with pre-BIP141 rules before the fork") txid = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 1) tmpl = self.nodes[0].getblocktemplate({}) + assert(tmpl['sizelimit'] == 1000000) + assert('weightlimit' not in tmpl) assert(tmpl['sigoplimit'] == 20000) assert(tmpl['transactions'][0]['hash'] == txid) assert(tmpl['transactions'][0]['sigops'] == 2) tmpl = self.nodes[0].getblocktemplate({'rules':['segwit']}) + assert(tmpl['sizelimit'] == 1000000) + assert('weightlimit' not in tmpl) assert(tmpl['sigoplimit'] == 20000) assert(tmpl['transactions'][0]['hash'] == txid) assert(tmpl['transactions'][0]['sigops'] == 2) @@ -241,6 +242,8 @@ class SegWitTest(BitcoinTestFramework): print("Verify sigops are counted in GBT with BIP141 rules after the fork") txid = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 1) tmpl = self.nodes[0].getblocktemplate({'rules':['segwit']}) + assert(tmpl['sizelimit'] >= 3999577) # actual maximum size is lower due to minimum mandatory non-witness data + assert(tmpl['weightlimit'] == 4000000) assert(tmpl['sigoplimit'] == 80000) assert(tmpl['transactions'][0]['txid'] == txid) assert(tmpl['transactions'][0]['sigops'] == 8) @@ -250,6 +253,8 @@ class SegWitTest(BitcoinTestFramework): try: tmpl = self.nodes[0].getblocktemplate({}) assert(len(tmpl['transactions']) == 1) # Doesn't include witness tx + assert(tmpl['sizelimit'] == 1000000) + assert('weightlimit' not in tmpl) assert(tmpl['sigoplimit'] == 20000) assert(tmpl['transactions'][0]['hash'] == txid) assert(tmpl['transactions'][0]['sigops'] == 2) diff --git a/qa/rpc-tests/sendheaders.py b/qa/rpc-tests/sendheaders.py index 37b98c576e..16ca4a4913 100755 --- a/qa/rpc-tests/sendheaders.py +++ b/qa/rpc-tests/sendheaders.py @@ -2,14 +2,7 @@ # Copyright (c) 2014-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. - -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. +"""Test behavior of headers messages to announce blocks. Setup: @@ -78,7 +71,13 @@ d. Announce 49 headers that don't connect. Expect: getheaders message each time. e. Announce one more that doesn't connect. Expect: disconnect. -''' +""" + +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 + direct_fetch_response_time = 0.05 diff --git a/qa/rpc-tests/signmessages.py b/qa/rpc-tests/signmessages.py index 31b6f14a26..91f5abef5d 100755 --- a/qa/rpc-tests/signmessages.py +++ b/qa/rpc-tests/signmessages.py @@ -2,13 +2,12 @@ # 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. +"""Test RPC commands for signing and verifying messages.""" from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * - class SignMessagesTest(BitcoinTestFramework): - """Tests RPC commands for signing and verifying messages.""" def __init__(self): super().__init__() diff --git a/qa/rpc-tests/signrawtransactions.py b/qa/rpc-tests/signrawtransactions.py index c61a280616..b24162ab97 100755 --- a/qa/rpc-tests/signrawtransactions.py +++ b/qa/rpc-tests/signrawtransactions.py @@ -2,14 +2,13 @@ # Copyright (c) 2015-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. +"""Test transaction signing using the signrawtransaction RPC.""" from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * class SignRawTransactionsTest(BitcoinTestFramework): - """Tests transaction signing via RPC command "signrawtransaction".""" - def __init__(self): super().__init__() self.setup_clean_chain = True @@ -20,18 +19,20 @@ class SignRawTransactionsTest(BitcoinTestFramework): self.is_network_split = False def successful_signing_test(self): - """Creates and signs a valid raw transaction with one input. + """Create and sign a valid raw transaction with one input. Expected results: 1) The transaction has a complete set of signatures 2) No script verification error occurred""" - privKeys = ['cUeKHd5orzT3mz8P9pxyREHfsWtVfgsfDjiZZBcjUBAaGk1BTj7N'] + privKeys = ['cUeKHd5orzT3mz8P9pxyREHfsWtVfgsfDjiZZBcjUBAaGk1BTj7N', 'cVKpPfVKSJxKqVpE9awvXNWuLHCa5j5tiE7K6zbUSptFpTEtiFrA'] inputs = [ - # Valid pay-to-pubkey script + # Valid pay-to-pubkey scripts {'txid': '9b907ef1e3c26fc71fe4a4b3580bc75264112f95050014157059c736f0202e71', 'vout': 0, - 'scriptPubKey': '76a91460baa0f494b38ce3c940dea67f3804dc52d1fb9488ac'} + 'scriptPubKey': '76a91460baa0f494b38ce3c940dea67f3804dc52d1fb9488ac'}, + {'txid': '83a4f6a6b73660e13ee6cb3c6063fa3759c50c9b7521d0536022961898f4fb02', 'vout': 0, + 'scriptPubKey': '76a914669b857c03a5ed269d5d85a1ffac9ed5d663072788ac'}, ] outputs = {'mpLQjfK79b7CCV4VMJWEWAj5Mpx8Up5zxB': 0.1} @@ -46,8 +47,24 @@ class SignRawTransactionsTest(BitcoinTestFramework): # 2) No script verification error occurred assert 'errors' not in rawTxSigned + # Check that signrawtransaction doesn't blow up on garbage merge attempts + dummyTxInconsistent = self.nodes[0].createrawtransaction([inputs[0]], outputs) + rawTxUnsigned = self.nodes[0].signrawtransaction(rawTx + dummyTxInconsistent, inputs) + + assert 'complete' in rawTxUnsigned + assert_equal(rawTxUnsigned['complete'], False) + + # Check that signrawtransaction properly merges unsigned and signed txn, even with garbage in the middle + rawTxSigned2 = self.nodes[0].signrawtransaction(rawTxUnsigned["hex"] + dummyTxInconsistent + rawTxSigned["hex"], inputs) + + assert 'complete' in rawTxSigned2 + assert_equal(rawTxSigned2['complete'], True) + + assert 'errors' not in rawTxSigned2 + + def script_verification_error_test(self): - """Creates and signs a raw transaction with valid (vin 0), invalid (vin 1) and one missing (vin 2) input script. + """Create and sign a raw transaction with valid (vin 0), invalid (vin 1) and one missing (vin 2) input script. Expected results: @@ -78,6 +95,16 @@ class SignRawTransactionsTest(BitcoinTestFramework): outputs = {'mpLQjfK79b7CCV4VMJWEWAj5Mpx8Up5zxB': 0.1} rawTx = self.nodes[0].createrawtransaction(inputs, outputs) + + # Make sure decoderawtransaction is at least marginally sane + decodedRawTx = self.nodes[0].decoderawtransaction(rawTx) + for i, inp in enumerate(inputs): + assert_equal(decodedRawTx["vin"][i]["txid"], inp["txid"]) + assert_equal(decodedRawTx["vin"][i]["vout"], inp["vout"]) + + # Make sure decoderawtransaction throws if there is extra data + assert_raises(JSONRPCException, self.nodes[0].decoderawtransaction, rawTx + "00") + rawTxSigned = self.nodes[0].signrawtransaction(rawTx, scripts, privKeys) # 3) The transaction has no complete set of signatures diff --git a/qa/rpc-tests/smartfees.py b/qa/rpc-tests/smartfees.py index 2c56f954a2..bde454968f 100755 --- a/qa/rpc-tests/smartfees.py +++ b/qa/rpc-tests/smartfees.py @@ -2,10 +2,7 @@ # Copyright (c) 2014-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. - -# -# Test fee estimation code -# +"""Test fee estimation code.""" from collections import OrderedDict from test_framework.test_framework import BitcoinTestFramework @@ -21,7 +18,7 @@ P2SH_2 = "2NBdpwq8Aoo1EEKEXPNrKvr5xQr3M9UfcZA" # P2SH of "OP_2 OP_DROP" SCRIPT_SIG = ["0451025175", "0451025275"] def small_txpuzzle_randfee(from_node, conflist, unconflist, amount, min_fee, fee_increment): - ''' + """ Create and send a transaction with a random fee. The transaction pays to a trivial P2SH script, and assumes that its inputs are of the same form. @@ -29,7 +26,7 @@ def small_txpuzzle_randfee(from_node, conflist, unconflist, amount, min_fee, fee and attempts to use the confirmed list first for its inputs. It adds the newly created outputs to the unconfirmed list. Returns (raw transaction, fee) - ''' + """ # It's best to exponentially distribute our random fees # because the buckets are exponentially spaced. # Exponentially distributed from 1-128 * fee_increment @@ -71,12 +68,12 @@ def small_txpuzzle_randfee(from_node, conflist, unconflist, amount, min_fee, fee return (completetx, fee) def split_inputs(from_node, txins, txouts, initial_split = False): - ''' + """ We need to generate a lot of very small inputs so we can generate a ton of transactions and they will have low priority. This function takes an input from txins, and creates and sends a transaction which splits the value into 2 outputs which are appended to txouts. - ''' + """ prevtxout = txins.pop() inputs = [] inputs.append({ "txid" : prevtxout["txid"], "vout" : prevtxout["vout"] }) @@ -95,10 +92,10 @@ def split_inputs(from_node, txins, txouts, initial_split = False): txouts.append({ "txid" : txid, "vout" : 1 , "amount" : rem_change}) def check_estimates(node, fees_seen, max_invalid, print_estimates = True): - ''' + """ This function calls estimatefee and verifies that the estimates meet certain invariants. - ''' + """ all_estimates = [ node.estimatefee(i) for i in range(1,26) ] if print_estimates: print([str(all_estimates[e-1]) for e in [1,2,3,6,15,25]]) @@ -151,11 +148,11 @@ class EstimateFeeTest(BitcoinTestFramework): self.setup_clean_chain = False def setup_network(self): - ''' + """ We'll setup the network to have 3 nodes that all mine with different parameters. But first we need to use one node to create a lot of small low priority outputs which we will use to generate our transactions. - ''' + """ self.nodes = [] # Use node0 to mine blocks for input splitting self.nodes.append(start_node(0, self.options.tmpdir, ["-maxorphantx=1000", diff --git a/qa/rpc-tests/test_framework/address.py b/qa/rpc-tests/test_framework/address.py index 50b999be61..96bebe1ea1 100644 --- a/qa/rpc-tests/test_framework/address.py +++ b/qa/rpc-tests/test_framework/address.py @@ -2,12 +2,7 @@ # 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. - -# -# address.py -# -# This file encodes and decodes BASE58 P2PKH and P2SH addresses -# +"""Encode and decode BASE58, P2PKH and P2SH addresses.""" from .script import hash256, hash160, sha256, CScript, OP_0 from .util import bytes_to_hex_str, hex_str_to_bytes diff --git a/qa/rpc-tests/test_framework/authproxy.py b/qa/rpc-tests/test_framework/authproxy.py index 09ed611299..9ab3094b06 100644 --- a/qa/rpc-tests/test_framework/authproxy.py +++ b/qa/rpc-tests/test_framework/authproxy.py @@ -1,37 +1,36 @@ - -""" - Copyright (c) 2011 Jeff Garzik - - AuthServiceProxy has the following improvements over python-jsonrpc's - ServiceProxy class: - - - HTTP connections persist for the life of the AuthServiceProxy object - (if server supports HTTP/1.1) - - sends protocol 'version', per JSON-RPC 1.1 - - sends proper, incrementing 'id' - - sends Basic HTTP authentication headers - - parses all JSON numbers that look like floats as Decimal - - uses standard Python json lib - - Previous copyright, from python-jsonrpc/jsonrpc/proxy.py: - - Copyright (c) 2007 Jan-Klaas Kollhof - - This file is part of jsonrpc. - - jsonrpc is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - This software is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this software; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# Copyright (c) 2011 Jeff Garzik +# +# Previous copyright, from python-jsonrpc/jsonrpc/proxy.py: +# +# Copyright (c) 2007 Jan-Klaas Kollhof +# +# This file is part of jsonrpc. +# +# jsonrpc is free software; you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. +# +# This software is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this software; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +"""HTTP proxy for opening RPC connection to bitcoind. + +AuthServiceProxy has the following improvements over python-jsonrpc's +ServiceProxy class: + +- HTTP connections persist for the life of the AuthServiceProxy object + (if server supports HTTP/1.1) +- sends protocol 'version', per JSON-RPC 1.1 +- sends proper, incrementing 'id' +- sends Basic HTTP authentication headers +- parses all JSON numbers that look like floats as Decimal +- uses standard Python json lib """ try: diff --git a/qa/rpc-tests/test_framework/bignum.py b/qa/rpc-tests/test_framework/bignum.py index ef800e4d57..024611da6e 100644 --- a/qa/rpc-tests/test_framework/bignum.py +++ b/qa/rpc-tests/test_framework/bignum.py @@ -1,15 +1,11 @@ #!/usr/bin/env python3 # -# bignum.py -# -# This file is copied from python-bitcoinlib. -# # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. -# - -"""Bignum routines""" +"""Big number routines. +This file is copied from python-bitcoinlib. +""" import struct diff --git a/qa/rpc-tests/test_framework/blockstore.py b/qa/rpc-tests/test_framework/blockstore.py index 28a6b92b81..5280d18cdc 100644 --- a/qa/rpc-tests/test_framework/blockstore.py +++ b/qa/rpc-tests/test_framework/blockstore.py @@ -2,16 +2,20 @@ # Copyright (c) 2015-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. -# BlockStore: a helper class that keeps a map of blocks and implements -# helper functions for responding to getheaders and getdata, -# and for constructing a getheaders message -# +"""BlockStore and TxStore helper classes.""" from .mininode import * from io import BytesIO import dbm.dumb as dbmd class BlockStore(object): + """BlockStore helper class. + + BlockStore keeps a map of blocks and implements helper functions for + responding to getheaders and getdata, and for constructing a getheaders + message. + """ + def __init__(self, datadir): self.blockDB = dbmd.open(datadir + "/blocks", 'c') self.currentBlock = 0 diff --git a/qa/rpc-tests/test_framework/blocktools.py b/qa/rpc-tests/test_framework/blocktools.py index f69958823c..2c9a0857df 100644 --- a/qa/rpc-tests/test_framework/blocktools.py +++ b/qa/rpc-tests/test_framework/blocktools.py @@ -1,8 +1,8 @@ #!/usr/bin/env python3 -# blocktools.py - utilities for manipulating blocks and transactions # Copyright (c) 2015-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. +"""Utilities for manipulating blocks and transactions.""" from .mininode import * from .script import CScript, OP_TRUE, OP_CHECKSIG, OP_RETURN diff --git a/qa/rpc-tests/test_framework/comptool.py b/qa/rpc-tests/test_framework/comptool.py index 17679fc7e1..b617895cac 100755 --- a/qa/rpc-tests/test_framework/comptool.py +++ b/qa/rpc-tests/test_framework/comptool.py @@ -2,34 +2,29 @@ # Copyright (c) 2015-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. - -from .mininode import * -from .blockstore import BlockStore, TxStore -from .util import p2p_port - -''' -This is a tool for comparing two or more bitcoinds to each other -using a script provided. +"""Compare two or more bitcoinds to each other. To use, create a class that implements get_tests(), and pass it in as the test generator to TestManager. get_tests() should be a python generator that returns TestInstance objects. See below for definition. -''' -# TestNode behaves as follows: -# Configure with a BlockStore and TxStore -# on_inv: log the message but don't request -# on_headers: log the chain tip -# on_pong: update ping response map (for synchronization) -# on_getheaders: provide headers via BlockStore -# on_getdata: provide blocks via BlockStore +TestNode behaves as follows: + Configure with a BlockStore and TxStore + on_inv: log the message but don't request + on_headers: log the chain tip + on_pong: update ping response map (for synchronization) + on_getheaders: provide headers via BlockStore + on_getdata: provide blocks via BlockStore +""" + +from .mininode import * +from .blockstore import BlockStore, TxStore +from .util import p2p_port global mininode_lock class RejectResult(object): - ''' - Outcome that expects rejection of a transaction or block. - ''' + """Outcome that expects rejection of a transaction or block.""" def __init__(self, code, reason=b''): self.code = code self.reason = reason diff --git a/qa/rpc-tests/test_framework/coverage.py b/qa/rpc-tests/test_framework/coverage.py index 13b33869f5..3f87ef91f6 100644 --- a/qa/rpc-tests/test_framework/coverage.py +++ b/qa/rpc-tests/test_framework/coverage.py @@ -2,15 +2,12 @@ # Copyright (c) 2015-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. +"""Utilities for doing coverage analysis on the RPC interface. -""" -This module contains utilities for doing coverage analysis on the RPC -interface. - -It provides a way to track which RPC commands are exercised during +Provides a way to track which RPC commands are exercised during testing. - """ + import os diff --git a/qa/rpc-tests/test_framework/key.py b/qa/rpc-tests/test_framework/key.py index c63a15c1e0..85a6158a2f 100644 --- a/qa/rpc-tests/test_framework/key.py +++ b/qa/rpc-tests/test_framework/key.py @@ -1,14 +1,10 @@ # Copyright (c) 2011 Sam Rushing -# -# key.py - OpenSSL wrapper -# -# This file is modified from python-bitcoinlib. -# - -"""ECC secp256k1 crypto routines +"""ECC secp256k1 OpenSSL wrapper. WARNING: This module does not mlock() secrets; your private keys may end up on disk in swap! Use with caution! + +This file is modified from python-bitcoinlib. """ import ctypes diff --git a/qa/rpc-tests/test_framework/mininode.py b/qa/rpc-tests/test_framework/mininode.py index 91daa4ab1f..b2292f6477 100755 --- a/qa/rpc-tests/test_framework/mininode.py +++ b/qa/rpc-tests/test_framework/mininode.py @@ -4,23 +4,21 @@ # Copyright (c) 2010-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. - -# -# mininode.py - Bitcoin P2P network half-a-node -# -# This python code was modified from ArtForz' public domain half-a-node, as -# found in the mini-node branch of http://github.com/jgarzik/pynode. -# -# NodeConn: an object which manages p2p connectivity to a bitcoin node -# NodeConnCB: a base class that describes the interface for receiving -# callbacks with network messages from a NodeConn -# CBlock, CTransaction, CBlockHeader, CTxIn, CTxOut, etc....: -# data structures that should map to corresponding structures in -# bitcoin/primitives -# msg_block, msg_tx, msg_headers, etc.: -# data structures that represent network messages -# ser_*, deser_*: functions that handle serialization/deserialization - +"""Bitcoin P2P network half-a-node. + +This python code was modified from ArtForz' public domain half-a-node, as +found in the mini-node branch of http://github.com/jgarzik/pynode. + +NodeConn: an object which manages p2p connectivity to a bitcoin node +NodeConnCB: a base class that describes the interface for receiving + callbacks with network messages from a NodeConn +CBlock, CTransaction, CBlockHeader, CTxIn, CTxOut, etc....: + data structures that should map to corresponding structures in + bitcoin/primitives +msg_block, msg_tx, msg_headers, etc.: + data structures that represent network messages +ser_*, deser_*: functions that handle serialization/deserialization +""" import struct import socket @@ -1540,6 +1538,7 @@ class NodeConnCB(object): if conn.ver_send > BIP0031_VERSION: conn.send_message(msg_pong(message.nonce)) def on_reject(self, conn, message): pass + def on_open(self, conn): pass def on_close(self, conn): pass def on_mempool(self, conn): pass def on_pong(self, conn, message): pass @@ -1614,7 +1613,7 @@ class NodeConn(asyncore.dispatcher): "regtest": b"\xfa\xbf\xb5\xda", # regtest } - def __init__(self, dstaddr, dstport, rpc, callback, net="regtest", services=NODE_NETWORK): + def __init__(self, dstaddr, dstport, rpc, callback, net="regtest", services=NODE_NETWORK, send_version=True): asyncore.dispatcher.__init__(self, map=mininode_socket_map) self.log = logging.getLogger("NodeConn(%s:%d)" % (dstaddr, dstport)) self.dstaddr = dstaddr @@ -1631,14 +1630,16 @@ class NodeConn(asyncore.dispatcher): self.disconnect = False self.nServices = 0 - # 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" - vt.addrFrom.port = 0 - self.send_message(vt, True) + if send_version: + # 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" + vt.addrFrom.port = 0 + self.send_message(vt, True) + print('MiniNode: Connecting to Bitcoin Node IP # ' + dstaddr + ':' \ + str(dstport)) @@ -1652,8 +1653,10 @@ class NodeConn(asyncore.dispatcher): self.log.debug(msg) def handle_connect(self): - self.show_debug_msg("MiniNode: Connected & Listening: \n") - self.state = "connected" + if self.state != "connected": + self.show_debug_msg("MiniNode: Connected & Listening: \n") + self.state = "connected" + self.cb.on_open(self) def handle_close(self): self.show_debug_msg("MiniNode: Closing Connection to %s:%d... " @@ -1681,11 +1684,20 @@ class NodeConn(asyncore.dispatcher): def writable(self): with mininode_lock: + pre_connection = self.state == "connecting" length = len(self.sendbuf) - return (length > 0) + return (length > 0 or pre_connection) def handle_write(self): with mininode_lock: + # asyncore does not expose socket connection, only the first read/write + # event, thus we must check connection manually here to know when we + # actually connect + if self.state == "connecting": + self.handle_connect() + if not self.writable(): + return + try: sent = self.send(self.sendbuf) except: diff --git a/qa/rpc-tests/test_framework/netutil.py b/qa/rpc-tests/test_framework/netutil.py index b92a9f6e1c..45d8e22d22 100644 --- a/qa/rpc-tests/test_framework/netutil.py +++ b/qa/rpc-tests/test_framework/netutil.py @@ -2,8 +2,10 @@ # Copyright (c) 2014-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. +"""Linux network utilities. -# Linux network utilities +Roughly based on http://voorloopnul.com/blog/a-python-netstat-in-less-than-100-lines-of-code/ by Ricardo Pascal +""" import sys import socket @@ -13,7 +15,6 @@ import array import os from binascii import unhexlify, hexlify -# Roughly based on http://voorloopnul.com/blog/a-python-netstat-in-less-than-100-lines-of-code/ by Ricardo Pascal STATE_ESTABLISHED = '01' STATE_SYN_SENT = '02' STATE_SYN_RECV = '03' diff --git a/qa/rpc-tests/test_framework/script.py b/qa/rpc-tests/test_framework/script.py index 83bbf20479..3d9572788e 100644 --- a/qa/rpc-tests/test_framework/script.py +++ b/qa/rpc-tests/test_framework/script.py @@ -2,19 +2,11 @@ # Copyright (c) 2015-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. +"""Functionality to build scripts, as well as SignatureHash(). -# -# script.py -# -# This file is modified from python-bitcoinlib. -# - -"""Scripts - -Functionality to build scripts, as well as SignatureHash(). +This file is modified from python-bitcoinlib. """ - from .mininode import CTransaction, CTxOut, sha256, hash256, uint256_from_str, ser_uint256, ser_string from binascii import hexlify import hashlib diff --git a/qa/rpc-tests/test_framework/siphash.py b/qa/rpc-tests/test_framework/siphash.py index 9c0574bd93..f68ecad36b 100644 --- a/qa/rpc-tests/test_framework/siphash.py +++ b/qa/rpc-tests/test_framework/siphash.py @@ -2,11 +2,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. +"""Specialized SipHash-2-4 implementations. -# -# siphash.py - Specialized SipHash-2-4 implementations -# -# This implements SipHash-2-4 for 256-bit integers. +This implements SipHash-2-4 for 256-bit integers. +""" def rotl64(n, b): return n >> (64 - b) | (n & ((1 << (64 - b)) - 1)) << b diff --git a/qa/rpc-tests/test_framework/socks5.py b/qa/rpc-tests/test_framework/socks5.py index 372f5ed605..450bf3775e 100644 --- a/qa/rpc-tests/test_framework/socks5.py +++ b/qa/rpc-tests/test_framework/socks5.py @@ -2,9 +2,7 @@ # Copyright (c) 2015-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. -''' -Dummy Socks5 server for testing. -''' +"""Dummy Socks5 server for testing.""" import socket, threading, queue import traceback, sys @@ -20,7 +18,7 @@ class AddressType: ### Utility functions def recvall(s, n): - '''Receive n bytes from a socket, or fail''' + """Receive n bytes from a socket, or fail.""" rv = bytearray() while n > 0: d = s.recv(n) @@ -32,7 +30,7 @@ def recvall(s, n): ### Implementation classes class Socks5Configuration(object): - '''Proxy configuration''' + """Proxy configuration.""" def __init__(self): self.addr = None # Bind address (must be set) self.af = socket.AF_INET # Bind address family @@ -40,7 +38,7 @@ class Socks5Configuration(object): self.auth = False # Support authentication class Socks5Command(object): - '''Information about an incoming socks5 command''' + """Information about an incoming socks5 command.""" def __init__(self, cmd, atyp, addr, port, username, password): self.cmd = cmd # Command (one of Command.*) self.atyp = atyp # Address type (one of AddressType.*) @@ -58,9 +56,7 @@ class Socks5Connection(object): self.peer = peer def handle(self): - ''' - Handle socks5 request according to RFC1928 - ''' + """Handle socks5 request according to RFC192.""" try: # Verify socks version ver = recvall(self.conn, 1)[0] diff --git a/qa/rpc-tests/test_framework/test_framework.py b/qa/rpc-tests/test_framework/test_framework.py index 98c4f6070b..c5e9c6a658 100755 --- a/qa/rpc-tests/test_framework/test_framework.py +++ b/qa/rpc-tests/test_framework/test_framework.py @@ -2,8 +2,7 @@ # Copyright (c) 2014-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. - -# Base class for RPC testing +"""Base class for RPC testing.""" import logging import optparse diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py index aca82c8b6f..e838a40582 100644 --- a/qa/rpc-tests/test_framework/util.py +++ b/qa/rpc-tests/test_framework/util.py @@ -2,11 +2,7 @@ # Copyright (c) 2014-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. - - -# -# Helpful routines for regression testing -# +"""Helpful routines for regression testing.""" import os import sys @@ -375,28 +371,19 @@ def stop_node(node, i): node.stop() except http.client.CannotSendRequest as e: print("WARN: Unable to stop node: " + repr(e)) - bitcoind_processes[i].wait(timeout=BITCOIND_PROC_WAIT_TIMEOUT) + return_code = bitcoind_processes[i].wait(timeout=BITCOIND_PROC_WAIT_TIMEOUT) + assert_equal(return_code, 0) del bitcoind_processes[i] def stop_nodes(nodes): - for node in nodes: - try: - node.stop() - except http.client.CannotSendRequest as e: - print("WARN: Unable to stop node: " + repr(e)) - del nodes[:] # Emptying array closes connections as a side effect - wait_bitcoinds() + for i, node in enumerate(nodes): + stop_node(node, i) + assert not bitcoind_processes.values() # All connections must be gone now def set_node_times(nodes, t): for node in nodes: node.setmocktime(t) -def wait_bitcoinds(): - # Wait for all bitcoinds to cleanly exit - for bitcoind in bitcoind_processes.values(): - bitcoind.wait(timeout=BITCOIND_PROC_WAIT_TIMEOUT) - bitcoind_processes.clear() - def connect_nodes(from_connection, node_num): ip_port = "127.0.0.1:"+str(p2p_port(node_num)) from_connection.addnode(ip_port, "onetry") @@ -550,13 +537,30 @@ def assert_raises_message(exc, message, fun, *args, **kwds): else: raise AssertionError("No exception raised") -def assert_raises_jsonrpc(code, fun, *args, **kwds): - '''Check for specific JSONRPC exception code''' +def assert_raises_jsonrpc(code, message, fun, *args, **kwds): + """Run an RPC and verify that a specific JSONRPC exception code and message is raised. + + Calls function `fun` with arguments `args` and `kwds`. Catches a JSONRPCException + and verifies that the error code and message are as expected. Throws AssertionError if + no JSONRPCException was returned or if the error code/message are not as expected. + + Args: + code (int), optional: the error code returned by the RPC call (defined + in src/rpc/protocol.h). Set to None if checking the error code is not required. + message (string), optional: [a substring of] the error string returned by the + RPC call. Set to None if checking the error string is not required + fun (function): the function to call. This should be the name of an RPC. + args*: positional arguments for the function. + kwds**: named arguments for the function. + """ try: fun(*args, **kwds) except JSONRPCException as e: - if e.error["code"] != code: + # JSONRPCException was thrown as expected. Check the code and message values are correct. + if (code is not None) and (code != e.error["code"]): raise AssertionError("Unexpected JSONRPC error code %i" % e.error["code"]) + if (message is not None) and (message not in e.error['message']): + raise AssertionError("Expected substring not found:"+e.error['message']) except Exception as e: raise AssertionError("Unexpected exception raised: "+type(e).__name__) else: diff --git a/qa/rpc-tests/txn_clone.py b/qa/rpc-tests/txn_clone.py index 22f850ece6..7a3b8d3474 100755 --- a/qa/rpc-tests/txn_clone.py +++ b/qa/rpc-tests/txn_clone.py @@ -2,10 +2,7 @@ # Copyright (c) 2014-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. - -# -# Test proper accounting with an equivalent malleability clone -# +"""Test the wallet accounts properly when there are cloned transactions with malleated scriptsigs.""" from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * diff --git a/qa/rpc-tests/txn_doublespend.py b/qa/rpc-tests/txn_doublespend.py index 84944c3c19..5b12cf4c29 100755 --- a/qa/rpc-tests/txn_doublespend.py +++ b/qa/rpc-tests/txn_doublespend.py @@ -2,10 +2,7 @@ # Copyright (c) 2014-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. - -# -# Test proper accounting with a double-spend conflict -# +"""Test the wallet accounts properly when there is a double-spend conflict.""" from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * diff --git a/qa/rpc-tests/wallet-accounts.py b/qa/rpc-tests/wallet-accounts.py index c51181e4f8..ea12d4ec22 100755 --- a/qa/rpc-tests/wallet-accounts.py +++ b/qa/rpc-tests/wallet-accounts.py @@ -2,16 +2,22 @@ # 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. +"""Test account RPCs. + +RPCs tested are: + - getaccountaddress + - getaddressesbyaccount + - setaccount + - sendfrom (with account arguments) + - move (with account arguments) +""" from test_framework.test_framework import BitcoinTestFramework from test_framework.util import ( start_nodes, - start_node, assert_equal, - connect_nodes_bi, ) - class WalletAccountsTest(BitcoinTestFramework): def __init__(self): diff --git a/qa/rpc-tests/wallet-dump.py b/qa/rpc-tests/wallet-dump.py index c6dc2e3d10..b819b72b75 100755 --- a/qa/rpc-tests/wallet-dump.py +++ b/qa/rpc-tests/wallet-dump.py @@ -2,6 +2,7 @@ # 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. +"""Test the dumpwallet RPC.""" from test_framework.test_framework import BitcoinTestFramework from test_framework.util import (start_nodes, start_node, assert_equal, bitcoind_processes) diff --git a/qa/rpc-tests/wallet-hd.py b/qa/rpc-tests/wallet-hd.py index a49d91f6f4..bf07590098 100755 --- a/qa/rpc-tests/wallet-hd.py +++ b/qa/rpc-tests/wallet-hd.py @@ -2,6 +2,7 @@ # 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. +"""Test Hierarchical Deterministic wallet function.""" from test_framework.test_framework import BitcoinTestFramework from test_framework.util import ( diff --git a/qa/rpc-tests/wallet.py b/qa/rpc-tests/wallet.py index f325ecb4a3..ddeac657e5 100755 --- a/qa/rpc-tests/wallet.py +++ b/qa/rpc-tests/wallet.py @@ -2,7 +2,7 @@ # Copyright (c) 2014-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. - +"""Test the wallet.""" from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * @@ -359,7 +359,6 @@ class WalletTest (BitcoinTestFramework): rawtx = self.nodes[0].createrawtransaction([{"txid":singletxid, "vout":0}], {chain_addrs[0]:node0_balance/2-Decimal('0.01'), chain_addrs[1]:node0_balance/2-Decimal('0.01')}) signedtx = self.nodes[0].signrawtransaction(rawtx) singletxid = self.nodes[0].sendrawtransaction(signedtx["hex"]) - txids = [singletxid, singletxid] self.nodes[0].generate(1) # Make a long chain of unconfirmed payments without hitting mempool limit diff --git a/qa/rpc-tests/walletbackup.py b/qa/rpc-tests/walletbackup.py index e12cb10a50..ea249096cf 100755 --- a/qa/rpc-tests/walletbackup.py +++ b/qa/rpc-tests/walletbackup.py @@ -2,9 +2,7 @@ # Copyright (c) 2014-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. - -""" -Exercise the wallet backup code. Ported from walletbackup.sh. +"""Test the wallet backup features. Test case is: 4 nodes. 1 2 and 3 send transactions between each other, diff --git a/qa/rpc-tests/zapwallettxes.py b/qa/rpc-tests/zapwallettxes.py index 17ba53a844..9597d05f3a 100755 --- a/qa/rpc-tests/zapwallettxes.py +++ b/qa/rpc-tests/zapwallettxes.py @@ -2,7 +2,16 @@ # Copyright (c) 2014-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. +"""Test the zapwallettxes functionality. +- start three bitcoind nodes +- create four transactions on node 0 - two are confirmed and two are + unconfirmed. +- restart node 1 and verify that both the confirmed and the unconfirmed + transactions are still available. +- restart node 0 and verify that the confirmed transactions are still + available, but that the unconfirmed transaction has been zapped. +""" from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * diff --git a/qa/rpc-tests/zmq_test.py b/qa/rpc-tests/zmq_test.py index e9afb2b09a..1e2f06bd54 100755 --- a/qa/rpc-tests/zmq_test.py +++ b/qa/rpc-tests/zmq_test.py @@ -2,10 +2,7 @@ # Copyright (c) 2015-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. - -# -# Test ZMQ interface -# +"""Test the ZMQ API.""" from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * diff --git a/share/certs/PrivateKeyNotes.md b/share/certs/PrivateKeyNotes.md index da299d168f..8d50144c21 100644 --- a/share/certs/PrivateKeyNotes.md +++ b/share/certs/PrivateKeyNotes.md @@ -2,7 +2,7 @@ Code-signing private key notes == The private keys for these certificates were generated on Gavin's main work machine, -following the certificate authoritys' recommendations for generating certificate +following the certificate authority's recommendations for generating certificate signing requests. For OSX, the private key was generated by Keychain.app on Gavin's main work machine. diff --git a/src/.clang-format b/src/.clang-format index 129f062ef8..fc53509138 100644 --- a/src/.clang-format +++ b/src/.clang-format @@ -6,7 +6,7 @@ AlignTrailingComments: true AllowAllParametersOfDeclarationOnNextLine: false AllowShortBlocksOnASingleLine: false AllowShortFunctionsOnASingleLine: All -AllowShortIfStatementsOnASingleLine: false +AllowShortIfStatementsOnASingleLine: true AllowShortLoopsOnASingleLine: false AlwaysBreakBeforeMultilineStrings: false AlwaysBreakTemplateDeclarations: true diff --git a/src/Makefile.am b/src/Makefile.am index a2072865a3..e8d22313dc 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -5,7 +5,7 @@ DIST_SUBDIRS = secp256k1 univalue AM_LDFLAGS = $(PTHREAD_CFLAGS) $(LIBTOOL_LDFLAGS) $(HARDENED_LDFLAGS) -AM_CXXFLAGS = $(HARDENED_CXXFLAGS) +AM_CXXFLAGS = $(HARDENED_CXXFLAGS) $(ERROR_CXXFLAGS) AM_CPPFLAGS = $(HARDENED_CPPFLAGS) EXTRA_LIBRARIES = diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 4d44b35bb6..55a587cf87 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -110,6 +110,7 @@ BITCOIN_TESTS =\ test/policyestimator_tests.cpp \ test/pow_tests.cpp \ test/prevector_tests.cpp \ + test/random_tests.cpp \ test/raii_event_tests.cpp \ test/reverselock_tests.cpp \ test/rpc_tests.cpp \ diff --git a/src/addrman.cpp b/src/addrman.cpp index 662e931d25..b6ab4c6305 100644 --- a/src/addrman.cpp +++ b/src/addrman.cpp @@ -53,14 +53,7 @@ bool CAddrInfo::IsTerrible(int64_t nNow) const double CAddrInfo::GetChance(int64_t nNow) const { double fChance = 1.0; - - int64_t nSinceLastSeen = nNow - nTime; - int64_t nSinceLastTry = nNow - nLastTry; - - if (nSinceLastSeen < 0) - nSinceLastSeen = 0; - if (nSinceLastTry < 0) - nSinceLastTry = 0; + int64_t nSinceLastTry = std::max<int64_t>(nNow - nLastTry, 0); // deprioritize very recent attempts away if (nSinceLastTry < 60 * 10) @@ -255,7 +248,7 @@ bool CAddrMan::Add_(const CAddress& addr, const CNetAddr& source, int64_t nTimeP int nId; CAddrInfo* pinfo = Find(addr, &nId); - // Do not set a penality for a source's self-announcement + // Do not set a penalty for a source's self-announcement if (addr == source) { nTimePenalty = 0; } diff --git a/src/base58.h b/src/base58.h index cccebc9e0e..3998283bb1 100644 --- a/src/base58.h +++ b/src/base58.h @@ -147,7 +147,7 @@ public: K GetKey() { K ret; if (vchData.size() == Size) { - //if base58 encouded data not holds a ext key, return a !IsValid() key + // If base58 encoded data does not hold an ext key, return a !IsValid() key ret.Decode(&vchData[0]); } return ret; diff --git a/src/bench/bench.cpp b/src/bench/bench.cpp index 1bd9d06b80..3c9df4f713 100644 --- a/src/bench/bench.cpp +++ b/src/bench/bench.cpp @@ -9,7 +9,10 @@ #include <iomanip> #include <sys/time.h> -std::map<std::string, benchmark::BenchFunction> benchmark::BenchRunner::benchmarks; +benchmark::BenchRunner::BenchmarkMap &benchmark::BenchRunner::benchmarks() { + static std::map<std::string, benchmark::BenchFunction> benchmarks_map; + return benchmarks_map; +} static double gettimedouble(void) { struct timeval tv; @@ -19,7 +22,7 @@ static double gettimedouble(void) { benchmark::BenchRunner::BenchRunner(std::string name, benchmark::BenchFunction func) { - benchmarks.insert(std::make_pair(name, func)); + benchmarks().insert(std::make_pair(name, func)); } void @@ -29,12 +32,9 @@ benchmark::BenchRunner::RunAll(double elapsedTimeForOne) std::cout << "#Benchmark" << "," << "count" << "," << "min" << "," << "max" << "," << "average" << "," << "min_cycles" << "," << "max_cycles" << "," << "average_cycles" << "\n"; - for (std::map<std::string,benchmark::BenchFunction>::iterator it = benchmarks.begin(); - it != benchmarks.end(); ++it) { - - State state(it->first, elapsedTimeForOne); - benchmark::BenchFunction& func = it->second; - func(state); + for (const auto &p: benchmarks()) { + State state(p.first, elapsedTimeForOne); + p.second(state); } perf_fini(); } diff --git a/src/bench/bench.h b/src/bench/bench.h index 80dad6a8ef..0e7605c726 100644 --- a/src/bench/bench.h +++ b/src/bench/bench.h @@ -63,7 +63,8 @@ namespace benchmark { class BenchRunner { - static std::map<std::string, BenchFunction> benchmarks; + typedef std::map<std::string, BenchFunction> BenchmarkMap; + static BenchmarkMap &benchmarks(); public: BenchRunner(std::string name, BenchFunction func); diff --git a/src/bench/perf.cpp b/src/bench/perf.cpp index 1f43e5d3ac..a549ec29ea 100644 --- a/src/bench/perf.cpp +++ b/src/bench/perf.cpp @@ -6,7 +6,7 @@ #if defined(__i386__) || defined(__x86_64__) -/* These architectures support quering the cycle counter +/* These architectures support querying the cycle counter * from user space, no need for any syscall overhead. */ void perf_init(void) { } diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp index 9bab3a2026..a3d02afcdb 100644 --- a/src/bitcoind.cpp +++ b/src/bitcoind.cpp @@ -136,17 +136,17 @@ bool AppInit(int argc, char* argv[]) if (!AppInitBasicSetup()) { // InitError will have been called with detailed error, which ends up on console - exit(1); + exit(EXIT_FAILURE); } if (!AppInitParameterInteraction()) { // InitError will have been called with detailed error, which ends up on console - exit(1); + exit(EXIT_FAILURE); } if (!AppInitSanityChecks()) { // InitError will have been called with detailed error, which ends up on console - exit(1); + exit(EXIT_FAILURE); } if (GetBoolArg("-daemon", false)) { diff --git a/src/blockencodings.h b/src/blockencodings.h index 281db9fe01..5a1d80d421 100644 --- a/src/blockencodings.h +++ b/src/blockencodings.h @@ -99,7 +99,7 @@ public: } }; -// Dumb serialization/storage-helper for CBlockHeaderAndShortTxIDs and PartiallyDownlaodedBlock +// Dumb serialization/storage-helper for CBlockHeaderAndShortTxIDs and PartiallyDownloadedBlock struct PrefilledTransaction { // Used as an offset since last prefilled tx in CBlockHeaderAndShortTxIDs, // as a proper transaction-in-block-index in PartiallyDownloadedBlock diff --git a/src/bloom.cpp b/src/bloom.cpp index 520e10cdc8..8d47cb76e8 100644 --- a/src/bloom.cpp +++ b/src/bloom.cpp @@ -19,15 +19,13 @@ #define LN2SQUARED 0.4804530139182014246671025263266649717305529515945455 #define LN2 0.6931471805599453094172321214581765680755001343602552 -using namespace std; - CBloomFilter::CBloomFilter(unsigned int nElements, double nFPRate, unsigned int nTweakIn, unsigned char nFlagsIn) : /** * The ideal size for a bloom filter with a given number of elements and false positive rate is: * - nElements * log(fp rate) / ln(2)^2 * We ignore filter parameters which will create a bloom filter larger than the protocol limits */ - vData(min((unsigned int)(-1 / LN2SQUARED * nElements * log(nFPRate)), MAX_BLOOM_FILTER_SIZE * 8) / 8), + vData(std::min((unsigned int)(-1 / LN2SQUARED * nElements * log(nFPRate)), MAX_BLOOM_FILTER_SIZE * 8) / 8), /** * The ideal number of hash functions is filter size * ln(2) / number of elements * Again, we ignore filter parameters which will create a bloom filter with more hash functions than the protocol limits @@ -35,7 +33,7 @@ CBloomFilter::CBloomFilter(unsigned int nElements, double nFPRate, unsigned int */ isFull(false), isEmpty(true), - nHashFuncs(min((unsigned int)(vData.size() * 8 / nElements * LN2), MAX_HASH_FUNCS)), + nHashFuncs(std::min((unsigned int)(vData.size() * 8 / nElements * LN2), MAX_HASH_FUNCS)), nTweak(nTweakIn), nFlags(nFlagsIn) { @@ -58,7 +56,7 @@ inline unsigned int CBloomFilter::Hash(unsigned int nHashNum, const std::vector< return MurmurHash3(nHashNum * 0xFBA4C795 + nTweak, vDataToHash) % (vData.size() * 8); } -void CBloomFilter::insert(const vector<unsigned char>& vKey) +void CBloomFilter::insert(const std::vector<unsigned char>& vKey) { if (isFull) return; @@ -75,17 +73,17 @@ void CBloomFilter::insert(const COutPoint& outpoint) { CDataStream stream(SER_NETWORK, PROTOCOL_VERSION); stream << outpoint; - vector<unsigned char> data(stream.begin(), stream.end()); + std::vector<unsigned char> data(stream.begin(), stream.end()); insert(data); } void CBloomFilter::insert(const uint256& hash) { - vector<unsigned char> data(hash.begin(), hash.end()); + std::vector<unsigned char> data(hash.begin(), hash.end()); insert(data); } -bool CBloomFilter::contains(const vector<unsigned char>& vKey) const +bool CBloomFilter::contains(const std::vector<unsigned char>& vKey) const { if (isFull) return true; @@ -105,13 +103,13 @@ bool CBloomFilter::contains(const COutPoint& outpoint) const { CDataStream stream(SER_NETWORK, PROTOCOL_VERSION); stream << outpoint; - vector<unsigned char> data(stream.begin(), stream.end()); + std::vector<unsigned char> data(stream.begin(), stream.end()); return contains(data); } bool CBloomFilter::contains(const uint256& hash) const { - vector<unsigned char> data(hash.begin(), hash.end()); + std::vector<unsigned char> data(hash.begin(), hash.end()); return contains(data); } @@ -154,7 +152,7 @@ bool CBloomFilter::IsRelevantAndUpdate(const CTransaction& tx) // This means clients don't have to update the filter themselves when a new relevant tx // is discovered in order to find spending transactions, which avoids round-tripping and race conditions. CScript::const_iterator pc = txout.scriptPubKey.begin(); - vector<unsigned char> data; + std::vector<unsigned char> data; while (pc < txout.scriptPubKey.end()) { opcodetype opcode; @@ -168,7 +166,7 @@ bool CBloomFilter::IsRelevantAndUpdate(const CTransaction& tx) else if ((nFlags & BLOOM_UPDATE_MASK) == BLOOM_UPDATE_P2PUBKEY_ONLY) { txnouttype type; - vector<vector<unsigned char> > vSolutions; + std::vector<std::vector<unsigned char> > vSolutions; if (Solver(txout.scriptPubKey, type, vSolutions) && (type == TX_PUBKEY || type == TX_MULTISIG)) insert(COutPoint(hash, i)); @@ -189,7 +187,7 @@ bool CBloomFilter::IsRelevantAndUpdate(const CTransaction& tx) // Match if the filter contains any arbitrary script data element in any scriptSig in tx CScript::const_iterator pc = txin.scriptSig.begin(); - vector<unsigned char> data; + std::vector<unsigned char> data; while (pc < txin.scriptSig.end()) { opcodetype opcode; @@ -280,7 +278,7 @@ void CRollingBloomFilter::insert(const std::vector<unsigned char>& vKey) void CRollingBloomFilter::insert(const uint256& hash) { - vector<unsigned char> vData(hash.begin(), hash.end()); + std::vector<unsigned char> vData(hash.begin(), hash.end()); insert(vData); } @@ -300,7 +298,7 @@ bool CRollingBloomFilter::contains(const std::vector<unsigned char>& vKey) const bool CRollingBloomFilter::contains(const uint256& hash) const { - vector<unsigned char> vData(hash.begin(), hash.end()); + std::vector<unsigned char> vData(hash.begin(), hash.end()); return contains(vData); } diff --git a/src/chain.cpp b/src/chain.cpp index 0f4d422b9f..a5b369c4fc 100644 --- a/src/chain.cpp +++ b/src/chain.cpp @@ -5,8 +5,6 @@ #include "chain.h" -using namespace std; - /** * CChain implementation */ diff --git a/src/chainparams.cpp b/src/chainparams.cpp index d99f800f0a..8c38558829 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -97,10 +97,10 @@ public: consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout = 1510704000; // November 15th, 2017. // The best chain should have at least this much work. - consensus.nMinimumChainWork = uint256S("0x0000000000000000000000000000000000000000002cb971dd56d1c583c20f90"); + consensus.nMinimumChainWork = uint256S("0x0000000000000000000000000000000000000000003f94d1ad391682fe038bf5"); // By default assume that the signatures in ancestors of this block are valid. - consensus.defaultAssumeValid = uint256S("0x0000000000000000030abc968e1bd635736e880b946085c93152969b9a81a6e2"); //447235 + consensus.defaultAssumeValid = uint256S("0x00000000000000000013176bf8d7dfeab4e1db31dc93bc311b436e82ab226b90"); //453354 /** * The message start string is designed to be unlikely to occur in normal data. @@ -124,8 +124,8 @@ public: vSeeds.push_back(CDNSSeedData("bluematt.me", "dnsseed.bluematt.me", true)); // Matt Corallo, only supports x9 vSeeds.push_back(CDNSSeedData("dashjr.org", "dnsseed.bitcoin.dashjr.org")); // Luke Dashjr vSeeds.push_back(CDNSSeedData("bitcoinstats.com", "seed.bitcoinstats.com", true)); // Christian Decker, supports x1 - xf - vSeeds.push_back(CDNSSeedData("xf2.org", "bitseed.xf2.org")); // Jeff Garzik vSeeds.push_back(CDNSSeedData("bitcoin.jonasschnelli.ch", "seed.bitcoin.jonasschnelli.ch", true)); // Jonas Schnelli, only supports x1, x5, x9, and xd + vSeeds.push_back(CDNSSeedData("petertodd.org", "seed.btc.petertodd.org", true)); // Peter Todd, only supports x1, x5, x9, and xd base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1,0); base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,5); @@ -202,10 +202,10 @@ public: consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout = 1493596800; // May 1st 2017 // The best chain should have at least this much work. - consensus.nMinimumChainWork = uint256S("0x0000000000000000000000000000000000000000000000198b4def2baa9338d6"); + consensus.nMinimumChainWork = uint256S("0x00000000000000000000000000000000000000000000001f057509eba81aed91"); // By default assume that the signatures in ancestors of this block are valid. - consensus.defaultAssumeValid = uint256S("0x000000000871ee6842d3648317ccc8a435eb8cc3c2429aee94faff9ba26b05a0"); //1043841 + consensus.defaultAssumeValid = uint256S("0x00000000000128796ee387cf110ccb9d2f36cffaf7f73079c995377c65ac0dcc"); //1079274 pchMessageStart[0] = 0x0b; pchMessageStart[1] = 0x11; diff --git a/src/chainparamsseeds.h b/src/chainparamsseeds.h index 1406e86805..396a411689 100644 --- a/src/chainparamsseeds.h +++ b/src/chainparamsseeds.h @@ -8,943 +8,1174 @@ * 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,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,0x02,0x07,0x08,0x0c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x02,0xe4,0x46,0xc6}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x27,0x40,0x07}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x2d,0x50,0x22}, 38333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x33,0xa0,0x26}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x3d,0x21,0x21}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x3d,0x25,0x0c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x5f,0x50,0x2f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x66,0xa4,0xad}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0xaf,0x47,0x82}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0xbd,0xa5,0x16}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0xc7,0x82,0xe4}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0xe4,0x64,0xde}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0xff,0x40,0xe7}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x0d,0x5d,0x06,0x85}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x12,0x55,0x22,0x0a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x12,0xf1,0x00,0x3f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0x1c,0x80,0x41}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0xf8,0x71,0x34}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0xfd,0x97,0x49}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x04,0x60,0x79}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x45,0x41,0xbf}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x57,0x08,0x2b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x96,0xe0,0x6e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0xe3,0x45,0x92}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1b,0x00,0xeb,0x21}, 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,0x1f,0xb8,0xc5,0x60}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0xd6,0xf0,0x38}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0x01,0xca,0x86}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0x12,0x4a,0xe8}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0x22,0x30,0x11}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0x30,0x40,0x8c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0x61,0x8d,0x74}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0x78,0xa4,0x10}, 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,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,0x25,0x8f,0x09,0x80}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0x99,0xac,0xe3}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xc1,0xe3,0x10}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xcd,0x08,0x4e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xdc,0x00,0x72}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xe8,0xda,0xc7}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x26,0x8c,0xa1,0x35}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x28,0x57,0x46,0x78}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x29,0xa2,0xa3,0x5d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2a,0x02,0xc6,0x30}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x14,0x43,0x01}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x37,0xc5,0x4d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x38,0x61,0x3f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x3a,0x26,0xa2}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x3f,0x01,0x21}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x4f,0x02,0x46}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x10,0xf0,0x62}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x13,0x89,0x4a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x1c,0xce,0x92}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x20,0xfc,0xc5}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x3b,0x0d,0x3b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x3b,0x27,0xc3}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x94,0x10,0xd2}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xa0,0xc3,0x79}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xa6,0x8e,0x15}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xa6,0xa0,0x1d}, 8330}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xbc,0x2c,0x14}, 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,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,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,0x2e,0xe7,0x10,0x95}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2f,0x58,0x64,0x82}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2f,0x59,0xc0,0x86}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2f,0xb9,0xc2,0xa0}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2f,0xbd,0x81,0xda}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x31,0x41,0x02,0x8c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x03,0x48,0x81}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x1f,0x63,0xe1}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x33,0xaf,0x21,0x5f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x34,0x01,0xa5,0xdb}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x34,0x0a,0xaa,0xba}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x34,0x33,0x80,0xd8}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xc5,0x82,0xf4}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3a,0x3b,0x02,0x16}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3a,0x54,0x06,0x51}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3b,0x7d,0x08,0x8f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3b,0xa7,0x82,0x8b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3d,0x2f,0x02,0x14}, 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,0x41,0x27,0x0c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0x4c,0x60,0x06}, 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,0x0f,0x3a}, 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,0x85,0xc2,0x9c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0x8a,0x01,0x5f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0xd8,0xee,0x03}, 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,0x3f,0x89,0x28,0xcf}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3f,0xe7,0x60,0x6d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x40,0x4e,0xf0,0x96}, 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,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,0x96,0x69,0x4d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x40,0x89,0xec,0x44}, 8833}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x40,0x9c,0xc1,0x78}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0x4f,0xa0,0x52}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0x5b,0xe6,0xe7}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0x87,0x80,0x79}, 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,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,0xd7,0x22,0x1a}, 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,0xcd,0x60,0x6c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0xcd,0x80,0x05}, 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,0x43,0xdd,0xc1,0x37}, 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,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,0x44,0x64,0xc4,0x76}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x44,0x84,0xc1,0xde}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x44,0xa8,0x76,0xea}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x0b,0x61,0x2b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x1e,0xe5,0x0a}, 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,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,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,0x45,0x7d,0xc1,0x91}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0xa2,0x8b,0x7d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x46,0x23,0x62,0x27}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x46,0x70,0x20,0x1d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0x7e,0xb5,0x92}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0xb4,0x20,0x69}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x49,0xe2,0x40,0x91}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0x53,0x8c,0xf2}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0x54,0x80,0x9e}, 9333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0x7a,0xed,0x7c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0xd7,0x85,0x91}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4b,0x4c,0x65,0xa9}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4b,0x55,0x0d,0x08}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4b,0x56,0xa8,0x0d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4b,0xaa,0x61,0x19}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4b,0xb1,0x89,0x86}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4c,0x4c,0xe3,0x88}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0x35,0x88,0x06}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0x6e,0x0b,0x34}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x19,0x20,0xce}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x22,0x08,0x78}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x2e,0x20,0x63}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x38,0x09,0xd6}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x38,0xe5,0xb1}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x81,0xed,0xf5}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0xc4,0xac,0x2d}, 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,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,0x4f,0xac,0xc2,0xdb}, 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,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,0x50,0x59,0x89,0x73}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0x5d,0x24,0xad}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0x65,0xa7,0x64}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0x72,0x22,0x9e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0x7f,0x88,0x32}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0xbc,0x8b,0x52}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0xde,0x27,0x4d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0xdf,0x69,0x45}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0xe5,0x97,0xbb}, 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,0x07,0x0a,0xee}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0x07,0x0d,0x54}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0x1b,0x60,0x5c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0x23,0x8f,0x62}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0x52,0xc9,0x05}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0x53,0x60,0x05}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0xa9,0xe3,0x24}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0xab,0x02,0x77}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0xab,0x26,0x82}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0xaf,0xff,0x76}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0xcf,0x08,0x31}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0xe4,0xc2,0xbb}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0x09,0x01,0x4d}, 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,0x66,0x0d,0x75}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0x74,0xcb,0xf0}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0x82,0x67,0x10}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0x88,0x41,0xe3}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0x9e,0xe3,0xee}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xc5,0xd4,0x19}, 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,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,0xc8,0xcc,0x29}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xc8,0xcc,0x77}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xdd,0x69,0xdf}, 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,0x52,0xdd,0x6f,0x88}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xdd,0x8b,0x61}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0x89,0x29,0x0a}, 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,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,0x18,0x45,0x3b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xa9,0x02,0x2b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xd9,0xcb,0x82}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xf9,0x58,0x34}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0x1a,0xa2,0x5c}, 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,0xd6,0x42,0xa8}, 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,0x54,0x86,0xc2,0x73}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0xc9,0x20,0x73}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0xd4,0xe8,0x47}, 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,0x55,0x0a,0x68,0x22}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0x15,0x90,0xe2}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0x19,0xc2,0x0c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0x90,0x4f,0xbe}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0x91,0xe4,0xc0}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0xc2,0xee,0x82}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0xe4,0xc9,0x50}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0xe5,0xe4,0xae}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0xec,0xe9,0x57}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x56,0x50,0xcc,0xb9}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x56,0x69,0xe3,0xbe}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x56,0x87,0x27,0x28}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0x6a,0x8b,0x7f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0x78,0x08,0x05}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0x78,0x25,0xe6}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0xef,0x65,0x66}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0xf3,0xc5,0x52}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0x70,0x70,0xad}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0x96,0xc0,0x11}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xb9,0x9b,0x86}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xca,0xca,0xdd}, 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,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,0x58,0xd0,0x27,0xb6}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0x22,0x63,0x29}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0xa3,0xe0,0xbb}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0xa9,0xe9,0x96}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0xb8,0x41,0x55}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0xd4,0x5b,0xdb}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0xf9,0xb2,0x24}, 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,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,0x41,0x61,0x9d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x6b,0x40,0x8f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x72,0x23,0x6b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x87,0x00,0xbb}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x91,0x6e,0x5f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x9d,0x26,0x97}, 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,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,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,0x5b,0xcd,0xb0,0x36}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xce,0xcb,0x0a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xce,0xcb,0x12}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xd7,0x23,0x82}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xdb,0xef,0x9f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xdf,0x85,0x02}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xdf,0x85,0x28}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xe2,0x0a,0x5a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xf0,0x8d,0xa9}, 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,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,0x5c,0x59,0x43,0xcf}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5c,0xdd,0xc9,0x8a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5d,0x5f,0xbb,0x7a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5d,0x67,0x49,0xbb}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5d,0x7b,0x50,0x2f}, 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,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,0xec,0xc6,0xfd}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5d,0xbe,0x45,0xf2}, 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,0x5e,0x9c,0x80,0x74}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xb1,0xab,0x49}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xb5,0x2c,0x68}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xed,0x1a,0xad}, 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,0x5e,0xff,0x80,0x62}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0x4f,0x23,0x32}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0x5b,0x29,0x27}, 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,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,0x80,0xe1,0xdf}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0x80,0x30,0xd1}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0xb7,0x30,0x47}, 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,0x61,0x40,0xb1,0x0a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x61,0x68,0xc9,0x5f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0x1d,0xc5,0x95}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0xa9,0x02,0x6b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x63,0xe8,0x30,0x48}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x65,0x64,0x8d,0x37}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x67,0x07,0x20,0x28}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x67,0x35,0xe1,0x45}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x67,0xf9,0x6a,0x4a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0x80,0xe0,0x0d}, 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,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,0x9b,0x01,0x9e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0xa8,0x80,0x32}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0xc7,0xa0,0xe4}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0xcc,0x6d,0x0b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0xdb,0xfb,0x76}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0xdf,0x03,0x81}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0xdf,0x03,0xdb}, 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,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,0x68,0xf5,0x63,0xe3}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6a,0x26,0xea,0x59}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6a,0x68,0x86,0xda}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6b,0x88,0x06,0x47}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6b,0x96,0x2d,0xd2}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6b,0x97,0x90,0x67}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6b,0xaa,0x2c,0x63}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6b,0xb5,0x89,0x85}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6b,0xbf,0x66,0x0d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0x3a,0xfc,0x52}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0x3b,0x09,0xa7}, 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,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,0x6c,0xa2,0x6a,0xd7}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0xa8,0x85,0xa4}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0xad,0xca,0x65}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0xb4,0x6e,0xbe}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0x1d,0x4b,0x28}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0x78,0xc2,0x88}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xe6,0xe6,0x58}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xeb,0x43,0x73}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xeb,0x45,0x78}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xec,0x5a,0xc7}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xff,0x00,0x6b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6e,0x0a,0x82,0x0c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6e,0x0a,0xb0,0x5e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6e,0x84,0xac,0xfb}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6f,0x5a,0x9e,0x11}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x73,0x42,0xcd,0xab}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x74,0x1f,0x7b,0x8b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x76,0xc0,0x30,0x2e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x76,0xc1,0xa4,0x62}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x77,0x1d,0x9c,0xe7}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x77,0x3f,0x2c,0x85}, 19980}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x77,0x51,0x63,0x1b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x77,0x6a,0x0c,0xa9}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x77,0x93,0x89,0x9b}, 19980}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x77,0xb9,0x01,0xb6}, 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,0x7f,0x26,0xc3}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x79,0xfe,0xad,0x17}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x79,0xfe,0xad,0x28}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x7b,0x38,0x81,0x2d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x7b,0xcb,0xa3,0x80}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x7b,0xce,0x20,0xc6}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x7c,0xbd,0xa0,0xdd}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x7c,0xbd,0xc0,0xe8}, 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,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,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,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,0x80,0xc7,0x44,0xcd}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x82,0xea,0xcf,0x73}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x83,0x71,0x29,0x7b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x83,0x72,0x48,0x68}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x84,0xcc,0x6c,0x9b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x86,0x77,0x0d,0xe6}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x86,0xd5,0x85,0xce}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x86,0xd5,0x85,0xcf}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x87,0x17,0x05,0x03}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x89,0x4a,0x00,0x42}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8a,0x44,0x01,0x2d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8a,0x44,0x02,0xc2}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8a,0x44,0x40,0x13}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8a,0x44,0x40,0x1c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8b,0x3b,0x2a,0xf8}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8b,0xdc,0xf0,0x99}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8c,0x70,0x6b,0x76}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8c,0xba,0xe0,0x70}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8d,0x34,0x40,0x8d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8e,0x44,0xed,0x6b}, 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,0x92,0x3c,0xcc,0x5c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x92,0xb9,0xa1,0xd1}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x94,0x67,0x07,0x77}, 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,0x96,0xe5,0x00,0x8f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x97,0xe7,0xee,0x19}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x97,0xf8,0xa0,0xe3}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x99,0xe6,0xe4,0x0f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x9b,0x85,0x2b,0xf9}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x9e,0x3a,0xee,0x91}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x9e,0x6d,0x4f,0x0d}, 34821}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x9f,0xcb,0x46,0xd0}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa0,0x10,0xce,0x1f}, 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,0xf8,0x63,0xa4}, 53011}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xd8,0xc0,0xe7}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xf3,0x64,0x6f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xf6,0x0b,0xc2}, 8333}, {{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,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,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,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,0xa2,0xfc,0x2e,0x53}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa3,0xac,0x21,0x4e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa3,0xac,0xc2,0x1e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa9,0xe5,0xc6,0x6a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xaa,0x4b,0xc3,0xa8}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xac,0x67,0xcd,0xc5}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xac,0xf5,0xe1,0x7e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xb3,0x25,0x08}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xd0,0xcb,0x4a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xfc,0x2e,0x10}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x75,0x8d,0x7c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xaf,0x7e,0x26,0x9e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xaf,0x7e,0x26,0xb1}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xaf,0x8b,0x6a,0x77}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xaf,0x8c,0xe8,0x42}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x09,0x75,0x64}, 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,0x24,0x63,0xde}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x38,0xe3,0x24}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x64,0x64,0xce}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x6a,0x90,0xb7}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x7b,0x07,0x94}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x7e,0xa7,0x0a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0xdf,0xc9,0xc6}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x3e,0x44,0x3e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x3e,0x66,0x38}, 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,0x7c,0xc5,0x65}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xaa,0x8a,0xca}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xaf,0x81,0x12}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xbc,0x2f,0x3e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xc7,0xf0,0x16}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xda,0xd1,0xa2}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xed,0x23,0x22}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xee,0xe0,0xf2}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xfe,0x22,0x90}, 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,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,0xb3,0x2b,0xb7,0x02}, 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,0xb6,0x5d,0x22,0x82}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x08,0xee,0xc5}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x0b,0x8b,0xac}, 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,0x9b,0x88,0x46}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x18,0xe9,0x64}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x19,0x30,0x47}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x19,0x30,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,0x46,0x69,0x98}, 8339}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x4d,0x80,0x45}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x4d,0x80,0xf1}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x56,0x4f,0x57}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x59,0x66,0x02}, 3333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x59,0x66,0x35}, 3333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x6d,0x90,0x9b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x75,0x4b,0x32}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x79,0xad,0xdf}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x80,0x29,0x9d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x82,0xe2,0x6a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x91,0x82,0x4c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x3f,0xc0,0x68}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x71,0xa4,0xe7}, 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,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,0xbc,0xd6,0x80,0x4d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbe,0x0a,0x08,0xd3}, 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,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,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,0xbe,0x6f,0xe7,0x13}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x83,0x2c,0x5d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0xce,0xca,0x06}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0xe3,0xf5,0x85}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0xf1,0x4a,0x7b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0xf1,0x4a,0x7e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0xfe,0x47,0xde}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0x0a,0x40,0x55}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0x2e,0x50,0x65}, 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,0x5d,0x4f,0xd7}, 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,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,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,0xc1,0xef,0x50,0x9b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc2,0x3f,0x8c,0xd0}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc2,0x57,0x01,0xe8}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc2,0xbb,0xe3,0x12}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc2,0xf7,0x0c,0x88}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0x5b,0xb0,0x56}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc4,0x1c,0x62,0x14}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x2c,0xf9,0x23}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x54,0xac,0xfc}, 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,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,0xc6,0xd3,0x61,0x2e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc7,0x42,0x40,0xc6}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc7,0x65,0x64,0x3a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc7,0x65,0x64,0x3b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc7,0x7f,0xe0,0x32}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc8,0x2e,0xf1,0x47}, 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,0xcc,0x70,0xcb,0x34}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcb,0x09,0xe1,0x0d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcb,0xb1,0x8e,0x25}, 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,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,0xcd,0xd1,0x83,0x96}, 13838}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xce,0x35,0x40,0x4a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xce,0x48,0xc0,0x45}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xce,0x7b,0x70,0xb4}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd0,0x42,0xd0,0x99}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd0,0x44,0xae,0x4c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd0,0x6b,0x61,0xf2}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd0,0x6f,0x30,0x84}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd0,0x76,0xeb,0xbe}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0x06,0xcd,0x7e}, 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,0x3a,0x82,0x89}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0x49,0x8e,0xe2}, 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,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,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,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,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,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,0xd1,0x7e,0x45,0xf3}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0x7e,0x6c,0x5b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0xc3,0x04,0x12}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0xfa,0x06,0xbe}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd2,0x36,0x25,0xe1}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd2,0xdf,0x03,0x2c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd3,0x95,0xea,0x6d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0x33,0x8c,0xb7}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0x5a,0xb3,0xce}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0x5d,0xe2,0x5a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0x6e,0xab,0x76}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0xca,0x84,0x11}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0x5b,0xcd,0x86}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0xa5,0x44,0xda}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0xc4,0xc8,0xd5}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0x3b,0x04,0xd4}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0x4a,0x20,0x6d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0x9e,0xe1,0x46}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0xa4,0x8a,0x0d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0xa7,0xec,0xf7}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0xc5,0x4f,0x4a}, 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,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,0x0c,0xc7,0xcf}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x14,0x82,0x48}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x17,0x06,0x94}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x17,0x8c,0x67}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x1c,0x60,0xb4}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x23,0x82,0x2a}, 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,0xdc,0xf5,0xc4,0x25}, 8333}, - {{0x20,0x01,0x12,0x91,0x02,0xbf,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0xa8,0x8f,0xa9}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0xd1,0x20,0xdb}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xda,0xa1,0x21,0xa5}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xdd,0x79,0x90,0x8a}, 8333}, + {{0x20,0x01,0x00,0x00,0x41,0x37,0x9e,0x76,0x20,0x48,0x3a,0x84,0xbb,0x91,0xe8,0x46}, 8333}, + {{0x20,0x01,0x00,0x00,0x41,0x37,0x9e,0x76,0x20,0x66,0x0e,0x9e,0xb4,0x89,0xf8,0xb8}, 8333}, + {{0x20,0x01,0x00,0x00,0x41,0x37,0x9e,0x76,0x38,0x54,0x12,0x11,0xb5,0xac,0xa9,0x6b}, 8333}, + {{0x20,0x01,0x00,0x00,0x41,0x37,0x9e,0x76,0x04,0xe3,0x1f,0x66,0xcd,0x4c,0x82,0x9f}, 8333}, + {{0x20,0x01,0x00,0x00,0x41,0x37,0x9e,0x76,0x00,0xad,0x01,0xf4,0x9e,0xa9,0xfa,0x2e}, 8333}, + {{0x20,0x01,0x00,0x00,0x41,0x37,0x9e,0x76,0x00,0xe5,0x0b,0xaa,0xb6,0x6f,0xf4,0x18}, 8333}, + {{0x20,0x01,0x00,0x00,0x53,0xaa,0x06,0x4c,0x20,0xa2,0x59,0xc4,0xad,0x22,0x93,0xea}, 8333}, + {{0x20,0x01,0x00,0x00,0x53,0xaa,0x06,0x4c,0x00,0x59,0x61,0x7f,0xa1,0x0d,0x00,0xe0}, 8333}, + {{0x20,0x01,0x00,0x00,0x5e,0xf5,0x79,0xfb,0x20,0x0f,0x3a,0xe5,0x3c,0xbc,0x74,0xc9}, 8333}, + {{0x20,0x01,0x00,0x00,0x5e,0xf5,0x79,0xfb,0x38,0xf2,0x13,0xb4,0xb2,0x08,0x56,0x04}, 8333}, + {{0x20,0x01,0x00,0x00,0x5e,0xf5,0x79,0xfd,0x20,0x0b,0x22,0xa7,0xcc,0x50,0xf5,0x2d}, 8333}, + {{0x20,0x01,0x00,0x00,0x5e,0xf5,0x79,0xfd,0x24,0xef,0x1a,0xef,0xa9,0x94,0x30,0x3d}, 8333}, + {{0x20,0x01,0x00,0x00,0x5e,0xf5,0x79,0xfd,0x24,0xfc,0x0b,0x5d,0xad,0x4f,0x4d,0xb2}, 8333}, + {{0x20,0x01,0x00,0x00,0x5e,0xf5,0x79,0xfd,0x28,0xbf,0x2d,0x23,0xe0,0x2e,0xc3,0xef}, 8333}, + {{0x20,0x01,0x00,0x00,0x5e,0xf5,0x79,0xfd,0x3c,0xd0,0x3c,0x2e,0xda,0x44,0xa7,0x59}, 8333}, + {{0x20,0x01,0x00,0x00,0x5e,0xf5,0x79,0xfd,0x08,0x7e,0x0f,0xd7,0xb1,0xc2,0x01,0xb4}, 8333}, + {{0x20,0x01,0x00,0x00,0x9d,0x38,0x6a,0xb8,0x18,0xdb,0x3b,0xda,0xab,0x90,0xe8,0x1e}, 8333}, + {{0x20,0x01,0x00,0x00,0x9d,0x38,0x6a,0xb8,0x04,0xe7,0x16,0x60,0x86,0x2f,0xa6,0xd7}, 8333}, + {{0x20,0x01,0x00,0x00,0x9d,0x38,0x6a,0xb8,0x00,0x06,0x00,0x2b,0x50,0x74,0x95,0x88}, 8333}, + {{0x20,0x01,0x00,0x00,0x9d,0x38,0x6a,0xbd,0x10,0xf8,0xa7,0xd7,0xbb,0x90,0xf5,0x24}, 8333}, + {{0x20,0x01,0x13,0xd8,0x1c,0x01,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x11}, 8333}, + {{0x20,0x01,0x15,0xc0,0x65,0xff,0x06,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x20,0x01,0x16,0x08,0x00,0x10,0x01,0x56,0x00,0xae,0x00,0x00,0x00,0x00,0x4a,0xdb}, 8333}, + {{0x20,0x01,0x16,0x20,0x0b,0x1b,0x88,0x88,0x02,0x0d,0xb9,0xff,0xfe,0x41,0x67,0x10}, 8333}, + {{0x20,0x01,0x16,0x20,0x0b,0x1b,0xfa,0xce,0x02,0x0d,0xb9,0xff,0xfe,0x41,0x67,0x10}, 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,0x16,0x80,0x01,0x01,0x01,0xae,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x16,0xd8,0xff,0x00,0x85,0xde,0x02,0x0c,0x29,0xff,0xfe,0x52,0x95,0x94}, 8333}, + {{0x20,0x01,0x19,0xf0,0x44,0x00,0x43,0x4d,0x54,0x00,0x00,0xff,0xfe,0x42,0x26,0x78}, 8333}, + {{0x20,0x01,0x19,0xf0,0x50,0x00,0x8c,0x8b,0x54,0x00,0x00,0xff,0xfe,0x1f,0xc0,0x23}, 8333}, + {{0x20,0x01,0x19,0xf0,0x50,0x00,0x8c,0xe6,0x54,0x00,0x00,0xff,0xfe,0x1b,0x24,0xa9}, 8333}, + {{0x20,0x01,0x19,0xf0,0x00,0x05,0x03,0x14,0x54,0x00,0x00,0xff,0xfe,0x2c,0x42,0xe8}, 8333}, + {{0x20,0x01,0x19,0xf0,0x00,0x05,0x05,0x1b,0x54,0x00,0x00,0xff,0xfe,0x49,0xfe,0x5b}, 8333}, + {{0x20,0x01,0x19,0xf0,0x00,0x05,0x00,0xbc,0x54,0x00,0x00,0xff,0xfe,0x3b,0x93,0x39}, 8333}, + {{0x20,0x01,0x1a,0xf8,0x40,0x20,0xa0,0x20,0x00,0x05,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, + {{0x20,0x01,0x1b,0xc8,0x01,0xa0,0x59,0x0e,0x02,0xe0,0xf4,0xff,0xfe,0x16,0x3a,0x39}, 8333}, + {{0x20,0x01,0x1c,0x04,0x14,0x01,0x8f,0x00,0xf4,0xfe,0x4f,0xff,0xfe,0x0c,0xdf,0x40}, 8333}, + {{0x20,0x01,0x41,0x28,0x61,0x35,0x00,0x10,0x02,0x0c,0x29,0xff,0xfe,0x69,0x9e,0x81}, 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,0x28,0x61,0x35,0xe0,0x01,0x50,0x54,0x00,0xff,0xfe,0x37,0xe9,0xeb}, 8333}, + {{0x20,0x01,0x41,0xd0,0x10,0x00,0x10,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, + {{0x20,0x01,0x41,0xd0,0x10,0x00,0x14,0x33,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, + {{0x20,0x01,0x41,0xd0,0x10,0x04,0x22,0xae,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, + {{0x20,0x01,0x41,0xd0,0x10,0x04,0x29,0x96,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, + {{0x20,0x01,0x41,0xd0,0x10,0x08,0x11,0xe0,0x00,0x00,0x00,0x00,0x1a,0x5c,0x6d,0x9d}, 8333}, + {{0x20,0x01,0x41,0xd0,0x10,0x08,0x11,0xe0,0x00,0x00,0x00,0x00,0x0b,0x74,0xba,0xf7}, 8333}, + {{0x20,0x01,0x41,0xd0,0x10,0x08,0x23,0x7a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, + {{0x20,0x01,0x41,0xd0,0x10,0x08,0x27,0x52,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, + {{0x20,0x01,0x41,0xd0,0x10,0x08,0x04,0x94,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 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,0x56,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x01,0x6f,0x57,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x01,0x80,0x1e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x01,0x88,0x52,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, {{0x20,0x01,0x41,0xd0,0x00,0x01,0x8b,0x26,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,0xa5,0xb8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, {{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,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,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,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,0x01,0xd2,0x27,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x01,0xdb,0xc4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x01,0xdc,0x5d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x01,0xe1,0x3b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x01,0xef,0x5b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x02,0x16,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x02,0x20,0x3c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x02,0x38,0xc5,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x02,0x05,0x19,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,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,0xb7,0x92,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x02,0xbf,0x2a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x02,0xc7,0x93,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,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,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,0x03,0x03,0x04,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x08,0x1a,0x8a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x08,0x3f,0xa9,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x08,0x46,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x08,0x4f,0x48,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,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,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,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,0x08,0x72,0xc2,0x00,0x0d,0x02,0x42,0xac,0x11,0x00,0x02}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x08,0x80,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x08,0xa7,0x1c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x08,0xbc,0xcc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x08,0xbd,0x45,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x08,0xc6,0x7c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x08,0xde,0x3d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x08,0xe2,0x57,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x08,0xe3,0xe4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x0a,0x14,0xcc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x0a,0x15,0xb2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x0a,0x1a,0xc9,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x0a,0x24,0x96,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x0a,0x30,0x8c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x0a,0x58,0x79,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x0a,0x68,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x0a,0x68,0x2d,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,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,0x0a,0xf5,0x2a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x0d,0x11,0x1c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x0e,0x13,0x88,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, {{0x20,0x01,0x41,0xd0,0x00,0x0e,0x02,0x6b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x0e,0x0f,0x73,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,0x72,0xf3,0x95,0xff,0xfe,0x09,0x75,0x21}, 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,0x44,0x28,0x02,0x00,0x81,0x71,0x0d,0xb6,0x2f,0xf4,0x9c,0x0e,0xa2,0xda}, 8333}, + {{0x20,0x01,0x04,0x70,0x1f,0x07,0x15,0x1c,0xba,0xac,0x6f,0xff,0xfe,0xb7,0x3b,0xa9}, 8333}, + {{0x20,0x01,0x04,0x70,0x1f,0x0b,0x0a,0xd6,0x0a,0x60,0x6e,0xff,0xfe,0xc6,0x23,0x23}, 8333}, + {{0x20,0x01,0x04,0x70,0x1f,0x11,0x06,0x17,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x0f}, 8333}, + {{0x20,0x01,0x04,0x70,0x1f,0x14,0x07,0x3e,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,0x00,0x27,0x00,0xce,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x20,0x01,0x04,0x70,0x1f,0x15,0x11,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10}, 8333}, + {{0x20,0x01,0x04,0x70,0x1f,0x15,0x1b,0x95,0x2c,0x3e,0x8a,0x9a,0x24,0xe1,0x70,0x84}, 8333}, + {{0x20,0x01,0x04,0x70,0x1f,0x15,0x0e,0x9b,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xef}, 8333}, + {{0x20,0x01,0x04,0x70,0x1f,0x1d,0x03,0xa9,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10}, 8333}, + {{0x20,0x01,0x04,0x70,0x00,0x25,0x04,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x20,0x01,0x04,0x70,0x00,0x27,0x01,0x9f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x20,0x01,0x04,0x70,0x00,0x27,0x06,0x65,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x20,0x01,0x04,0x70,0x00,0x28,0x03,0x65,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04}, 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,0x6c,0x4f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xca,0xfe}, 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,0xd0,0x0d,0x00,0x00,0x36,0x64,0xa9,0xff,0xfe,0x9a,0x51,0x50}, 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,0x04,0x70,0x72,0x7b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x11,0x00,0x14}, 8333}, + {{0x20,0x01,0x04,0x70,0x00,0x07,0x02,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x20,0x01,0x04,0x70,0x00,0x07,0x00,0x65,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x20,0x01,0x04,0x70,0x7f,0x85,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x20,0x01,0x04,0x70,0x00,0x08,0x02,0xe1,0x58,0x25,0x39,0xdf,0x3e,0x4c,0x54,0xa8}, 8333}, + {{0x20,0x01,0x04,0x70,0x00,0x08,0x02,0xe1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x43}, 8333}, + {{0x20,0x01,0x04,0x70,0x00,0x08,0x02,0xe1,0xae,0x2a,0xe2,0x57,0x44,0x70,0x63,0x50}, 8333}, + {{0x20,0x01,0x04,0x70,0x00,0x0a,0x0c,0x13,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 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,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}, 8333}, - {{0x20,0x01,0x4d,0xd0,0xff,0x00,0x86,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03}, 8333}, + {{0x20,0x01,0x4b,0xa0,0xba,0xbe,0x08,0x32,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, + {{0x20,0x01,0x4b,0xa0,0xca,0xfe,0x03,0x79,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x4b,0xa0,0xff,0xee,0x00,0x33,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10}, 8333}, {{0x20,0x01,0x4d,0xd0,0xff,0x00,0x9a,0x67,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09}, 8333}, - {{0x20,0x01,0x05,0xc0,0x14,0x00,0x00,0x0b,0x00,0x00,0x00,0x00,0x00,0x00,0x3c,0xc7}, 8333}, {{0x20,0x01,0x06,0x10,0x1b,0x19,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03}, 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,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,0x06,0x78,0x01,0x74,0x40,0x21,0x00,0x00,0x00,0x00,0x00,0x02,0x83,0x33}, 8333}, + {{0x20,0x01,0x06,0x7c,0x16,0xdc,0x12,0x01,0x50,0x54,0x00,0xff,0xfe,0x17,0x4d,0xac}, 8333}, + {{0x20,0x01,0x06,0x7c,0x21,0x28,0xff,0xff,0x60,0x62,0x36,0xff,0xfe,0x30,0x65,0x32}, 8333}, + {{0x20,0x01,0x06,0x7c,0x25,0x64,0x03,0x31,0x35,0x47,0x6e,0x28,0x85,0xa4,0xfb,0x27}, 8333}, + {{0x20,0x01,0x06,0xa0,0x02,0x00,0x03,0x68,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x20,0x01,0x07,0x18,0x08,0x01,0x03,0x11,0x50,0x54,0x00,0xff,0xfe,0x19,0xc4,0x83}, 8333}, + {{0x20,0x01,0x07,0xb8,0x02,0xff,0x00,0x8f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x20,0x01,0x08,0xd8,0x08,0xa6,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0x08,0x6c}, 8333}, + {{0x20,0x01,0x08,0xd8,0x09,0x23,0x84,0x00,0x00,0x00,0x00,0x00,0x00,0x87,0x0e,0xbd}, 8333}, + {{0x20,0x01,0x09,0x60,0x06,0x6d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 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,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,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,0x01,0x0b,0xa8,0x01,0xf1,0xf0,0x69,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x20,0x01,0x0b,0xc8,0x22,0x5f,0x01,0x0e,0x05,0x05,0x65,0x73,0x75,0x73,0x0d,0x0a}, 8333}, + {{0x20,0x01,0x0b,0xc8,0x27,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x0b,0xc8,0x32,0x3c,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x53}, 8333}, + {{0x20,0x01,0x0b,0xc8,0x32,0x3c,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x04}, 8333}, + {{0x20,0x01,0x0b,0xc8,0x32,0x3c,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xca,0xfe}, 8333}, + {{0x20,0x01,0x0b,0xc8,0x36,0x80,0x42,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x0b,0xc8,0x39,0x9f,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x0b,0xc8,0x3c,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05}, 8333}, + {{0x20,0x01,0x0b,0xc8,0x47,0x00,0x23,0x00,0x00,0x00,0x00,0x00,0x00,0x19,0x08,0x07}, 8333}, + {{0x20,0x01,0x0e,0x42,0x01,0x02,0x18,0x05,0x01,0x60,0x00,0x16,0x02,0x06,0x00,0x31}, 8333}, + {{0x20,0x02,0x12,0xf1,0x00,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x12,0xf1,0x00,0x3f}, 8333}, + {{0x20,0x02,0x01,0xe2,0x53,0x49,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xe2,0x53,0x49}, 8333}, + {{0x20,0x02,0x01,0xe2,0x55,0x88,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xe2,0x55,0x88}, 8333}, + {{0x20,0x02,0x25,0x01,0xcf,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x25,0x01,0xcf,0x62}, 8333}, + {{0x20,0x02,0x26,0x8c,0xa1,0x35,0x00,0x00,0x00,0x00,0x00,0x00,0x26,0x8c,0xa1,0x35}, 8333}, + {{0x20,0x02,0x2a,0x33,0x99,0xdb,0x00,0x00,0x00,0x00,0x00,0x00,0x2a,0x33,0x99,0xdb}, 8332}, + {{0x20,0x02,0x2e,0xbc,0x2c,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07}, 8333}, + {{0x20,0x02,0x2f,0x59,0x2c,0x9c,0x00,0x00,0x00,0x00,0x00,0x00,0x2f,0x59,0x2c,0x9c}, 11885}, + {{0x20,0x02,0x2f,0x5a,0x36,0x19,0x00,0x00,0x00,0x00,0x00,0x00,0x2f,0x5a,0x36,0x19}, 8333}, + {{0x20,0x02,0x2f,0x5a,0x36,0xa4,0x00,0x00,0x00,0x00,0x00,0x00,0x2f,0x5a,0x36,0xa4}, 8333}, + {{0x20,0x02,0x2f,0x5a,0x04,0x29,0x00,0x00,0x00,0x00,0x00,0x00,0x2f,0x5a,0x04,0x29}, 8333}, + {{0x20,0x02,0x2f,0x5a,0x56,0x2a,0x00,0x00,0x00,0x00,0x00,0x00,0x2f,0x5a,0x56,0x2a}, 8333}, + {{0x20,0x02,0x3a,0x3b,0x02,0x16,0x00,0x00,0x00,0x00,0x00,0x00,0x3a,0x3b,0x02,0x16}, 8333}, + {{0x20,0x02,0x3d,0xfa,0x5d,0x23,0x00,0x00,0x00,0x00,0x00,0x00,0x3d,0xfa,0x5d,0x23}, 8333}, + {{0x20,0x02,0x42,0x4f,0xa0,0x52,0x00,0x00,0x00,0x00,0x00,0x00,0x42,0x4f,0xa0,0x52}, 8333}, + {{0x20,0x02,0x45,0x1e,0xe9,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x45,0x1e,0xe9,0x22}, 8333}, + {{0x20,0x02,0x45,0x40,0x4b,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x45,0x40,0x4b,0x30}, 8333}, + {{0x20,0x02,0x51,0xab,0x07,0xcc,0x00,0x00,0x00,0x00,0x00,0x00,0x51,0xab,0x07,0xcc}, 8333}, + {{0x20,0x02,0x05,0x27,0xde,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x27,0xde,0x11}, 8333}, + {{0x20,0x02,0x53,0x95,0x7d,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x53,0x95,0x7d,0x01}, 8333}, + {{0x20,0x02,0x53,0x95,0x7d,0x2a,0x00,0x00,0x00,0x00,0x00,0x00,0x53,0x95,0x7d,0x2a}, 8333}, + {{0x20,0x02,0x56,0x69,0xe3,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x56,0x69,0xe3,0xbe}, 8333}, + {{0x20,0x02,0x56,0x6a,0x5d,0x6d,0x00,0x00,0x00,0x00,0x00,0x00,0x56,0x6a,0x5d,0x6d}, 8333}, + {{0x20,0x02,0x59,0xb9,0xf8,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x59,0xb9,0xf8,0x20}, 8333}, + {{0x20,0x02,0x59,0xf8,0xac,0x69,0x00,0x00,0x00,0x00,0x00,0x00,0x59,0xf8,0xac,0x69}, 8333}, + {{0x20,0x02,0x5b,0xd4,0xb6,0x5a,0x00,0x00,0x00,0x00,0x00,0x00,0x5b,0xd4,0xb6,0x5a}, 8333}, + {{0x20,0x02,0x5c,0x3f,0x39,0xdb,0x00,0x00,0x00,0x00,0x00,0x00,0x5c,0x3f,0x39,0xdb}, 8333}, + {{0x20,0x02,0x5d,0x33,0x8d,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x5d,0x33,0x8d,0x03}, 8333}, + {{0x20,0x02,0x5d,0x67,0x49,0xbb,0x00,0x00,0x00,0x00,0x00,0x00,0x5d,0x67,0x49,0xbb}, 8333}, + {{0x20,0x02,0x5d,0xae,0x5d,0x5f,0x00,0x00,0x00,0x00,0x00,0x00,0x5d,0xae,0x5d,0x5f}, 8333}, + {{0x20,0x02,0x5d,0xbe,0x8c,0xc6,0x00,0x00,0x00,0x00,0x00,0x00,0x5d,0xbe,0x8c,0xc6}, 8333}, + {{0x20,0x02,0x5d,0xbe,0x95,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x5d,0xbe,0x95,0x03}, 8333}, + {{0x20,0x02,0x5f,0xd3,0x89,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x5f,0xd3,0x89,0x44}, 8333}, + {{0x20,0x02,0x5f,0xd3,0x94,0x67,0x00,0x00,0x00,0x00,0x00,0x00,0x5f,0xd3,0x94,0x67}, 8333}, + {{0x20,0x02,0x67,0xf9,0x6a,0x48,0x00,0x00,0x00,0x00,0x00,0x00,0x67,0xf9,0x6a,0x48}, 8333}, + {{0x20,0x02,0x67,0xf9,0x6a,0x4a,0x00,0x00,0x00,0x00,0x00,0x00,0x67,0xf9,0x6a,0x4a}, 8333}, + {{0x20,0x02,0x67,0xf9,0x6a,0x95,0x00,0x00,0x00,0x00,0x00,0x00,0x67,0xf9,0x6a,0x95}, 8333}, + {{0x20,0x02,0x6a,0x0e,0x3e,0xa8,0x00,0x00,0x00,0x00,0x00,0x00,0x6a,0x0e,0x3e,0xa8}, 10011}, + {{0x20,0x02,0x6b,0x96,0x37,0x5a,0x00,0x00,0x00,0x00,0x00,0x00,0x6b,0x96,0x37,0x5a}, 8333}, + {{0x20,0x02,0x6c,0xa8,0xcf,0xfb,0x00,0x00,0x00,0x00,0x00,0x00,0x6c,0xa8,0xcf,0xfb}, 8333}, + {{0x20,0x02,0x6c,0xaf,0x02,0x34,0x00,0x00,0x00,0x00,0x00,0x00,0x6c,0xaf,0x02,0x34}, 8333}, + {{0x20,0x02,0x6d,0xec,0x58,0xf5,0x00,0x00,0x00,0x00,0x00,0x00,0x6d,0xec,0x58,0xf5}, 8333}, + {{0x20,0x02,0x6d,0xec,0x5a,0xc7,0x00,0x00,0x00,0x00,0x00,0x00,0x6d,0xec,0x5a,0xc7}, 8333}, + {{0x20,0x02,0x72,0x37,0x4a,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x72,0x37,0x4a,0x02}, 20033}, + {{0x20,0x02,0x72,0x37,0x94,0xfd,0x00,0x00,0x00,0x00,0x00,0x00,0x72,0x37,0x94,0xfd}, 10011}, + {{0x20,0x02,0x72,0x37,0xe4,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x72,0x37,0xe4,0x28}, 8333}, + {{0x20,0x02,0x72,0x37,0xfc,0xf6,0x00,0x00,0x00,0x00,0x00,0x00,0x72,0x37,0xfc,0xf6}, 20188}, + {{0x20,0x02,0x76,0xc0,0x96,0xe6,0x00,0x00,0x00,0x00,0x00,0x00,0x76,0xc0,0x96,0xe6}, 8333}, + {{0x20,0x02,0x78,0x19,0x7e,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x19,0x7e,0x80}, 7743}, + {{0x20,0x02,0x78,0x1a,0xea,0x86,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x1a,0xea,0x86}, 8333}, + {{0x20,0x02,0x78,0x1a,0xf3,0xc2,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x1a,0xf3,0xc2}, 14475}, + {{0x20,0x02,0x78,0x4c,0xc2,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x4c,0xc2,0xc0}, 8333}, + {{0x20,0x02,0x78,0x4c,0xec,0x97,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x4c,0xec,0x97}, 8333}, + {{0x20,0x02,0x79,0x2b,0x26,0x1a,0x00,0x00,0x00,0x00,0x00,0x00,0x79,0x2b,0x26,0x1a}, 8333}, + {{0x20,0x02,0x88,0xf3,0x8c,0xca,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0xf3,0x8c,0xca}, 8333}, + {{0x20,0x02,0x88,0xf3,0xa8,0x3c,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0xf3,0xa8,0x3c}, 8333}, + {{0x20,0x02,0x8a,0xc9,0x51,0x6f,0x00,0x00,0x00,0x00,0x00,0x00,0x8a,0xc9,0x51,0x6f}, 8333}, + {{0x20,0x02,0x8b,0x81,0x6d,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x8b,0x81,0x6d,0x78}, 50344}, + {{0x20,0x02,0x8b,0x81,0x6e,0x5c,0x00,0x00,0x00,0x00,0x00,0x00,0x8b,0x81,0x6e,0x5c}, 38176}, + {{0x20,0x02,0x8b,0xc4,0x90,0xa6,0x00,0x00,0x00,0x00,0x00,0x00,0x8b,0xc4,0x90,0xa6}, 8333}, + {{0x20,0x02,0xac,0x52,0xb8,0x54,0x00,0x00,0x00,0x00,0x00,0x00,0xac,0x52,0xb8,0x54}, 8333}, + {{0x20,0x02,0xad,0xd0,0xc1,0x4a,0x00,0x00,0x00,0x00,0x00,0x00,0xad,0xd0,0xc1,0x4a}, 8333}, + {{0x20,0x02,0xb0,0x7e,0xa7,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0xb0,0x7e,0xa7,0x0a}, 8333}, + {{0x20,0x02,0xb2,0x7c,0xc5,0x65,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x50}, 8333}, + {{0x20,0x02,0xb2,0x7c,0xc5,0x65,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x02,0xb9,0x4d,0x80,0xf1,0x00,0x00,0x00,0x00,0x00,0x00,0xb9,0x4d,0x80,0xf1}, 8333}, + {{0x20,0x02,0xb9,0x82,0xe2,0x6a,0x00,0x00,0x00,0x00,0x00,0x00,0xb9,0x82,0xe2,0x6a}, 8333}, + {{0x20,0x02,0xbc,0xd5,0x31,0x45,0x00,0x00,0x00,0x00,0x00,0x00,0xbc,0xd5,0x31,0x45}, 8333}, + {{0x20,0x02,0xc0,0x8a,0xd2,0x2b,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x8a,0xd2,0x2b}, 8333}, + {{0x20,0x02,0xc0,0xc7,0xf8,0xe3,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xc7,0xf8,0xe3}, 32771}, + {{0x20,0x02,0xc1,0xa9,0xfc,0x5a,0x00,0x00,0x00,0x00,0x00,0x00,0xc1,0xa9,0xfc,0x5a}, 8333}, + {{0x20,0x02,0xc2,0x3f,0x8f,0xc5,0x00,0x00,0x00,0x00,0x00,0x00,0xc2,0x3f,0x8f,0xc5}, 8333}, + {{0x20,0x02,0xd3,0x95,0xea,0x6d,0x00,0x00,0x00,0x00,0x00,0x00,0xd3,0x95,0xea,0x6d}, 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,0xa8,0x19,0x34}, 8333}, - {{0x24,0x00,0x89,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x26,0xc4,0xd6}, 8333}, + {{0x20,0x02,0xd9,0x17,0x0e,0x91,0x00,0x00,0x00,0x00,0x00,0x00,0xd9,0x17,0x0e,0x91}, 8333}, + {{0x20,0x02,0xdb,0x71,0xf4,0x34,0x00,0x00,0x00,0x00,0x00,0x00,0xdb,0x71,0xf4,0x34}, 8333}, + {{0x24,0x00,0x26,0x51,0x01,0x61,0x10,0x00,0x68,0x47,0xd4,0x0f,0xaa,0xa3,0x48,0x48}, 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,0x01,0x25,0x00,0x02,0x03,0x00,0x10,0x01,0x53,0x01,0x20,0x01,0x56,0x00,0x83}, 8333}, + {{0x24,0x01,0xa4,0x00,0x32,0x00,0x56,0x00,0x14,0xee,0xf3,0x61,0x4b,0xdc,0x1f,0x7c}, 8333}, + {{0x24,0x03,0x42,0x00,0x04,0x03,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff}, 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,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}, + {{0x24,0x0b,0x00,0x10,0xca,0x20,0x00,0xf0,0x02,0x24,0xe8,0xff,0xfe,0x1f,0x60,0xd9}, 8333}, + {{0x24,0x0b,0x02,0x50,0x01,0xe0,0x24,0x00,0xb9,0xef,0x8f,0xe3,0xa6,0x9a,0x73,0x78}, 8333}, + {{0x24,0x0d,0x00,0x1a,0x03,0x02,0x86,0x00,0x88,0x76,0xa3,0x6d,0x12,0xee,0xf2,0x85}, 8333}, + {{0x26,0x00,0x3c,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x91,0x3e,0x49}, 8333}, + {{0x26,0x00,0x3c,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0xbb,0x98,0x1e}, 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,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,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,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x91,0x6a,0x29}, 8333}, + {{0x26,0x00,0x3c,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0xf1,0x1e,0xaa}, 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,0x28,0x14,0x45}, 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,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,0x00,0x3c,0x03,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x89,0x11,0x6f}, 8333}, + {{0x26,0x00,0x3c,0x03,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0xb0,0x5f,0xc4}, 8333}, + {{0x26,0x00,0x3c,0x03,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0xe0,0x23,0x3e}, 8333}, + {{0x26,0x00,0x3c,0x03,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0xe0,0x00,0x51}, 8333}, + {{0x26,0x00,0x88,0x05,0x24,0x00,0x01,0x4e,0x02,0x26,0x4a,0xff,0xfe,0x02,0x2b,0xa4}, 8333}, + {{0x26,0x00,0x88,0x07,0x50,0x80,0x33,0x01,0x14,0x87,0x83,0xb7,0x33,0xd7,0xeb,0x97}, 8333}, + {{0x26,0x01,0x01,0x86,0xc1,0x00,0x6b,0xcd,0x16,0xbd,0xce,0xa1,0x23,0x5d,0x1c,0x19}, 8333}, + {{0x26,0x01,0x01,0x8c,0x42,0x00,0x28,0xd0,0x0e,0x4d,0xe9,0xff,0xfe,0xc5,0x76,0xd0}, 8333}, + {{0x26,0x01,0x02,0x47,0x82,0x01,0x62,0x51,0x30,0xe6,0x7b,0x95,0x69,0xbf,0x92,0x48}, 8333}, + {{0x26,0x01,0x06,0x02,0x99,0x80,0x0f,0x78,0x02,0x11,0x11,0xff,0xfe,0xc5,0x01,0xae}, 8333}, + {{0x26,0x02,0x00,0xae,0x19,0x93,0xde,0x00,0x2c,0x50,0x9a,0x44,0x8f,0x11,0x77,0xa5}, 8333}, + {{0x26,0x02,0xff,0x68,0x00,0x00,0x00,0x01,0x02,0x1e,0x0b,0xff,0xfe,0xca,0xdb,0x72}, 8333}, + {{0x26,0x02,0xff,0x68,0x00,0x00,0x00,0x01,0x02,0xbd,0x27,0xff,0xfe,0xb0,0xad,0xf8}, 8333}, + {{0x26,0x02,0xff,0x68,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05}, 8333}, + {{0x26,0x02,0xff,0x68,0x00,0x00,0x00,0x05,0x02,0xbd,0x27,0xff,0xfe,0xb0,0xad,0xf8}, 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,0x9e,0x63,0x27,0xa2}, 8333}, + {{0x26,0x02,0xff,0xc5,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0x30,0x1c,0x75}, 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,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,0x00,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x24,0xc4,0xd9,0xfd}, 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,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,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,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,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,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,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,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,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}, + {{0x26,0x04,0x01,0x80,0x00,0x02,0x0e,0xee,0x00,0x00,0x00,0x00,0x00,0x00,0xca,0x46}, 8333}, + {{0x26,0x04,0x08,0x80,0x00,0x0d,0x00,0x85,0x00,0x00,0x00,0x00,0x00,0x00,0xbe,0x37}, 8333}, + {{0x26,0x04,0x9a,0x00,0x21,0x00,0xa0,0x09,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, + {{0x26,0x04,0xa8,0x80,0x00,0x02,0x00,0xd0,0x00,0x00,0x00,0x00,0x03,0x01,0x80,0x01}, 8333}, + {{0x26,0x04,0xa8,0x80,0x00,0x02,0x00,0xd0,0x00,0x00,0x00,0x00,0x04,0xa9,0x10,0x01}, 8333}, + {{0x26,0x04,0xa8,0x80,0x00,0x02,0x00,0xd0,0x00,0x00,0x00,0x00,0x05,0x3a,0xc0,0x01}, 8333}, + {{0x26,0x04,0xa8,0x80,0x04,0x00,0x00,0xd0,0x00,0x00,0x00,0x00,0x0a,0xd7,0xe0,0x01}, 8333}, + {{0x26,0x04,0xa8,0x80,0x04,0x00,0x00,0xd0,0x00,0x00,0x00,0x00,0x0d,0xcf,0xf0,0x01}, 8333}, + {{0x26,0x05,0x4d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x50}, 8333}, + {{0x26,0x05,0x60,0x00,0xed,0xc8,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xdd,0xfe}, 8333}, + {{0x26,0x05,0x60,0x00,0xff,0xc0,0x00,0x70,0x74,0xd5,0x22,0x5c,0xf5,0x53,0x5b,0xb8}, 8333}, + {{0x26,0x06,0x60,0x00,0xc1,0x48,0x70,0x03,0x50,0x54,0x00,0xff,0xfe,0x78,0x66,0xff}, 8333}, + {{0x26,0x06,0x60,0x00,0xe6,0xd6,0xd7,0x01,0xd4,0x28,0x5e,0x44,0xa2,0xc9,0x3f,0xf6}, 8333}, + {{0x26,0x06,0xc6,0x80,0x00,0x01,0x00,0x4a,0x20,0x16,0xd1,0xff,0xfe,0x93,0x52,0xa7}, 8333}, + {{0x26,0x07,0x53,0x00,0x02,0x03,0x01,0x18,0x37,0x33,0x00,0x00,0x00,0x00,0x14,0x14}, 8333}, + {{0x26,0x07,0x53,0x00,0x00,0x60,0x13,0xbb,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x26,0x07,0x53,0x00,0x00,0x60,0x19,0x66,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x26,0x07,0x53,0x00,0x00,0x60,0x22,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, + {{0x26,0x07,0x53,0x00,0x00,0x60,0x37,0x75,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, + {{0x26,0x07,0x53,0x00,0x00,0x60,0x3d,0xdf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, + {{0x26,0x07,0x53,0x00,0x00,0x60,0xa6,0x54,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, + {{0x26,0x07,0x53,0x00,0x00,0x60,0xa7,0xa3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, + {{0x26,0x07,0x53,0x00,0x00,0x60,0x0a,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x26,0x07,0x53,0x00,0x00,0x60,0xcf,0x97,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, + {{0x26,0x07,0xf0,0xd0,0x19,0x01,0x00,0x19,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06}, 8333}, + {{0x26,0x07,0xf1,0x28,0x00,0x40,0x12,0x02,0x00,0x69,0x01,0x62,0x01,0x39,0x01,0x25}, 8333}, + {{0x26,0x07,0xf1,0x28,0x00,0x40,0x17,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x26,0x07,0xf1,0x78,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x06}, 8333}, + {{0x26,0x07,0xf1,0xc0,0x08,0x4d,0x89,0x00,0x00,0x00,0x00,0x00,0x00,0x7e,0x0c,0xad}, 8333}, + {{0x26,0x07,0xf9,0x48,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x40}, 8333}, + {{0x26,0x07,0xfc,0xd0,0x01,0x00,0x23,0x02,0x00,0x00,0x00,0x00,0x60,0x94,0x63,0x5a}, 8333}, + {{0x26,0x07,0xfc,0xd0,0x01,0x00,0x6a,0x00,0x00,0x00,0x00,0x00,0x3a,0x96,0x00,0x01}, 8333}, + {{0x26,0x07,0xfc,0xd0,0x01,0x00,0x6a,0x02,0x00,0x00,0x00,0x00,0x7f,0xf0,0x00,0x01}, 8333}, + {{0x26,0x07,0xfc,0xd0,0x01,0x00,0x82,0x03,0x00,0x00,0x00,0x00,0x8c,0x58,0x0d,0xbc}, 8333}, + {{0x26,0x07,0xfe,0xa8,0x13,0x60,0x09,0xc2,0x22,0x1a,0x06,0xff,0xfe,0x47,0x77,0x6d}, 8333}, + {{0x26,0x07,0xfe,0xa8,0x4d,0xa0,0x09,0xce,0x51,0x14,0xa8,0xec,0x20,0xf5,0xa5,0x0b}, 8333}, + {{0x26,0x07,0xfe,0xa8,0x05,0xdf,0xfd,0xa0,0xfe,0xaa,0x14,0xff,0xfe,0xda,0xc7,0x9a}, 8333}, + {{0x26,0x07,0xfe,0xa8,0x84,0xc0,0x01,0x63,0xf4,0x2c,0xba,0xff,0xfe,0xcc,0x6b,0xbf}, 8333}, + {{0x26,0x07,0xff,0x10,0x00,0xc5,0x05,0x02,0x02,0x25,0x90,0xff,0xfe,0x32,0xd4,0x46}, 8333}, + {{0x26,0x07,0xff,0x48,0xaa,0x81,0x08,0x00,0x00,0x00,0x00,0x00,0x96,0xcf,0x00,0x01}, 8333}, + {{0x26,0x20,0x01,0x1c,0x50,0x01,0x11,0x18,0xd2,0x67,0xe5,0xff,0xfe,0xe9,0xe6,0x73}, 8333}, + {{0x26,0x20,0x00,0xb8,0x40,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x93,0x00,0x01}, 8333}, + {{0x28,0x00,0x01,0xa0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09}, 8333}, + {{0x2a,0x00,0x11,0x78,0x00,0x02,0x00,0x43,0x19,0xfd,0xd4,0x3e,0x0b,0x77,0xed,0xeb}, 8333}, + {{0x2a,0x00,0x11,0x78,0x00,0x02,0x00,0x43,0xb4,0xe3,0xe5,0x62,0xf8,0x11,0xd7,0x61}, 8333}, {{0x2a,0x00,0x14,0xf0,0xe0,0x00,0x80,0xd2,0xcd,0x1a,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x2a,0x00,0x16,0x30,0x00,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01}, 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,0x16,0x30,0x00,0x02,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04}, 8333}, + {{0x2a,0x00,0x17,0x68,0x20,0x01,0x00,0x24,0x00,0x00,0x00,0x00,0x01,0x48,0x02,0x18}, 8333}, + {{0x2a,0x00,0x17,0x68,0x20,0x01,0x00,0x27,0x00,0x00,0x00,0x00,0x01,0x42,0x00,0x21}, 8333}, + {{0x2a,0x00,0x1a,0x48,0x78,0x10,0x01,0x01,0xbe,0x76,0x4e,0xff,0xfe,0x08,0xc7,0x74}, 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,0x1d,0xc0,0x22,0x55,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x00,0x7c,0x80,0x00,0x00,0x00,0x71,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08}, 8333}, + {{0x2a,0x00,0x7c,0x80,0x00,0x00,0x00,0x97,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07}, 8333}, + {{0x2a,0x00,0xbb,0xe0,0x00,0x00,0x00,0x42,0x02,0x22,0x64,0xff,0xfe,0x9a,0xe2,0x06}, 8333}, + {{0x2a,0x00,0x0c,0x98,0x20,0x50,0xa0,0x20,0x00,0x03,0x00,0x00,0x00,0x00,0x01,0x10}, 8333}, + {{0x2a,0x00,0xdc,0xc0,0x0e,0xda,0x00,0x98,0x01,0x83,0x01,0x93,0x1d,0x24,0xb5,0x3a}, 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,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,0x00,0x0f,0x90,0x0f,0xf0,0xc1,0x00,0x53,0xc4,0x97,0xa7,0x8b,0x59,0x79,0x6a}, 8333}, + {{0x2a,0x01,0x02,0x38,0x43,0x5c,0xde,0x00,0xb1,0x10,0x38,0xcf,0x19,0x2d,0x0b,0x2c}, 28333}, + {{0x2a,0x01,0x03,0x48,0x00,0x06,0x07,0xcf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x03,0x68,0xe0,0x12,0x88,0x88,0x02,0x16,0x3e,0xff,0xfe,0x24,0x11,0x62}, 8333}, + {{0x2a,0x01,0x04,0x88,0x00,0x66,0x10,0x00,0x53,0xa9,0x02,0x2b,0x00,0x00,0x00,0x01}, 8333}, + {{0x2a,0x01,0x04,0x88,0x00,0x67,0x10,0x00,0x05,0x23,0xff,0xa7,0x00,0x00,0x00,0x01}, 8333}, + {{0x2a,0x01,0x04,0x88,0x00,0x67,0x10,0x00,0xb0,0x1c,0x33,0x79,0x00,0x00,0x00,0x01}, 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,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,0x0a,0x02,0xe4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x0a,0x03,0x4e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x0a,0x05,0x1d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x0a,0x06,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x0a,0x08,0x5f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x0a,0x08,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x0a,0x0d,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x10,0x33,0x4c,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,0x82,0x03,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,0x11,0xea,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x21,0x43,0x46,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,0x93,0x4f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x31,0x33,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,0x31,0xb0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x40,0x40,0x88,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x40,0x93,0x1a,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,0x13,0xad,0x00,0x00,0x00,0x00,0x00,0x00,0xc4,0x51}, 8333}, {{0x2a,0x01,0x04,0xf8,0x01,0x41,0x01,0x86,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 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,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,0x41,0x22,0xae,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x41,0x32,0x2c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x50,0x11,0xd4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x50,0x44,0x0f,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,0x72,0x6b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x51,0x30,0xc9,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 15000}, + {{0x2a,0x01,0x04,0xf8,0x01,0x51,0x41,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x51,0x41,0xcc,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,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,0x51,0x60,0x0b,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x01}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x51,0x71,0x75,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x60,0x41,0xf0,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x33}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x60,0x53,0x28,0x00,0x00,0x00,0x00,0x27,0xf0,0x18,0x7a}, 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,0x21,0xad,0x00,0x00,0x00,0x00,0x03,0x33,0x00,0x30}, 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,0x62,0x41,0x10,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,0x71,0x1c,0x1b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x71,0x01,0xc3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x71,0x22,0x58,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x71,0x2a,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x71,0x2e,0x1b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x71,0x2f,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x71,0x32,0x48,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x71,0x38,0x0c,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,0x71,0x0d,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x72,0x11,0x6c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x72,0x12,0x87,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x72,0x17,0xa9,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x72,0x1c,0xa7,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x72,0x21,0x59,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x72,0x3a,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x72,0x3b,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x72,0x3e,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x72,0x3e,0xc2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x72,0x0a,0xeb,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x72,0x0a,0xec,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x73,0x10,0xab,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x73,0x15,0x51,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x73,0x1b,0xca,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x73,0x1e,0x2e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x73,0x21,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x73,0x21,0xe6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x73,0x00,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x73,0x0c,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x90,0x12,0x53,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x90,0x24,0xeb,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x90,0x34,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x90,0x52,0x8d,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,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,0x92,0x11,0xb2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x91,0x81,0x65,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 22556}, + {{0x2a,0x01,0x04,0xf8,0x01,0x91,0x81,0xb7,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x91,0x83,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x92,0x11,0xb2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8343}, {{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,0x22,0xaf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x92,0x24,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x92,0x34,0xd0,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,0x52,0x30,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,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,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,0x00,0x41,0x4e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x02,0x00,0x41,0x6a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x02,0x01,0x21,0xa7,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x02,0x01,0x40,0x17,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x11}, 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,0x12,0xd6,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,0x32,0xc6,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,0x11,0x14,0xcf,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,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,0x04,0xf8,0x02,0x11,0x1e,0xc5,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x02,0x11,0x04,0x83,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x02,0x11,0x0d,0x99,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x02,0x12,0x18,0x26,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x02,0x12,0x27,0xa8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x02,0x21,0x08,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x00,0xa0,0x12,0xcc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x00,0xa0,0x74,0x6a,0x01,0x01,0x00,0x01,0x00,0x01,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x00,0xa0,0x82,0x8a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x0c,0x17,0x2e,0xef,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x0c,0x17,0x2f,0x3c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 3333}, + {{0x2a,0x01,0x04,0xf8,0x0c,0x17,0x3b,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x0c,0x17,0x42,0x45,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x0c,0x17,0x46,0x4f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x0c,0x17,0x4a,0x1c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x0c,0x17,0x4c,0x5d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x0c,0x17,0x67,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x0c,0x17,0x6d,0xd0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x0c,0x17,0x71,0x0b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x0c,0x17,0x07,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x0c,0x17,0x72,0xc6,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,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,0x06,0x80,0x00,0x10,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x2a,0x01,0x06,0xf0,0xff,0xff,0x01,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x8d,0xcb}, 8333}, + {{0x2a,0x01,0x07,0x9c,0xce,0xbc,0x85,0x7c,0x98,0xc1,0x88,0xff,0xfe,0xf5,0x90,0xde}, 8333}, + {{0x2a,0x01,0x07,0x9d,0x73,0x77,0x26,0x29,0x7e,0x57,0x7e,0x57,0x00,0x01,0x00,0x01}, 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,0x39,0x42}, 8333}, + {{0x2a,0x01,0x07,0xc8,0xaa,0xb5,0x03,0xe6,0x50,0x54,0x00,0xff,0xfe,0xd7,0x4e,0x54}, 8333}, + {{0x2a,0x01,0x07,0xc8,0xaa,0xbd,0x03,0xd5,0x50,0x54,0x00,0xff,0xfe,0x95,0xf5,0x86}, 8333}, + {{0x2a,0x01,0x07,0xc8,0xaa,0xc1,0x04,0x53,0xd0,0xd2,0xaf,0x96,0xfa,0x88,0x5d,0x0e}, 8333}, + {{0x2a,0x01,0x07,0xc8,0xaa,0xc3,0x06,0x63,0x50,0x54,0x00,0xff,0xfe,0x25,0x8c,0x69}, 8333}, + {{0x2a,0x01,0x07,0xc8,0xaa,0xc3,0x00,0x97,0x50,0x54,0x00,0xff,0xfe,0xa7,0x37,0x80}, 8333}, + {{0x2a,0x01,0x07,0xc8,0xaa,0xc4,0x05,0x67,0x50,0x54,0x00,0xff,0xfe,0xdc,0x51,0x8a}, 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,0x50,0x94,0xb8}, 8333}, + {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x55,0x00,0x2c}, 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,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,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x89,0x53,0xfd}, 8333}, + {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0xdf,0xb7,0x0f}, 8333}, + {{0x2a,0x01,0xb0,0x00,0x00,0x00,0x00,0x00,0x41,0x66,0x51,0x5b,0xef,0x9e,0x00,0xb3}, 8333}, + {{0x2a,0x01,0xb2,0xe0,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40}, 8333}, + {{0x2a,0x01,0x0e,0x34,0xec,0x29,0x24,0xc0,0x00,0xf3,0xdd,0xaf,0x9f,0x59,0x58,0x6f}, 8333}, + {{0x2a,0x01,0x0e,0x34,0xee,0xd7,0x66,0x70,0xec,0x1b,0xbf,0x7c,0xb0,0x12,0x60,0x69}, 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,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,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,0x01,0x0e,0x35,0x8b,0xff,0x70,0xb0,0x1e,0x1b,0x0d,0xff,0xfe,0x0b,0x23,0x6d}, 8333}, + {{0x2a,0x02,0x12,0x05,0x34,0xc3,0xa4,0xe0,0xd6,0x3d,0x7e,0xff,0xfe,0x98,0x10,0xc8}, 8333}, + {{0x2a,0x02,0x12,0x05,0x34,0xda,0xaa,0x00,0x58,0x82,0x24,0x9d,0xdd,0xbf,0xbc,0x43}, 8333}, + {{0x2a,0x02,0x12,0x05,0x50,0x51,0xa6,0x40,0xd6,0xae,0x52,0xff,0xfe,0xa3,0x00,0xac}, 8333}, + {{0x2a,0x02,0x12,0x05,0xc6,0x89,0xd9,0x80,0xba,0xae,0xed,0xff,0xfe,0xea,0x94,0x45}, 8333}, + {{0x2a,0x02,0x12,0x0b,0x2c,0x2a,0x5e,0xc0,0x10,0xdd,0x31,0xff,0xfe,0x42,0x50,0x79}, 8333}, + {{0x2a,0x02,0x12,0x0b,0x2c,0x35,0x69,0xd0,0x02,0x19,0x99,0xff,0xfe,0x6b,0x4e,0xc3}, 8333}, + {{0x2a,0x02,0x12,0x0b,0xc3,0xc2,0xff,0x60,0x02,0x1f,0x5b,0xff,0xfe,0xc3,0xa7,0xad}, 24312}, + {{0x2a,0x02,0x13,0xb8,0x40,0x00,0x10,0x00,0x02,0x16,0xe6,0xff,0xfe,0x92,0x86,0x19}, 8333}, + {{0x2a,0x02,0x13,0xb8,0x40,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x27}, 8333}, + {{0x2a,0x02,0x17,0xd0,0x00,0x2a,0x44,0x00,0x04,0x0f,0x3d,0xd4,0xb0,0x53,0x47,0xad}, 8333}, + {{0x2a,0x02,0x01,0x80,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x05,0x17,0x0a,0xfb}, 8333}, + {{0x2a,0x02,0x01,0x80,0x00,0x06,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18}, 8333}, + {{0x2a,0x02,0x18,0x10,0x1d,0x11,0xf9,0x00,0x68,0x72,0xf2,0x8e,0x81,0x26,0xf6,0x35}, 8333}, + {{0x2a,0x02,0x27,0xa8,0x00,0x00,0x00,0x01,0x52,0xe5,0x49,0xff,0xfe,0xe3,0x3b,0x49}, 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,0x03,0x90,0x90,0x00,0x00,0x00,0x02,0x18,0x7d,0xff,0xfe,0x10,0xbe,0x33}, 8333}, + {{0x2a,0x02,0x05,0x82,0x78,0xc1,0x76,0x00,0x2d,0x49,0x62,0x12,0x29,0xd3,0x0a,0xbb}, 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,0x07,0x50,0x00,0x07,0x33,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x75}, 8333}, + {{0x2a,0x02,0x07,0x52,0x01,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x53}, 8333}, + {{0x2a,0x02,0x7a,0xa0,0x12,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x75,0x01,0xd9,0x50}, 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,0x02,0x7a,0xa0,0x16,0x19,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x37,0x69,0xa6}, 8333}, + {{0x2a,0x02,0x81,0x0d,0x14,0xc0,0x86,0x94,0xd2,0x50,0x99,0xff,0xfe,0x81,0x23,0xd9}, 8333}, + {{0x2a,0x02,0x0a,0x50,0x00,0x00,0x00,0x00,0xda,0xcb,0x8a,0xff,0xfe,0x36,0x8d,0x2d}, 8333}, + {{0x2a,0x02,0xc2,0x00,0x00,0x00,0x00,0x10,0x00,0x03,0x00,0x00,0x25,0x91,0x00,0x01}, 8333}, + {{0x2a,0x02,0xc2,0x00,0x00,0x01,0x00,0x10,0x00,0x02,0x00,0x05,0x99,0x82,0x00,0x01}, 8333}, + {{0x2a,0x02,0xc2,0x00,0x00,0x01,0x00,0x10,0x00,0x03,0x00,0x00,0x92,0x90,0x00,0x01}, 8333}, + {{0x2a,0x02,0xc2,0x05,0x30,0x00,0x71,0x58,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x2a,0x02,0xc2,0x05,0x30,0x01,0x45,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x2a,0x02,0xc2,0x05,0x30,0x01,0x65,0x49,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x2a,0x02,0xc2,0x07,0x20,0x08,0x37,0x72,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x2a,0x02,0xc2,0x07,0x20,0x08,0x65,0x19,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x2a,0x02,0xc2,0x07,0x20,0x09,0x02,0x13,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x2a,0x02,0xc2,0x07,0x20,0x09,0x78,0x58,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x2a,0x02,0xc2,0x07,0x20,0x10,0x03,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x2a,0x02,0xc2,0x07,0x30,0x01,0x58,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x2a,0x02,0xce,0x80,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, {{0x2a,0x03,0x40,0x00,0x00,0x02,0x04,0x96,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08}, 8333}, + {{0x2a,0x03,0x40,0x00,0x00,0x06,0x41,0x6c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x53}, 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,0x40,0x00,0x00,0x09,0x00,0x8e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x2a,0x03,0x73,0x80,0x21,0x40,0x00,0x17,0x51,0xfe,0x35,0x19,0xb5,0x71,0x4a,0x13}, 8333}, + {{0x2a,0x03,0xb0,0xc0,0x00,0x00,0x10,0x10,0x00,0x00,0x00,0x00,0x07,0xa3,0x10,0x01}, 8333}, + {{0x2a,0x03,0xb0,0xc0,0x00,0x00,0x10,0x10,0x00,0x00,0x00,0x00,0x07,0xaa,0x40,0x01}, 8333}, + {{0x2a,0x03,0xb0,0xc0,0x00,0x03,0x00,0xd0,0x00,0x00,0x00,0x00,0x1b,0x99,0xc0,0x01}, 8333}, + {{0x2a,0x03,0xb0,0xc0,0x00,0x03,0x00,0xd0,0x00,0x00,0x00,0x00,0x1b,0x99,0xe0,0x01}, 8333}, + {{0x2a,0x03,0xb0,0xc0,0x00,0x03,0x00,0xd0,0x00,0x00,0x00,0x00,0x1b,0x9a,0x30,0x01}, 8333}, + {{0x2a,0x03,0xb0,0xc0,0x00,0x03,0x00,0xd0,0x00,0x00,0x00,0x00,0x22,0x08,0x60,0x01}, 8333}, + {{0x2a,0x03,0xb0,0xc0,0x00,0x03,0x00,0xd0,0x00,0x00,0x00,0x00,0x23,0xf7,0x10,0x01}, 8333}, + {{0x2a,0x03,0xb0,0xc0,0x00,0x03,0x00,0xd0,0x00,0x00,0x00,0x00,0x23,0xf7,0x90,0x01}, 8333}, + {{0x2a,0x03,0xb0,0xc0,0x00,0x03,0x00,0xd0,0x00,0x00,0x00,0x00,0x23,0xfb,0x20,0x01}, 8333}, + {{0x2a,0x03,0xb0,0xc0,0x00,0x03,0x00,0xd0,0x00,0x00,0x00,0x00,0x23,0xfb,0x30,0x01}, 8333}, + {{0x2a,0x03,0xb0,0xc0,0x00,0x03,0x00,0xd0,0x00,0x00,0x00,0x00,0x23,0xfb,0x50,0x01}, 8333}, + {{0x2a,0x03,0xb0,0xc0,0x00,0x03,0x00,0xd0,0x00,0x00,0x00,0x00,0x23,0xfb,0x70,0x01}, 8333}, + {{0x2a,0x03,0xb0,0xc0,0x00,0x03,0x00,0xd0,0x00,0x00,0x00,0x00,0x24,0x00,0x00,0x01}, 8333}, + {{0x2a,0x03,0xb0,0xc0,0x00,0x03,0x00,0xd0,0x00,0x00,0x00,0x00,0x24,0x00,0x30,0x01}, 8333}, + {{0x2a,0x03,0xb0,0xc0,0x00,0x03,0x00,0xd0,0x00,0x00,0x00,0x00,0x24,0x00,0xe0,0x01}, 8333}, + {{0x2a,0x03,0xb0,0xc0,0x00,0x03,0x00,0xd0,0x00,0x00,0x00,0x00,0x24,0x01,0xe0,0x01}, 8333}, + {{0x2a,0x03,0xb0,0xc0,0x00,0x03,0x00,0xd0,0x00,0x00,0x00,0x00,0x24,0x02,0x20,0x01}, 8333}, + {{0x2a,0x03,0xb0,0xc0,0x00,0x03,0x00,0xd0,0x00,0x00,0x00,0x00,0x24,0x02,0x80,0x01}, 8333}, + {{0x2a,0x03,0xb0,0xc0,0x00,0x03,0x00,0xd0,0x00,0x00,0x00,0x00,0x24,0x02,0x90,0x01}, 8333}, + {{0x2a,0x03,0xb0,0xc0,0x00,0x03,0x00,0xd0,0x00,0x00,0x00,0x00,0x24,0x02,0xb0,0x01}, 8333}, + {{0x2a,0x03,0xb0,0xc0,0x00,0x03,0x00,0xd0,0x00,0x00,0x00,0x00,0x24,0x02,0xd0,0x01}, 8333}, + {{0x2a,0x03,0xb0,0xc0,0x00,0x03,0x00,0xd0,0x00,0x00,0x00,0x00,0x24,0x03,0x10,0x01}, 8333}, + {{0x2a,0x03,0xb0,0xc0,0x00,0x03,0x00,0xd0,0x00,0x00,0x00,0x00,0x24,0x03,0x20,0x01}, 8333}, + {{0x2a,0x03,0xb0,0xc0,0x00,0x03,0x00,0xd0,0x00,0x00,0x00,0x00,0x24,0x03,0x40,0x01}, 8333}, + {{0x2a,0x03,0xb0,0xc0,0x00,0x03,0x00,0xd0,0x00,0x00,0x00,0x00,0x24,0x03,0x60,0x01}, 8333}, + {{0x2a,0x03,0xb0,0xc0,0x00,0x03,0x00,0xd0,0x00,0x00,0x00,0x00,0x24,0x03,0xa0,0x01}, 8333}, + {{0x2a,0x03,0xb0,0xc0,0x00,0x03,0x00,0xd0,0x00,0x00,0x00,0x00,0x24,0x03,0xb0,0x01}, 8333}, + {{0x2a,0x03,0xb0,0xc0,0x00,0x03,0x00,0xd0,0x00,0x00,0x00,0x00,0x24,0x03,0xf0,0x01}, 8333}, + {{0x2a,0x03,0xb0,0xc0,0x00,0x03,0x00,0xd0,0x00,0x00,0x00,0x00,0x24,0x04,0x60,0x01}, 8333}, + {{0x2a,0x03,0xb0,0xc0,0x00,0x03,0x00,0xd0,0x00,0x00,0x00,0x00,0x24,0x04,0xb0,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}, + {{0x2a,0x04,0x19,0x80,0x31,0x00,0x1a,0xac,0xe6,0x1d,0x2d,0xff,0xfe,0x29,0xf2,0x41}, 8333}, + {{0x2a,0x04,0x19,0x80,0x31,0x00,0x1a,0xac,0xe6,0x1d,0x2d,0xff,0xfe,0x29,0xf2,0x51}, 8333}, + {{0x2a,0x04,0x21,0x80,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x5a,0x49,0x3c,0x06}, 8333}, + {{0x2a,0x04,0x21,0x80,0x00,0x01,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03}, 8333}, + {{0x2a,0x04,0x2e,0x00,0x00,0x05,0x00,0x2e,0x9a,0x4b,0xe1,0xff,0xfe,0x62,0x6d,0xc0}, 8333}, + {{0x2a,0x04,0x35,0x42,0x10,0x00,0x09,0x10,0x84,0x92,0xb8,0xff,0xfe,0x91,0x71,0x1d}, 8333}, + {{0x2a,0x04,0xdb,0xc3,0xff,0xfe,0x00,0x00,0xe6,0x1f,0x13,0xff,0xfe,0x95,0x84,0x01}, 8333}, + {{0x2a,0x06,0x9f,0xc0,0x2a,0x06,0x9f,0xc0,0x2a,0x06,0x9f,0xc1,0x06,0x7c,0xe7,0x06}, 8333}, + {{0x2c,0x0f,0xf7,0x38,0x20,0x04,0x00,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xd1,0xe3,0x80,0xee,0x87,0xdc,0xf3,0x63,0x37,0x00}, 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,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,0xdc,0x09,0x14,0x6e,0x6c,0x3e,0x58,0xf2,0x1b,0x15}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xe5,0x86,0xa6,0xb0,0x82,0x31,0xc4,0xc1,0x2e,0x1d}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xee,0xe7,0x24,0xcf,0xd9,0x86,0xd0,0x09,0x57,0xb0}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xe8,0x8d,0xf8,0x13,0x16,0xad,0x9d,0xea,0xdd,0xf3}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xe9,0x82,0x28,0x9a,0x17,0x10,0x6e,0x9d,0x77,0x72}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xf0,0x9b,0xc4,0x2c,0x36,0x54,0x54,0x7f,0x9a,0xce}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xf1,0x38,0x98,0xb5,0xbf,0x41,0x89,0x0b,0xb1,0x65}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xf6,0x18,0x60,0xd5,0xad,0xf0,0xfa,0xd2,0xb2,0xbc}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xf6,0x64,0x7d,0x84,0xa3,0xa1,0xde,0xef,0xac,0x6b}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xfe,0x8b,0x0f,0x3c,0xf5,0xe1,0x4d,0xc8,0x9e,0xa7}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xf9,0x87,0x07,0xf9,0xaf,0xa4,0x95,0xc5,0x96,0xca}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x07,0xc8,0xcb,0xb9,0x7d,0xe9,0x3d,0xad,0xae,0x02}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x04,0xa4,0x14,0x60,0x79,0x44,0x3f,0xfc,0x81,0x48}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x08,0x0a,0xae,0xa1,0xc0,0x9a,0xcd,0x3f,0x8c,0xcb}, 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,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,0x0c,0x6d,0x02,0x65,0xbe,0x59,0x3b,0xcb,0x68,0x21}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x0c,0xb8,0x18,0x7a,0x5e,0x82,0xab,0x3e,0x9d,0xe8}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x0d,0x1f,0xd6,0xf4,0x9b,0x55,0x23,0x54,0xe4,0xbb}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x16,0xa6,0xf8,0x28,0x19,0xe2,0x0e,0x9c,0xd8,0xc1}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x11,0x22,0xd8,0xb2,0x2a,0xee,0x5c,0xcc,0xbb,0x2d}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x11,0x70,0x43,0x27,0xdc,0x3c,0xf6,0x97,0xb8,0x71}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x11,0xbb,0x53,0x77,0x82,0x06,0x72,0xfa,0xba,0x86}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x11,0x95,0xca,0x69,0x77,0x8d,0x58,0xbe,0x26,0xa1}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x12,0x70,0x61,0xfd,0xf4,0xea,0xe0,0xa5,0x63,0xa9}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x1f,0xad,0x40,0xc8,0x73,0x8f,0x3c,0x31,0xf5,0x48}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x19,0x61,0xec,0x24,0x5b,0x01,0x16,0xf5,0xda,0x3c}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x1c,0x1f,0x7b,0x2d,0xed,0xae,0xf3,0xb3,0xe5,0xab}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x20,0x18,0x57,0x49,0xf4,0xa9,0x00,0x10,0x21,0x83}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x23,0xf4,0xc4,0xe5,0xd7,0xda,0xaa,0x1f,0x02,0xfc}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x2b,0xc3,0x70,0xf2,0xc9,0xa0,0xd1,0x6d,0x5b,0xa0}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x2d,0x3a,0x72,0xc8,0x21,0x2f,0x53,0x69,0x54,0xf5}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x37,0x0b,0x12,0x39,0x01,0x90,0xb3,0x44,0xac,0x9b}, 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,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,0x31,0x87,0x8d,0x3c,0x3a,0x05,0x56,0x19,0xa6,0xd0}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x31,0xf4,0x04,0x0c,0x79,0xbb,0x2b,0x88,0xb6,0x84}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x33,0x6e,0x6c,0x2c,0x26,0xcd,0x40,0x0c,0xaa,0x1f}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x3b,0x51,0x91,0xdd,0xa4,0x49,0x17,0xee,0x50,0x2a}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x3c,0xea,0x31,0x31,0x62,0xd8,0x02,0x94,0x68,0x01}, 8443}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x3d,0xa8,0x17,0x39,0x12,0xe1,0xa4,0xba,0x3c,0xd7}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x3d,0xf3,0xe3,0x3a,0xcb,0xa0,0xd6,0x9f,0x0f,0xa0}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x4f,0xa8,0xc7,0x70,0x2d,0x96,0x66,0xf9,0x39,0xa2}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x48,0xe8,0xd6,0x01,0xc2,0xb0,0x42,0xdb,0x77,0xdd}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x54,0xeb,0xb8,0x2e,0xeb,0xfd,0xea,0xc1,0xac,0xbc}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x55,0x47,0xce,0x4a,0xdf,0x92,0x83,0xd2,0xb9,0x76}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x55,0x90,0xc6,0xe5,0x9e,0xa8,0xf9,0x90,0x2a,0xab}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x58,0x3b,0x73,0xab,0x6b,0x7c,0x6f,0x9b,0xb3,0x3a}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x58,0xbe,0x2b,0xfb,0xe4,0x68,0xf5,0xea,0x52,0x6f}, 8352}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x65,0xa9,0xd7,0x1b,0x40,0x30,0xa4,0xf6,0x19,0x57}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x66,0x6e,0xa4,0x3d,0x18,0x22,0x80,0xe3,0xfd,0x98}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x6f,0xa3,0x65,0xc6,0x76,0x7c,0x05,0xf8,0x59,0xdf}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x6a,0x77,0xee,0x6b,0x98,0x10,0xa0,0xf3,0xfb,0x59}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x76,0xbb,0xeb,0x7e,0x7b,0xa8,0x8c,0xa9,0xb2,0xea}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x77,0x24,0xbe,0xb4,0x1e,0x49,0x20,0x64,0x6d,0x7e}, 8333}, {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x72,0x87,0x94,0x82,0x36,0x22,0x83,0x23,0xb5,0xc5}, 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,0x76,0x08,0x1c,0x0d,0x7a,0x78,0x05,0x7f,0x57,0x5e}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x7f,0x59,0x7d,0x21,0x89,0xff,0x46,0xf6,0x21,0x84}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x7c,0x84,0xef,0x06,0xe9,0x25,0x96,0x98,0x8b,0x37}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x7d,0xe6,0x69,0x58,0x93,0xf4,0xd6,0x68,0x86,0xc9}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x88,0x79,0x5d,0x94,0xe6,0xbe,0xb3,0x1e,0x46,0x24}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x8a,0x56,0xd7,0xec,0xf6,0xac,0x64,0xc0,0x3f,0xc4}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x8a,0xc0,0x54,0x31,0x42,0x9d,0x73,0xed,0xad,0x66}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x8d,0xd3,0x5c,0x74,0x98,0x9c,0xc8,0xfe,0xce,0x72}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x91,0x1d,0x25,0x50,0x79,0x57,0xaa,0xdf,0x32,0x19}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x9b,0xcc,0x3a,0x16,0xf7,0x95,0xb6,0x95,0x44,0x65}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x9d,0x11,0x8a,0xc0,0xc8,0xdb,0xbd,0xfe,0xbd,0x21}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x9d,0xf9,0x91,0xfc,0x7d,0x25,0xdc,0xd6,0x85,0x67}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xa3,0x94,0x6f,0x02,0xa5,0x30,0x4e,0xe2,0xae,0x5b}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xae,0xcc,0x97,0x9c,0xd0,0xc7,0x4f,0x83,0x09,0x8b}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xa9,0xc6,0xeb,0xc2,0x1e,0xdd,0xe3,0xdd,0xb9,0x7f}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xaa,0x24,0x4a,0xc5,0x19,0xce,0xe1,0x4c,0x00,0xc9}, 8333}, {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xac,0x1f,0x82,0x69,0x5d,0x88,0xa1,0x54,0xf5,0x90}, 8333}, - {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xb3,0xd1,0xf8,0xbe,0xa7,0x6b,0x46,0xbe,0xe8,0x84}, 8333} + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xb1,0x65,0x7d,0x19,0x1f,0x1a,0x4f,0x8d,0x68,0xea}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xb1,0xbd,0x5b,0x30,0x31,0xce,0x31,0x90,0x3e,0x8d}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xbd,0x03,0xcb,0x6e,0xdc,0xb5,0x95,0xdf,0x5d,0x10}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xc0,0x91,0x56,0xb9,0x9c,0xe0,0xd9,0x7b,0xf1,0xc1}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xc5,0xa4,0xaa,0x14,0x5e,0xd0,0x4b,0xa2,0xd1,0x9c}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xcf,0x0a,0x0b,0xea,0xb7,0x36,0xb7,0x3d,0x0c,0x65}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xcb,0xba,0x35,0x2e,0xc4,0x5b,0x07,0x17,0xbb,0xad}, 8333} }; static SeedSpec6 pnSeed6_test[] = { diff --git a/src/clientversion.h b/src/clientversion.h index 0cd7e517ee..69154d546d 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -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 13 +#define CLIENT_VERSION_MINOR 14 #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 2016 +#define COPYRIGHT_YEAR 2017 #endif //HAVE_CONFIG_H diff --git a/src/consensus/params.h b/src/consensus/params.h index 3f98938f7e..6240e82857 100644 --- a/src/consensus/params.h +++ b/src/consensus/params.h @@ -47,7 +47,7 @@ struct Params { /** Block height at which BIP66 becomes active */ int BIP66Height; /** - * Minimum blocks including miner confirmation of the total of 2016 blocks in a retargetting period, + * Minimum blocks including miner confirmation of the total of 2016 blocks in a retargeting period, * (nPowTargetTimespan / nPowTargetSpacing) which is also used for BIP9 deployments. * Examples: 1916 for 95%, 1512 for testchains. */ diff --git a/src/core_read.cpp b/src/core_read.cpp index 85bb62c176..a8d667e3bc 100644 --- a/src/core_read.cpp +++ b/src/core_read.cpp @@ -20,13 +20,11 @@ #include <boost/algorithm/string/split.hpp> #include <boost/assign/list_of.hpp> -using namespace std; - CScript ParseScript(const std::string& s) { CScript result; - static map<string, opcodetype> mapOpNames; + static std::map<std::string, opcodetype> mapOpNames; if (mapOpNames.empty()) { @@ -39,7 +37,7 @@ CScript ParseScript(const std::string& s) const char* name = GetOpName((opcodetype)op); if (strcmp(name, "OP_UNKNOWN") == 0) continue; - string strName(name); + std::string strName(name); mapOpNames[strName] = (opcodetype)op; // Convenience: OP_ADD and just ADD are both recognized: boost::algorithm::replace_first(strName, "OP_", ""); @@ -47,7 +45,7 @@ CScript ParseScript(const std::string& s) } } - vector<string> words; + std::vector<std::string> words; boost::algorithm::split(words, s, boost::algorithm::is_any_of(" \t\n"), boost::algorithm::token_compress_on); for (std::vector<std::string>::const_iterator w = words.begin(); w != words.end(); ++w) @@ -57,16 +55,16 @@ CScript ParseScript(const std::string& s) // Empty string, ignore. (boost::split given '' will return one word) } else if (all(*w, boost::algorithm::is_digit()) || - (boost::algorithm::starts_with(*w, "-") && all(string(w->begin()+1, w->end()), boost::algorithm::is_digit()))) + (boost::algorithm::starts_with(*w, "-") && all(std::string(w->begin()+1, w->end()), boost::algorithm::is_digit()))) { // Number int64_t n = atoi64(*w); result << n; } - else if (boost::algorithm::starts_with(*w, "0x") && (w->begin()+2 != w->end()) && IsHex(string(w->begin()+2, w->end()))) + else if (boost::algorithm::starts_with(*w, "0x") && (w->begin()+2 != w->end()) && IsHex(std::string(w->begin()+2, w->end()))) { // Raw hex data, inserted NOT pushed onto stack: - std::vector<unsigned char> raw = ParseHex(string(w->begin()+2, w->end())); + std::vector<unsigned char> raw = ParseHex(std::string(w->begin()+2, w->end())); result.insert(result.end(), raw.begin(), raw.end()); } else if (w->size() >= 2 && boost::algorithm::starts_with(*w, "'") && boost::algorithm::ends_with(*w, "'")) @@ -83,7 +81,7 @@ CScript ParseScript(const std::string& s) } else { - throw runtime_error("script parse error"); + throw std::runtime_error("script parse error"); } } @@ -95,7 +93,7 @@ bool DecodeHexTx(CMutableTransaction& tx, const std::string& strHexTx, bool fTry if (!IsHex(strHexTx)) return false; - vector<unsigned char> txData(ParseHex(strHexTx)); + std::vector<unsigned char> txData(ParseHex(strHexTx)); if (fTryNoWitness) { CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS); @@ -113,6 +111,8 @@ bool DecodeHexTx(CMutableTransaction& tx, const std::string& strHexTx, bool fTry CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION); try { ssData >> tx; + if (!ssData.empty()) + return false; } catch (const std::exception&) { return false; @@ -138,9 +138,9 @@ bool DecodeHexBlk(CBlock& block, const std::string& strHexBlk) return true; } -uint256 ParseHashUV(const UniValue& v, const string& strName) +uint256 ParseHashUV(const UniValue& v, const std::string& strName) { - string strHex; + std::string strHex; if (v.isStr()) strHex = v.getValStr(); return ParseHashStr(strHex, strName); // Note: ParseHashStr("") throws a runtime_error @@ -149,19 +149,19 @@ uint256 ParseHashUV(const UniValue& v, const string& strName) uint256 ParseHashStr(const std::string& strHex, const std::string& strName) { if (!IsHex(strHex)) // Note: IsHex("") is false - throw runtime_error(strName+" must be hexadecimal string (not '"+strHex+"')"); + throw std::runtime_error(strName + " must be hexadecimal string (not '" + strHex + "')"); uint256 result; result.SetHex(strHex); return result; } -vector<unsigned char> ParseHexUV(const UniValue& v, const string& strName) +std::vector<unsigned char> ParseHexUV(const UniValue& v, const std::string& strName) { - string strHex; + std::string strHex; if (v.isStr()) strHex = v.getValStr(); if (!IsHex(strHex)) - throw runtime_error(strName+" must be hexadecimal string (not '"+strHex+"')"); + throw std::runtime_error(strName + " must be hexadecimal string (not '" + strHex + "')"); return ParseHex(strHex); } diff --git a/src/core_write.cpp b/src/core_write.cpp index ee8a897ca4..b0993a131f 100644 --- a/src/core_write.cpp +++ b/src/core_write.cpp @@ -18,16 +18,14 @@ #include <boost/assign/list_of.hpp> #include <boost/foreach.hpp> -using namespace std; - -string FormatScript(const CScript& script) +std::string FormatScript(const CScript& script) { - string ret; + std::string ret; CScript::const_iterator it = script.begin(); opcodetype op; while (it != script.end()) { CScript::const_iterator it2 = it; - vector<unsigned char> vch; + std::vector<unsigned char> vch; if (script.GetOp2(it, op, &vch)) { if (op == OP_0) { ret += "0 "; @@ -36,9 +34,9 @@ string FormatScript(const CScript& script) ret += strprintf("%i ", op - OP_1NEGATE - 1); continue; } else if (op >= OP_NOP && op <= OP_NOP10) { - string str(GetOpName(op)); - if (str.substr(0, 3) == string("OP_")) { - ret += str.substr(3, string::npos) + " "; + std::string str(GetOpName(op)); + if (str.substr(0, 3) == std::string("OP_")) { + ret += str.substr(3, std::string::npos) + " "; continue; } } @@ -55,14 +53,14 @@ string FormatScript(const CScript& script) return ret.substr(0, ret.size() - 1); } -const map<unsigned char, string> mapSigHashTypes = +const std::map<unsigned char, std::string> mapSigHashTypes = boost::assign::map_list_of - (static_cast<unsigned char>(SIGHASH_ALL), string("ALL")) - (static_cast<unsigned char>(SIGHASH_ALL|SIGHASH_ANYONECANPAY), string("ALL|ANYONECANPAY")) - (static_cast<unsigned char>(SIGHASH_NONE), string("NONE")) - (static_cast<unsigned char>(SIGHASH_NONE|SIGHASH_ANYONECANPAY), string("NONE|ANYONECANPAY")) - (static_cast<unsigned char>(SIGHASH_SINGLE), string("SINGLE")) - (static_cast<unsigned char>(SIGHASH_SINGLE|SIGHASH_ANYONECANPAY), string("SINGLE|ANYONECANPAY")) + (static_cast<unsigned char>(SIGHASH_ALL), std::string("ALL")) + (static_cast<unsigned char>(SIGHASH_ALL|SIGHASH_ANYONECANPAY), std::string("ALL|ANYONECANPAY")) + (static_cast<unsigned char>(SIGHASH_NONE), std::string("NONE")) + (static_cast<unsigned char>(SIGHASH_NONE|SIGHASH_ANYONECANPAY), std::string("NONE|ANYONECANPAY")) + (static_cast<unsigned char>(SIGHASH_SINGLE), std::string("SINGLE")) + (static_cast<unsigned char>(SIGHASH_SINGLE|SIGHASH_ANYONECANPAY), std::string("SINGLE|ANYONECANPAY")) ; /** @@ -72,11 +70,11 @@ const map<unsigned char, string> mapSigHashTypes = * of a signature. Only pass true for scripts you believe could contain signatures. For example, * pass false, or omit the this argument (defaults to false), for scriptPubKeys. */ -string ScriptToAsmStr(const CScript& script, const bool fAttemptSighashDecode) +std::string ScriptToAsmStr(const CScript& script, const bool fAttemptSighashDecode) { - string str; + std::string str; opcodetype opcode; - vector<unsigned char> vch; + std::vector<unsigned char> vch; CScript::const_iterator pc = script.begin(); while (pc < script.end()) { if (!str.empty()) { @@ -87,12 +85,12 @@ string ScriptToAsmStr(const CScript& script, const bool fAttemptSighashDecode) return str; } if (0 <= opcode && opcode <= OP_PUSHDATA4) { - if (vch.size() <= static_cast<vector<unsigned char>::size_type>(4)) { + if (vch.size() <= static_cast<std::vector<unsigned char>::size_type>(4)) { str += strprintf("%d", CScriptNum(vch, false).getint()); } else { // the IsUnspendable check makes sure not to try to decode OP_RETURN data that may match the format of a signature if (fAttemptSighashDecode && !script.IsUnspendable()) { - string strSigHashDecode; + std::string strSigHashDecode; // goal: only attempt to decode a defined sighash type from data that looks like a signature within a scriptSig. // this won't decode correctly formatted public keys in Pubkey or Multisig scripts due to // the restrictions on the pubkey formats (see IsCompressedOrUncompressedPubKey) being incongruous with the @@ -116,7 +114,7 @@ string ScriptToAsmStr(const CScript& script, const bool fAttemptSighashDecode) return str; } -string EncodeHexTx(const CTransaction& tx, const int serialFlags) +std::string EncodeHexTx(const CTransaction& tx, const int serialFlags) { CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION | serialFlags); ssTx << tx; @@ -127,7 +125,7 @@ void ScriptPubKeyToUniv(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex) { txnouttype type; - vector<CTxDestination> addresses; + std::vector<CTxDestination> addresses; int nRequired; out.pushKV("asm", ScriptToAsmStr(scriptPubKey)); diff --git a/src/cuckoocache.h b/src/cuckoocache.h index efd6a820b5..ff47e9776b 100644 --- a/src/cuckoocache.h +++ b/src/cuckoocache.h @@ -257,7 +257,7 @@ private: * * First, epoch_check decrements and checks the cheap heuristic, and then does * a more expensive scan if the cheap heuristic runs out. If the expensive - * scan suceeds, the epochs are aged and old elements are allow_erased. The + * scan succeeds, the epochs are aged and old elements are allow_erased. The * cheap heuristic is reset to retrigger after the worst case growth of the * current epoch's elements would exceed the epoch_size. */ @@ -395,7 +395,7 @@ public: * 1) On first iteration, last_loc == invalid(), find returns last, so * last_loc defaults to locs[0]. * 2) On further iterations, where last_loc == locs[k], last_loc will - * go to locs[k+1 % 8], i.e., next of the 8 indicies wrapping around + * go to locs[k+1 % 8], i.e., next of the 8 indices wrapping around * to 0 if needed. * * This prevents moving the element we just put in. diff --git a/src/hash.cpp b/src/hash.cpp index a399ca9252..a14a2386a2 100644 --- a/src/hash.cpp +++ b/src/hash.cpp @@ -57,7 +57,7 @@ unsigned int MurmurHash3(unsigned int nHashSeed, const std::vector<unsigned char k1 = ROTL32(k1, 15); k1 *= c2; h1 ^= k1; - }; + } } //---------- diff --git a/src/hash.h b/src/hash.h index 3b86fcc033..eacb8f04fe 100644 --- a/src/hash.h +++ b/src/hash.h @@ -25,9 +25,9 @@ public: static const size_t OUTPUT_SIZE = CSHA256::OUTPUT_SIZE; void Finalize(unsigned char hash[OUTPUT_SIZE]) { - unsigned char buf[sha.OUTPUT_SIZE]; + unsigned char buf[CSHA256::OUTPUT_SIZE]; sha.Finalize(buf); - sha.Reset().Write(buf, sha.OUTPUT_SIZE).Finalize(hash); + sha.Reset().Write(buf, CSHA256::OUTPUT_SIZE).Finalize(hash); } CHash256& Write(const unsigned char *data, size_t len) { @@ -49,9 +49,9 @@ public: static const size_t OUTPUT_SIZE = CRIPEMD160::OUTPUT_SIZE; void Finalize(unsigned char hash[OUTPUT_SIZE]) { - unsigned char buf[sha.OUTPUT_SIZE]; + unsigned char buf[CSHA256::OUTPUT_SIZE]; sha.Finalize(buf); - CRIPEMD160().Write(buf, sha.OUTPUT_SIZE).Finalize(hash); + CRIPEMD160().Write(buf, CSHA256::OUTPUT_SIZE).Finalize(hash); } CHash160& Write(const unsigned char *data, size_t len) { diff --git a/src/httprpc.cpp b/src/httprpc.cpp index 93beda09a4..8ac6925acd 100644 --- a/src/httprpc.cpp +++ b/src/httprpc.cpp @@ -25,7 +25,7 @@ static const char* WWW_AUTH_HEADER_DATA = "Basic realm=\"jsonrpc\""; /** Simple one-shot callback timer to be used by the RPC mechanism to e.g. - * re-lock the wellet. + * re-lock the wallet. */ class HTTPRPCTimer : public RPCTimerBase { @@ -112,7 +112,7 @@ static bool multiUserAuthorized(std::string strUserPass) std::string strSalt = vFields[1]; std::string strHash = vFields[2]; - unsigned int KEY_SIZE = 32; + static const unsigned int KEY_SIZE = 32; unsigned char out[KEY_SIZE]; CHMAC_SHA256(reinterpret_cast<const unsigned char*>(strSalt.c_str()), strSalt.size()).Write(reinterpret_cast<const unsigned char*>(strPass.c_str()), strPass.size()).Finalize(out); diff --git a/src/httpserver.cpp b/src/httpserver.cpp index 1692b43f28..e1763c6ad2 100644 --- a/src/httpserver.cpp +++ b/src/httpserver.cpp @@ -118,7 +118,7 @@ public: void Run() { ThreadCounter count(*this); - while (running) { + while (true) { std::unique_ptr<WorkItem> i; { std::unique_lock<std::mutex> lock(cs); diff --git a/src/init.cpp b/src/init.cpp index 5be011f944..da389fd23d 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -65,8 +65,6 @@ #include "zmq/zmqnotificationinterface.h" #endif -using namespace std; - bool fFeeEstimatesInitialized = false; static const bool DEFAULT_PROXYRANDOMIZE = true; static const bool DEFAULT_REST_ENABLE = false; @@ -120,10 +118,6 @@ static const char* FEE_ESTIMATES_FILENAME="fee_estimates.dat"; // threads that should only be stopped after the main network-processing // threads have exited. // -// Note that if running -daemon the parent process returns from AppInit2 -// before adding any threads to the threadGroup, so .join_all() returns -// immediately and the parent exits from main(). -// // Shutdown for Qt is very similar, only it uses a QTimer to detect // fRequestShutdown getting set, and then does the normal Qt // shutdown thing. @@ -190,7 +184,7 @@ void Shutdown() if (!lockShutdown) return; - /// Note: Shutdown() must be able to handle cases in which AppInit2() failed part of the way, + /// Note: Shutdown() must be able to handle cases in which initialization failed part of the way, /// for example if the data directory was found to be locked. /// Be sure that anything that writes files or flushes caches only does this if the respective /// module was initialized. @@ -310,10 +304,10 @@ void OnRPCStopped() void OnRPCPreCommand(const CRPCCommand& cmd) { // Observe safe mode - string strWarning = GetWarnings("rpc"); + std::string strWarning = GetWarnings("rpc"); if (strWarning != "" && !GetBoolArg("-disablesafemode", DEFAULT_DISABLE_SAFEMODE) && !cmd.okSafeMode) - throw JSONRPCError(RPC_FORBIDDEN_BY_SAFE_MODE, string("Safe mode: ") + strWarning); + throw JSONRPCError(RPC_FORBIDDEN_BY_SAFE_MODE, std::string("Safe mode: ") + strWarning); } std::string HelpMessage(HelpMessageMode mode) @@ -322,7 +316,7 @@ 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:")); + std::string strUsage = HelpMessageGroup(_("Options:")); strUsage += HelpMessageOpt("-?", _("Print this help message and exit")); strUsage += HelpMessageOpt("-version", _("Print version and exit")); strUsage += HelpMessageOpt("-alertnotify=<cmd>", _("Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)")); @@ -436,7 +430,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-limitdescendantsize=<n>", strprintf("Do not accept transactions if any ancestor would have more than <n> kilobytes of in-mempool descendants (default: %u).", DEFAULT_DESCENDANT_SIZE_LIMIT)); strUsage += HelpMessageOpt("-bip9params=deployment:start:end", "Use given start/end times for specified BIP9 deployment (regtest-only)"); } - string debugCategories = "addrman, alert, bench, cmpctblock, coindb, db, http, libevent, lock, mempool, mempoolrej, net, proxy, prune, rand, reindex, rpc, selectcoins, tor, zmq"; // Don't translate these and qt below + std::string debugCategories = "addrman, alert, bench, cmpctblock, coindb, db, http, libevent, lock, mempool, mempoolrej, net, proxy, prune, rand, reindex, rpc, selectcoins, tor, zmq"; // Don't translate these and qt below if (mode == HMM_BITCOIN_QT) debugCategories += ", qt"; strUsage += HelpMessageOpt("-debug=<category>", strprintf(_("Output debugging information (default: %u, supplying <category> is optional)"), 0) + ". " + @@ -576,15 +570,14 @@ struct CImportingNow // works correctly. void CleanupBlockRevFiles() { - using namespace boost::filesystem; - map<string, path> mapBlockFiles; + std::map<std::string, boost::filesystem::path> mapBlockFiles; // Glob all blk?????.dat and rev?????.dat files from the blocks directory. // Remove the rev files immediately and insert the blk file paths into an // ordered map keyed by block file index. LogPrintf("Removing unusable blk?????.dat and rev?????.dat files for -reindex with -prune\n"); - path blocksdir = GetDataDir() / "blocks"; - for (directory_iterator it(blocksdir); it != directory_iterator(); it++) { + boost::filesystem::path blocksdir = GetDataDir() / "blocks"; + for (boost::filesystem::directory_iterator it(blocksdir); it != boost::filesystem::directory_iterator(); it++) { if (is_regular_file(*it) && it->path().filename().string().length() == 12 && it->path().filename().string().substr(8,4) == ".dat") @@ -601,7 +594,7 @@ void CleanupBlockRevFiles() // keeping a separate counter. Once we hit a gap (or if 0 doesn't exist) // start removing block files. int nContigCounter = 0; - BOOST_FOREACH(const PAIRTYPE(string, path)& item, mapBlockFiles) { + BOOST_FOREACH(const PAIRTYPE(std::string, boost::filesystem::path)& item, mapBlockFiles) { if (atoi(item.first) == nContigCounter) { nContigCounter++; continue; @@ -690,9 +683,15 @@ bool InitSanityCheck(void) InitError("Elliptic curve cryptography sanity check failure. Aborting."); return false; } + if (!glibc_sanity_test() || !glibcxx_sanity_test()) return false; + if (!Random_SanityCheck()) { + InitError("OS cryptographic RNG sanity check failure. Aborting."); + return false; + } + return true; } @@ -804,6 +803,19 @@ ServiceFlags nLocalServices = NODE_NETWORK; } +[[noreturn]] static void new_handler_terminate() +{ + // Rather than throwing std::bad-alloc if allocation fails, terminate + // immediately to (try to) avoid chain corruption. + // Since LogPrintf may itself allocate memory, set the handler directly + // to terminate first. + std::set_new_handler(std::terminate); + LogPrintf("Error: Out of memory. Terminating.\n"); + + // The log was successful, terminate now. + std::terminate(); +}; + bool AppInitBasicSetup() { // ********************************************************* Step 1: setup @@ -856,6 +868,9 @@ bool AppInitBasicSetup() // Ignore SIGPIPE, otherwise it will bring the daemon down if the client closes unexpectedly signal(SIGPIPE, SIG_IGN); #endif + + std::set_new_handler(new_handler_terminate); + return true; } @@ -894,8 +909,8 @@ bool AppInitParameterInteraction() fDebug = mapMultiArgs.count("-debug"); // Special-case: if -debug=0/-nodebug is set, turn off debugging messages if (fDebug) { - const vector<string>& categories = mapMultiArgs.at("-debug"); - if (GetBoolArg("-nodebug", false) || find(categories.begin(), categories.end(), string("0")) != categories.end()) + const std::vector<std::string>& categories = mapMultiArgs.at("-debug"); + if (GetBoolArg("-nodebug", false) || find(categories.begin(), categories.end(), std::string("0")) != categories.end()) fDebug = false; } @@ -937,7 +952,7 @@ bool AppInitParameterInteraction() 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))); - // incremental relay fee sets the minimimum feerate increase necessary for BIP 125 replacement in the mempool + // incremental relay fee sets the minimum feerate increase necessary for BIP 125 replacement in the mempool // and the amount the mempool min fee increases above the feerate of txs evicted due to mempool limiting. if (IsArgSet("-incrementalrelayfee")) { @@ -1063,7 +1078,7 @@ bool AppInitParameterInteraction() if (!chainparams.MineBlocksOnDemand()) { return InitError("BIP9 parameters may only be overridden on regtest."); } - const vector<string>& deployments = mapMultiArgs.at("-bip9params"); + const std::vector<std::string>& deployments = mapMultiArgs.at("-bip9params"); for (auto i : deployments) { std::vector<std::string> vDeploymentParams; boost::split(vDeploymentParams, i, boost::is_any_of(":")); @@ -1149,8 +1164,11 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) #ifndef WIN32 CreatePidFile(GetPidFile(), getpid()); #endif - if (GetBoolArg("-shrinkdebugfile", !fDebug)) + if (GetBoolArg("-shrinkdebugfile", !fDebug)) { + // Do this first since it both loads a bunch of debug.log into memory, + // and because this needs to happen before any other debug.log printing ShrinkDebugFile(); + } if (fPrintToDebugLog) OpenDebugLog(); @@ -1208,9 +1226,9 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) RegisterNodeSignals(GetNodeSignals()); // sanitize comments per BIP-0014, format user agent and check total size - std::vector<string> uacomments; + std::vector<std::string> uacomments; if (mapMultiArgs.count("-uacomment")) { - BOOST_FOREACH(string cmt, mapMultiArgs.at("-uacomment")) + BOOST_FOREACH(std::string cmt, mapMultiArgs.at("-uacomment")) { if (cmt != SanitizeString(cmt, SAFE_CHARS_UA_COMMENT)) return InitError(strprintf(_("User Agent comment (%s) contains unsafe characters."), cmt)); @@ -1353,32 +1371,7 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) fReindex = GetBoolArg("-reindex", false); bool fReindexChainState = GetBoolArg("-reindex-chainstate", false); - // Upgrading to 0.8; hard-link the old blknnnn.dat files into /blocks/ - boost::filesystem::path blocksDir = GetDataDir() / "blocks"; - if (!boost::filesystem::exists(blocksDir)) - { - boost::filesystem::create_directories(blocksDir); - bool linked = false; - for (unsigned int i = 1; i < 10000; i++) { - boost::filesystem::path source = GetDataDir() / strprintf("blk%04u.dat", i); - if (!boost::filesystem::exists(source)) break; - boost::filesystem::path dest = blocksDir / strprintf("blk%05u.dat", i-1); - try { - boost::filesystem::create_hard_link(source, dest); - LogPrintf("Hardlinked %s -> %s\n", source.string(), dest.string()); - linked = true; - } catch (const boost::filesystem::filesystem_error& e) { - // Note: hardlink creation failing is not a disaster, it just means - // blocks will get re-downloaded from peers. - LogPrintf("Error hardlinking blk%04u.dat: %s\n", i, e.what()); - break; - } - } - if (linked) - { - fReindex = true; - } - } + boost::filesystem::create_directories(GetDataDir() / "blocks"); // cache size calculations int64_t nTotalCache = (GetArg("-dbcache", nDefaultDbCache) << 20); @@ -1553,7 +1546,7 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) } if (chainparams.GetConsensus().vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout != 0) { - // Only advertize witness capabilities if they have a reasonable start time. + // Only advertise witness capabilities if they have a reasonable start time. // This allows us to have the code merged without a defined softfork, by setting its // end time to 0. // Note that setting NODE_WITNESS is never required: the only downside from not diff --git a/src/merkleblock.cpp b/src/merkleblock.cpp index 86c8172a31..e3f3e4621a 100644 --- a/src/merkleblock.cpp +++ b/src/merkleblock.cpp @@ -9,14 +9,12 @@ #include "consensus/consensus.h" #include "utilstrencodings.h" -using namespace std; - CMerkleBlock::CMerkleBlock(const CBlock& block, CBloomFilter& filter) { header = block.GetBlockHeader(); - vector<bool> vMatch; - vector<uint256> vHashes; + std::vector<bool> vMatch; + std::vector<uint256> vHashes; vMatch.reserve(block.vtx.size()); vHashes.reserve(block.vtx.size()); @@ -27,7 +25,7 @@ CMerkleBlock::CMerkleBlock(const CBlock& block, CBloomFilter& filter) if (filter.IsRelevantAndUpdate(*block.vtx[i])) { vMatch.push_back(true); - vMatchedTxn.push_back(make_pair(i, hash)); + vMatchedTxn.push_back(std::make_pair(i, hash)); } else vMatch.push_back(false); @@ -41,8 +39,8 @@ CMerkleBlock::CMerkleBlock(const CBlock& block, const std::set<uint256>& txids) { header = block.GetBlockHeader(); - vector<bool> vMatch; - vector<uint256> vHashes; + std::vector<bool> vMatch; + std::vector<uint256> vHashes; vMatch.reserve(block.vtx.size()); vHashes.reserve(block.vtx.size()); diff --git a/src/miner.cpp b/src/miner.cpp index acded94168..167e74284c 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -31,8 +31,6 @@ #include <queue> #include <utility> -using namespace std; - ////////////////////////////////////////////////////////////////////////////// // // BitcoinMiner @@ -74,43 +72,56 @@ int64_t UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParam return nNewTime - nOldTime; } -BlockAssembler::BlockAssembler(const CChainParams& _chainparams) - : chainparams(_chainparams) +BlockAssembler::Options::Options() { + blockMinFeeRate = CFeeRate(DEFAULT_BLOCK_MIN_TX_FEE); + nBlockMaxWeight = DEFAULT_BLOCK_MAX_WEIGHT; + nBlockMaxSize = DEFAULT_BLOCK_MAX_SIZE; +} + +BlockAssembler::BlockAssembler(const CChainParams& params, const Options& options) : chainparams(params) +{ + blockMinFeeRate = options.blockMinFeeRate; + // Limit weight to between 4K and MAX_BLOCK_WEIGHT-4K for sanity: + nBlockMaxWeight = std::max<size_t>(4000, std::min<size_t>(MAX_BLOCK_WEIGHT - 4000, options.nBlockMaxWeight)); + // Limit size to between 1K and MAX_BLOCK_SERIALIZED_SIZE-1K for sanity: + nBlockMaxSize = std::max<size_t>(1000, std::min<size_t>(MAX_BLOCK_SERIALIZED_SIZE - 1000, options.nBlockMaxSize)); + // Whether we need to account for byte usage (in addition to weight usage) + fNeedSizeAccounting = (nBlockMaxSize < MAX_BLOCK_SERIALIZED_SIZE - 1000); +} + +static BlockAssembler::Options DefaultOptions(const CChainParams& params) { // Block resource limits // If neither -blockmaxsize or -blockmaxweight is given, limit to DEFAULT_BLOCK_MAX_* // If only one is given, only restrict the specified resource. // If both are given, restrict both. - nBlockMaxWeight = DEFAULT_BLOCK_MAX_WEIGHT; - nBlockMaxSize = DEFAULT_BLOCK_MAX_SIZE; + BlockAssembler::Options options; + options.nBlockMaxWeight = DEFAULT_BLOCK_MAX_WEIGHT; + options.nBlockMaxSize = DEFAULT_BLOCK_MAX_SIZE; bool fWeightSet = false; if (IsArgSet("-blockmaxweight")) { - nBlockMaxWeight = GetArg("-blockmaxweight", DEFAULT_BLOCK_MAX_WEIGHT); - nBlockMaxSize = MAX_BLOCK_SERIALIZED_SIZE; + options.nBlockMaxWeight = GetArg("-blockmaxweight", DEFAULT_BLOCK_MAX_WEIGHT); + options.nBlockMaxSize = MAX_BLOCK_SERIALIZED_SIZE; fWeightSet = true; } if (IsArgSet("-blockmaxsize")) { - nBlockMaxSize = GetArg("-blockmaxsize", DEFAULT_BLOCK_MAX_SIZE); + options.nBlockMaxSize = GetArg("-blockmaxsize", DEFAULT_BLOCK_MAX_SIZE); if (!fWeightSet) { - nBlockMaxWeight = nBlockMaxSize * WITNESS_SCALE_FACTOR; + options.nBlockMaxWeight = options.nBlockMaxSize * WITNESS_SCALE_FACTOR; } } if (IsArgSet("-blockmintxfee")) { CAmount n = 0; ParseMoney(GetArg("-blockmintxfee", ""), n); - blockMinFeeRate = CFeeRate(n); + options.blockMinFeeRate = CFeeRate(n); } else { - blockMinFeeRate = CFeeRate(DEFAULT_BLOCK_MIN_TX_FEE); + options.blockMinFeeRate = CFeeRate(DEFAULT_BLOCK_MIN_TX_FEE); } - - // Limit weight to between 4K and MAX_BLOCK_WEIGHT-4K for sanity: - nBlockMaxWeight = std::max((unsigned int)4000, std::min((unsigned int)(MAX_BLOCK_WEIGHT-4000), nBlockMaxWeight)); - // Limit size to between 1K and MAX_BLOCK_SERIALIZED_SIZE-1K for sanity: - nBlockMaxSize = std::max((unsigned int)1000, std::min((unsigned int)(MAX_BLOCK_SERIALIZED_SIZE-1000), nBlockMaxSize)); - // Whether we need to account for byte usage (in addition to weight usage) - fNeedSizeAccounting = (nBlockMaxSize < MAX_BLOCK_SERIALIZED_SIZE-1000); + return options; } +BlockAssembler::BlockAssembler(const CChainParams& params) : BlockAssembler(params, DefaultOptions(params)) {} + void BlockAssembler::resetBlock() { inBlock.clear(); @@ -500,7 +511,7 @@ void BlockAssembler::addPackageTxs() } // Package can be added. Sort the entries in a valid order. - vector<CTxMemPool::txiter> sortedEntries; + std::vector<CTxMemPool::txiter> sortedEntries; SortForBlock(ancestors, iter, sortedEntries); for (size_t i=0; i<sortedEntries.size(); ++i) { @@ -529,7 +540,7 @@ void BlockAssembler::addPriorityTxs() fNeedSizeAccounting = true; // This vector will be sorted into a priority queue: - vector<TxCoinAgePriority> vecPriority; + std::vector<TxCoinAgePriority> vecPriority; TxCoinAgePriorityCompare pricomparer; std::map<CTxMemPool::txiter, double, CTxMemPool::CompareIteratorByHash> waitPriMap; typedef std::map<CTxMemPool::txiter, double, CTxMemPool::CompareIteratorByHash>::iterator waitPriIter; diff --git a/src/miner.h b/src/miner.h index 3ba92b16b8..fc2526ff5a 100644 --- a/src/miner.h +++ b/src/miner.h @@ -163,7 +163,16 @@ private: bool blockFinished; public: - BlockAssembler(const CChainParams& chainparams); + struct Options { + Options(); + size_t nBlockMaxWeight; + size_t nBlockMaxSize; + CFeeRate blockMinFeeRate; + }; + + BlockAssembler(const CChainParams& params); + BlockAssembler(const CChainParams& params, const Options& options); + /** Construct a new block template with coinbase to scriptPubKeyIn */ std::unique_ptr<CBlockTemplate> CreateNewBlock(const CScript& scriptPubKeyIn); diff --git a/src/net.cpp b/src/net.cpp index 1019d59544..e38d3b344e 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -164,8 +164,9 @@ int GetnScore(const CService& addr) // Is our peer's addrLocal potentially useful as an external IP source? bool IsPeerAddrLocalGood(CNode *pnode) { - return fDiscover && pnode->addr.IsRoutable() && pnode->addrLocal.IsRoutable() && - !IsLimited(pnode->addrLocal.GetNetwork()); + CService addrLocal = pnode->GetAddrLocal(); + return fDiscover && pnode->addr.IsRoutable() && addrLocal.IsRoutable() && + !IsLimited(addrLocal.GetNetwork()); } // pushes our own address to a peer @@ -180,7 +181,7 @@ void AdvertiseLocal(CNode *pnode) if (IsPeerAddrLocalGood(pnode) && (!addrLocal.IsRoutable() || GetRand((GetnScore(addrLocal) > LOCAL_MANUAL) ? 8:2) == 0)) { - addrLocal.SetIP(pnode->addrLocal); + addrLocal.SetIP(pnode->GetAddrLocal()); } if (addrLocal.IsRoutable()) { @@ -307,9 +308,11 @@ CNode* CConnman::FindNode(const CSubNet& subNet) CNode* CConnman::FindNode(const std::string& addrName) { LOCK(cs_vNodes); - BOOST_FOREACH(CNode* pnode, vNodes) - if (pnode->addrName == addrName) + BOOST_FOREACH(CNode* pnode, vNodes) { + if (pnode->GetAddrName() == addrName) { return (pnode); + } + } return NULL; } @@ -342,8 +345,8 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo CNode* pnode = FindNode((CService)addrConnect); if (pnode) { - pnode->AddRef(); - return pnode; + LogPrintf("Failed to open new connection, already connected\n"); + return NULL; } } @@ -369,18 +372,14 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo // In that case, drop the connection that was just created, and return the existing CNode instead. // Also store the name we used to connect in that CNode, so that future FindNode() calls to that // name catch this early. + LOCK(cs_vNodes); CNode* pnode = FindNode((CService)addrConnect); if (pnode) { - pnode->AddRef(); - { - LOCK(cs_vNodes); - if (pnode->addrName.empty()) { - pnode->addrName = std::string(pszDest); - } - } + pnode->MaybeSetAddrName(std::string(pszDest)); CloseSocket(hSocket); - return pnode; + LogPrintf("Failed to open new connection, already connected\n"); + return NULL; } } @@ -391,13 +390,7 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo uint64_t nonce = GetDeterministicRandomizer(RANDOMIZER_ID_LOCALHOSTNONCE).Write(id).Finalize(); CNode* pnode = new CNode(id, nLocalServices, GetBestHeight(), hSocket, addrConnect, CalculateKeyedNetGroup(addrConnect), nonce, pszDest ? pszDest : "", false); pnode->nServicesExpected = ServiceFlags(addrConnect.nServices & nRelevantServices); - pnode->nTimeConnected = GetTime(); pnode->AddRef(); - GetNodeSignals().InitializeNode(pnode, *this); - { - LOCK(cs_vNodes); - vNodes.push_back(pnode); - } return pnode; } else if (!proxyConnectionFailed) { @@ -432,6 +425,7 @@ void CConnman::DumpBanlist() void CNode::CloseSocketDisconnect() { fDisconnect = true; + LOCK(cs_hSocket); if (hSocket != INVALID_SOCKET) { LogPrint("net", "disconnecting peer=%d\n", id); @@ -600,6 +594,33 @@ void CConnman::AddWhitelistedRange(const CSubNet &subnet) { vWhitelistedRange.push_back(subnet); } + +std::string CNode::GetAddrName() const { + LOCK(cs_addrName); + return addrName; +} + +void CNode::MaybeSetAddrName(const std::string& addrNameIn) { + LOCK(cs_addrName); + if (addrName.empty()) { + addrName = addrNameIn; + } +} + +CService CNode::GetAddrLocal() const { + LOCK(cs_addrLocal); + return addrLocal; +} + +void CNode::SetAddrLocal(const CService& addrLocalIn) { + LOCK(cs_addrLocal); + if (addrLocal.IsValid()) { + error("Addr local already set for node: %i. Refusing to change from %s to %s", id, addrLocal.ToString(), addrLocalIn.ToString()); + } else { + addrLocal = addrLocalIn; + } +} + #undef X #define X(name) stats.name = name void CNode::copyStats(CNodeStats &stats) @@ -607,21 +628,33 @@ void CNode::copyStats(CNodeStats &stats) stats.nodeid = this->GetId(); X(nServices); X(addr); - X(fRelayTxes); + { + LOCK(cs_filter); + X(fRelayTxes); + } X(nLastSend); X(nLastRecv); X(nTimeConnected); X(nTimeOffset); - X(addrName); + stats.addrName = GetAddrName(); X(nVersion); - X(cleanSubVer); + { + LOCK(cs_SubVer); + X(cleanSubVer); + } X(fInbound); X(fAddnode); X(nStartingHeight); - X(nSendBytes); - X(mapSendBytesPerMsgCmd); - X(nRecvBytes); - X(mapRecvBytesPerMsgCmd); + { + LOCK(cs_vSend); + X(mapSendBytesPerMsgCmd); + X(nSendBytes); + } + { + LOCK(cs_vRecv); + X(mapRecvBytesPerMsgCmd); + X(nRecvBytes); + } X(fWhitelisted); // It is common for nodes with good ping times to suddenly become lagged, @@ -641,7 +674,8 @@ void CNode::copyStats(CNodeStats &stats) stats.dPingWait = (((double)nPingUsecWait) / 1e6); // Leave string empty if addrLocal invalid (not filled in yet) - stats.addrLocal = addrLocal.IsValid() ? addrLocal.ToString() : ""; + CService addrLocalUnlocked = GetAddrLocal(); + stats.addrLocal = addrLocalUnlocked.IsValid() ? addrLocalUnlocked.ToString() : ""; } #undef X @@ -649,6 +683,7 @@ bool CNode::ReceiveMsgBytes(const char *pch, unsigned int nBytes, bool& complete { complete = false; int64_t nTimeMicros = GetTimeMicros(); + LOCK(cs_vRecv); nLastRecv = nTimeMicros / 1000000; nRecvBytes += nBytes; while (nBytes > 0) { @@ -696,6 +731,33 @@ bool CNode::ReceiveMsgBytes(const char *pch, unsigned int nBytes, bool& complete return true; } +void CNode::SetSendVersion(int nVersionIn) +{ + // Send version may only be changed in the version message, and + // only one version message is allowed per session. We can therefore + // treat this value as const and even atomic as long as it's only used + // once a version message has been successfully processed. Any attempt to + // set this twice is an error. + if (nSendVersion != 0) { + error("Send version already set for node: %i. Refusing to change from %i to %i", id, nSendVersion, nVersionIn); + } else { + nSendVersion = nVersionIn; + } +} + +int CNode::GetSendVersion() const +{ + // The send version should always be explicitly set to + // INIT_PROTO_VERSION rather than using this value until SetSendVersion + // has been called. + if (nSendVersion == 0) { + error("Requesting unset send version for node: %i. Using %i", id, INIT_PROTO_VERSION); + return INIT_PROTO_VERSION; + } + return nSendVersion; +} + + int CNetMessage::readHeader(const char *pch, unsigned int nBytes) { // copy data to temporary parsing buffer @@ -761,7 +823,7 @@ const uint256& CNetMessage::GetMessageHash() const // requires LOCK(cs_vSend) -size_t CConnman::SocketSendData(CNode *pnode) +size_t CConnman::SocketSendData(CNode *pnode) const { auto it = pnode->vSendMsg.begin(); size_t nSentSize = 0; @@ -769,9 +831,15 @@ size_t CConnman::SocketSendData(CNode *pnode) while (it != pnode->vSendMsg.end()) { const auto &data = *it; assert(data.size() > pnode->nSendOffset); - int nBytes = send(pnode->hSocket, reinterpret_cast<const char*>(data.data()) + pnode->nSendOffset, data.size() - pnode->nSendOffset, MSG_NOSIGNAL | MSG_DONTWAIT); + int nBytes = 0; + { + LOCK(pnode->cs_hSocket); + if (pnode->hSocket == INVALID_SOCKET) + break; + nBytes = send(pnode->hSocket, reinterpret_cast<const char*>(data.data()) + pnode->nSendOffset, data.size() - pnode->nSendOffset, MSG_NOSIGNAL | MSG_DONTWAIT); + } if (nBytes > 0) { - pnode->nLastSend = GetTime(); + pnode->nLastSend = GetSystemTimeInSeconds(); pnode->nSendBytes += nBytes; pnode->nSendOffset += nBytes; nSentSize += nBytes; @@ -1073,20 +1141,18 @@ void CConnman::ThreadSocketHandler() BOOST_FOREACH(CNode* pnode, vNodesDisconnectedCopy) { // wait until threads are done using it - if (pnode->GetRefCount() <= 0) - { + if (pnode->GetRefCount() <= 0) { bool fDelete = false; { - TRY_LOCK(pnode->cs_vSend, lockSend); - if (lockSend) - { - TRY_LOCK(pnode->cs_inventory, lockInv); - if (lockInv) - fDelete = true; + TRY_LOCK(pnode->cs_inventory, lockInv); + if (lockInv) { + TRY_LOCK(pnode->cs_vSend, lockSend); + if (lockSend) { + fDelete = true; + } } } - if (fDelete) - { + if (fDelete) { vNodesDisconnected.remove(pnode); DeleteNode(pnode); } @@ -1130,12 +1196,6 @@ void CConnman::ThreadSocketHandler() LOCK(cs_vNodes); BOOST_FOREACH(CNode* pnode, vNodes) { - if (pnode->hSocket == INVALID_SOCKET) - continue; - FD_SET(pnode->hSocket, &fdsetError); - hSocketMax = std::max(hSocketMax, pnode->hSocket); - have_fds = true; - // Implement the following logic: // * If there is data to send, select() for sending data. As this only // happens when optimistic write failed, we choose to first drain the @@ -1146,16 +1206,28 @@ void CConnman::ThreadSocketHandler() // receiving data. // * Hand off all complete messages to the processor, to be handled without // blocking here. + + bool select_recv = !pnode->fPauseRecv; + bool select_send; { LOCK(pnode->cs_vSend); - if (!pnode->vSendMsg.empty()) { - FD_SET(pnode->hSocket, &fdsetSend); - continue; - } + select_send = !pnode->vSendMsg.empty(); } - { - if (!pnode->fPauseRecv) - FD_SET(pnode->hSocket, &fdsetRecv); + + LOCK(pnode->cs_hSocket); + if (pnode->hSocket == INVALID_SOCKET) + continue; + + FD_SET(pnode->hSocket, &fdsetError); + hSocketMax = std::max(hSocketMax, pnode->hSocket); + have_fds = true; + + if (select_send) { + FD_SET(pnode->hSocket, &fdsetSend); + continue; + } + if (select_recv) { + FD_SET(pnode->hSocket, &fdsetRecv); } } } @@ -1209,15 +1281,30 @@ void CConnman::ThreadSocketHandler() // // Receive // - if (pnode->hSocket == INVALID_SOCKET) - continue; - if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError)) + bool recvSet = false; + bool sendSet = false; + bool errorSet = false; + { + LOCK(pnode->cs_hSocket); + if (pnode->hSocket == INVALID_SOCKET) + continue; + recvSet = FD_ISSET(pnode->hSocket, &fdsetRecv); + sendSet = FD_ISSET(pnode->hSocket, &fdsetSend); + errorSet = FD_ISSET(pnode->hSocket, &fdsetError); + } + if (recvSet || errorSet) { { { // typical socket buffer is 8K-64K char pchBuf[0x10000]; - int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT); + int nBytes = 0; + { + LOCK(pnode->cs_hSocket); + if (pnode->hSocket == INVALID_SOCKET) + continue; + nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT); + } if (nBytes > 0) { bool notify = false; @@ -1266,9 +1353,7 @@ void CConnman::ThreadSocketHandler() // // Send // - if (pnode->hSocket == INVALID_SOCKET) - continue; - if (FD_ISSET(pnode->hSocket, &fdsetSend)) + if (sendSet) { LOCK(pnode->cs_vSend); size_t nBytes = SocketSendData(pnode); @@ -1280,7 +1365,7 @@ void CConnman::ThreadSocketHandler() // // Inactivity checking // - int64_t nTime = GetTime(); + int64_t nTime = GetSystemTimeInSeconds(); if (nTime - pnode->nTimeConnected > 60) { if (pnode->nLastRecv == 0 || pnode->nLastSend == 0) @@ -1303,6 +1388,11 @@ void CConnman::ThreadSocketHandler() LogPrintf("ping timeout: %fs\n", 0.000001 * (GetTimeMicros() - pnode->nPingUsecStart)); pnode->fDisconnect = true; } + else if (!pnode->fSuccessfullyConnected) + { + LogPrintf("version handshake timeout from %d\n", pnode->id); + pnode->fDisconnect = true; + } } } { @@ -1742,8 +1832,9 @@ std::vector<AddedNodeInfo> CConnman::GetAddedNodeInfo() if (pnode->addr.IsValid()) { mapConnected[pnode->addr] = pnode->fInbound; } - if (!pnode->addrName.empty()) { - mapConnectedByName[pnode->addrName] = std::make_pair(pnode->fInbound, static_cast<const CService&>(pnode->addr)); + std::string addrName = pnode->GetAddrName(); + if (!addrName.empty()) { + mapConnectedByName[std::move(addrName)] = std::make_pair(pnode->fInbound, static_cast<const CService&>(pnode->addr)); } } } @@ -1840,6 +1931,12 @@ bool CConnman::OpenNetworkConnection(const CAddress& addrConnect, bool fCountFai if (fAddnode) pnode->fAddnode = true; + GetNodeSignals().InitializeNode(pnode, *this); + { + LOCK(cs_vNodes); + vNodes.push_back(pnode); + } + return true; } @@ -2113,8 +2210,9 @@ bool CConnman::Start(CScheduler& scheduler, std::string& strNodeError, Options c SetBestHeight(connOptions.nBestHeight); clientInterface = connOptions.uiInterface; - if (clientInterface) - clientInterface->InitMessage(_("Loading addresses...")); + if (clientInterface) { + clientInterface->InitMessage(_("Loading P2P addresses...")); + } // Load addresses from peers.dat int64_t nStart = GetTimeMillis(); { @@ -2251,8 +2349,7 @@ void CConnman::Stop() // Close sockets BOOST_FOREACH(CNode* pnode, vNodes) - if (pnode->hSocket != INVALID_SOCKET) - CloseSocket(pnode->hSocket); + pnode->CloseSocketDisconnect(); BOOST_FOREACH(ListenSocket& hListenSocket, vhListenSocket) if (hListenSocket.socket != INVALID_SOCKET) if (!CloseSocket(hListenSocket.socket)) @@ -2365,32 +2462,14 @@ void CConnman::GetNodeStats(std::vector<CNodeStats>& vstats) vstats.reserve(vNodes.size()); for(std::vector<CNode*>::iterator it = vNodes.begin(); it != vNodes.end(); ++it) { CNode* pnode = *it; - CNodeStats stats; - pnode->copyStats(stats); - vstats.push_back(stats); + vstats.emplace_back(); + pnode->copyStats(vstats.back()); } } -bool CConnman::DisconnectAddress(const CNetAddr& netAddr) -{ - if (CNode* pnode = FindNode(netAddr)) { - pnode->fDisconnect = true; - return true; - } - return false; -} - -bool CConnman::DisconnectSubnet(const CSubNet& subNet) -{ - if (CNode* pnode = FindNode(subNet)) { - pnode->fDisconnect = true; - return true; - } - return false; -} - bool CConnman::DisconnectNode(const std::string& strNode) { + LOCK(cs_vNodes); if (CNode* pnode = FindNode(strNode)) { pnode->fDisconnect = true; return true; @@ -2409,16 +2488,6 @@ bool CConnman::DisconnectNode(NodeId id) return false; } -void CConnman::RelayTransaction(const CTransaction& tx) -{ - CInv inv(MSG_TX, tx.GetHash()); - LOCK(cs_vNodes); - BOOST_FOREACH(CNode* pnode, vNodes) - { - pnode->PushInventory(inv); - } -} - void CConnman::RecordBytesRecv(uint64_t bytes) { LOCK(cs_totalBytesRecv); @@ -2546,6 +2615,7 @@ unsigned int CConnman::GetReceiveFloodSize() const { return nReceiveFloodSize; } unsigned int CConnman::GetSendBufferSize() const{ return nSendBufferMaxSize; } CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn, SOCKET hSocketIn, const CAddress& addrIn, uint64_t nKeyedNetGroupIn, uint64_t nLocalHostNonceIn, const std::string& addrNameIn, bool fInboundIn) : + nTimeConnected(GetSystemTimeInSeconds()), addr(addrIn), fInbound(fInboundIn), id(idIn), @@ -2565,7 +2635,6 @@ CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn nLastRecv = 0; nSendBytes = 0; nRecvBytes = 0; - nTimeConnected = GetTime(); nTimeOffset = 0; addrName = addrNameIn == "" ? addr.ToStringIPPort() : addrNameIn; nVersion = 0; @@ -2658,6 +2727,11 @@ void CNode::AskFor(const CInv& inv) mapAskFor.insert(std::make_pair(nRequestTime, inv)); } +bool CConnman::NodeFullyConnected(const CNode* pnode) +{ + return pnode && pnode->fSuccessfullyConnected && !pnode->fDisconnect; +} + void CConnman::PushMessage(CNode* pnode, CSerializedNetMsg&& msg) { size_t nMessageSize = msg.data.size(); @@ -2675,9 +2749,6 @@ void CConnman::PushMessage(CNode* pnode, CSerializedNetMsg&& msg) size_t nBytesSent = 0; { LOCK(pnode->cs_vSend); - if(pnode->hSocket == INVALID_SOCKET) { - return; - } bool optimisticSend(pnode->vSendMsg.empty()); //log total amount of bytes per command @@ -2708,19 +2779,19 @@ bool CConnman::ForNode(NodeId id, std::function<bool(CNode* pnode)> func) break; } } - return found != nullptr && func(found); + return found != nullptr && NodeFullyConnected(found) && func(found); } 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); } -CSipHasher CConnman::GetDeterministicRandomizer(uint64_t id) +CSipHasher CConnman::GetDeterministicRandomizer(uint64_t id) const { return CSipHasher(nSeed0, nSeed1).Write(id); } -uint64_t CConnman::CalculateKeyedNetGroup(const CAddress& ad) +uint64_t CConnman::CalculateKeyedNetGroup(const CAddress& ad) const { std::vector<unsigned char> vchNetGroup(ad.GetGroup()); @@ -162,75 +162,33 @@ public: void PushMessage(CNode* pnode, CSerializedNetMsg&& msg); template<typename Callable> - bool ForEachNodeContinueIf(Callable&& func) - { - LOCK(cs_vNodes); - for (auto&& node : vNodes) - if(!func(node)) - return false; - return true; - }; - - template<typename Callable> - bool ForEachNodeContinueIf(Callable&& func) const - { - LOCK(cs_vNodes); - for (const auto& node : vNodes) - if(!func(node)) - return false; - return true; - }; - - template<typename Callable, typename CallableAfter> - bool ForEachNodeContinueIfThen(Callable&& pre, CallableAfter&& post) - { - bool ret = true; - LOCK(cs_vNodes); - for (auto&& node : vNodes) - if(!pre(node)) { - ret = false; - break; - } - post(); - return ret; - }; - - template<typename Callable, typename CallableAfter> - bool ForEachNodeContinueIfThen(Callable&& pre, CallableAfter&& post) const - { - bool ret = true; - LOCK(cs_vNodes); - for (const auto& node : vNodes) - if(!pre(node)) { - ret = false; - break; - } - post(); - return ret; - }; - - template<typename Callable> void ForEachNode(Callable&& func) { LOCK(cs_vNodes); - for (auto&& node : vNodes) - func(node); + for (auto&& node : vNodes) { + if (NodeFullyConnected(node)) + func(node); + } }; template<typename Callable> void ForEachNode(Callable&& func) const { LOCK(cs_vNodes); - for (const auto& node : vNodes) - func(node); + for (auto&& node : vNodes) { + if (NodeFullyConnected(node)) + func(node); + } }; template<typename Callable, typename CallableAfter> void ForEachNodeThen(Callable&& pre, CallableAfter&& post) { LOCK(cs_vNodes); - for (auto&& node : vNodes) - pre(node); + for (auto&& node : vNodes) { + if (NodeFullyConnected(node)) + pre(node); + } post(); }; @@ -238,13 +196,13 @@ public: void ForEachNodeThen(Callable&& pre, CallableAfter&& post) const { LOCK(cs_vNodes); - for (const auto& node : vNodes) - pre(node); + for (auto&& node : vNodes) { + if (NodeFullyConnected(node)) + pre(node); + } post(); }; - void RelayTransaction(const CTransaction& tx); - // Addrman functions size_t GetAddressCount() const; void SetServices(const CService &addr, ServiceFlags nServices); @@ -286,10 +244,8 @@ public: size_t GetNodeCount(NumConnections num); void GetNodeStats(std::vector<CNodeStats>& vstats); - bool DisconnectAddress(const CNetAddr& addr); bool DisconnectNode(const std::string& node); bool DisconnectNode(NodeId id); - bool DisconnectSubnet(const CSubNet& subnet); unsigned int GetSendBufferSize() const; @@ -325,7 +281,7 @@ public: int GetBestHeight() const; /** Get a unique deterministic randomizer. */ - CSipHasher GetDeterministicRandomizer(uint64_t id); + CSipHasher GetDeterministicRandomizer(uint64_t id) const; unsigned int GetReceiveFloodSize() const; @@ -346,7 +302,7 @@ private: void ThreadSocketHandler(); void ThreadDNSAddressSeed(); - uint64_t CalculateKeyedNetGroup(const CAddress& ad); + uint64_t CalculateKeyedNetGroup(const CAddress& ad) const; CNode* FindNode(const CNetAddr& ip); CNode* FindNode(const CSubNet& subNet); @@ -361,7 +317,7 @@ private: NodeId GetNewNodeId(); - size_t SocketSendData(CNode *pnode); + size_t SocketSendData(CNode *pnode) const; //!check is the banlist has unwritten changes bool BannedSetIsDirty(); //!set the "dirty" flag for the banlist @@ -376,6 +332,9 @@ private: void RecordBytesRecv(uint64_t bytes); void RecordBytesSent(uint64_t bytes); + // Whether the node should be passed out in ForEach* callbacks + static bool NodeFullyConnected(const CNode* pnode); + // Network usage totals CCriticalSection cs_totalBytesRecv; CCriticalSection cs_totalBytesSent; @@ -605,7 +564,7 @@ class CNode friend class CConnman; public: // socket - ServiceFlags nServices; + std::atomic<ServiceFlags> nServices; ServiceFlags nServicesExpected; SOCKET hSocket; size_t nSendSize; // total size of all vSendMsg entries @@ -613,6 +572,8 @@ public: uint64_t nSendBytes; std::deque<std::vector<unsigned char>> vSendMsg; CCriticalSection cs_vSend; + CCriticalSection cs_hSocket; + CCriticalSection cs_vRecv; CCriticalSection cs_vProcessMsg; std::list<CNetMessage> vProcessMsg; @@ -624,26 +585,25 @@ public: uint64_t nRecvBytes; std::atomic<int> nRecvVersion; - int64_t nLastSend; - int64_t nLastRecv; - int64_t nTimeConnected; - int64_t nTimeOffset; + std::atomic<int64_t> nLastSend; + std::atomic<int64_t> nLastRecv; + const int64_t nTimeConnected; + std::atomic<int64_t> nTimeOffset; const CAddress addr; - std::string addrName; - CService addrLocal; - int nVersion; + std::atomic<int> nVersion; // strSubVer is whatever byte array we read from the wire. However, this field is intended // to be printed out, displayed to humans in various forms and so on. So we sanitize it and // store the sanitized version in cleanSubVer. The original should be used when dealing with // the network or wire types and the cleaned string used when displayed or logged. std::string strSubVer, cleanSubVer; + CCriticalSection cs_SubVer; // used for both cleanSubVer and strSubVer bool fWhitelisted; // This peer can bypass DoS banning. bool fFeeler; // If true this node is being used as a short lived feeler. bool fOneShot; bool fAddnode; bool fClient; const bool fInbound; - bool fSuccessfullyConnected; + std::atomic_bool fSuccessfullyConnected; std::atomic_bool fDisconnect; // We use fRelayTxes for two purposes - // a) it allows us to not relay tx invs before receiving the peer's version message @@ -654,7 +614,7 @@ public: CSemaphoreGrant grantOutbound; CCriticalSection cs_filter; CBloomFilter* pfilter; - int nRefCount; + std::atomic<int> nRefCount; const NodeId id; const uint64_t nKeyedNetGroup; @@ -667,7 +627,7 @@ protected: public: uint256 hashContinue; - int nStartingHeight; + std::atomic<int> nStartingHeight; // flood relay std::vector<CAddress> vAddrToSend; @@ -705,15 +665,15 @@ public: // Ping time measurement: // The pong reply we're expecting, or 0 if no pong expected. - uint64_t nPingNonceSent; + std::atomic<uint64_t> nPingNonceSent; // Time (in usec) the last ping was sent, or 0 if no ping was ever sent. - int64_t nPingUsecStart; + std::atomic<int64_t> nPingUsecStart; // Last measured round-trip time. - int64_t nPingUsecTime; + std::atomic<int64_t> nPingUsecTime; // Best measured round-trip time. - int64_t nMinPingUsecTime; + std::atomic<int64_t> nMinPingUsecTime; // Whether a ping is requested. - bool fPingQueued; + std::atomic<bool> fPingQueued; // Minimum fee rate with which to filter inv's to this node CAmount minFeeFilter; CCriticalSection cs_feeFilter; @@ -734,6 +694,12 @@ private: const int nMyStartingHeight; int nSendVersion; std::list<CNetMessage> vRecvMsg; // Used only by SocketHandler thread + + mutable CCriticalSection cs_addrName; + std::string addrName; + + CService addrLocal; + mutable CCriticalSection cs_addrLocal; public: NodeId GetId() const { @@ -764,25 +730,12 @@ public: { return nRecvVersion; } - void SetSendVersion(int nVersionIn) - { - // Send version may only be changed in the version message, and - // only one version message is allowed per session. We can therefore - // treat this value as const and even atomic as long as it's only used - // once the handshake is complete. Any attempt to set this twice is an - // error. - assert(nSendVersion == 0); - nSendVersion = nVersionIn; - } + void SetSendVersion(int nVersionIn); + int GetSendVersion() const; - int GetSendVersion() const - { - // The send version should always be explicitly set to - // INIT_PROTO_VERSION rather than using this value until the handshake - // is complete. - assert(nSendVersion != 0); - return nSendVersion; - } + CService GetAddrLocal() const; + //! May not be called more than once + void SetAddrLocal(const CService& addrLocalIn); CNode* AddRef() { @@ -853,6 +806,10 @@ public: { return nLocalServices; } + + std::string GetAddrName() const; + //! Sets the addrName only if it was not previously set + void MaybeSetAddrName(const std::string& addrNameIn); }; diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 36a5257635..3ec1a1c27d 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -32,13 +32,11 @@ #include <boost/thread.hpp> -using namespace std; - #if defined(NDEBUG) # error "Bitcoin cannot be compiled without assertions." #endif -int64_t nTimeBestReceived = 0; // Used only to inform the wallet of when we last received a block +std::atomic<int64_t> nTimeBestReceived(0); // Used only to inform the wallet of when we last received a block struct IteratorComparator { @@ -55,8 +53,8 @@ struct COrphanTx { NodeId fromPeer; int64_t nTimeExpire; }; -map<uint256, COrphanTx> mapOrphanTransactions GUARDED_BY(cs_main); -map<COutPoint, set<map<uint256, COrphanTx>::iterator, IteratorComparator>> mapOrphanTransactionsByPrev GUARDED_BY(cs_main); +std::map<uint256, COrphanTx> mapOrphanTransactions GUARDED_BY(cs_main); +std::map<COutPoint, std::set<std::map<uint256, COrphanTx>::iterator, IteratorComparator>> mapOrphanTransactionsByPrev GUARDED_BY(cs_main); void EraseOrphansFor(NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(cs_main); static size_t vExtraTxnForCompactIt = 0; @@ -76,7 +74,7 @@ namespace { * Set mapBlockSource[hash].second to false if the node should not be * punished if the block is invalid. */ - map<uint256, std::pair<NodeId, bool>> mapBlockSource; + std::map<uint256, std::pair<NodeId, bool>> mapBlockSource; /** * Filter for transactions that were recently rejected by @@ -108,10 +106,10 @@ namespace { bool fValidatedHeaders; //!< Whether this block has validated headers at the time of request. std::unique_ptr<PartiallyDownloadedBlock> partialBlock; //!< Optional, used for CMPCTBLOCK downloads }; - map<uint256, pair<NodeId, list<QueuedBlock>::iterator> > mapBlocksInFlight; + std::map<uint256, std::pair<NodeId, std::list<QueuedBlock>::iterator> > mapBlocksInFlight; /** Stack of nodes which we have set to announce using compact blocks */ - list<NodeId> lNodesAnnouncingHeaderAndIDs; + std::list<NodeId> lNodesAnnouncingHeaderAndIDs; /** Number of preferable block download peers. */ int nPreferredDownload = 0; @@ -135,7 +133,7 @@ namespace { struct CBlockReject { unsigned char chRejectCode; - string strRejectReason; + std::string strRejectReason; uint256 hashBlock; }; @@ -172,7 +170,7 @@ struct CNodeState { bool fSyncStarted; //! Since when we're stalling block download progress (in microseconds), or 0. int64_t nStallingSince; - list<QueuedBlock> vBlocksInFlight; + std::list<QueuedBlock> vBlocksInFlight; //! When the first entry in vBlocksInFlight started downloading. Don't care when vBlocksInFlight is empty. int64_t nDownloadingSince; int nBlocksInFlight; @@ -224,11 +222,11 @@ struct CNodeState { }; /** Map maintaining per-node state. Requires cs_main. */ -map<NodeId, CNodeState> mapNodeState; +std::map<NodeId, CNodeState> mapNodeState; // Requires cs_main. CNodeState *State(NodeId pnode) { - map<NodeId, CNodeState>::iterator it = mapNodeState.find(pnode); + std::map<NodeId, CNodeState>::iterator it = mapNodeState.find(pnode); if (it == mapNodeState.end()) return NULL; return &it->second; @@ -266,7 +264,7 @@ void PushNodeVersion(CNode *pnode, CConnman& connman, int64_t nTime) void InitializeNode(CNode *pnode, CConnman& connman) { CAddress addr = pnode->addr; - std::string addrName = pnode->addrName; + std::string addrName = pnode->GetAddrName(); NodeId nodeid = pnode->GetId(); { LOCK(cs_main); @@ -310,7 +308,7 @@ void FinalizeNode(NodeId nodeid, bool& fUpdateConnectionTime) { // Returns a bool indicating whether we requested this block. // Also used if a block was /not/ received and timed out or started with another peer bool MarkBlockAsReceived(const uint256& hash) { - map<uint256, pair<NodeId, list<QueuedBlock>::iterator> >::iterator itInFlight = mapBlocksInFlight.find(hash); + std::map<uint256, std::pair<NodeId, std::list<QueuedBlock>::iterator> >::iterator itInFlight = mapBlocksInFlight.find(hash); if (itInFlight != mapBlocksInFlight.end()) { CNodeState *state = State(itInFlight->second.first); state->nBlocksInFlightValidHeaders -= itInFlight->second.second->fValidatedHeaders; @@ -334,12 +332,12 @@ bool MarkBlockAsReceived(const uint256& hash) { // Requires cs_main. // returns false, still setting pit, if the block was already in flight from the same peer // pit will only be valid as long as the same cs_main lock is being held -bool MarkBlockAsInFlight(NodeId nodeid, const uint256& hash, const Consensus::Params& consensusParams, const CBlockIndex *pindex = NULL, list<QueuedBlock>::iterator **pit = NULL) { +bool MarkBlockAsInFlight(NodeId nodeid, const uint256& hash, const Consensus::Params& consensusParams, const CBlockIndex* pindex = NULL, std::list<QueuedBlock>::iterator** pit = NULL) { CNodeState *state = State(nodeid); assert(state != NULL); // Short-circuit most stuff in case its from the same node - map<uint256, pair<NodeId, list<QueuedBlock>::iterator> >::iterator itInFlight = mapBlocksInFlight.find(hash); + std::map<uint256, std::pair<NodeId, std::list<QueuedBlock>::iterator> >::iterator itInFlight = mapBlocksInFlight.find(hash); if (itInFlight != mapBlocksInFlight.end() && itInFlight->second.first == nodeid) { *pit = &itInFlight->second.second; return false; @@ -348,7 +346,7 @@ bool MarkBlockAsInFlight(NodeId nodeid, const uint256& hash, const Consensus::Pa // Make sure it's not listed somewhere already. MarkBlockAsReceived(hash); - list<QueuedBlock>::iterator it = state->vBlocksInFlight.insert(state->vBlocksInFlight.end(), + std::list<QueuedBlock>::iterator it = state->vBlocksInFlight.insert(state->vBlocksInFlight.end(), {hash, pindex, pindex != NULL, std::unique_ptr<PartiallyDownloadedBlock>(pit ? new PartiallyDownloadedBlock(&mempool) : NULL)}); state->nBlocksInFlight++; state->nBlocksInFlightValidHeaders += it->fValidatedHeaders; @@ -640,7 +638,7 @@ bool AddOrphanTx(const CTransactionRef& tx, NodeId peer) EXCLUSIVE_LOCKS_REQUIRE int static EraseOrphanTx(uint256 hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main) { - map<uint256, COrphanTx>::iterator it = mapOrphanTransactions.find(hash); + std::map<uint256, COrphanTx>::iterator it = mapOrphanTransactions.find(hash); if (it == mapOrphanTransactions.end()) return 0; BOOST_FOREACH(const CTxIn& txin, it->second.tx->vin) @@ -659,10 +657,10 @@ int static EraseOrphanTx(uint256 hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main) void EraseOrphansFor(NodeId peer) { int nErased = 0; - map<uint256, COrphanTx>::iterator iter = mapOrphanTransactions.begin(); + std::map<uint256, COrphanTx>::iterator iter = mapOrphanTransactions.begin(); while (iter != mapOrphanTransactions.end()) { - map<uint256, COrphanTx>::iterator maybeErase = iter++; // increment to avoid iterator becoming invalid + std::map<uint256, COrphanTx>::iterator maybeErase = iter++; // increment to avoid iterator becoming invalid if (maybeErase->second.fromPeer == peer) { nErased += EraseOrphanTx(maybeErase->second.tx->GetHash()); @@ -681,10 +679,10 @@ unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans) EXCLUSIVE_LOCKS_REQUIRE // Sweep out expired orphan pool entries: int nErased = 0; int64_t nMinExpTime = nNow + ORPHAN_TX_EXPIRE_TIME - ORPHAN_TX_EXPIRE_INTERVAL; - map<uint256, COrphanTx>::iterator iter = mapOrphanTransactions.begin(); + std::map<uint256, COrphanTx>::iterator iter = mapOrphanTransactions.begin(); while (iter != mapOrphanTransactions.end()) { - map<uint256, COrphanTx>::iterator maybeErase = iter++; + std::map<uint256, COrphanTx>::iterator maybeErase = iter++; if (maybeErase->second.nTimeExpire <= nNow) { nErased += EraseOrphanTx(maybeErase->second.tx->GetHash()); } else { @@ -699,7 +697,7 @@ unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans) EXCLUSIVE_LOCKS_REQUIRE { // Evict a random orphan: uint256 randomhash = GetRandHash(); - map<uint256, COrphanTx>::iterator it = mapOrphanTransactions.lower_bound(randomhash); + std::map<uint256, COrphanTx>::iterator it = mapOrphanTransactions.lower_bound(randomhash); if (it == mapOrphanTransactions.end()) it = mapOrphanTransactions.begin(); EraseOrphanTx(it->first); @@ -780,7 +778,7 @@ static uint256 most_recent_block_hash; void PeerLogicValidation::NewPoWValidBlock(const CBlockIndex *pindex, const std::shared_ptr<const CBlock>& pblock) { std::shared_ptr<const CBlockHeaderAndShortTxIDs> pcmpctblock = std::make_shared<const CBlockHeaderAndShortTxIDs> (*pblock, true); - CNetMsgMaker msgMaker(PROTOCOL_VERSION); + const CNetMsgMaker msgMaker(PROTOCOL_VERSION); LOCK(cs_main); @@ -865,7 +863,15 @@ void PeerLogicValidation::BlockChecked(const CBlock& block, const CValidationSta Misbehaving(it->second.first, nDoS); } } - else if (state.IsValid() && !IsInitialBlockDownload() && mapBlocksInFlight.count(hash) == mapBlocksInFlight.size()) { + // Check that: + // 1. The block is valid + // 2. We're not in initial block download + // 3. This is currently the best block we're aware of. We haven't updated + // the tip yet so we have no way to check this directly here. Instead we + // just check that there are currently no other blocks in flight. + else if (state.IsValid() && + !IsInitialBlockDownload() && + mapBlocksInFlight.count(hash) == mapBlocksInFlight.size()) { if (it != mapBlockSource.end()) { MaybeSetPeerAsAnnouncingHeaderAndIDs(it->second.first, *connman); } @@ -958,11 +964,11 @@ static void RelayAddress(const CAddress& addr, bool fReachable, CConnman& connma connman.ForEachNodeThen(std::move(sortfunc), std::move(pushfunc)); } -void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParams, CConnman& connman, std::atomic<bool>& interruptMsgProc) +void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParams, CConnman& connman, const std::atomic<bool>& interruptMsgProc) { std::deque<CInv>::iterator it = pfrom->vRecvGetData.begin(); - vector<CInv> vNotFound; - CNetMsgMaker msgMaker(pfrom->GetSendVersion()); + std::vector<CInv> vNotFound; + const CNetMsgMaker msgMaker(pfrom->GetSendVersion()); LOCK(cs_main); while (it != pfrom->vRecvGetData.end()) { @@ -1083,7 +1089,7 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam // Bypass PushInventory, this must send even if redundant, // and we want it right after the last block so they don't // wait for other stuff first. - vector<CInv> vInv; + std::vector<CInv> vInv; vInv.push_back(CInv(MSG_BLOCK, chainActive.Tip()->GetBlockHash())); connman.PushMessage(pfrom, msgMaker.Make(NetMsgType::INV, vInv)); pfrom->hashContinue.SetNull(); @@ -1155,12 +1161,12 @@ inline void static SendBlockTransactions(const CBlock& block, const BlockTransac resp.txn[i] = block.vtx[req.indexes[i]]; } LOCK(cs_main); - CNetMsgMaker msgMaker(pfrom->GetSendVersion()); + const CNetMsgMaker msgMaker(pfrom->GetSendVersion()); int nSendFlags = State(pfrom->GetId())->fWantsCmpctWitness ? 0 : SERIALIZE_TRANSACTION_NO_WITNESS; connman.PushMessage(pfrom, msgMaker.Make(nSendFlags, NetMsgType::BLOCKTXN, resp)); } -bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, int64_t nTimeReceived, const CChainParams& chainparams, CConnman& connman, std::atomic<bool>& interruptMsgProc) +bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStream& vRecv, int64_t nTimeReceived, const CChainParams& chainparams, CConnman& connman, const std::atomic<bool>& interruptMsgProc) { LogPrint("net", "received: %s (%u bytes) peer=%d\n", SanitizeString(strCommand), vRecv.size(), pfrom->id); if (IsArgSet("-dropmessagestest") && GetRand(GetArg("-dropmessagestest", 0)) == 0) @@ -1184,13 +1190,36 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } } + if (strCommand == NetMsgType::REJECT) + { + if (fDebug) { + try { + std::string strMsg; unsigned char ccode; std::string strReason; + vRecv >> LIMITED_STRING(strMsg, CMessageHeader::COMMAND_SIZE) >> ccode >> LIMITED_STRING(strReason, MAX_REJECT_MESSAGE_LENGTH); + + std::ostringstream ss; + ss << strMsg << " code " << itostr(ccode) << ": " << strReason; + + if (strMsg == NetMsgType::BLOCK || strMsg == NetMsgType::TX) + { + uint256 hash; + vRecv >> hash; + ss << ": hash " << hash.ToString(); + } + LogPrint("net", "Reject %s\n", SanitizeString(ss.str())); + } catch (const std::ios_base::failure&) { + // Avoid feedback loops by preventing reject messages from triggering a new reject message. + LogPrint("net", "Unparseable reject message received\n"); + } + } + } - if (strCommand == NetMsgType::VERSION) + else if (strCommand == NetMsgType::VERSION) { // Each connection can only send one version message if (pfrom->nVersion != 0) { - connman.PushMessage(pfrom, CNetMsgMaker(INIT_PROTO_VERSION).Make(NetMsgType::REJECT, strCommand, REJECT_DUPLICATE, string("Duplicate version message"))); + connman.PushMessage(pfrom, CNetMsgMaker(INIT_PROTO_VERSION).Make(NetMsgType::REJECT, strCommand, REJECT_DUPLICATE, std::string("Duplicate version message"))); LOCK(cs_main); Misbehaving(pfrom->GetId(), 1); return false; @@ -1201,50 +1230,53 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, CAddress addrFrom; uint64_t nNonce = 1; uint64_t nServiceInt; - vRecv >> pfrom->nVersion >> nServiceInt >> nTime >> addrMe; - pfrom->nServices = ServiceFlags(nServiceInt); + ServiceFlags nServices; + int nVersion; + int nSendVersion; + std::string strSubVer; + std::string cleanSubVer; + int nStartingHeight = -1; + bool fRelay = true; + + vRecv >> nVersion >> nServiceInt >> nTime >> addrMe; + nSendVersion = std::min(nVersion, PROTOCOL_VERSION); + nServices = ServiceFlags(nServiceInt); if (!pfrom->fInbound) { - connman.SetServices(pfrom->addr, pfrom->nServices); + connman.SetServices(pfrom->addr, nServices); } - if (pfrom->nServicesExpected & ~pfrom->nServices) + if (pfrom->nServicesExpected & ~nServices) { - LogPrint("net", "peer=%d does not offer the expected services (%08x offered, %08x expected); disconnecting\n", pfrom->id, pfrom->nServices, pfrom->nServicesExpected); + LogPrint("net", "peer=%d does not offer the expected services (%08x offered, %08x expected); disconnecting\n", pfrom->id, nServices, pfrom->nServicesExpected); connman.PushMessage(pfrom, CNetMsgMaker(INIT_PROTO_VERSION).Make(NetMsgType::REJECT, strCommand, REJECT_NONSTANDARD, strprintf("Expected to offer services %08x", pfrom->nServicesExpected))); pfrom->fDisconnect = true; return false; } - if (pfrom->nVersion < MIN_PEER_PROTO_VERSION) + if (nVersion < MIN_PEER_PROTO_VERSION) { // disconnect from peers older than this proto version - LogPrintf("peer=%d using obsolete version %i; disconnecting\n", pfrom->id, pfrom->nVersion); + LogPrintf("peer=%d using obsolete version %i; disconnecting\n", pfrom->id, nVersion); connman.PushMessage(pfrom, CNetMsgMaker(INIT_PROTO_VERSION).Make(NetMsgType::REJECT, strCommand, REJECT_OBSOLETE, strprintf("Version must be %d or greater", MIN_PEER_PROTO_VERSION))); pfrom->fDisconnect = true; return false; } - if (pfrom->nVersion == 10300) - pfrom->nVersion = 300; + if (nVersion == 10300) + nVersion = 300; if (!vRecv.empty()) vRecv >> addrFrom >> nNonce; if (!vRecv.empty()) { - vRecv >> LIMITED_STRING(pfrom->strSubVer, MAX_SUBVERSION_LENGTH); - pfrom->cleanSubVer = SanitizeString(pfrom->strSubVer); + vRecv >> LIMITED_STRING(strSubVer, MAX_SUBVERSION_LENGTH); + cleanSubVer = SanitizeString(strSubVer); } if (!vRecv.empty()) { - vRecv >> pfrom->nStartingHeight; - } - { - LOCK(pfrom->cs_filter); - if (!vRecv.empty()) - vRecv >> pfrom->fRelayTxes; // set to true after we get the first filter* message - else - pfrom->fRelayTxes = true; + vRecv >> nStartingHeight; } - + if (!vRecv.empty()) + vRecv >> fRelay; // Disconnect if we connected to ourself if (pfrom->fInbound && !connman.CheckIncomingNonce(nNonce)) { @@ -1253,7 +1285,6 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, return true; } - pfrom->addrLocal = addrMe; if (pfrom->fInbound && addrMe.IsRoutable()) { SeenLocal(addrMe); @@ -1263,9 +1294,27 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, if (pfrom->fInbound) PushNodeVersion(pfrom, connman, GetAdjustedTime()); - pfrom->fClient = !(pfrom->nServices & NODE_NETWORK); + connman.PushMessage(pfrom, CNetMsgMaker(INIT_PROTO_VERSION).Make(NetMsgType::VERACK)); + + pfrom->nServices = nServices; + pfrom->SetAddrLocal(addrMe); + { + LOCK(pfrom->cs_SubVer); + pfrom->strSubVer = strSubVer; + pfrom->cleanSubVer = cleanSubVer; + } + pfrom->nStartingHeight = nStartingHeight; + pfrom->fClient = !(nServices & NODE_NETWORK); + { + LOCK(pfrom->cs_filter); + pfrom->fRelayTxes = fRelay; // set to true after we get the first filter* message + } + + // Change version + pfrom->SetSendVersion(nSendVersion); + pfrom->nVersion = nVersion; - if((pfrom->nServices & NODE_WITNESS)) + if((nServices & NODE_WITNESS)) { LOCK(cs_main); State(pfrom->GetId())->fHaveWitness = true; @@ -1277,11 +1326,6 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, UpdatePreferredDownload(pfrom, State(pfrom->GetId())); } - // Change version - connman.PushMessage(pfrom, CNetMsgMaker(INIT_PROTO_VERSION).Make(NetMsgType::VERACK)); - int nSendVersion = std::min(pfrom->nVersion, PROTOCOL_VERSION); - pfrom->SetSendVersion(nSendVersion); - if (!pfrom->fInbound) { // Advertise our address @@ -1294,7 +1338,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, LogPrint("net", "ProcessMessages: advertising address %s\n", addr.ToString()); pfrom->PushAddress(addr, insecure_rand); } else if (IsPeerAddrLocalGood(pfrom)) { - addr.SetIP(pfrom->addrLocal); + addr.SetIP(addrMe); LogPrint("net", "ProcessMessages: advertising address %s\n", addr.ToString()); pfrom->PushAddress(addr, insecure_rand); } @@ -1309,14 +1353,12 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, connman.MarkAddressGood(pfrom->addr); } - pfrom->fSuccessfullyConnected = true; - - string remoteAddr; + std::string remoteAddr; if (fLogIPs) remoteAddr = ", peeraddr=" + pfrom->addr.ToString(); LogPrintf("receive version message: %s: version %d, blocks=%d, us=%s, peer=%d%s\n", - pfrom->cleanSubVer, pfrom->nVersion, + cleanSubVer, pfrom->nVersion, pfrom->nStartingHeight, addrMe.ToString(), pfrom->id, remoteAddr); @@ -1324,6 +1366,12 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, pfrom->nTimeOffset = nTimeOffset; AddTimeData(pfrom->addr, nTimeOffset); + // If the peer is old enough to have the old alert system, send it the final alert. + if (pfrom->nVersion <= 70012) { + CDataStream finalAlert(ParseHex("60010000000000000000000000ffffff7f00000000ffffff7ffeffff7f01ffffff7f00000000ffffff7f00ffffff7f002f555247454e543a20416c657274206b657920636f6d70726f6d697365642c2075706772616465207265717569726564004630440220653febd6410f470f6bae11cad19c48413becb1ac2c17f908fd0fd53bdc3abd5202206d0e9c96fe88d4a0f01ed9dedae2b6f9e00da94cad0fecaae66ecf689bf71b50"), SER_NETWORK, PROTOCOL_VERSION); + connman.PushMessage(pfrom, CNetMsgMaker(nSendVersion).Make("alert", finalAlert)); + } + // Feeler connections exist only to verify if address is online. if (pfrom->fFeeler) { assert(pfrom->fInbound == false); @@ -1342,11 +1390,11 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } // At this point, the outgoing message serialization version can't change. - CNetMsgMaker msgMaker(pfrom->GetSendVersion()); + const CNetMsgMaker msgMaker(pfrom->GetSendVersion()); if (strCommand == NetMsgType::VERACK) { - pfrom->SetRecvVersion(min(pfrom->nVersion, PROTOCOL_VERSION)); + pfrom->SetRecvVersion(std::min(pfrom->nVersion.load(), PROTOCOL_VERSION)); if (!pfrom->fInbound) { // Mark this node as currently connected, so we update its timestamp later. @@ -1374,12 +1422,20 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, nCMPCTBLOCKVersion = 1; connman.PushMessage(pfrom, msgMaker.Make(NetMsgType::SENDCMPCT, fAnnounceUsingCMPCTBLOCK, nCMPCTBLOCKVersion)); } + pfrom->fSuccessfullyConnected = true; } + else if (!pfrom->fSuccessfullyConnected) + { + // Must have a verack message before anything else + LOCK(cs_main); + Misbehaving(pfrom->GetId(), 1); + return false; + } else if (strCommand == NetMsgType::ADDR) { - vector<CAddress> vAddr; + std::vector<CAddress> vAddr; vRecv >> vAddr; // Don't want addr from older versions unless seeding @@ -1393,7 +1449,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } // Store the new addresses - vector<CAddress> vAddrOk; + std::vector<CAddress> vAddrOk; int64_t nNow = GetAdjustedTime(); int64_t nSince = nNow - 10 * 60; BOOST_FOREACH(CAddress& addr, vAddr) @@ -1456,7 +1512,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, else if (strCommand == NetMsgType::INV) { - vector<CInv> vInv; + std::vector<CInv> vInv; vRecv >> vInv; if (vInv.size() > MAX_INV_SZ) { @@ -1523,7 +1579,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, else if (strCommand == NetMsgType::GETDATA) { - vector<CInv> vInv; + std::vector<CInv> vInv; vRecv >> vInv; if (vInv.size() > MAX_INV_SZ) { @@ -1685,7 +1741,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } // we must use CBlocks, as CBlockHeaders won't include the 0x00 nTx count at the end - vector<CBlock> vHeaders; + std::vector<CBlock> vHeaders; int nLimit = MAX_HEADERS_RESULTS; LogPrint("net", "getheaders %d to %s from peer=%d\n", (pindex ? pindex->nHeight : -1), hashStop.IsNull() ? "end" : hashStop.ToString(), pfrom->id); for (; pindex; pindex = chainActive.Next(pindex)) @@ -1721,8 +1777,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, return true; } - deque<COutPoint> vWorkQueue; - vector<uint256> vEraseQueue; + std::deque<COutPoint> vWorkQueue; + std::vector<uint256> vEraseQueue; CTransactionRef ptx; vRecv >> ptx; const CTransaction& tx = *ptx; @@ -1755,7 +1811,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, mempool.size(), mempool.DynamicMemoryUsage() / 1000); // Recursively process any orphan transactions that depended on this one - set<NodeId> setMisbehaving; + std::set<NodeId> setMisbehaving; while (!vWorkQueue.empty()) { auto itByPrev = mapOrphanTransactionsByPrev.find(vWorkQueue.front()); vWorkQueue.pop_front(); @@ -1877,8 +1933,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } } - for (const CTransactionRef& tx : lRemovedTxn) - AddToCompactExtraTransactions(tx); + for (const CTransactionRef& removedTx : lRemovedTxn) + AddToCompactExtraTransactions(removedTx); int nDoS = 0; if (state.IsInvalid(nDoS)) @@ -1949,7 +2005,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, assert(pindex); UpdateBlockAvailability(pfrom->GetId(), pindex->GetBlockHash()); - std::map<uint256, pair<NodeId, list<QueuedBlock>::iterator> >::iterator blockInFlightIt = mapBlocksInFlight.find(pindex->GetBlockHash()); + std::map<uint256, std::pair<NodeId, std::list<QueuedBlock>::iterator> >::iterator blockInFlightIt = mapBlocksInFlight.find(pindex->GetBlockHash()); bool fAlreadyInFlight = blockInFlightIt != mapBlocksInFlight.end(); if (pindex->nStatus & BLOCK_HAVE_DATA) // Nothing to do here @@ -1984,7 +2040,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, if (pindex->nHeight <= chainActive.Height() + 2) { if ((!fAlreadyInFlight && nodestate->nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) || (fAlreadyInFlight && blockInFlightIt->second.first == pfrom->GetId())) { - list<QueuedBlock>::iterator *queuedBlockIt = NULL; + std::list<QueuedBlock>::iterator* queuedBlockIt = NULL; if (!MarkBlockAsInFlight(pfrom->GetId(), pindex->GetBlockHash(), chainparams.GetConsensus(), pindex, &queuedBlockIt)) { if (!(*queuedBlockIt)->partialBlock) (*queuedBlockIt)->partialBlock.reset(new PartiallyDownloadedBlock(&mempool)); @@ -2102,7 +2158,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, { LOCK(cs_main); - map<uint256, pair<NodeId, list<QueuedBlock>::iterator> >::iterator it = mapBlocksInFlight.find(resp.blockhash); + std::map<uint256, std::pair<NodeId, std::list<QueuedBlock>::iterator> >::iterator it = mapBlocksInFlight.find(resp.blockhash); if (it == mapBlocksInFlight.end() || !it->second.second->partialBlock || it->second.first != pfrom->GetId()) { LogPrint("net", "Peer %d sent us block transactions for block we weren't expecting\n", pfrom->id); @@ -2259,7 +2315,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // 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<const CBlockIndex *> vToFetch; + std::vector<const CBlockIndex*> vToFetch; const 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) { @@ -2280,7 +2336,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, pindexLast->GetBlockHash().ToString(), pindexLast->nHeight); } else { - vector<CInv> vGetData; + std::vector<CInv> vGetData; // Download as much as possible, from earliest to latest. BOOST_REVERSE_FOREACH(const CBlockIndex *pindex, vToFetch) { if (nodestate->nBlocksInFlight >= MAX_BLOCKS_IN_TRANSIT_PER_PEER) { @@ -2359,7 +2415,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, pfrom->fSentAddr = true; pfrom->vAddrToSend.clear(); - vector<CAddress> vAddr = connman.GetAddresses(); + std::vector<CAddress> vAddr = connman.GetAddresses(); FastRandomContext insecure_rand; BOOST_FOREACH(const CAddress &addr, vAddr) pfrom->PushAddress(addr, insecure_rand); @@ -2429,7 +2485,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, if (pingUsecTime > 0) { // Successful ping time measurement, replace previous pfrom->nPingUsecTime = pingUsecTime; - pfrom->nMinPingUsecTime = std::min(pfrom->nMinPingUsecTime, pingUsecTime); + pfrom->nMinPingUsecTime = std::min(pfrom->nMinPingUsecTime.load(), pingUsecTime); } else { // This should never happen sProblem = "Timing mishap"; @@ -2490,7 +2546,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, else if (strCommand == NetMsgType::FILTERADD) { - vector<unsigned char> vData; + std::vector<unsigned char> vData; vRecv >> vData; // Nodes must NEVER send a data item > 520 bytes (the max size for a script data object, @@ -2523,31 +2579,6 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, pfrom->fRelayTxes = true; } - - else if (strCommand == NetMsgType::REJECT) - { - if (fDebug) { - try { - string strMsg; unsigned char ccode; string strReason; - vRecv >> LIMITED_STRING(strMsg, CMessageHeader::COMMAND_SIZE) >> ccode >> LIMITED_STRING(strReason, MAX_REJECT_MESSAGE_LENGTH); - - ostringstream ss; - ss << strMsg << " code " << itostr(ccode) << ": " << strReason; - - if (strMsg == NetMsgType::BLOCK || strMsg == NetMsgType::TX) - { - uint256 hash; - vRecv >> hash; - ss << ": hash " << hash.ToString(); - } - LogPrint("net", "Reject %s\n", SanitizeString(ss.str())); - } catch (const std::ios_base::failure&) { - // Avoid feedback loops by preventing reject messages from triggering a new reject message. - LogPrint("net", "Unparseable reject message received\n"); - } - } - } - else if (strCommand == NetMsgType::FEEFILTER) { CAmount newFeeFilter = 0; vRecv >> newFeeFilter; @@ -2575,7 +2606,37 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, return true; } -bool ProcessMessages(CNode* pfrom, CConnman& connman, std::atomic<bool>& interruptMsgProc) +static bool SendRejectsAndCheckIfBanned(CNode* pnode, CConnman& connman) +{ + AssertLockHeld(cs_main); + CNodeState &state = *State(pnode->GetId()); + + BOOST_FOREACH(const CBlockReject& reject, state.rejects) { + connman.PushMessage(pnode, CNetMsgMaker(INIT_PROTO_VERSION).Make(NetMsgType::REJECT, (std::string)NetMsgType::BLOCK, reject.chRejectCode, reject.strRejectReason, reject.hashBlock)); + } + state.rejects.clear(); + + if (state.fShouldBan) { + state.fShouldBan = false; + if (pnode->fWhitelisted) + LogPrintf("Warning: not punishing whitelisted peer %s!\n", pnode->addr.ToString()); + else if (pnode->fAddnode) + LogPrintf("Warning: not punishing addnoded peer %s!\n", pnode->addr.ToString()); + else { + pnode->fDisconnect = true; + if (pnode->addr.IsLocal()) + LogPrintf("Warning: not banning local peer %s!\n", pnode->addr.ToString()); + else + { + connman.Ban(pnode->addr, BanReasonNodeMisbehaving); + } + } + return true; + } + return false; +} + +bool ProcessMessages(CNode* pfrom, CConnman& connman, const std::atomic<bool>& interruptMsgProc) { const CChainParams& chainparams = Params(); // @@ -2629,7 +2690,7 @@ bool ProcessMessages(CNode* pfrom, CConnman& connman, std::atomic<bool>& interru LogPrintf("PROCESSMESSAGE: ERRORS IN HEADER %s peer=%d\n", SanitizeString(hdr.GetCommand()), pfrom->id); return fMoreWork; } - string strCommand = hdr.GetCommand(); + std::string strCommand = hdr.GetCommand(); // Message size unsigned int nMessageSize = hdr.nMessageSize; @@ -2658,7 +2719,7 @@ bool ProcessMessages(CNode* pfrom, CConnman& connman, std::atomic<bool>& interru } catch (const std::ios_base::failure& e) { - connman.PushMessage(pfrom, CNetMsgMaker(INIT_PROTO_VERSION).Make(NetMsgType::REJECT, strCommand, REJECT_MALFORMED, string("error parsing message"))); + connman.PushMessage(pfrom, CNetMsgMaker(INIT_PROTO_VERSION).Make(NetMsgType::REJECT, strCommand, REJECT_MALFORMED, std::string("error parsing message"))); if (strstr(e.what(), "end of data")) { // Allow exceptions from under-length message on vRecv @@ -2685,8 +2746,12 @@ bool ProcessMessages(CNode* pfrom, CConnman& connman, std::atomic<bool>& interru PrintExceptionContinue(NULL, "ProcessMessages()"); } - if (!fRet) + if (!fRet) { LogPrintf("%s(%s, %u bytes) FAILED peer=%d\n", __func__, SanitizeString(strCommand), nMessageSize, pfrom->id); + } + + LOCK(cs_main); + SendRejectsAndCheckIfBanned(pfrom, connman); return fMoreWork; } @@ -2708,16 +2773,16 @@ public: } }; -bool SendMessages(CNode* pto, CConnman& connman, std::atomic<bool>& interruptMsgProc) +bool SendMessages(CNode* pto, CConnman& connman, const std::atomic<bool>& interruptMsgProc) { const Consensus::Params& consensusParams = Params().GetConsensus(); { - // Don't send anything until we get its version message - if (pto->nVersion == 0 || pto->fDisconnect) + // Don't send anything until the version handshake is complete + if (!pto->fSuccessfullyConnected || pto->fDisconnect) return true; // If we get here, the outgoing message serialization version is set and can't change. - CNetMsgMaker msgMaker(pto->GetSendVersion()); + const CNetMsgMaker msgMaker(pto->GetSendVersion()); // // Message: ping @@ -2752,30 +2817,10 @@ bool SendMessages(CNode* pto, CConnman& connman, std::atomic<bool>& interruptMsg if (!lockMain) return true; + if (SendRejectsAndCheckIfBanned(pto, connman)) + return true; CNodeState &state = *State(pto->GetId()); - BOOST_FOREACH(const CBlockReject& reject, state.rejects) - connman.PushMessage(pto, msgMaker.Make(NetMsgType::REJECT, (string)NetMsgType::BLOCK, reject.chRejectCode, reject.strRejectReason, reject.hashBlock)); - state.rejects.clear(); - - if (state.fShouldBan) { - state.fShouldBan = false; - if (pto->fWhitelisted) - LogPrintf("Warning: not punishing whitelisted peer %s!\n", pto->addr.ToString()); - else if (pto->fAddnode) - LogPrintf("Warning: not punishing addnoded peer %s!\n", pto->addr.ToString()); - else { - pto->fDisconnect = true; - if (pto->addr.IsLocal()) - LogPrintf("Warning: not banning local peer %s!\n", pto->addr.ToString()); - else - { - connman.Ban(pto->addr, BanReasonNodeMisbehaving); - } - return true; - } - } - // Address refresh broadcast int64_t nNow = GetTimeMicros(); if (!IsInitialBlockDownload() && pto->nNextLocalAddrSend < nNow) { @@ -2788,7 +2833,7 @@ bool SendMessages(CNode* pto, CConnman& connman, std::atomic<bool>& interruptMsg // if (pto->nNextAddrSend < nNow) { pto->nNextAddrSend = PoissonNextSend(nNow, AVG_ADDRESS_BROADCAST_INTERVAL); - vector<CAddress> vAddr; + std::vector<CAddress> vAddr; vAddr.reserve(pto->vAddrToSend.size()); BOOST_FOREACH(const CAddress& addr, pto->vAddrToSend) { @@ -2856,7 +2901,7 @@ bool SendMessages(CNode* pto, CConnman& connman, std::atomic<bool>& interruptMsg // blocks, or if the peer doesn't want headers, just // add all to the inv queue. LOCK(pto->cs_inventory); - vector<CBlock> vHeaders; + std::vector<CBlock> vHeaders; bool fRevertToInv = ((!state.fPreferHeaders && (!state.fPreferHeaderAndIDs || pto->vBlockHashesToAnnounce.size() > 1)) || pto->vBlockHashesToAnnounce.size() > MAX_BLOCKS_TO_ANNOUNCE); @@ -2988,7 +3033,7 @@ bool SendMessages(CNode* pto, CConnman& connman, std::atomic<bool>& interruptMsg // // Message: inventory // - vector<CInv> vInv; + std::vector<CInv> vInv; { LOCK(pto->cs_inventory); vInv.reserve(std::max<size_t>(pto->vInventoryBlockToSend.size(), INVENTORY_BROADCAST_MAX)); @@ -3053,7 +3098,7 @@ bool SendMessages(CNode* pto, CConnman& connman, std::atomic<bool>& interruptMsg // Determine transactions to relay if (fSendTrickle) { // Produce a vector with all candidates for sending - vector<std::set<uint256>::iterator> vInvTx; + std::vector<std::set<uint256>::iterator> vInvTx; vInvTx.reserve(pto->setInventoryTxToSend.size()); for (std::set<uint256>::iterator it = pto->setInventoryTxToSend.begin(); it != pto->setInventoryTxToSend.end(); it++) { vInvTx.push_back(it); @@ -3147,9 +3192,9 @@ bool SendMessages(CNode* pto, CConnman& connman, std::atomic<bool>& interruptMsg // // Message: getdata (blocks) // - vector<CInv> vGetData; + std::vector<CInv> vGetData; if (!pto->fClient && (fFetch || !IsInitialBlockDownload()) && state.nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) { - vector<const CBlockIndex*> vToDownload; + std::vector<const CBlockIndex*> vToDownload; NodeId staller = -1; FindNextBlocksToDownload(pto->GetId(), MAX_BLOCKS_IN_TRANSIT_PER_PEER - state.nBlocksInFlight, vToDownload, staller, consensusParams); BOOST_FOREACH(const CBlockIndex *pindex, vToDownload) { diff --git a/src/net_processing.h b/src/net_processing.h index 7351c0e99c..9e3f1b7156 100644 --- a/src/net_processing.h +++ b/src/net_processing.h @@ -49,7 +49,7 @@ bool GetNodeStateStats(NodeId nodeid, CNodeStateStats &stats); void Misbehaving(NodeId nodeid, int howmuch); /** Process protocol messages received from a given node */ -bool ProcessMessages(CNode* pfrom, CConnman& connman, std::atomic<bool>& interrupt); +bool ProcessMessages(CNode* pfrom, CConnman& connman, const std::atomic<bool>& interrupt); /** * Send queued protocol messages to be sent to a give node. * @@ -58,6 +58,6 @@ bool ProcessMessages(CNode* pfrom, CConnman& connman, std::atomic<bool>& interru * @param[in] interrupt Interrupt condition for processing threads * @return True if there is more work to be done */ -bool SendMessages(CNode* pto, CConnman& connman, std::atomic<bool>& interrupt); +bool SendMessages(CNode* pto, CConnman& connman, const std::atomic<bool>& interrupt); #endif // BITCOIN_NET_PROCESSING_H diff --git a/src/netaddress.h b/src/netaddress.h index bc430dd823..a85c2b7452 100644 --- a/src/netaddress.h +++ b/src/netaddress.h @@ -49,7 +49,7 @@ class CNetAddr bool IsIPv4() const; // IPv4 mapped address (::FFFF:0:0/96, 0.0.0.0/0) bool IsIPv6() const; // IPv6 address (not mapped IPv4, not Tor) bool IsRFC1918() const; // IPv4 private networks (10.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12) - bool IsRFC2544() const; // IPv4 inter-network communcations (192.18.0.0/15) + bool IsRFC2544() const; // IPv4 inter-network communications (192.18.0.0/15) bool IsRFC6598() const; // IPv4 ISP-level NAT (100.64.0.0/10) bool IsRFC5737() const; // IPv4 documentation addresses (192.0.2.0/24, 198.51.100.0/24, 203.0.113.0/24) bool IsRFC3849() const; // IPv6 documentation address (2001:0DB8::/32) diff --git a/src/netbase.cpp b/src/netbase.cpp index 8fd2a8efd2..fc9a6ed0be 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -198,6 +198,14 @@ struct timeval MillisToTimeval(int64_t nTimeout) return timeout; } +enum class IntrRecvError { + OK, + Timeout, + Disconnected, + NetworkError, + Interrupted +}; + /** * Read bytes from socket. This will either read the full number of bytes requested * or return False on error or timeout. @@ -209,7 +217,7 @@ struct timeval MillisToTimeval(int64_t nTimeout) * * @note This function requires that hSocket is in non-blocking mode. */ -bool static InterruptibleRecv(char* data, size_t len, int timeout, SOCKET& hSocket) +static IntrRecvError InterruptibleRecv(char* data, size_t len, int timeout, SOCKET& hSocket) { int64_t curTime = GetTimeMillis(); int64_t endTime = curTime + timeout; @@ -222,12 +230,12 @@ bool static InterruptibleRecv(char* data, size_t len, int timeout, SOCKET& hSock len -= ret; data += ret; } else if (ret == 0) { // Unexpected disconnection - return false; + return IntrRecvError::Disconnected; } else { // Other error or blocking int nErr = WSAGetLastError(); if (nErr == WSAEINPROGRESS || nErr == WSAEWOULDBLOCK || nErr == WSAEINVAL) { if (!IsSelectableSocket(hSocket)) { - return false; + return IntrRecvError::NetworkError; } struct timeval tval = MillisToTimeval(std::min(endTime - curTime, maxWait)); fd_set fdset; @@ -235,17 +243,17 @@ bool static InterruptibleRecv(char* data, size_t len, int timeout, SOCKET& hSock FD_SET(hSocket, &fdset); int nRet = select(hSocket + 1, &fdset, NULL, NULL, &tval); if (nRet == SOCKET_ERROR) { - return false; + return IntrRecvError::NetworkError; } } else { - return false; + return IntrRecvError::NetworkError; } } if (interruptSocks5Recv) - return false; + return IntrRecvError::Interrupted; curTime = GetTimeMillis(); } - return len == 0; + return len == 0 ? IntrRecvError::OK : IntrRecvError::Timeout; } struct ProxyCredentials @@ -272,6 +280,7 @@ std::string Socks5ErrorString(int err) /** Connect using SOCKS5 (as described in RFC1928) */ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials *auth, SOCKET& hSocket) { + IntrRecvError recvr; LogPrint("net", "SOCKS5 connecting %s\n", strDest); if (strDest.size() > 255) { CloseSocket(hSocket); @@ -294,7 +303,7 @@ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials return error("Error sending to proxy"); } char pchRet1[2]; - if (!InterruptibleRecv(pchRet1, 2, SOCKS5_RECV_TIMEOUT, hSocket)) { + if ((recvr = InterruptibleRecv(pchRet1, 2, SOCKS5_RECV_TIMEOUT, hSocket)) != IntrRecvError::OK) { CloseSocket(hSocket); LogPrintf("Socks5() connect to %s:%d failed: InterruptibleRecv() timeout or other failure\n", strDest, port); return false; @@ -320,7 +329,7 @@ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials } LogPrint("proxy", "SOCKS5 sending proxy authentication %s:%s\n", auth->username, auth->password); char pchRetA[2]; - if (!InterruptibleRecv(pchRetA, 2, SOCKS5_RECV_TIMEOUT, hSocket)) { + if ((recvr = InterruptibleRecv(pchRetA, 2, SOCKS5_RECV_TIMEOUT, hSocket)) != IntrRecvError::OK) { CloseSocket(hSocket); return error("Error reading proxy authentication response"); } @@ -349,9 +358,16 @@ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials return error("Error sending to proxy"); } char pchRet2[4]; - if (!InterruptibleRecv(pchRet2, 4, SOCKS5_RECV_TIMEOUT, hSocket)) { + if ((recvr = InterruptibleRecv(pchRet2, 4, SOCKS5_RECV_TIMEOUT, hSocket)) != IntrRecvError::OK) { CloseSocket(hSocket); - return error("Error reading proxy response"); + if (recvr == IntrRecvError::Timeout) { + /* If a timeout happens here, this effectively means we timed out while connecting + * to the remote node. This is very common for Tor, so do not print an + * error message. */ + return false; + } else { + return error("Error while reading proxy response"); + } } if (pchRet2[0] != 0x05) { CloseSocket(hSocket); @@ -370,26 +386,26 @@ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials char pchRet3[256]; switch (pchRet2[3]) { - case 0x01: ret = InterruptibleRecv(pchRet3, 4, SOCKS5_RECV_TIMEOUT, hSocket); break; - case 0x04: ret = InterruptibleRecv(pchRet3, 16, SOCKS5_RECV_TIMEOUT, hSocket); break; + case 0x01: recvr = InterruptibleRecv(pchRet3, 4, SOCKS5_RECV_TIMEOUT, hSocket); break; + case 0x04: recvr = InterruptibleRecv(pchRet3, 16, SOCKS5_RECV_TIMEOUT, hSocket); break; case 0x03: { - ret = InterruptibleRecv(pchRet3, 1, SOCKS5_RECV_TIMEOUT, hSocket); - if (!ret) { + recvr = InterruptibleRecv(pchRet3, 1, SOCKS5_RECV_TIMEOUT, hSocket); + if (recvr != IntrRecvError::OK) { CloseSocket(hSocket); return error("Error reading from proxy"); } int nRecv = pchRet3[0]; - ret = InterruptibleRecv(pchRet3, nRecv, SOCKS5_RECV_TIMEOUT, hSocket); + recvr = InterruptibleRecv(pchRet3, nRecv, SOCKS5_RECV_TIMEOUT, hSocket); break; } default: CloseSocket(hSocket); return error("Error: malformed proxy response"); } - if (!ret) { + if (recvr != IntrRecvError::OK) { CloseSocket(hSocket); return error("Error reading from proxy"); } - if (!InterruptibleRecv(pchRet3, 2, SOCKS5_RECV_TIMEOUT, hSocket)) { + if ((recvr = InterruptibleRecv(pchRet3, 2, SOCKS5_RECV_TIMEOUT, hSocket)) != IntrRecvError::OK) { CloseSocket(hSocket); return error("Error reading from proxy"); } diff --git a/src/netmessagemaker.h b/src/netmessagemaker.h index 7167434a19..8e8a6e4a02 100644 --- a/src/netmessagemaker.h +++ b/src/netmessagemaker.h @@ -15,7 +15,7 @@ public: CNetMsgMaker(int nVersionIn) : nVersion(nVersionIn){} template <typename... Args> - CSerializedNetMsg Make(int nFlags, std::string sCommand, Args&&... args) + CSerializedNetMsg Make(int nFlags, std::string sCommand, Args&&... args) const { CSerializedNetMsg msg; msg.command = std::move(sCommand); @@ -24,7 +24,7 @@ public: } template <typename... Args> - CSerializedNetMsg Make(std::string sCommand, Args&&... args) + CSerializedNetMsg Make(std::string sCommand, Args&&... args) const { return Make(0, std::move(sCommand), std::forward<Args>(args)...); } diff --git a/src/policy/fees.cpp b/src/policy/fees.cpp index 5407aefb45..8f6a1e60f4 100644 --- a/src/policy/fees.cpp +++ b/src/policy/fees.cpp @@ -482,10 +482,7 @@ void CBlockPolicyEstimator::Read(CAutoFile& filein, int nFileVersion) filein >> nFileBestSeenHeight; feeStats.Read(filein); nBestSeenHeight = nFileBestSeenHeight; - if (nFileVersion < 139900) { - TxConfirmStats priStats; - priStats.Read(filein); - } + // if nVersionThatWrote < 139900 then another TxConfirmStats (for priority) follows but can be ignored. } FeeFilterRounder::FeeFilterRounder(const CFeeRate& minIncrementalFee) diff --git a/src/prevector.h b/src/prevector.h index 6b2f578f5c..cba2e30057 100644 --- a/src/prevector.h +++ b/src/prevector.h @@ -5,6 +5,7 @@ #ifndef _BITCOIN_PREVECTOR_H_ #define _BITCOIN_PREVECTOR_H_ +#include <assert.h> #include <stdlib.h> #include <stdint.h> #include <string.h> @@ -170,10 +171,15 @@ private: } } else { if (!is_direct()) { + /* FIXME: Because malloc/realloc here won't call new_handler if allocation fails, assert + success. These should instead use an allocator or new/delete so that handlers + are called as necessary, but performance would be slightly degraded by doing so. */ _union.indirect = static_cast<char*>(realloc(_union.indirect, ((size_t)sizeof(T)) * new_capacity)); + assert(_union.indirect); _union.capacity = new_capacity; } else { char* new_indirect = static_cast<char*>(malloc(((size_t)sizeof(T)) * new_capacity)); + assert(new_indirect); T* src = direct_ptr(0); T* dst = reinterpret_cast<T*>(new_indirect); memcpy(dst, src, size() * sizeof(T)); diff --git a/src/qt/bantablemodel.cpp b/src/qt/bantablemodel.cpp index 00a915dd8d..4b34e73eb7 100644 --- a/src/qt/bantablemodel.cpp +++ b/src/qt/bantablemodel.cpp @@ -64,7 +64,7 @@ public: } if (sortColumn >= 0) - // sort cachedBanlist (use stable sort to prevent rows jumping around unneceesarily) + // sort cachedBanlist (use stable sort to prevent rows jumping around unnecessarily) qStableSort(cachedBanlist.begin(), cachedBanlist.end(), BannedNodeLessThan(sortColumn, sortOrder)); } diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 72f5f4aac9..662e8037ca 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -178,8 +178,8 @@ public Q_SLOTS: void shutdown(); Q_SIGNALS: - void initializeResult(int retval); - void shutdownResult(int retval); + void initializeResult(bool success); + void shutdownResult(); void runawayException(const QString &message); private: @@ -223,8 +223,8 @@ public: WId getMainWinId() const; public Q_SLOTS: - void initializeResult(int retval); - void shutdownResult(int retval); + void initializeResult(bool success); + void shutdownResult(); /// Handle runaway exceptions. Shows a message box with the problem and quits the program. void handleRunawayException(const QString &message); @@ -268,7 +268,7 @@ void BitcoinCore::initialize() { try { - qDebug() << __func__ << ": Running AppInit2 in thread"; + qDebug() << __func__ << ": Running initialization in thread"; if (!AppInitBasicSetup()) { Q_EMIT initializeResult(false); @@ -284,7 +284,7 @@ void BitcoinCore::initialize() Q_EMIT initializeResult(false); return; } - int rv = AppInitMain(threadGroup, scheduler); + bool rv = AppInitMain(threadGroup, scheduler); Q_EMIT initializeResult(rv); } catch (const std::exception& e) { handleRunawayException(&e); @@ -302,7 +302,7 @@ void BitcoinCore::shutdown() threadGroup.join_all(); Shutdown(); qDebug() << __func__ << ": Shutdown finished"; - Q_EMIT shutdownResult(1); + Q_EMIT shutdownResult(); } catch (const std::exception& e) { handleRunawayException(&e); } catch (...) { @@ -398,8 +398,8 @@ void BitcoinApplication::startThread() executor->moveToThread(coreThread); /* communication to and from thread */ - connect(executor, SIGNAL(initializeResult(int)), this, SLOT(initializeResult(int))); - connect(executor, SIGNAL(shutdownResult(int)), this, SLOT(shutdownResult(int))); + connect(executor, SIGNAL(initializeResult(bool)), this, SLOT(initializeResult(bool))); + connect(executor, SIGNAL(shutdownResult()), this, SLOT(shutdownResult())); connect(executor, SIGNAL(runawayException(QString)), this, SLOT(handleRunawayException(QString))); connect(this, SIGNAL(requestedInitialize()), executor, SLOT(initialize())); connect(this, SIGNAL(requestedShutdown()), executor, SLOT(shutdown())); @@ -450,14 +450,14 @@ void BitcoinApplication::requestShutdown() Q_EMIT requestedShutdown(); } -void BitcoinApplication::initializeResult(int retval) +void BitcoinApplication::initializeResult(bool success) { - qDebug() << __func__ << ": Initialization result: " << retval; - // Set exit result: 0 if successful, 1 if failure - returnValue = retval ? 0 : 1; - if(retval) + qDebug() << __func__ << ": Initialization result: " << success; + // Set exit result. + returnValue = success ? EXIT_SUCCESS : EXIT_FAILURE; + if(success) { - // Log this only after AppInit2 finishes, as then logging setup is guaranteed complete + // Log this only after AppInitMain finishes, as then logging setup is guaranteed complete qWarning() << "Platform customization:" << platformStyle->getName(); #ifdef ENABLE_WALLET PaymentServer::LoadRootCAs(); @@ -507,9 +507,8 @@ void BitcoinApplication::initializeResult(int retval) } } -void BitcoinApplication::shutdownResult(int retval) +void BitcoinApplication::shutdownResult() { - qDebug() << __func__ << ": Shutdown result: " << retval; quit(); // Exit main loop after shutdown finished } diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index b86437cede..be79a67990 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -31,6 +31,7 @@ #include "macdockiconhandler.h" #endif +#include "chainparams.h" #include "init.h" #include "ui_interface.h" #include "util.h" @@ -517,7 +518,10 @@ void BitcoinGUI::setClientModel(ClientModel *_clientModel) // Propagate cleared model to child objects rpcConsole->setClientModel(nullptr); #ifdef ENABLE_WALLET - walletFrame->setClientModel(nullptr); + if (walletFrame) + { + walletFrame->setClientModel(nullptr); + } #endif // ENABLE_WALLET unitDisplayControl->setOptionsModel(nullptr); } @@ -752,8 +756,8 @@ void BitcoinGUI::updateHeadersSyncProgressLabel() { int64_t headersTipTime = clientModel->getHeaderTipTime(); int headersTipHeight = clientModel->getHeaderTipHeight(); - int estHeadersLeft = (GetTime() - headersTipTime)/600; - if (estHeadersLeft > REQ_HEADER_HEIGHT_DELTA_SYNC) + int estHeadersLeft = (GetTime() - headersTipTime) / Params().GetConsensus().nPowTargetSpacing; + if (estHeadersLeft > HEADER_HEIGHT_DELTA_SYNC) progressBarLabel->setText(tr("Syncing Headers (%1%)...").arg(QString::number(100.0 / (headersTipHeight+estHeadersLeft)*headersTipHeight, 'f', 1))); } @@ -769,7 +773,7 @@ void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate, double nVer if (!clientModel) return; - // Prevent orphan statusbar messages (e.g. hover Quit in main menu, wait until chain-sync starts -> garbelled text) + // Prevent orphan statusbar messages (e.g. hover Quit in main menu, wait until chain-sync starts -> garbled text) statusBar()->clearMessage(); // Acquire current block source diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index f8aba70d92..d4fd8bd372 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -563,9 +563,7 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog) } // after fee - nAfterFee = nAmount - nPayFee; - if (nAfterFee < 0) - nAfterFee = 0; + nAfterFee = std::max<CAmount>(nAmount - nPayFee, 0); } // actually update labels diff --git a/src/qt/forms/intro.ui b/src/qt/forms/intro.ui index e4ff3da1ab..cfdd8482e3 100644 --- a/src/qt/forms/intro.ui +++ b/src/qt/forms/intro.ui @@ -7,7 +7,7 @@ <x>0</x> <y>0</y> <width>674</width> - <height>363</height> + <height>415</height> </rect> </property> <property name="windowTitle"> @@ -55,9 +55,6 @@ </item> <item> <widget class="QLabel" name="sizeWarningLabel"> - <property name="text"> - <string>%1 will download and store a copy of the Bitcoin block chain. At least %2GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory.</string> - </property> <property name="wordWrap"> <bool>true</bool> </property> @@ -204,6 +201,36 @@ </layout> </item> <item> + <widget class="QLabel" name="lblExplanation1"> + <property name="text"> + <string>When you click OK, %1 will begin to download and process the full %4 block chain (%2GB) starting with the earliest transactions in %3 when %4 initially launched.</string> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="lblExplanation2"> + <property name="text"> + <string>This initial synchronisation is very demanding, and may expose hardware problems with your computer that had previously gone unnoticed. Each time you run %1, it will continue downloading where it left off.</string> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="lblExplanation3"> + <property name="text"> + <string>If you have chosen to limit block chain storage (pruning), the historical data must still be downloaded and processed, but will be deleted afterward to keep your disk usage low.</string> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + </widget> + </item> + <item> <spacer name="verticalSpacer"> <property name="orientation"> <enum>Qt::Vertical</enum> diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index ea80a1f549..fd3dcac424 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -37,9 +37,7 @@ #include <boost/filesystem.hpp> #include <boost/filesystem/fstream.hpp> -#if BOOST_FILESYSTEM_VERSION >= 3 #include <boost/filesystem/detail/utf8_codecvt_facet.hpp> -#endif #include <boost/scoped_array.hpp> #include <QAbstractItemView> @@ -67,9 +65,7 @@ #include <QFontDatabase> #endif -#if BOOST_FILESYSTEM_VERSION >= 3 static boost::filesystem::detail::utf8_codecvt_facet utf8; -#endif #if defined(Q_OS_MAC) extern double NSAppKitVersionNumber; @@ -536,7 +532,7 @@ int TableViewLastColumnResizingFixer::getAvailableWidthForColumn(int column) return nResult; } -// Make sure we don't make the columns wider than the tables viewport width. +// Make sure we don't make the columns wider than the table's viewport width. void TableViewLastColumnResizingFixer::adjustTableColumnsWidth() { disconnectViewHeadersSignals(); @@ -570,7 +566,7 @@ void TableViewLastColumnResizingFixer::on_sectionResized(int logicalIndex, int o } } -// When the tabless geometry is ready, we manually perform the stretch of the "Message" column, +// When the table's geometry is ready, we manually perform the stretch of the "Message" column, // as the "Stretch" resize mode does not allow for interactive resizing. void TableViewLastColumnResizingFixer::on_geometriesChanged() { @@ -762,6 +758,8 @@ bool SetStartOnSystemStartup(bool fAutoStart) #elif defined(Q_OS_MAC) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" // based on: https://github.com/Mozketo/LaunchAtLoginController/blob/master/LaunchAtLoginController.m #include <CoreFoundation/CoreFoundation.h> @@ -824,6 +822,7 @@ bool SetStartOnSystemStartup(bool fAutoStart) } return true; } +#pragma GCC diagnostic pop #else bool GetStartOnSystemStartup() { return false; } @@ -860,7 +859,6 @@ void setClipboard(const QString& str) QApplication::clipboard()->setText(str, QClipboard::Selection); } -#if BOOST_FILESYSTEM_VERSION >= 3 boost::filesystem::path qstringToBoostPath(const QString &path) { return boost::filesystem::path(path.toStdString(), utf8); @@ -870,18 +868,6 @@ QString boostPathToQString(const boost::filesystem::path &path) { return QString::fromStdString(path.string(utf8)); } -#else -#warning Conversion between boost path and QString can use invalid character encoding with boost_filesystem v2 and older -boost::filesystem::path qstringToBoostPath(const QString &path) -{ - return boost::filesystem::path(path.toStdString()); -} - -QString boostPathToQString(const boost::filesystem::path &path) -{ - return QString::fromStdString(path.string()); -} -#endif QString formatDurationStr(int secs) { diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h index 5765b2ec4a..913aa5e24b 100644 --- a/src/qt/guiutil.h +++ b/src/qt/guiutil.h @@ -140,7 +140,7 @@ namespace GUIUtil * Also makes sure the column widths are never larger than the table's viewport. * In Qt, all columns are resizable from the right, but it's not intuitive resizing the last column from the right. * Usually our second to last columns behave as if stretched, and when on strech mode, columns aren't resizable - * interactively or programatically. + * interactively or programmatically. * * This helper object takes care of this issue. * diff --git a/src/qt/intro.cpp b/src/qt/intro.cpp index e0678f45fc..4939648ff0 100644 --- a/src/qt/intro.cpp +++ b/src/qt/intro.cpp @@ -23,7 +23,7 @@ static const uint64_t GB_BYTES = 1000000000LL; /* Minimum free space (in GB) needed for data directory */ -static const uint64_t BLOCK_CHAIN_SIZE = 80; +static const uint64_t BLOCK_CHAIN_SIZE = 120; /* 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) */ @@ -124,11 +124,34 @@ 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->lblExplanation1->setText(ui->lblExplanation1->text() + .arg(tr(PACKAGE_NAME)) + .arg(BLOCK_CHAIN_SIZE) + .arg(2009) + .arg(tr("Bitcoin")) + ); + ui->lblExplanation2->setText(ui->lblExplanation2->text().arg(tr(PACKAGE_NAME))); + uint64_t pruneTarget = std::max<int64_t>(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)); + QString storageRequiresMsg = tr("At least %1 GB of data will be stored in this directory, and it will grow over time."); + if (pruneTarget) { + uint64_t prunedGBs = std::ceil(pruneTarget * 1024 * 1024.0 / GB_BYTES); + if (prunedGBs <= requiredSpace) { + requiredSpace = prunedGBs; + storageRequiresMsg = tr("Approximately %1 GB of data will be stored in this directory."); + } + ui->lblExplanation3->setVisible(true); + } else { + ui->lblExplanation3->setVisible(false); + } + requiredSpace += CHAIN_STATE_SIZE; + ui->sizeWarningLabel->setText( + tr("%1 will download and store a copy of the Bitcoin block chain.").arg(tr(PACKAGE_NAME)) + " " + + storageRequiresMsg.arg(requiredSpace) + " " + + tr("The wallet will also be stored in this directory.") + ); startThread(); } diff --git a/src/qt/locale/bitcoin_af.ts b/src/qt/locale/bitcoin_af.ts index 8cbf5aadc5..9726987b63 100644 --- a/src/qt/locale/bitcoin_af.ts +++ b/src/qt/locale/bitcoin_af.ts @@ -382,10 +382,6 @@ <translation>Blokke op skyf word geprosesseer...</translation> </message> <message> - <source>No block source available...</source> - <translation>Geen blokbron beskikbaar...</translation> - </message> - <message> <source>%1 behind</source> <translation>%1 agter</translation> </message> diff --git a/src/qt/locale/bitcoin_ar.ts b/src/qt/locale/bitcoin_ar.ts index 15c5158f21..9b865f29bf 100644 --- a/src/qt/locale/bitcoin_ar.ts +++ b/src/qt/locale/bitcoin_ar.ts @@ -422,10 +422,6 @@ <translation>معالجة الكتل على القرص...</translation> </message> <message> - <source>No block source available...</source> - <translation>لا يوجد أي مصدر الكتلة</translation> - </message> - <message> <source>%1 behind</source> <translation>خلف %1</translation> </message> diff --git a/src/qt/locale/bitcoin_be_BY.ts b/src/qt/locale/bitcoin_be_BY.ts index d2c52f2c16..62f2ffc9e6 100644 --- a/src/qt/locale/bitcoin_be_BY.ts +++ b/src/qt/locale/bitcoin_be_BY.ts @@ -390,10 +390,6 @@ <translation>Опцыі каманднага радка</translation> </message> <message> - <source>No block source available...</source> - <translation>Крыніца блокаў недасяжная...</translation> - </message> - <message> <source>%1 behind</source> <translation>%1 таму</translation> </message> diff --git a/src/qt/locale/bitcoin_bg.ts b/src/qt/locale/bitcoin_bg.ts index 5a0fd2aec2..c571698304 100644 --- a/src/qt/locale/bitcoin_bg.ts +++ b/src/qt/locale/bitcoin_bg.ts @@ -422,10 +422,6 @@ <translation>Обработване на блокове на диска...</translation> </message> <message> - <source>No block source available...</source> - <translation>Липсва източник на блоковете...</translation> - </message> - <message> <source>%1 behind</source> <translation>%1 зад</translation> </message> diff --git a/src/qt/locale/bitcoin_ca.ts b/src/qt/locale/bitcoin_ca.ts index fd5a197c3e..84f51d18a8 100644 --- a/src/qt/locale/bitcoin_ca.ts +++ b/src/qt/locale/bitcoin_ca.ts @@ -441,10 +441,6 @@ <source>Processing blocks on disk...</source> <translation>S'estan processant els blocs al disc...</translation> </message> - <message> - <source>No block source available...</source> - <translation>No hi ha cap font de bloc disponible...</translation> - </message> <message numerus="yes"> <source>Processed %n block(s) of transaction history.</source> <translation><numerusform>S'ha processat %n bloc de l'historial de transacció.</numerusform><numerusform>S'han processat %n blocs de l'historial de transacció.</numerusform></translation> diff --git a/src/qt/locale/bitcoin_ca@valencia.ts b/src/qt/locale/bitcoin_ca@valencia.ts index c4748c0afa..0123f8faab 100644 --- a/src/qt/locale/bitcoin_ca@valencia.ts +++ b/src/qt/locale/bitcoin_ca@valencia.ts @@ -394,10 +394,6 @@ <translation>Opcions de la &línia d'ordes</translation> </message> <message> - <source>No block source available...</source> - <translation>No hi ha cap font de bloc disponible...</translation> - </message> - <message> <source>%1 behind</source> <translation>%1 darrere</translation> </message> diff --git a/src/qt/locale/bitcoin_ca_ES.ts b/src/qt/locale/bitcoin_ca_ES.ts index f88508a10f..8cbb57bd35 100644 --- a/src/qt/locale/bitcoin_ca_ES.ts +++ b/src/qt/locale/bitcoin_ca_ES.ts @@ -441,10 +441,6 @@ <source>Processing blocks on disk...</source> <translation>S'estan processant els blocs al disc...</translation> </message> - <message> - <source>No block source available...</source> - <translation>No hi ha cap font de bloc disponible...</translation> - </message> <message numerus="yes"> <source>Processed %n block(s) of transaction history.</source> <translation><numerusform>S'ha processat %n bloc de l'historial de transacció.</numerusform><numerusform>S'han processat %n blocs de l'historial de transacció.</numerusform></translation> diff --git a/src/qt/locale/bitcoin_cs.ts b/src/qt/locale/bitcoin_cs.ts index 2e911af14c..f38c425137 100644 --- a/src/qt/locale/bitcoin_cs.ts +++ b/src/qt/locale/bitcoin_cs.ts @@ -330,6 +330,10 @@ <translation>Kliknutím opět umožníš spojení do sítě.</translation> </message> <message> + <source>Syncing Headers (%1%)...</source> + <translation>Synchronizuji záhlaví bloků (%1 %)…</translation> + </message> + <message> <source>Reindexing blocks on disk...</source> <translation>Vytvářím nový index bloků na disku...</translation> </message> @@ -441,10 +445,6 @@ <source>Processing blocks on disk...</source> <translation>Zpracovávám bloky na disku...</translation> </message> - <message> - <source>No block source available...</source> - <translation>Není dostupný žádný zdroj bloků...</translation> - </message> <message numerus="yes"> <source>Processed %n block(s) of transaction history.</source> <translation><numerusform>Zpracován %n blok transakční historie.</numerusform><numerusform>Zpracovány %n bloky transakční historie.</numerusform><numerusform>Zpracováno %n bloků transakční historie.</numerusform></translation> @@ -486,6 +486,10 @@ <translation>%1 klient</translation> </message> <message> + <source>Connecting to peers...</source> + <translation>Připojuji se…</translation> + </message> + <message> <source>Catching up...</source> <translation>Stahuji...</translation> </message> @@ -2205,6 +2209,14 @@ <translation>Upozornění: Neznámá adresa pro drobné</translation> </message> <message> + <source>Confirm custom change address</source> + <translation>Potvrď vlastní adresu pro drobné</translation> + </message> + <message> + <source>The address you selected for change is not part of this wallet. Any or all funds in your wallet may be sent to this address. Are you sure?</source> + <translation>Adresa, kterou jsi zvolil pro drobné, není součástí této peněženky. Potenciálně všechny prostředky z tvé peněženky mohou být na tuto adresu odeslány. Souhlasíš, aby se tak stalo?</translation> + </message> + <message> <source>(no label)</source> <translation>(bez označení)</translation> </message> @@ -3086,6 +3098,14 @@ <translation>Spustit příkaz, když se objeví transakce týkající se peněženky (%s se v příkazu nahradí za TxID)</translation> </message> <message> + <source>Extra transactions to keep in memory for compact block reconstructions (default: %u)</source> + <translation>Počet extra transakcí, které se mají držet v paměti pro účely rekonstrukce kompaktních bloků (výchozí: %u)</translation> + </message> + <message> + <source>If this block is in the chain assume that it and its ancestors are valid and potentially skip their script verification (0 to verify all, default: %s, testnet: %s)</source> + <translation>Pokud je tenhle blok v řetězci, tak předpokládat, že on i jeho následníci jsou platní, a potenciálně přeskočit ověřování jejich skriptů (0 = ověřovat vše, výchozí: %s, testnet: %s)</translation> + </message> + <message> <source>Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds)</source> <translation>Maximální povolené seřizování času mediánem časů protějšků. Místní vnímání času může být ovlivněno protějšky, a to dopředu nebo dozadu až o toto množství. (výchozí: %u vteřin)</translation> </message> @@ -3102,6 +3122,14 @@ <translation>Prosíme, zapoj se nebo přispěj, pokud ti %s přijde užitečný. Více informací o programu je na %s.</translation> </message> <message> + <source>Reduce storage requirements by enabling pruning (deleting) of old blocks. This allows the pruneblockchain RPC to be called to delete specific blocks, and enables automatic pruning of old blocks if a target size in MiB is provided. This mode is incompatible with -txindex and -rescan. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, 1 = allow manual pruning via RPC, >%u = automatically prune block files to stay under the specified target size in MiB)</source> + <translation>Omezit nároky na úložný prostor prořezáváním (mazáním) starých bloků. Tato volba také umožní použít RPC volání pruneblockchain ke smazání konkrétních bloků a dále automatické prořezávání starých bloků, pokud je zadána cílová velikost souborů s bloky v MiB. Tento režim není slučitelný s -txindex ani -rescan. Upozornění: opětovná změna tohoto nastavení bude vyžadovat nové stažení celého řetězce bloků. (výchozí: 0 = bloky neprořezávat, 1 = povolit ruční prořezávání skrze RPC, >%u = automatické prořezávání bloků tak, aby byla udržena cílová velikost souborů s bloky, v MiB)</translation> + </message> + <message> + <source>Set lowest fee rate (in %s/kB) for transactions to be included in block creation. (default: %s)</source> + <translation>Nastavit nejnižší akceptovatelný poplatek (v %s/kB) pro transakce, které mají být zahrnuty do nových bloků. (výchozí: %s)</translation> + </message> + <message> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> <translation>Nastavení počtu vláken pro verifikaci skriptů (%u až %d, 0 = automaticky, <0 = nechat daný počet jader volný, výchozí: %d)</translation> </message> @@ -3122,6 +3150,10 @@ <translation>Použít UPnP k namapování naslouchacího portu (výchozí: 1, pokud naslouchá a nepoužívá -proxy)</translation> </message> <message> + <source>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. The client then connects normally using the rpcuser=<USERNAME>/rpcpassword=<PASSWORD> pair of arguments. This option can be specified multiple times</source> + <translation>Uživatelské jméno a zahašované heslo pro JSON-RPC spojení. Pole <userpw> má formát: <UŽIVATELSKÉ_JMÉNO>:<SŮL>$<HAŠ>. Pomocný pythonní skript je přiložen v share/rpcuser. Klient se pak už připojuje normálně pomocí páru argumentů rpcuser=<UŽIVATELSKÉ_JMÉNO>/rpcpassword=<HESLO>. Tuto volbu lze použít i vícekrát</translation> + </message> + <message> <source>Wallet will not create transactions that violate mempool chain limits (default: %u)</source> <translation>Peněženka nebude vytvářet transakce, které by porušovaly limity transakčního zásobníku na řetězce (výchozí: %u)</translation> </message> diff --git a/src/qt/locale/bitcoin_da.ts b/src/qt/locale/bitcoin_da.ts index 75eb5ae94d..54ef4a2bdf 100644 --- a/src/qt/locale/bitcoin_da.ts +++ b/src/qt/locale/bitcoin_da.ts @@ -330,6 +330,10 @@ <translation>Klik for a aktivere netværksaktivitet igen.</translation> </message> <message> + <source>Syncing Headers (%1%)...</source> + <translation>Synkroniserer hoveder (%1%)…</translation> + </message> + <message> <source>Reindexing blocks on disk...</source> <translation>Genindekserer blokke på disken…</translation> </message> @@ -441,10 +445,6 @@ <source>Processing blocks on disk...</source> <translation>Bearbejder blokke på disken…</translation> </message> - <message> - <source>No block source available...</source> - <translation>Ingen blokkilde tilgængelig…</translation> - </message> <message numerus="yes"> <source>Processed %n block(s) of transaction history.</source> <translation><numerusform>Bearbejdede %n blok med transaktionshistorik.</numerusform><numerusform>Bearbejdede %n blokke med transaktionshistorik.</numerusform></translation> @@ -486,6 +486,10 @@ <translation>%1-klient</translation> </message> <message> + <source>Connecting to peers...</source> + <translation>Forbinder til knuder…</translation> + </message> + <message> <source>Catching up...</source> <translation>Indhenter…</translation> </message> @@ -3094,6 +3098,14 @@ <translation>Udfør kommando, når en transaktion i tegnebogen ændres (%s i kommandoen erstattes med TxID)</translation> </message> <message> + <source>Extra transactions to keep in memory for compact block reconstructions (default: %u)</source> + <translation>Ekstra transaktioner, der skal beholdes i hukommelsen til kompakte blokgenopbygninger (standard: %u)</translation> + </message> + <message> + <source>If this block is in the chain assume that it and its ancestors are valid and potentially skip their script verification (0 to verify all, default: %s, testnet: %s)</source> + <translation>Hvis denne blok er i kæden, så antag at den og dens forgængere er gyldige, og spring potentielt deres scriptverificering over (0 for at verificere alle, standard: %s, testnet: %s)</translation> + </message> + <message> <source>Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds)</source> <translation>Justering af maksimalt tilladt gennemsnitlig afvigelse fra peer-tid. Den lokale opfattelse af tid kan blive påvirket frem eller tilbage af peers med denne mængde tid. (standard: %u sekunder)</translation> </message> @@ -3110,6 +3122,14 @@ <translation>Overvej venligst at bidrage til udviklingen, hvis du finder %s brugbar. Besøg %s for yderligere information om softwaren.</translation> </message> <message> + <source>Reduce storage requirements by enabling pruning (deleting) of old blocks. This allows the pruneblockchain RPC to be called to delete specific blocks, and enables automatic pruning of old blocks if a target size in MiB is provided. This mode is incompatible with -txindex and -rescan. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, 1 = allow manual pruning via RPC, >%u = automatically prune block files to stay under the specified target size in MiB)</source> + <translation>Reducér pladskravene ved at beskære (slette, "prune") gamle blokke. Dette tillader pruneblockchain-RPC'en at blive kaldt for at slette specifikke blokke, og det aktiverer automatisk beskæring af gamle blokke, hvis en målstørrelse i MiB er angivet. Denne tilstand er ikke kompatibel med -txindex og -rescan. Advarsel: Fortrydelse af denne indstilling kræver download af hele blokkæden igen. (standard: 0 = slå beskæring af blokke fra, 1 = tillad manuel beskæring via RPC, >%u = beskær automatisk blokfiler for at bliver under den angivne målstørrelse i MiB)</translation> + </message> + <message> + <source>Set lowest fee rate (in %s/kB) for transactions to be included in block creation. (default: %s)</source> + <translation>Sæt den laveste gebyrrate (i %s/kB) for transaktioner, der skal inkluderes i blokoprettelse. (standard: %s)</translation> + </message> + <message> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> <translation>Sæt antallet af scriptverificeringstråde (%u til %d, 0 = auto, <0 = efterlad det antal kernet fri, standard: %d)</translation> </message> diff --git a/src/qt/locale/bitcoin_de.ts b/src/qt/locale/bitcoin_de.ts index 59a45e3175..af79d47736 100644 --- a/src/qt/locale/bitcoin_de.ts +++ b/src/qt/locale/bitcoin_de.ts @@ -330,6 +330,10 @@ <translation>Klicken zum Aktivieren der Netzwerkaktivität.</translation> </message> <message> + <source>Syncing Headers (%1%)...</source> + <translation>Kopfdaten werden synchronisiert (%1%)...</translation> + </message> + <message> <source>Reindexing blocks on disk...</source> <translation>Reindiziere Blöcke auf Datenträger...</translation> </message> @@ -441,10 +445,6 @@ <source>Processing blocks on disk...</source> <translation>Verarbeite Blöcke auf Datenträger...</translation> </message> - <message> - <source>No block source available...</source> - <translation>Keine Blockquelle verfügbar...</translation> - </message> <message numerus="yes"> <source>Processed %n block(s) of transaction history.</source> <translation><numerusform>%n Block des Transaktionsverlaufs verarbeitet.</numerusform><numerusform>%n Blöcke des Transaktionsverlaufs verarbeitet.</numerusform></translation> @@ -486,6 +486,10 @@ <translation>%1 Client</translation> </message> <message> + <source>Connecting to peers...</source> + <translation>Verbinde mit Netzwerk...</translation> + </message> + <message> <source>Catching up...</source> <translation>Hole auf...</translation> </message> @@ -2193,6 +2197,10 @@ <translation>Warnung: Unbekannte Wechselgeld-Adresse</translation> </message> <message> + <source>Confirm custom change address</source> + <translation>Bestätige benutzerdefinierte Wechselgeld-Adresse</translation> + </message> + <message> <source>(no label)</source> <translation>(keine Bezeichnung)</translation> </message> @@ -3102,6 +3110,10 @@ <translation>UPnP verwenden, um eine Portweiterleitung einzurichten (Standard: 1, wenn abgehört wird und -proxy nicht gesetzt ist)</translation> </message> <message> + <source>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. The client then connects normally using the rpcuser=<USERNAME>/rpcpassword=<PASSWORD> pair of arguments. This option can be specified multiple times</source> + <translation>Benutzername und gehashtes Passwort für JSON-RPC Verbindungen. Das Feld <userpw> kommt im Format: <USERNAME>:<SALT>$<HASH>. Ein kanonisches Pythonskript ist in share/rpcuser inbegriffen. Der client benutzt wie gehabt, die rpcuser/rpcpassword Parameter. Diese Option kann mehrere Male spezifiziert werden</translation> + </message> + <message> <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source> <translation>Warnung: Das Netzwerk scheint nicht vollständig übereinzustimmen! Einige Miner scheinen Probleme zu haben.</translation> </message> diff --git a/src/qt/locale/bitcoin_el_GR.ts b/src/qt/locale/bitcoin_el_GR.ts index b1caab06b1..0390a378e7 100644 --- a/src/qt/locale/bitcoin_el_GR.ts +++ b/src/qt/locale/bitcoin_el_GR.ts @@ -246,10 +246,6 @@ <translation>&Επιλογές γραμμής εντολών</translation> </message> <message> - <source>No block source available...</source> - <translation>Η πηγή του μπλοκ δεν ειναι διαθέσιμη... </translation> - </message> - <message> <source>%1 behind</source> <translation>%1 πίσω</translation> </message> diff --git a/src/qt/locale/bitcoin_en.ts b/src/qt/locale/bitcoin_en.ts index dcfd86f366..f62f1e4a73 100644 --- a/src/qt/locale/bitcoin_en.ts +++ b/src/qt/locale/bitcoin_en.ts @@ -299,7 +299,7 @@ <context> <name>BitcoinGUI</name> <message> - <location filename="../bitcoingui.cpp" line="+356"/> + <location filename="../bitcoingui.cpp" line="+357"/> <source>Sign &message...</source> <translation>Sign &message...</translation> </message> @@ -1083,7 +1083,7 @@ <translation>Use a custom data directory:</translation> </message> <message> - <location filename="../intro.cpp" line="+89"/> + <location filename="../intro.cpp" line="+94"/> <source>Error: Specified data directory "%1" cannot be created.</source> <translation type="unfinished"></translation> </message> @@ -1134,7 +1134,7 @@ <message> <location line="+7"/> <location line="+26"/> - <location filename="../modaloverlay.cpp" line="+136"/> + <location filename="../modaloverlay.cpp" line="+138"/> <source>Unknown...</source> <translation type="unfinished"></translation> </message> @@ -2533,7 +2533,7 @@ <name>SendCoinsDialog</name> <message> <location filename="../forms/sendcoinsdialog.ui" line="+14"/> - <location filename="../sendcoinsdialog.cpp" line="+553"/> + <location filename="../sendcoinsdialog.cpp" line="+554"/> <source>Send Coins</source> <translation>Send Coins</translation> </message> diff --git a/src/qt/locale/bitcoin_en_GB.ts b/src/qt/locale/bitcoin_en_GB.ts index df3aad5087..8af5db3e64 100644 --- a/src/qt/locale/bitcoin_en_GB.ts +++ b/src/qt/locale/bitcoin_en_GB.ts @@ -333,10 +333,6 @@ <source>Processing blocks on disk...</source> <translation>Processing blocks on disk...</translation> </message> - <message> - <source>No block source available...</source> - <translation>No block source available...</translation> - </message> <message numerus="yes"> <source>Processed %n block(s) of transaction history.</source> <translation><numerusform>Processed %n block of transaction history.</numerusform><numerusform>Processed %n blocks of transaction history.</numerusform></translation> diff --git a/src/qt/locale/bitcoin_eo.ts b/src/qt/locale/bitcoin_eo.ts index 2337c2bd29..b4ed5e7fd5 100644 --- a/src/qt/locale/bitcoin_eo.ts +++ b/src/qt/locale/bitcoin_eo.ts @@ -242,10 +242,6 @@ <translation>&Komandliniaj agordaĵoj</translation> </message> <message> - <source>No block source available...</source> - <translation>Neniu fonto de blokoj trovebla...</translation> - </message> - <message> <source>%1 behind</source> <translation>mankas %1</translation> </message> diff --git a/src/qt/locale/bitcoin_es.ts b/src/qt/locale/bitcoin_es.ts index b1e35148d7..fc71bf841b 100644 --- a/src/qt/locale/bitcoin_es.ts +++ b/src/qt/locale/bitcoin_es.ts @@ -330,6 +330,10 @@ <translation>Pulsar para volver a habilitar la actividad de red.</translation> </message> <message> + <source>Syncing Headers (%1%)...</source> + <translation>Sincronizando cabeceras (%1%)</translation> + </message> + <message> <source>Reindexing blocks on disk...</source> <translation>Reindexando bloques en disco...</translation> </message> @@ -441,10 +445,6 @@ <source>Processing blocks on disk...</source> <translation>Procesando bloques en disco...</translation> </message> - <message> - <source>No block source available...</source> - <translation>Ninguna fuente de bloques disponible...</translation> - </message> <message numerus="yes"> <source>Processed %n block(s) of transaction history.</source> <translation><numerusform>%n bloque procesado del historial de transacciones.</numerusform><numerusform>%n bloques procesados del historial de transacciones.</numerusform></translation> @@ -3619,6 +3619,11 @@ <translation>Mostrar depuración (por defecto: %u, proporcionar <category> es opcional)</translation> </message> <message> + <source>Sets the serialization of raw transaction or block hex returned in non-verbose mode, non-segwit(0) or segwit(1) (default: %d)</source> + <translation>https://www.transifex.com/joyful-world/breaking-english/ +Establecer la serialización de las transacciones sin procesar o el bloque hex devuelto en non-verbose mode, non-segwit(O) o segwit(1) (default: %d)</translation> + </message> + <message> <source>Support filtering of blocks and transaction with bloom filters (default: %u)</source> <translation>Admite filtrado de bloques, y transacciones con filtros Bloom. Reduce la carga de red. ( por defecto :%u)</translation> </message> diff --git a/src/qt/locale/bitcoin_es_DO.ts b/src/qt/locale/bitcoin_es_DO.ts index eb6583083b..77e6ef16f3 100644 --- a/src/qt/locale/bitcoin_es_DO.ts +++ b/src/qt/locale/bitcoin_es_DO.ts @@ -238,10 +238,6 @@ <translation>&Opciones de linea de comando</translation> </message> <message> - <source>No block source available...</source> - <translation>Ninguna fuente de bloques disponible ...</translation> - </message> - <message> <source>%1 behind</source> <translation>%1 atrás</translation> </message> diff --git a/src/qt/locale/bitcoin_es_ES.ts b/src/qt/locale/bitcoin_es_ES.ts index 996b209ea2..7865483183 100644 --- a/src/qt/locale/bitcoin_es_ES.ts +++ b/src/qt/locale/bitcoin_es_ES.ts @@ -429,10 +429,6 @@ <source>Processing blocks on disk...</source> <translation>Procesando bloques en disco...</translation> </message> - <message> - <source>No block source available...</source> - <translation>Ninguna fuente de bloques disponible ...</translation> - </message> <message numerus="yes"> <source>Processed %n block(s) of transaction history.</source> <translation><numerusform>%n bloque procesado del historial de transacciones.</numerusform><numerusform>%n bloques procesados del historial de transacciones.</numerusform></translation> diff --git a/src/qt/locale/bitcoin_et.ts b/src/qt/locale/bitcoin_et.ts index 0512b9f117..313d5e3be1 100644 --- a/src/qt/locale/bitcoin_et.ts +++ b/src/qt/locale/bitcoin_et.ts @@ -214,6 +214,10 @@ </context> <context> <name>BanTableModel</name> + <message> + <source>IP/Netmask</source> + <translation>IP/Võrgumask</translation> + </message> </context> <context> <name>BitcoinGUI</name> @@ -385,10 +389,6 @@ <source>Processing blocks on disk...</source> <translation>Kõvakettal olevate plokkide töötlemine...</translation> </message> - <message> - <source>No block source available...</source> - <translation>Plokkide allikas pole saadaval...</translation> - </message> <message numerus="yes"> <source>Processed %n block(s) of transaction history.</source> <translation><numerusform>Töödeldud %n plokk transaktsioonide ajaloost.</numerusform><numerusform>Töödeldud %n plokki transaktsioonide ajaloost.</numerusform></translation> @@ -792,6 +792,10 @@ <translation>&Aken</translation> </message> <message> + <source>Hide tray icon</source> + <translation>Peida tegumiriba ikoon</translation> + </message> + <message> <source>Show only a tray icon after minimizing the window.</source> <translation>Minimeeri systray alale.</translation> </message> @@ -908,9 +912,29 @@ <translation>N/A</translation> </message> <message> + <source>%1 ms</source> + <translation>%1 ms</translation> + </message> + <message numerus="yes"> + <source>%n hour(s)</source> + <translation><numerusform>%n tund</numerusform><numerusform>%n tundi</numerusform></translation> + </message> + <message numerus="yes"> + <source>%n day(s)</source> + <translation><numerusform>%n päev</numerusform><numerusform>%n päeva</numerusform></translation> + </message> + <message numerus="yes"> + <source>%n week(s)</source> + <translation><numerusform>%n nädal</numerusform><numerusform>%n nädalat</numerusform></translation> + </message> + <message> <source>%1 and %2</source> <translation>%1 ja %2</translation> </message> + <message numerus="yes"> + <source>%n year(s)</source> + <translation><numerusform>%n aasta</numerusform><numerusform>%n aastat</numerusform></translation> + </message> </context> <context> <name>QObject::QObject</name> diff --git a/src/qt/locale/bitcoin_fa.ts b/src/qt/locale/bitcoin_fa.ts index c1061822ca..c9cfad0f2a 100644 --- a/src/qt/locale/bitcoin_fa.ts +++ b/src/qt/locale/bitcoin_fa.ts @@ -357,10 +357,6 @@ <source>Processing blocks on disk...</source> <translation>پردازش بلوکها روی دیسک...</translation> </message> - <message> - <source>No block source available...</source> - <translation>منبعی برای دریافت بلاک در دسترس نیست...</translation> - </message> <message numerus="yes"> <source>Processed %n block(s) of transaction history.</source> <translation><numerusform>پردازش %n بلاک از تاریخچه ی تراکنش ها </numerusform></translation> diff --git a/src/qt/locale/bitcoin_fi.ts b/src/qt/locale/bitcoin_fi.ts index ba8880c4aa..ef76abc098 100644 --- a/src/qt/locale/bitcoin_fi.ts +++ b/src/qt/locale/bitcoin_fi.ts @@ -273,10 +273,6 @@ <source>Processing blocks on disk...</source> <translation>Käsitellään lohkoja levyllä...</translation> </message> - <message> - <source>No block source available...</source> - <translation>Lohkojen lähdettä ei saatavilla...</translation> - </message> <message numerus="yes"> <source>Processed %n block(s) of transaction history.</source> <translation><numerusform>Prosessoitu %n lohko rahansiirtohistoriasta.</numerusform><numerusform>Prosessoitu %n lohkoa rahansiirtohistoriasta.</numerusform></translation> diff --git a/src/qt/locale/bitcoin_fr.ts b/src/qt/locale/bitcoin_fr.ts index 23b4d2a66f..2180023159 100644 --- a/src/qt/locale/bitcoin_fr.ts +++ b/src/qt/locale/bitcoin_fr.ts @@ -330,6 +330,10 @@ <translation>Cliquer pour réactiver l'activité réseau.</translation> </message> <message> + <source>Syncing Headers (%1%)...</source> + <translation>Synchronisation des en-têtes (%1)...</translation> + </message> + <message> <source>Reindexing blocks on disk...</source> <translation>Réindexation des blocs sur le disque...</translation> </message> @@ -441,10 +445,6 @@ <source>Processing blocks on disk...</source> <translation>Traitement des blocs sur le disque...</translation> </message> - <message> - <source>No block source available...</source> - <translation>Aucune source de blocs disponible...</translation> - </message> <message numerus="yes"> <source>Processed %n block(s) of transaction history.</source> <translation><numerusform>%n bloc d'historique transactionnel a été traité</numerusform><numerusform>%n blocs d'historique transactionnel ont été traités</numerusform></translation> @@ -486,6 +486,10 @@ <translation>Client %1</translation> </message> <message> + <source>Connecting to peers...</source> + <translation>Connexion aux pairs...</translation> + </message> + <message> <source>Catching up...</source> <translation>Rattrapage…</translation> </message> @@ -3094,6 +3098,10 @@ <translation>Exécuter la commande lorsqu'une transaction de porte-monnaie change (%s dans la commande est remplacée par TxID)</translation> </message> <message> + <source>If this block is in the chain assume that it and its ancestors are valid and potentially skip their script verification (0 to verify all, default: %s, testnet: %s)</source> + <translation>Si ce bloc est dans la chaîne, supposer qu'il est valide, ainsi que ces ancêtres, et ignorer potentiellement la vérification de leur script (0 pour tout vérifier, valeur par défaut : %s, réseau de test : %s)</translation> + </message> + <message> <source>Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds)</source> <translation>Réglage moyen maximal autorisé de décalage de l'heure d'un pair. La perspective locale du temps peut être influencée par les pairs, en avance ou en retard, de cette valeur. (Par défaut : %u secondes)</translation> </message> diff --git a/src/qt/locale/bitcoin_fr_FR.ts b/src/qt/locale/bitcoin_fr_FR.ts index d53baed462..4d02aa5114 100644 --- a/src/qt/locale/bitcoin_fr_FR.ts +++ b/src/qt/locale/bitcoin_fr_FR.ts @@ -262,10 +262,6 @@ <translation>Indexation des blocs sur le disque...</translation> </message> <message> - <source>No block source available...</source> - <translation>Aucun bloc source disponible</translation> - </message> - <message> <source>%1 behind</source> <translation>en retard de %1</translation> </message> diff --git a/src/qt/locale/bitcoin_gl.ts b/src/qt/locale/bitcoin_gl.ts index 5d31c632ac..ff0804d79b 100644 --- a/src/qt/locale/bitcoin_gl.ts +++ b/src/qt/locale/bitcoin_gl.ts @@ -226,10 +226,6 @@ <translation>Opcións da liña de comandos</translation> </message> <message> - <source>No block source available...</source> - <translation>Non hai orixe de bloques dispoñible...</translation> - </message> - <message> <source>%1 behind</source> <translation>%1 detrás</translation> </message> diff --git a/src/qt/locale/bitcoin_he.ts b/src/qt/locale/bitcoin_he.ts index 9293b794ad..78ef446ff1 100644 --- a/src/qt/locale/bitcoin_he.ts +++ b/src/qt/locale/bitcoin_he.ts @@ -318,10 +318,6 @@ <translation>מעבד בלוקים על הדיסק...</translation> </message> <message> - <source>No block source available...</source> - <translation>אין מקור מקטעים זמין…</translation> - </message> - <message> <source>%1 behind</source> <translation>%1 מאחור</translation> </message> diff --git a/src/qt/locale/bitcoin_hu.ts b/src/qt/locale/bitcoin_hu.ts index 49b9dc7d1c..28270e8c2e 100644 --- a/src/qt/locale/bitcoin_hu.ts +++ b/src/qt/locale/bitcoin_hu.ts @@ -257,10 +257,6 @@ <source>%n active connection(s) to Bitcoin network</source> <translation><numerusform>%n aktív kapcsolat a Bitcoin hálózathoz</numerusform><numerusform>%n aktív kapcsolat a Bitcoin hálózathoz</numerusform></translation> </message> - <message> - <source>No block source available...</source> - <translation>Blokk forrása ismeretlen...</translation> - </message> <message numerus="yes"> <source>Processed %n block(s) of transaction history.</source> <translation><numerusform>%n blokk feldolgozva a tranzakció előzményből.</numerusform><numerusform>%n blokk feldolgozva a tranzakció előzményből.</numerusform></translation> diff --git a/src/qt/locale/bitcoin_id_ID.ts b/src/qt/locale/bitcoin_id_ID.ts index 5cc5d71c6d..fd77f07cd8 100644 --- a/src/qt/locale/bitcoin_id_ID.ts +++ b/src/qt/locale/bitcoin_id_ID.ts @@ -253,10 +253,6 @@ <source>%n active connection(s) to Bitcoin network</source> <translation><numerusform>%n koneksi aktif ke jaringan Bitcoin</numerusform></translation> </message> - <message> - <source>No block source available...</source> - <translation>Sumber blok tidak tersedia...</translation> - </message> <message numerus="yes"> <source>Processed %n block(s) of transaction history.</source> <translation><numerusform>%n blok dari riwayat transaksi diproses.</numerusform></translation> diff --git a/src/qt/locale/bitcoin_it.ts b/src/qt/locale/bitcoin_it.ts index 1e359e52e5..9f2c7626de 100644 --- a/src/qt/locale/bitcoin_it.ts +++ b/src/qt/locale/bitcoin_it.ts @@ -401,10 +401,6 @@ <source>Processing blocks on disk...</source> <translation>Processando i blocchi su disco...</translation> </message> - <message> - <source>No block source available...</source> - <translation>Nessuna fonte di blocchi disponibile...</translation> - </message> <message numerus="yes"> <source>Processed %n block(s) of transaction history.</source> <translation><numerusform>Elaborato %n blocco dello storico transazioni.</numerusform><numerusform>Elaborati %n blocchi dello storico transazioni.</numerusform></translation> @@ -707,10 +703,6 @@ <translation>Errore</translation> </message> <message numerus="yes"> - <source>%n GB of free space available</source> - <translation><numerusform>GB di spazio libero disponibile</numerusform><numerusform>%n GB di spazio disponibile</numerusform></translation> - </message> - <message numerus="yes"> <source>(of %n GB needed)</source> <translation><numerusform>(di %nGB richiesti)</numerusform><numerusform>(%n GB richiesti)</numerusform></translation> </message> diff --git a/src/qt/locale/bitcoin_ja.ts b/src/qt/locale/bitcoin_ja.ts index 0f3c9e596a..f81818896f 100644 --- a/src/qt/locale/bitcoin_ja.ts +++ b/src/qt/locale/bitcoin_ja.ts @@ -330,6 +330,10 @@ <translation>クリックするとネットワーク活動を再び有効化します。</translation> </message> <message> + <source>Syncing Headers (%1%)...</source> + <translation>未知。ヘッダを同期しています (%1%)...</translation> + </message> + <message> <source>Reindexing blocks on disk...</source> <translation>ディスク上のブロックのインデックスを再作成中...</translation> </message> @@ -441,10 +445,6 @@ <source>Processing blocks on disk...</source> <translation>ディスク上のブロックを処理しています...</translation> </message> - <message> - <source>No block source available...</source> - <translation>利用可能なブロックがありません...</translation> - </message> <message numerus="yes"> <source>Processed %n block(s) of transaction history.</source> <translation><numerusform>トランザクション履歴の %n ブロックを処理しました。</numerusform></translation> @@ -486,6 +486,10 @@ <translation>%1 クライアント</translation> </message> <message> + <source>Connecting to peers...</source> + <translation>ピアに接続しています...</translation> + </message> + <message> <source>Catching up...</source> <translation>追跡中...</translation> </message> @@ -3094,6 +3098,14 @@ <translation>ウォレットの取引を変更する際にコマンドを実行 (cmd の %s は TxID に置換される)</translation> </message> <message> + <source>Extra transactions to keep in memory for compact block reconstructions (default: %u)</source> + <translation>コンパクトブロック再構成のために追加のトランザクションをメモリ内に保管しておく (デフォルト: %u)</translation> + </message> + <message> + <source>If this block is in the chain assume that it and its ancestors are valid and potentially skip their script verification (0 to verify all, default: %s, testnet: %s)</source> + <translation>このブロックがブロックチェーン内に含まれていた場合には、このブロックおよびそれ以前のすべてのブロックを有効であるとみなし、スクリプトの検証を省略する (0ならすべてを検証、デフォルト: %s、テストネット: %s)</translation> + </message> + <message> <source>Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds)</source> <translation>時間オフセット調整値のピア中央値に対する最大の許容値。ローカル時間の見込み値は、接続するピアにより前方ないし後方へ影響されます。(初期値: %u 秒)</translation> </message> diff --git a/src/qt/locale/bitcoin_ka.ts b/src/qt/locale/bitcoin_ka.ts index 920f44758a..14378ebea1 100644 --- a/src/qt/locale/bitcoin_ka.ts +++ b/src/qt/locale/bitcoin_ka.ts @@ -238,10 +238,6 @@ <translation>საკომანდო სტრიქონის ოპ&ციები</translation> </message> <message> - <source>No block source available...</source> - <translation>ბლოკების წყარო მიუწვდომელია...</translation> - </message> - <message> <source>%1 behind</source> <translation>%1 გავლილია</translation> </message> diff --git a/src/qt/locale/bitcoin_ko_KR.ts b/src/qt/locale/bitcoin_ko_KR.ts index b5af4602c8..9b5c1c077e 100644 --- a/src/qt/locale/bitcoin_ko_KR.ts +++ b/src/qt/locale/bitcoin_ko_KR.ts @@ -429,10 +429,6 @@ <source>Processing blocks on disk...</source> <translation>디스크에서 블록 처리중...</translation> </message> - <message> - <source>No block source available...</source> - <translation>사용 가능한 블록이 없습니다...</translation> - </message> <message numerus="yes"> <source>Processed %n block(s) of transaction history.</source> <translation><numerusform>%n 블럭 만큼의 거래 기록이 처리됨.</numerusform></translation> diff --git a/src/qt/locale/bitcoin_la.ts b/src/qt/locale/bitcoin_la.ts index 3b67fa1e74..d84dd7e4e2 100644 --- a/src/qt/locale/bitcoin_la.ts +++ b/src/qt/locale/bitcoin_la.ts @@ -194,10 +194,6 @@ <translation>Optiones mandati initiantis</translation> </message> <message> - <source>No block source available...</source> - <translation>Nulla fons frustorum absens...</translation> - </message> - <message> <source>%1 behind</source> <translation>%1 post</translation> </message> diff --git a/src/qt/locale/bitcoin_lv_LV.ts b/src/qt/locale/bitcoin_lv_LV.ts index 750e0ff28d..2953da443a 100644 --- a/src/qt/locale/bitcoin_lv_LV.ts +++ b/src/qt/locale/bitcoin_lv_LV.ts @@ -230,10 +230,6 @@ <translation>&Komandrindas iespējas</translation> </message> <message> - <source>No block source available...</source> - <translation>Nav pieejams neviens bloku avots...</translation> - </message> - <message> <source>%1 behind</source> <translation>%1 aizmugurē</translation> </message> diff --git a/src/qt/locale/bitcoin_nb.ts b/src/qt/locale/bitcoin_nb.ts index 1f76fdb0b3..183cbac80a 100644 --- a/src/qt/locale/bitcoin_nb.ts +++ b/src/qt/locale/bitcoin_nb.ts @@ -265,10 +265,6 @@ <source>%n active connection(s) to Bitcoin network</source> <translation><numerusform>%n aktiv forbindelse til Bitcoin-nettverket</numerusform><numerusform>%n aktive forbindelser til Bitcoin-nettverket</numerusform></translation> </message> - <message> - <source>No block source available...</source> - <translation>Ingen kilde for blokker tilgjengelig...</translation> - </message> <message numerus="yes"> <source>Processed %n block(s) of transaction history.</source> <translation><numerusform>Lastet %n blokk med transaksjonshistorikk.</numerusform><numerusform>Lastet %n blokker med transaksjonshistorikk.</numerusform></translation> diff --git a/src/qt/locale/bitcoin_nl.ts b/src/qt/locale/bitcoin_nl.ts index 9094cd40a5..2b625b5a07 100644 --- a/src/qt/locale/bitcoin_nl.ts +++ b/src/qt/locale/bitcoin_nl.ts @@ -429,10 +429,6 @@ <source>Processing blocks on disk...</source> <translation>Bezig met verwerken van blokken op harde schijf...</translation> </message> - <message> - <source>No block source available...</source> - <translation>Geen bron voor blokken beschikbaar...</translation> - </message> <message numerus="yes"> <source>Processed %n block(s) of transaction history.</source> <translation><numerusform>%n blok aan transactiegeschiedenis verwerkt.</numerusform><numerusform>%n blokken aan transactiegeschiedenis verwerkt.</numerusform></translation> diff --git a/src/qt/locale/bitcoin_pl.ts b/src/qt/locale/bitcoin_pl.ts index ab6fb41870..4634814070 100644 --- a/src/qt/locale/bitcoin_pl.ts +++ b/src/qt/locale/bitcoin_pl.ts @@ -168,14 +168,34 @@ <translation>Potwierdź szyfrowanie portfela</translation> </message> <message> + <source>Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>!</source> + <translation>Uwaga: jeśli zaszyfrujesz swój portfel i zgubisz hasło <b>STRACISZ WSZYSTKIE SWOJE BITCOINY</b>!</translation> + </message> + <message> + <source>Are you sure you wish to encrypt your wallet?</source> + <translation>Jesteś pewien, że chcesz zaszyfrować swój portfel?</translation> + </message> + <message> <source>Wallet encrypted</source> <translation>Portfel zaszyfrowany</translation> </message> <message> + <source>%1 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.</source> + <translation>%1 zamknie się aby dokończyć proces szyfrowania. Pamiętaj, że szyfrowanie portfela nie zabezpiecza w pełni Twoich bitcoinów przed kradzieżą przez wirusy lub trojany mogące zainfekować Twój komputer.</translation> + </message> + <message> + <source>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.</source> + <translation>WAŻNE: Wszystkie wykonane wcześniej kopie pliku portfela powinny być zamienione na nowe, szyfrowane pliki. Z powodów bezpieczeństwa, poprzednie kopie nieszyfrowanych plików portfela staną się bezużyteczne jak tylko zaczniesz korzystać z nowego, szyfrowanego portfela.</translation> + </message> + <message> <source>Wallet encryption failed</source> <translation>Szyfrowanie portfela nie powiodło się</translation> </message> <message> + <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source> + <translation>Szyfrowanie portfela nie powiodło się z powodu wewnętrznego błędu. Twój portfel nie został zaszyfrowany.</translation> + </message> + <message> <source>The supplied passphrases do not match.</source> <translation>Podane hasła nie są takie same.</translation> </message> @@ -409,10 +429,6 @@ <source>Processing blocks on disk...</source> <translation>Przetwarzanie blocks on disk...</translation> </message> - <message> - <source>No block source available...</source> - <translation>Brak dostępnych źródeł bloków...</translation> - </message> <message numerus="yes"> <source>Processed %n block(s) of transaction history.</source> <translation><numerusform>Przetworzono %n bloków historii transakcji.</numerusform><numerusform>Przetworzono %n bloków historii transakcji.</numerusform><numerusform>Przetworzono %n bloków historii transakcji.</numerusform></translation> @@ -1981,10 +1997,34 @@ <translation>%1 do %2</translation> </message> <message> + <source>or</source> + <translation>lub</translation> + </message> + <message> + <source>The amount to pay must be larger than 0.</source> + <translation>Kwota do zapłacenia musi być większa od 0.</translation> + </message> + <message> + <source>Transaction creation failed!</source> + <translation>Utworzenie transakcji nie powiodło się!</translation> + </message> + <message> <source>Payment request expired.</source> <translation>Żądanie płatności upłynęło.</translation> </message> <message> + <source>Pay only the required fee of %1</source> + <translation>Zapłać tylko wymaganą opłatę w wysokości %1</translation> + </message> + <message> + <source>Warning: Invalid Bitcoin address</source> + <translation>Ostrzeżenie: nieprawidłowy adres Bitcoin</translation> + </message> + <message> + <source>Warning: Unknown change address</source> + <translation>Ostrzeżenie: Nieznany adres reszty</translation> + </message> + <message> <source>(no label)</source> <translation>(brak etykiety)</translation> </message> @@ -2070,7 +2110,11 @@ </context> <context> <name>SendConfirmationDialog</name> - </context> + <message> + <source>Yes</source> + <translation>Tak</translation> + </message> +</context> <context> <name>ShutdownWindow</name> <message> @@ -2169,6 +2213,22 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw <source>Reset all verify message fields</source> <translation>Resetuje wszystkie pola weryfikacji wiadomości</translation> </message> + <message> + <source>Wallet unlock was cancelled.</source> + <translation>Odblokowanie portfela zostało anulowane.</translation> + </message> + <message> + <source>Private key for the entered address is not available.</source> + <translation>Klucz prywatny dla podanego adresu nie jest dostępny.</translation> + </message> + <message> + <source>Message signing failed.</source> + <translation>Podpisanie wiadomości nie powiodło się.</translation> + </message> + <message> + <source>Message signed.</source> + <translation>Wiadomość podpisana.</translation> + </message> </context> <context> <name>SplashScreen</name> @@ -2731,6 +2791,10 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw <translation>Uruchom polecenie przy otrzymaniu odpowiedniego powiadomienia lub gdy zobaczymy naprawdę długie rozgałęzienie (%s w poleceniu jest podstawiane za komunikat)</translation> </message> <message> + <source>Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s)</source> + <translation>Opłaty (w %s/Kb) mniejsze niż ta, będą traktowane jako zerowe przy tworzeniu, przesyłaniu i zatwierdzaniu transakcji (domyślnie: %s)</translation> + </message> + <message> <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> <translation>Jeżeli nie ustawiono paytxfee, dołącz wystarczająca opłatę, aby transakcja mogła zostać zatwierdzona w ciągu średniej ilości n bloków (domyślnie: %u)</translation> </message> @@ -2751,6 +2815,10 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw <translation>Zbyt niska kwota transakcji do wysłania po odjęciu opłaty</translation> </message> <message> + <source>Use hierarchical deterministic key generation (HD) after BIP32. Only has effect during wallet creation/first start</source> + <translation>Użyj hierarchicznej deterministycznej metody generowania kluczy (HD) zgodnie z BIP32. Ma znaczenie tylko podczas tworzenia portfela/pierwszego startu.</translation> + </message> + <message> <source>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</source> <translation>Węzły z białej listy nie mogą zostać zbanowane za ataki DoS, a ich transakcje będą zawsze przekazywane, nawet jeżeli będą znajdywać się już w pamięci, przydatne np. dla bramek płatniczych</translation> </message> diff --git a/src/qt/locale/bitcoin_pt_BR.ts b/src/qt/locale/bitcoin_pt_BR.ts index e9ef5258f6..3202587cbd 100644 --- a/src/qt/locale/bitcoin_pt_BR.ts +++ b/src/qt/locale/bitcoin_pt_BR.ts @@ -23,7 +23,7 @@ </message> <message> <source>C&lose</source> - <translation>Fechar</translation> + <translation>&Fechar</translation> </message> <message> <source>Delete the currently selected address from the list</source> @@ -39,7 +39,7 @@ </message> <message> <source>&Delete</source> - <translation>&Excluir</translation> + <translation>E&xcluir</translation> </message> <message> <source>Choose the address to send coins to</source> @@ -102,7 +102,7 @@ <name>AddressTableModel</name> <message> <source>Label</source> - <translation>Rótuo</translation> + <translation>Rótulo</translation> </message> <message> <source>Address</source> @@ -110,7 +110,7 @@ </message> <message> <source>(no label)</source> - <translation>(sem rótuo)</translation> + <translation>(sem rótulo)</translation> </message> </context> <context> @@ -231,7 +231,7 @@ <name>BitcoinGUI</name> <message> <source>Sign &message...</source> - <translation>&Assinar mensagem...</translation> + <translation>Assinar &mensagem...</translation> </message> <message> <source>Synchronizing with network...</source> @@ -326,6 +326,10 @@ <translation>Clique para ativar a atividade de rede.</translation> </message> <message> + <source>Syncing Headers (%1%)...</source> + <translation>Sincronizando cabeçahos (%1%)...</translation> + </message> + <message> <source>Reindexing blocks on disk...</source> <translation>Reindexando blocos no disco...</translation> </message> @@ -371,7 +375,7 @@ </message> <message> <source>&Show / Hide</source> - <translation>&Exibir/Ocultar</translation> + <translation>&Exibir / Ocultar</translation> </message> <message> <source>Show or hide the main Window</source> @@ -437,10 +441,6 @@ <source>Processing blocks on disk...</source> <translation>Processando blocos no disco...</translation> </message> - <message> - <source>No block source available...</source> - <translation>Nenhum servidor disponível...</translation> - </message> <message numerus="yes"> <source>Processed %n block(s) of transaction history.</source> <translation><numerusform>%n bloco processado do histórico de transações.</numerusform><numerusform>%n blocos processados do histórico de transações.</numerusform></translation> @@ -479,7 +479,11 @@ </message> <message> <source>%1 client</source> - <translation>%1</translation> + <translation>%1 cliente</translation> + </message> + <message> + <source>Connecting to peers...</source> + <translation>Conectando...</translation> </message> <message> <source>Catching up...</source> @@ -684,7 +688,7 @@ </message> <message> <source>(no label)</source> - <translation>(sem rótuo)</translation> + <translation>(sem rótulo)</translation> </message> <message> <source>change from %1 (%2)</source> @@ -1357,6 +1361,10 @@ <translation>Nó/Serviço</translation> </message> <message> + <source>NodeId</source> + <translation>ID do nó</translation> + </message> + <message> <source>Ping</source> <translation>Ping</translation> </message> @@ -1896,7 +1904,7 @@ </message> <message> <source>Label</source> - <translation>Rótuo</translation> + <translation>Rótulo</translation> </message> <message> <source>Message</source> @@ -1919,7 +1927,7 @@ </message> <message> <source>Label</source> - <translation>Rótuo</translation> + <translation>Rótulo</translation> </message> <message> <source>Message</source> @@ -1927,7 +1935,7 @@ </message> <message> <source>(no label)</source> - <translation>(sem rótuo)</translation> + <translation>(sem rótulo)</translation> </message> <message> <source>(no message)</source> @@ -2206,7 +2214,7 @@ </message> <message> <source>(no label)</source> - <translation>(sem rótuo)</translation> + <translation>(sem rótulo)</translation> </message> </context> <context> @@ -2661,7 +2669,7 @@ </message> <message> <source>Label</source> - <translation>Rótuo</translation> + <translation>Rótulo</translation> </message> <message numerus="yes"> <source>Open for %n more block(s)</source> @@ -2737,7 +2745,7 @@ </message> <message> <source>(no label)</source> - <translation>(sem rótuo)</translation> + <translation>(sem rótulo)</translation> </message> <message> <source>Transaction status. Hover over this field to show number of confirmations.</source> @@ -2884,7 +2892,7 @@ </message> <message> <source>Label</source> - <translation>Rótuo</translation> + <translation>Rótulo</translation> </message> <message> <source>Address</source> @@ -3086,6 +3094,14 @@ <translation>Executa um comando quando uma transação da carteira mudar (%s no comando será substituído por TxID)</translation> </message> <message> + <source>Extra transactions to keep in memory for compact block reconstructions (default: %u)</source> + <translation>Transações extras para manter na memória para reconstruções de blocos compactos (padrão: %u)</translation> + </message> + <message> + <source>If this block is in the chain assume that it and its ancestors are valid and potentially skip their script verification (0 to verify all, default: %s, testnet: %s)</source> + <translation>Se este bloco está no blockchain, assume-se que ele e seus ancestrais são válidos e podem ignorar a verificação de scripts (0 para verificar todos, padrão: %s, testnet: %s)</translation> + </message> + <message> <source>Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds)</source> <translation>A media máxima permitida de peer time compensa o ajuste. Perspectiva local de horário pode ser influenciada por pares à frente ou atrás neste montante. (padrão: %u segundos)</translation> </message> @@ -3786,6 +3802,10 @@ <translation>Retransmitir P2SH não multisig (padrão: %u)</translation> </message> <message> + <source>Send transactions with full-RBF opt-in enabled (default: %u)</source> + <translation>Ativar opção full-RBF nas transações enviadas (padrão: %u)</translation> + </message> + <message> <source>Set key pool size to <n> (default: %u)</source> <translation>Defina o tamanho da chave para piscina<n> (padrão: %u)</translation> </message> @@ -3807,7 +3827,7 @@ </message> <message> <source>Specify pid file (default: %s)</source> - <translation>Especificar aqrquivo pid (padrão: %s)</translation> + <translation>Especificar arquivo pid (padrão: %s)</translation> </message> <message> <source>Spend unconfirmed change when sending transactions (default: %u)</source> diff --git a/src/qt/locale/bitcoin_pt_PT.ts b/src/qt/locale/bitcoin_pt_PT.ts index 785cc537b7..c97272d4b7 100644 --- a/src/qt/locale/bitcoin_pt_PT.ts +++ b/src/qt/locale/bitcoin_pt_PT.ts @@ -417,10 +417,6 @@ <source>Processing blocks on disk...</source> <translation>A processar blocos no disco...</translation> </message> - <message> - <source>No block source available...</source> - <translation>Nenhuma fonte de blocos disponível...</translation> - </message> <message numerus="yes"> <source>Processed %n block(s) of transaction history.</source> <translation><numerusform>Processado %n bloco do histórico de transações.</numerusform><numerusform>Processados %n blocos do histórico de transações.</numerusform></translation> diff --git a/src/qt/locale/bitcoin_ro_RO.ts b/src/qt/locale/bitcoin_ro_RO.ts index 92fc87f4f2..3d3a4b0431 100644 --- a/src/qt/locale/bitcoin_ro_RO.ts +++ b/src/qt/locale/bitcoin_ro_RO.ts @@ -253,10 +253,6 @@ <source>%n active connection(s) to Bitcoin network</source> <translation><numerusform>%n conexiune activă către reţeaua Bitcoin</numerusform><numerusform>%n conexiuni active către reţeaua Bitcoin</numerusform><numerusform>%n de conexiuni active către reţeaua Bitcoin</numerusform></translation> </message> - <message> - <source>No block source available...</source> - <translation>Nici o sursă de bloc disponibilă...</translation> - </message> <message numerus="yes"> <source>Processed %n block(s) of transaction history.</source> <translation><numerusform>S-a procesat %n bloc din istoricul tranzacţiilor.</numerusform><numerusform>S-au procesat %n blocuri din istoricul tranzacţiilor.</numerusform><numerusform>S-au procesat %n de blocuri din istoricul tranzacţiilor.</numerusform></translation> diff --git a/src/qt/locale/bitcoin_ru.ts b/src/qt/locale/bitcoin_ru.ts index 8dd94ff220..b5f40fc058 100644 --- a/src/qt/locale/bitcoin_ru.ts +++ b/src/qt/locale/bitcoin_ru.ts @@ -63,7 +63,7 @@ </message> <message> <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source> - <translation>Это ваши адреса Bitcoin для отправки платежей. Всегда проверяйте количество и адрес получателя перед отправкой перевода.</translation> + <translation>Это ваши адреса Bitcoin для отправки платежей. Всегда проверяйте сумму и адрес получателя перед отправкой перевода.</translation> </message> <message> <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source> @@ -441,10 +441,6 @@ <source>Processing blocks on disk...</source> <translation>Обработка блоков на диске...</translation> </message> - <message> - <source>No block source available...</source> - <translation>Источник блоков недоступен...</translation> - </message> <message numerus="yes"> <source>Processed %n block(s) of transaction history.</source> <translation><numerusform>Обработан %n блок истории транзакций.</numerusform><numerusform>Обработано %n блока истории транзакций.</numerusform><numerusform>Обработано %n блоков истории транзакций.</numerusform><numerusform>Обработано %n блоков истории транзакций.</numerusform></translation> @@ -486,6 +482,10 @@ <translation>%1 клиент</translation> </message> <message> + <source>Connecting to peers...</source> + <translation>Подключение к пирам...</translation> + </message> + <message> <source>Catching up...</source> <translation>Синхронизируется...</translation> </message> diff --git a/src/qt/locale/bitcoin_sk.ts b/src/qt/locale/bitcoin_sk.ts index 15a32b2050..87dc620f0e 100644 --- a/src/qt/locale/bitcoin_sk.ts +++ b/src/qt/locale/bitcoin_sk.ts @@ -277,10 +277,6 @@ <source>Processing blocks on disk...</source> <translation>Spracovávam bloky na disku...</translation> </message> - <message> - <source>No block source available...</source> - <translation>Nedostupný zdroj blokov...</translation> - </message> <message numerus="yes"> <source>Processed %n block(s) of transaction history.</source> <translation><numerusform>Spracovaných %n blok transakčnej histórie.</numerusform><numerusform>Spracovaných %n bloky transakčnej histórie.</numerusform><numerusform>Spracovaných %n blokov transakčnej histórie.</numerusform></translation> diff --git a/src/qt/locale/bitcoin_sl_SI.ts b/src/qt/locale/bitcoin_sl_SI.ts index 1c8cb4ce56..8a21f978ef 100644 --- a/src/qt/locale/bitcoin_sl_SI.ts +++ b/src/qt/locale/bitcoin_sl_SI.ts @@ -261,10 +261,6 @@ <source>Processing blocks on disk...</source> <translation>Obdelava blokov na disku ...</translation> </message> - <message> - <source>No block source available...</source> - <translation>Ni virov za prenos blokov ...</translation> - </message> <message numerus="yes"> <source>Processed %n block(s) of transaction history.</source> <translation><numerusform>%n obdelan blok zgodovine transakcij.</numerusform><numerusform>%n obdelana bloka zgodovine transakcij.</numerusform><numerusform>%n obdelani bloki zgodovine transakcij.</numerusform><numerusform>%n obdelanih blokov zgodovine transakcij.</numerusform></translation> diff --git a/src/qt/locale/bitcoin_sr.ts b/src/qt/locale/bitcoin_sr.ts index 0fda9b9350..f880dd227e 100644 --- a/src/qt/locale/bitcoin_sr.ts +++ b/src/qt/locale/bitcoin_sr.ts @@ -37,6 +37,22 @@ <source>&Delete</source> <translation>&Избриши</translation> </message> + <message> + <source>Choose the address to send coins to</source> + <translation>Izbirajte adresu za slanje</translation> + </message> + <message> + <source>Choose the address to receive coins with</source> + <translation>Izbirajte adresu za primanje</translation> + </message> + <message> + <source>Sending addresses</source> + <translation>Adresa za slanje</translation> + </message> + <message> + <source>Receiving addresses</source> + <translation>Adresa za primanje</translation> + </message> </context> <context> <name>AddressTableModel</name> @@ -146,6 +162,10 @@ <translation>Трака са картицама</translation> </message> <message> + <source>Error</source> + <translation>Greška</translation> + </message> + <message> <source>Up to date</source> <translation>Ажурно</translation> </message> @@ -220,6 +240,10 @@ </context> <context> <name>Intro</name> + <message> + <source>Error</source> + <translation>Greška</translation> + </message> </context> <context> <name>ModalOverlay</name> @@ -278,6 +302,14 @@ </context> <context> <name>RPCConsole</name> + <message> + <source>Yes</source> + <translation>Da</translation> + </message> + <message> + <source>No</source> + <translation>Ne</translation> + </message> </context> <context> <name>ReceiveCoinsDialog</name> @@ -293,6 +325,10 @@ <source>&Message:</source> <translation>Poruka:</translation> </message> + <message> + <source>Show</source> + <translation>Prikaži</translation> + </message> </context> <context> <name>ReceiveRequestDialog</name> @@ -348,7 +384,11 @@ </context> <context> <name>SendConfirmationDialog</name> - </context> + <message> + <source>Yes</source> + <translation>Da</translation> + </message> +</context> <context> <name>ShutdownWindow</name> </context> @@ -432,6 +472,10 @@ <translation>učitavam adrese....</translation> </message> <message> + <source>Insufficient funds</source> + <translation>Nedovoljno sredstava</translation> + </message> + <message> <source>Loading block index...</source> <translation>Učitavam blok indeksa...</translation> </message> @@ -447,5 +491,9 @@ <source>Done loading</source> <translation>Završeno učitavanje</translation> </message> - </context> + <message> + <source>Error</source> + <translation>Greška</translation> + </message> +</context> </TS>
\ No newline at end of file diff --git a/src/qt/locale/bitcoin_sv.ts b/src/qt/locale/bitcoin_sv.ts index fc7ccdeba2..2986115a62 100644 --- a/src/qt/locale/bitcoin_sv.ts +++ b/src/qt/locale/bitcoin_sv.ts @@ -319,6 +319,22 @@ Var vänlig och försök igen.</translation> <translation>Öppna &URI...</translation> </message> <message> + <source>Click to disable network activity.</source> + <translation>Klicka för att inaktivera nätverksaktivitet.</translation> + </message> + <message> + <source>Network activity disabled.</source> + <translation>Nätverksaktivitet inaktiverad.</translation> + </message> + <message> + <source>Click to enable network activity again.</source> + <translation>Klicka för att aktivera nätverksaktivitet igen.</translation> + </message> + <message> + <source>Syncing Headers (%1%)...</source> + <translation>Synkar huvuden (%1%)...</translation> + </message> + <message> <source>Reindexing blocks on disk...</source> <translation>Återindexerar block på disken...</translation> </message> @@ -430,10 +446,6 @@ Var vänlig och försök igen.</translation> <source>Processing blocks on disk...</source> <translation>Bearbetar block på disken...</translation> </message> - <message> - <source>No block source available...</source> - <translation>Ingen block-källa tillgänglig...</translation> - </message> <message numerus="yes"> <source>Processed %n block(s) of transaction history.</source> <translation><numerusform>Bearbetade %n block av transaktionshistoriken.</numerusform><numerusform>Bearbetade %n block av transaktionshistoriken.</numerusform></translation> @@ -475,6 +487,10 @@ Var vänlig och försök igen.</translation> <translation>%1-klient</translation> </message> <message> + <source>Connecting to peers...</source> + <translation>Ansluter till noder...</translation> + </message> + <message> <source>Catching up...</source> <translation>Hämtar senaste...</translation> </message> @@ -608,6 +624,18 @@ Var vänlig och försök igen.</translation> <translation>Kopiera belopp</translation> </message> <message> + <source>Copy transaction ID</source> + <translation>Kopiera transaktions-ID</translation> + </message> + <message> + <source>yes</source> + <translation>ja</translation> + </message> + <message> + <source>no</source> + <translation>nej</translation> + </message> + <message> <source>(no label)</source> <translation>(Ingen etikett)</translation> </message> @@ -634,6 +662,10 @@ Var vänlig och försök igen.</translation> <source>&Address</source> <translation>&Adress</translation> </message> + <message> + <source>Could not unlock wallet.</source> + <translation>Kunde inte låsa upp plånboken.</translation> + </message> </context> <context> <name>FreespaceChecker</name> @@ -763,14 +795,34 @@ Var vänlig och försök igen.</translation> <translation>Formulär</translation> </message> <message> + <source>Number of blocks left</source> + <translation>Antal block kvar</translation> + </message> + <message> + <source>Unknown...</source> + <translation>Okänt...</translation> + </message> + <message> <source>Last block time</source> <translation>Sista blocktid</translation> </message> <message> + <source>Progress</source> + <translation>Förlopp</translation> + </message> + <message> + <source>calculating...</source> + <translation>beräknar...</translation> + </message> + <message> <source>Hide</source> <translation>Göm</translation> </message> - </context> + <message> + <source>Unknown. Syncing Headers (%1)...</source> + <translation>Okänd. Synkar huvuden (%1)...</translation> + </message> +</context> <context> <name>OpenURIDialog</name> <message> @@ -1102,6 +1154,18 @@ Var vänlig och försök igen.</translation> </context> <context> <name>PaymentServer</name> + <message> + <source>URI handling</source> + <translation>URI-hantering</translation> + </message> + <message> + <source>Refund from %1</source> + <translation>Återbetalning från %1</translation> + </message> + <message> + <source>Bad response from server %1</source> + <translation>Felaktigt svar från server %1</translation> + </message> </context> <context> <name>PeerTableModel</name> @@ -1113,7 +1177,11 @@ Var vänlig och försök igen.</translation> <source>Node/Service</source> <translation>Nod/Tjänst</translation> </message> - </context> + <message> + <source>Ping</source> + <translation>Ping</translation> + </message> +</context> <context> <name>QObject</name> <message> @@ -1152,14 +1220,42 @@ Var vänlig och försök igen.</translation> <source>%1 ms</source> <translation>%1 ms</translation> </message> + <message numerus="yes"> + <source>%n second(s)</source> + <translation><numerusform>%n sekund</numerusform><numerusform>%n sekunder</numerusform></translation> + </message> + <message numerus="yes"> + <source>%n minute(s)</source> + <translation><numerusform>%n minut</numerusform><numerusform>%n minuter</numerusform></translation> + </message> + <message numerus="yes"> + <source>%n hour(s)</source> + <translation><numerusform>%n timme</numerusform><numerusform>%n timmar</numerusform></translation> + </message> + <message numerus="yes"> + <source>%n day(s)</source> + <translation><numerusform>%n dag</numerusform><numerusform>%n dagar</numerusform></translation> + </message> + <message numerus="yes"> + <source>%n week(s)</source> + <translation><numerusform>%n vecka</numerusform><numerusform>%n veckor</numerusform></translation> + </message> <message> <source>%1 and %2</source> <translation>%1 och %2</translation> </message> + <message numerus="yes"> + <source>%n year(s)</source> + <translation><numerusform>%n år</numerusform><numerusform>%n år</numerusform></translation> + </message> </context> <context> <name>QObject::QObject</name> - </context> + <message> + <source>Error: %1</source> + <translation>Fel: %1</translation> + </message> +</context> <context> <name>QRImageWidget</name> </context> @@ -1513,10 +1609,18 @@ Var vänlig och försök igen.</translation> <translation>Ta bort</translation> </message> <message> + <source>Copy URI</source> + <translation>Kopiera URI</translation> + </message> + <message> <source>Copy label</source> <translation>Kopiera etikett</translation> </message> <message> + <source>Copy message</source> + <translation>Kopiera meddelande</translation> + </message> + <message> <source>Copy amount</source> <translation>Kopiera belopp</translation> </message> @@ -1540,6 +1644,14 @@ Var vänlig och försök igen.</translation> <translation>&Spara Bild...</translation> </message> <message> + <source>Payment information</source> + <translation>Betalinformaton</translation> + </message> + <message> + <source>URI</source> + <translation>URI</translation> + </message> + <message> <source>Address</source> <translation>Adress</translation> </message> @@ -1547,17 +1659,33 @@ Var vänlig och försök igen.</translation> <source>Label</source> <translation>Etikett</translation> </message> + <message> + <source>Message</source> + <translation>Meddelande</translation> + </message> </context> <context> <name>RecentRequestsTableModel</name> <message> + <source>Date</source> + <translation>Datum</translation> + </message> + <message> <source>Label</source> <translation>Etikett</translation> </message> <message> + <source>Message</source> + <translation>Meddelande</translation> + </message> + <message> <source>(no label)</source> <translation>(Ingen etikett)</translation> </message> + <message> + <source>(no message)</source> + <translation>(inget meddelande)</translation> + </message> </context> <context> <name>SendCoinsDialog</name> @@ -1706,6 +1834,18 @@ Var vänlig och försök igen.</translation> <translation>Kopiera belopp</translation> </message> <message> + <source>%1 to %2</source> + <translation>%1 till %2</translation> + </message> + <message> + <source>or</source> + <translation>eller</translation> + </message> + <message numerus="yes"> + <source>%n block(s)</source> + <translation><numerusform>%n block</numerusform><numerusform>%n block</numerusform></translation> + </message> + <message> <source>(no label)</source> <translation>(Ingen etikett)</translation> </message> @@ -1791,7 +1931,11 @@ Var vänlig och försök igen.</translation> </context> <context> <name>SendConfirmationDialog</name> - </context> + <message> + <source>Yes</source> + <translation>Ja</translation> + </message> +</context> <context> <name>ShutdownWindow</name> <message> @@ -1889,7 +2033,19 @@ Var vänlig och försök igen.</translation> <source>Reset all verify message fields</source> <translation>Rensa alla fält</translation> </message> - </context> + <message> + <source>Message signed.</source> + <translation>Meddelande signerat.</translation> + </message> + <message> + <source>The signature could not be decoded.</source> + <translation>Signaturen kunde inte avkodas.</translation> + </message> + <message> + <source>Message verified.</source> + <translation>Meddelande verifierat.</translation> + </message> +</context> <context> <name>SplashScreen</name> <message> @@ -1906,6 +2062,18 @@ Var vänlig och försök igen.</translation> </context> <context> <name>TransactionDesc</name> + <message> + <source>Status</source> + <translation>Status</translation> + </message> + <message> + <source>Date</source> + <translation>Datum</translation> + </message> + <message> + <source>Message</source> + <translation>Meddelande</translation> + </message> </context> <context> <name>TransactionDescDialog</name> @@ -1917,6 +2085,10 @@ Var vänlig och försök igen.</translation> <context> <name>TransactionTableModel</name> <message> + <source>Date</source> + <translation>Datum</translation> + </message> + <message> <source>Label</source> <translation>Etikett</translation> </message> @@ -1940,10 +2112,18 @@ Var vänlig och försök igen.</translation> <translation>Kopiera belopp</translation> </message> <message> + <source>Copy transaction ID</source> + <translation>Kopiera transaktions-ID</translation> + </message> + <message> <source>Comma separated file (*.csv)</source> <translation>Kommaseparerad fil (*.csv)</translation> </message> <message> + <source>Date</source> + <translation>Datum</translation> + </message> + <message> <source>Label</source> <translation>Etikett</translation> </message> diff --git a/src/qt/locale/bitcoin_th_TH.ts b/src/qt/locale/bitcoin_th_TH.ts index 18e78847fc..ea84d11d39 100644 --- a/src/qt/locale/bitcoin_th_TH.ts +++ b/src/qt/locale/bitcoin_th_TH.ts @@ -41,6 +41,18 @@ <source>&Delete</source> <translation>&ลบ</translation> </message> + <message> + <source>Choose the address to send coins to</source> + <translation>เลือกที่อยู่เพื่อส่งเหรียญไปไว้</translation> + </message> + <message> + <source>Choose the address to receive coins with</source> + <translation>เลือกที่อยู่เพื่อส่งเหรียญไปไว้</translation> + </message> + <message> + <source>Sending addresses</source> + <translation>ส่งที่อยู่</translation> + </message> </context> <context> <name>AddressTableModel</name> @@ -273,10 +285,6 @@ <source>Processing blocks on disk...</source> <translation>กำลังดำเนินการกับบล็อกในดิสก์...</translation> </message> - <message> - <source>No block source available...</source> - <translation>ไม่มีบล็อกเริ่มต้น ให้ใช้ได้...</translation> - </message> <message numerus="yes"> <source>Processed %n block(s) of transaction history.</source> <translation><numerusform>%n บล็อกในประวัติรายการ ได้รับการดำเนินการเรียบร้อยแล้ว</numerusform></translation> diff --git a/src/qt/locale/bitcoin_tr.ts b/src/qt/locale/bitcoin_tr.ts index ae565ee665..2de0d14ddd 100644 --- a/src/qt/locale/bitcoin_tr.ts +++ b/src/qt/locale/bitcoin_tr.ts @@ -35,7 +35,7 @@ </message> <message> <source>&Export</source> - <translation>&Dışa aktar</translation> + <translation>&Dışarı aktar</translation> </message> <message> <source>&Delete</source> @@ -59,15 +59,23 @@ </message> <message> <source>Receiving addresses</source> - <translation>Alınan adresler</translation> + <translation>Alım adresleri</translation> + </message> + <message> + <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source> + <translation>Bunlar ödemeleri göndermek için kullanacağınız Bitcoin adreslerinizdir. Bitcoin yollamadan önce tutarı ve alıcının alım adresini her zaman kontrol ediniz.</translation> + </message> + <message> + <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source> + <translation>Bunlar ödemeleri almak için kullanacağınız Bitcoin adreslerinizdir. Her işlem için yeni bir alım adresi kullanmanız tavsiye edilir.</translation> </message> <message> <source>&Copy Address</source> - <translation>&Adres Kopyala</translation> + <translation>&Adresi Kopyala</translation> </message> <message> <source>Copy &Label</source> - <translation>&Etiketi kopyala</translation> + <translation>&Etiketi Kopyala</translation> </message> <message> <source>&Edit</source> @@ -75,13 +83,21 @@ </message> <message> <source>Export Address List</source> - <translation>Adres listesini dışarı aktar</translation> + <translation>Adres Listesini Dışarı Aktar</translation> + </message> + <message> + <source>Comma separated file (*.csv)</source> + <translation>Virgülle ayrılmış değerler dosyası (*.csv)</translation> </message> <message> <source>Exporting Failed</source> - <translation>Dışarı aktarmada hata</translation> + <translation>Dışarı Aktarım Başarısız Oldu</translation> + </message> + <message> + <source>There was an error trying to save the address list to %1. Please try again.</source> + <translation>Adres listesinin %1 konumuna kaydedilmesi sırasında bir hata meydana geldi. Lütfen tekrar deneyin.</translation> </message> - </context> +</context> <context> <name>AddressTableModel</name> <message> @@ -101,7 +117,7 @@ <name>AskPassphraseDialog</name> <message> <source>Passphrase Dialog</source> - <translation>Parola diyaloğu</translation> + <translation>Parola Diyaloğu</translation> </message> <message> <source>Enter passphrase</source> @@ -116,8 +132,16 @@ <translation>Yeni parolayı tekrarlayınız</translation> </message> <message> + <source>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>.</source> + <translation>Cüzdan için yeni parolayı giriniz.<br/>Lütfen <b>on ya da daha fazla rastgele karakter</b> veya <b>sekiz ya da daha fazla kelime</b> içeren bir parola kullanınız.</translation> + </message> + <message> <source>Encrypt wallet</source> - <translation>Şifrelenmiş cüzdan</translation> + <translation>Cüzdanı şifrele</translation> + </message> + <message> + <source>This operation needs your wallet passphrase to unlock the wallet.</source> + <translation>Bu eylem cüzdan kilidini açmak için cüzdan parolanızı gerektirir.</translation> </message> <message> <source>Unlock wallet</source> @@ -125,17 +149,29 @@ </message> <message> <source>This operation needs your wallet passphrase to decrypt the wallet.</source> - <translation>Bu işlem, cüzdan şifresini çözmek için cüzdan parolanıza ihtiyaç duyuyor.</translation> + <translation>Bu eylem, cüzdan şifresini çözmek için cüzdan parolanıza ihtiyaç duyuyor.</translation> + </message> + <message> + <source>Decrypt wallet</source> + <translation>Cüzdanın şifrelemesini aç</translation> </message> <message> <source>Change passphrase</source> <translation>Parola değiştir</translation> </message> <message> + <source>Enter the old passphrase and new passphrase to the wallet.</source> + <translation>Eski ve yeni parolanızı cüzdana giriniz.</translation> + </message> + <message> <source>Confirm wallet encryption</source> <translation>Cüzdan şifrelemesini onayla</translation> </message> <message> + <source>Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>!</source> + <translation>Uyarı: Eğer cüzdanınızı şifreler ve parolanızı kaybederseniz <b>TÜM BİTCOİNLERİNİZİ KAYBEDECEKSİNİZ</b>!</translation> + </message> + <message> <source>Are you sure you wish to encrypt your wallet?</source> <translation>Cüzdanınızı şifrelemek istediğinizden emin misiniz?</translation> </message> @@ -144,34 +180,66 @@ <translation>Cüzdan şifrelendi</translation> </message> <message> + <source>%1 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.</source> + <translation>Şifreleme işleminin bitirilmesi için %1 kapatılacak. Her ne kadar cüzdanınızı şifreleseniz de şifrelemenin bitcoinlerinizi bilgisayarınıza bulaşan zararlılardan tam olarak koruyamayacağını unutmayın.</translation> + </message> + <message> + <source>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.</source> + <translation>ÖNEMLİ: Önceden yapmış olduğunuz cüzdan dosyası yedeklemelerinin yeni oluşturulan şifrelenmiş cüzdan dosyası ile değiştirilmeleri gerekir. Güvenlik nedenleriyle yeni, şifrelenmiş cüzdanı kullanmaya başladığınızda eski şifrelenmemiş cüzdan dosyaları işe yaramaz hale gelecektir.</translation> + </message> + <message> <source>Wallet encryption failed</source> <translation>Cüzdan şifreleme başarısız</translation> </message> <message> + <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source> + <translation>Dahili bir hata yüzünden cüzdan şifrelemesi başarısız oldu. Cüzdanın şifrelenmedi.</translation> + </message> + <message> + <source>The supplied passphrases do not match.</source> + <translation>Girilen parolalar birbiriyle eşleşmiyor.</translation> + </message> + <message> <source>Wallet unlock failed</source> - <translation>Cüzdan kilidi kaldırma hatası</translation> + <translation>Cüzdan kilidini kaldırma başarısız oldu</translation> + </message> + <message> + <source>The passphrase entered for the wallet decryption was incorrect.</source> + <translation>Cüzdan şifresinin açılması için girilen parola yanlıştı.</translation> + </message> + <message> + <source>Wallet decryption failed</source> + <translation>Cüzdan şifresinin açılması başarısız oldu</translation> + </message> + <message> + <source>Wallet passphrase was successfully changed.</source> + <translation>Cüzdan parolası başarılı bir şekilde değiştirildi.</translation> + </message> + <message> + <source>Warning: The Caps Lock key is on!</source> + <translation>Uyarı: Caps Lock tuşu etkin durumda!</translation> </message> - </context> +</context> <context> <name>BanTableModel</name> <message> <source>IP/Netmask</source> - <translation>IP/Ağ maskesi</translation> + <translation>IP/Ağ Maskesi</translation> </message> <message> <source>Banned Until</source> - <translation>Şu vakte kadar yasaklı:</translation> + <translation>Şu zamana kadar yasaklı:</translation> </message> </context> <context> <name>BitcoinGUI</name> <message> <source>Sign &message...</source> - <translation>&Mesaj imzala...</translation> + <translation>&İleti imzala...</translation> </message> <message> <source>Synchronizing with network...</source> - <translation>Şebeke ile senkronizasyon...</translation> + <translation>Ağ ile senkronize ediliyor...</translation> </message> <message> <source>&Overview</source> @@ -187,15 +255,15 @@ </message> <message> <source>&Transactions</source> - <translation>&Muameleler</translation> + <translation>&İşlemler</translation> </message> <message> <source>Browse transaction history</source> - <translation>Muamele tarihçesini tara</translation> + <translation>İşlem geçmişine gözat</translation> </message> <message> <source>E&xit</source> - <translation>&Çık</translation> + <translation>Ç&ık</translation> </message> <message> <source>Quit application</source> @@ -203,7 +271,7 @@ </message> <message> <source>&About %1</source> - <translation>%1 &hakkında</translation> + <translation>%1 &Hakkında</translation> </message> <message> <source>Show information about %1</source> @@ -211,11 +279,11 @@ </message> <message> <source>About &Qt</source> - <translation>&Qt hakkında</translation> + <translation>&Qt Hakkında</translation> </message> <message> <source>Show information about Qt</source> - <translation>Qt hakkında bilgi görüntü</translation> + <translation>Qt hakkında bilgi göster</translation> </message> <message> <source>&Options...</source> @@ -227,15 +295,15 @@ </message> <message> <source>&Encrypt Wallet...</source> - <translation>Cüzdanı &şifrele...</translation> + <translation>Cüzdanı &Şifrele...</translation> </message> <message> <source>&Backup Wallet...</source> - <translation>Cüzdanı &yedekle...</translation> + <translation>Cüzdanı &Yedekle...</translation> </message> <message> <source>&Change Passphrase...</source> - <translation>Parolayı &değiştir...</translation> + <translation>Parolayı &Değiştir...</translation> </message> <message> <source>&Sending addresses...</source> @@ -247,15 +315,31 @@ </message> <message> <source>Open &URI...</source> - <translation>&URI aç...</translation> + <translation>&URI Aç...</translation> + </message> + <message> + <source>Click to disable network activity.</source> + <translation>Ağ etkinliğini devre dışı bırakmak için tıklayın.</translation> + </message> + <message> + <source>Network activity disabled.</source> + <translation>Ağ etkinliği devre dışı bırakılmış.</translation> + </message> + <message> + <source>Click to enable network activity again.</source> + <translation>Ağ etkinliğini yeniden etkinleştirmek için tıklayın.</translation> + </message> + <message> + <source>Syncing Headers (%1%)...</source> + <translation>Üstbilgiler Senkronize Ediliyor (%1%)...</translation> </message> <message> <source>Reindexing blocks on disk...</source> - <translation>Diskteki bloklar yeniden endeksleniyor...</translation> + <translation>Diskteki bloklar yeniden indeksleniyor...</translation> </message> <message> <source>Send coins to a Bitcoin address</source> - <translation>Bir Bitcoin adresine Bitcoin yolla</translation> + <translation>Bir bitcoin adresine bitcoin gönder</translation> </message> <message> <source>Backup wallet to another location</source> @@ -275,7 +359,7 @@ </message> <message> <source>&Verify message...</source> - <translation>Mesaj &kontrol et...</translation> + <translation>İletiyi &kontrol et...</translation> </message> <message> <source>Bitcoin</source> @@ -295,23 +379,23 @@ </message> <message> <source>&Show / Hide</source> - <translation>&Göster / Sakla</translation> + <translation>&Göster / Gizle</translation> </message> <message> <source>Show or hide the main Window</source> - <translation>Ana pencereyi görüntüle ya da sakla</translation> + <translation>Ana pencereyi göster ya da gizle</translation> </message> <message> <source>Encrypt the private keys that belong to your wallet</source> - <translation>Cüzdanınızın özel anahtarlarını şifrele</translation> + <translation>Cüzdanınıza ait özel anahtarları şifreleyin</translation> </message> <message> <source>Sign messages with your Bitcoin addresses to prove you own them</source> - <translation>Mesajları adreslerin size ait olduğunu ispatlamak için Bitcoin adresleri ile imzala</translation> + <translation>İletileri adreslerin size ait olduğunu ispatlamak için Bitcoin adresleri ile imzala</translation> </message> <message> <source>Verify messages to ensure they were signed with specified Bitcoin addresses</source> - <translation>Belirtilen Bitcoin adresleri ile imzalandıklarından emin olmak için mesajları kontrol et</translation> + <translation>Belirtilen Bitcoin adresleri ile imzalandıklarından emin olmak için iletileri kontrol et</translation> </message> <message> <source>&File</source> @@ -351,7 +435,7 @@ </message> <message numerus="yes"> <source>%n active connection(s) to Bitcoin network</source> - <translation><numerusform>Bitcoin şebekesine %n faal bağlantı</numerusform><numerusform>Bitcoin şebekesine %n faal bağlantı</numerusform></translation> + <translation><numerusform>Bitcoin şebekesine %n faal bağlantı</numerusform><numerusform>Bitcoin ağına %n etkin bağlantı var</numerusform></translation> </message> <message> <source>Indexing blocks on disk...</source> @@ -359,15 +443,11 @@ </message> <message> <source>Processing blocks on disk...</source> - <translation>Bloklar diske yazıdırılıyor...</translation> - </message> - <message> - <source>No block source available...</source> - <translation>Hiçbir blok kaynağı mevcut değil...</translation> + <translation>Bloklar diske işleniyor...</translation> </message> <message numerus="yes"> <source>Processed %n block(s) of transaction history.</source> - <translation><numerusform>Muamele tarihçesinden %n blok işlendi.</numerusform><numerusform>Muamele tarihçesinden %n blok işlendi</numerusform></translation> + <translation><numerusform>Muamele tarihçesinden %n blok işlendi.</numerusform><numerusform>İşlem tarihçesinden %n blok işlendi</numerusform></translation> </message> <message> <source>%1 behind</source> @@ -375,11 +455,11 @@ </message> <message> <source>Last received block was generated %1 ago.</source> - <translation>Son alınan blok %1 evvel oluşturulmuştu.</translation> + <translation>Son alınan blok %1 önce oluşturulmuştu.</translation> </message> <message> <source>Transactions after this will not yet be visible.</source> - <translation>Bundan sonraki muameleler henüz görüntülenemez.</translation> + <translation>Bundan sonraki işlemler henüz görüntülenemez.</translation> </message> <message> <source>Error</source> @@ -403,7 +483,11 @@ </message> <message> <source>%1 client</source> - <translation>%1 istemcisi</translation> + <translation>%1 istemci</translation> + </message> + <message> + <source>Connecting to peers...</source> + <translation>Eşlere bağlanılıyor...</translation> </message> <message> <source>Catching up...</source> @@ -418,7 +502,7 @@ <message> <source>Amount: %1 </source> - <translation>Meblağ: %1 + <translation>Tutar: %1 </translation> </message> <message> @@ -441,11 +525,19 @@ </message> <message> <source>Sent transaction</source> - <translation>Muamele yollandı</translation> + <translation>İşlem gönderildi</translation> </message> <message> <source>Incoming transaction</source> - <translation>Gelen muamele</translation> + <translation>Gelen işlem</translation> + </message> + <message> + <source>HD key generation is <b>enabled</b></source> + <translation>HD anahtar oluşturma <b>etkin</b></translation> + </message> + <message> + <source>HD key generation is <b>disabled</b></source> + <translation>HD anahtar oluşturma <b>devre dışı</b></translation> </message> <message> <source>Wallet is <b>encrypted</b> and currently <b>unlocked</b></source> @@ -455,7 +547,11 @@ <source>Wallet is <b>encrypted</b> and currently <b>locked</b></source> <translation>Cüzdan <b>şifrelenmiştir</b> ve şu anda <b>kilitlidir</b></translation> </message> - </context> + <message> + <source>A fatal error occurred. Bitcoin can no longer continue safely and will quit.</source> + <translation>Ölümcül bir hata oluştu. Bitcoin yazılımı artık güvenli bir şekilde çalışmaya devam edemediği için kapatılacaktır.</translation> + </message> +</context> <context> <name>CoinControlDialog</name> <message> @@ -472,7 +568,7 @@ </message> <message> <source>Amount:</source> - <translation>Meblağ:</translation> + <translation>Tutar:</translation> </message> <message> <source>Fee:</source> @@ -504,7 +600,7 @@ </message> <message> <source>Amount</source> - <translation>Meblağ</translation> + <translation>Tutar</translation> </message> <message> <source>Received with label</source> @@ -536,13 +632,77 @@ </message> <message> <source>Copy amount</source> + <translation>Tutarı kopyala</translation> + </message> + <message> + <source>Copy transaction ID</source> + <translation>İşlem ID'sini kopyala</translation> + </message> + <message> + <source>Lock unspent</source> + <translation>Harcanmamışı kilitle</translation> + </message> + <message> + <source>Unlock unspent</source> + <translation>Harcanmamışın kilidini aç</translation> + </message> + <message> + <source>Copy quantity</source> <translation>Miktarı kopyala</translation> </message> <message> + <source>Copy fee</source> + <translation>Ücreti kopyala</translation> + </message> + <message> + <source>Copy after fee</source> + <translation>Ücretten sonrasını kopyala</translation> + </message> + <message> + <source>Copy bytes</source> + <translation>Baytları kopyala</translation> + </message> + <message> + <source>Copy dust</source> + <translation>Tozu kopyala</translation> + </message> + <message> + <source>Copy change</source> + <translation>Para üstünü kopyala</translation> + </message> + <message> + <source>(%1 locked)</source> + <translation>(%1 kilitlendi)</translation> + </message> + <message> + <source>yes</source> + <translation>evet</translation> + </message> + <message> + <source>no</source> + <translation>hayır</translation> + </message> + <message> + <source>This label turns red if any recipient receives an amount smaller than the current dust threshold.</source> + <translation>Eğer herhangi bir alıcı mevcut toz eşiğinden daha düşük bir tutar alırsa bu etiket kırmızıya dönüşür.</translation> + </message> + <message> + <source>Can vary +/- %1 satoshi(s) per input.</source> + <translation>Girdi başına +/- %1 satoshi değişebilir.</translation> + </message> + <message> <source>(no label)</source> <translation>(etiket yok)</translation> </message> - </context> + <message> + <source>change from %1 (%2)</source> + <translation>%1 ögesinden para üstü (%2)</translation> + </message> + <message> + <source>(change)</source> + <translation>(para üstü)</translation> + </message> +</context> <context> <name>EditAddressDialog</name> <message> @@ -565,7 +725,39 @@ <source>&Address</source> <translation>&Adres</translation> </message> - </context> + <message> + <source>New receiving address</source> + <translation>Yeni alım adresi</translation> + </message> + <message> + <source>New sending address</source> + <translation>Yeni gönderi adresi</translation> + </message> + <message> + <source>Edit receiving address</source> + <translation>Alım adresini düzenle</translation> + </message> + <message> + <source>Edit sending address</source> + <translation>Gönderi adresini düzenle</translation> + </message> + <message> + <source>The entered address "%1" is not a valid Bitcoin address.</source> + <translation>Girilen "%1" adresi geçerli bir Bitcoin adresi değildir.</translation> + </message> + <message> + <source>The entered address "%1" is already in the address book.</source> + <translation>Girilen "%1" adresi zaten adres defterinde mevcuttur.</translation> + </message> + <message> + <source>Could not unlock wallet.</source> + <translation>Cüzdan kilidi açılamadı.</translation> + </message> + <message> + <source>New key generation failed.</source> + <translation>Yeni anahtar oluşturulması başarısız oldu.</translation> + </message> +</context> <context> <name>FreespaceChecker</name> <message> @@ -578,7 +770,7 @@ </message> <message> <source>Directory already exists. Add %1 if you intend to create a new directory here.</source> - <translation>Klasör hâlihazırda mevcuttur. Burada yeni bir klasör oluşturmak istiyorsanız, %1 ilâve ediniz.</translation> + <translation>Klasör zaten mevcuttur. Burada yeni bir klasör oluşturmak istiyorsanız, %1 ekleyiniz.</translation> </message> <message> <source>Path already exists, and is not a directory.</source> @@ -660,7 +852,7 @@ </message> <message> <source>%1 will download and store a copy of the Bitcoin block chain. At least %2GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory.</source> - <translation>%1, Bitcoin blok zincirinin bir kopyasını indirecek ve saklayacaktır. Bu klasörde en az %2GB veri saklanacak ve bu zamanla artacaktır. Cüzdan da bu klasörde saklanacaktır.</translation> + <translation>%1, Bitcoin blok zincirinin bir kopyasını indirecek ve saklayacaktır. Bu klasörde en az %2 GB veri saklanacak ve bu zamanla artacaktır. Cüzdan da bu klasörde saklanacaktır.</translation> </message> <message> <source>Use the default data directory</source> @@ -694,19 +886,55 @@ <translation>Form</translation> </message> <message> + <source>Recent transactions may not yet be visible, and therefore your wallet's balance might be incorrect. This information will be correct once your wallet has finished synchronizing with the bitcoin network, as detailed below.</source> + <translation>Son işlemler henüz görünmeyebilir ve bu nedenle cüzdanınızın bakiyesi yanlış olabilir. Bu bilgiler, aşağıda detaylandırıldığı gibi, cüzdanınız bitcoin ağı ile senkronizasyonunu tamamladığında doğru olacaktır. </translation> + </message> + <message> + <source>Attempting to spend bitcoins that are affected by not-yet-displayed transactions will not be accepted by the network.</source> + <translation>Henüz görüntülenmeyen işlemlerden etkilenen bitcoinleri harcama girişiminde bulunmak ağ tarafından kabul edilmeyecektir.</translation> + </message> + <message> + <source>Number of blocks left</source> + <translation>Kalan blok sayısı</translation> + </message> + <message> + <source>Unknown...</source> + <translation>Bilinmiyor...</translation> + </message> + <message> <source>Last block time</source> <translation>Son blok zamanı</translation> </message> <message> + <source>Progress</source> + <translation>İlerleme</translation> + </message> + <message> + <source>Progress increase per hour</source> + <translation>Saat başı ilerleme artışı</translation> + </message> + <message> + <source>calculating...</source> + <translation>hesaplanıyor...</translation> + </message> + <message> + <source>Estimated time left until synced</source> + <translation>Senkronize edilene kadar kalan tahmini süre</translation> + </message> + <message> <source>Hide</source> - <translation>Sakla</translation> + <translation>Gizle</translation> </message> - </context> + <message> + <source>Unknown. Syncing Headers (%1)...</source> + <translation>Bilinmeyen. Üstbilgiler Senkronize Ediliyor (%1)...</translation> + </message> +</context> <context> <name>OpenURIDialog</name> <message> <source>Open URI</source> - <translation>URI aç</translation> + <translation>URI Aç</translation> </message> <message> <source>Open payment request from URI or file</source> @@ -720,7 +948,11 @@ <source>Select payment request file</source> <translation>Ödeme talebi dosyasını seç</translation> </message> - </context> + <message> + <source>Select payment request file to open</source> + <translation>Açılacak ödeme talebi dosyasını seç</translation> + </message> +</context> <context> <name>OptionsDialog</name> <message> @@ -729,7 +961,7 @@ </message> <message> <source>&Main</source> - <translation>&Esas ayarlar</translation> + <translation>&Genel</translation> </message> <message> <source>Automatically start %1 after logging in to the system.</source> @@ -741,7 +973,7 @@ </message> <message> <source>Size of &database cache</source> - <translation>&Veritabanı tamponunun boyutu</translation> + <translation>&Veritabanı önbelleğinin boyutu</translation> </message> <message> <source>MB</source> @@ -769,15 +1001,15 @@ </message> <message> <source>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 |.</source> - <translation>Muameleler sekmesinde bağlam menüsü unsurları olarak görünen üçüncü taraf bağlantıları (mesela bir blok tarayıcısı). URL'deki %s, muamele hash değeri ile değiştirilecektir. Birden çok bağlantılar düşey çubuklar | ile ayrılacaktır.</translation> + <translation>İşlemler sekmesinde bağlam menüsü unsurları olarak görünen üçüncü taraf bağlantıları (mesela bir blok tarayıcısı). URL'deki %s, işlem hash değeri ile değiştirilecektir. Birden çok bağlantılar düşey çubuklar | ile ayrılacaktır.</translation> </message> <message> <source>Third party transaction URLs</source> - <translation>Üçüncü taraf muamele URL'leri</translation> + <translation>Üçüncü parti işlem URL'leri</translation> </message> <message> <source>Active command-line options that override above options:</source> - <translation>Yukarıdaki seçeneklerin yerine geçen faal komut satırı seçenekleri:</translation> + <translation>Yukarıdaki seçeneklerin yerine geçen etkin komut satırı seçenekleri:</translation> </message> <message> <source>Reset all client options to default.</source> @@ -785,11 +1017,11 @@ </message> <message> <source>&Reset Options</source> - <translation>Seçenekleri Sıfı&rla</translation> + <translation>Seçenekleri &Sıfırla</translation> </message> <message> <source>&Network</source> - <translation>&Şebeke</translation> + <translation>&Ağ</translation> </message> <message> <source>(0 = auto, <0 = leave that many cores free)</source> @@ -809,11 +1041,11 @@ </message> <message> <source>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.</source> - <translation>Teyit edilmemiş para üstünü harcamayı devre dışı bırakırsanız, bir muamelenin para üstü bu muamele için en az bir teyit olana dek harcanamaz. Bu, aynı zamanda bakiyenizin nasıl hesaplandığını da etkiler.</translation> + <translation>Doğrulanmamış para üstünü harcamayı devre dışı bırakırsanız, bir işlemin para üstü bu işlem için en az bir doğrulama olana dek harcanamaz. Bu, aynı zamanda bakiyenizin nasıl hesaplandığını da etkiler.</translation> </message> <message> <source>&Spend unconfirmed change</source> - <translation>Teyit edilmemiş para üstünü &harca</translation> + <translation>Doğrulanmamış para üstünü &harca</translation> </message> <message> <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source> @@ -825,15 +1057,15 @@ </message> <message> <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source> - <translation>Bitcoin şebekesine SOCKS5 vekil sunucusu vasıtasıyla bağlan.</translation> + <translation>Bitcoin ağına bir SOCKS5 vekil sunucusu aracılığıyla bağlan.</translation> </message> <message> <source>&Connect through SOCKS5 proxy (default proxy):</source> - <translation>SOCKS5 vekil sunucusu vasıtasıyla &bağlan (varsayılan vekil sunucusu):</translation> + <translation>SOCKS5 vekil sunucusu aracılığıyla &bağlan (varsayılan vekil sunucusu):</translation> </message> <message> <source>Proxy &IP:</source> - <translation>Vekil &İP:</translation> + <translation>Vekil &IP:</translation> </message> <message> <source>&Port:</source> @@ -845,11 +1077,11 @@ </message> <message> <source>Used for reaching peers via:</source> - <translation>Eşlere ulaşmak için kullanılır, şu yoluyla:</translation> + <translation>Eşlere ulaşmak için kullanılır, şu üzerinden:</translation> </message> <message> <source>Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type.</source> - <translation>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.</translation> + <translation>Bu ağ türü yoluyla eşlere bağlanmak için belirtilen varsayılan SOCKS5 vekil sunucusunun kullanılıp kullanılmadığını gösterir.</translation> </message> <message> <source>IPv4</source> @@ -865,7 +1097,7 @@ </message> <message> <source>Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor hidden services.</source> - <translation>Bitcoin şebekesine gizli Tor servisleri için ayrı bir SOCKS5 vekil sunucusu vasıtasıyla bağlan.</translation> + <translation>Bitcoin ağına gizli Tor servisleri için ayrı bir SOCKS5 vekil sunucusu aracılığıyla bağlan.</translation> </message> <message> <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services:</source> @@ -877,15 +1109,15 @@ </message> <message> <source>&Hide the icon from the system tray.</source> - <translation>İkonu sistem çekmecesinden &sakla</translation> + <translation>Simgeyi görev çubuğundan &gizle</translation> </message> <message> <source>Hide tray icon</source> - <translation>Sistem çekmecesi ikonunu sakla</translation> + <translation>Görev çubuğu simgesini gizle</translation> </message> <message> <source>Show only a tray icon after minimizing the window.</source> - <translation>Küçültüldükten sonra sadece çekmece ikonu göster.</translation> + <translation>Küçültüldükten sonra sadece tepsi simgesi göster.</translation> </message> <message> <source>&Minimize to the tray instead of the taskbar</source> @@ -909,7 +1141,7 @@ </message> <message> <source>&Unit to show amounts in:</source> - <translation>Meblağları göstermek için &birim:</translation> + <translation>Tutarı göstermek için &birim:</translation> </message> <message> <source>Choose the default subdivision unit to show in the interface and when sending coins.</source> @@ -964,7 +1196,7 @@ </message> <message> <source>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.</source> - <translation>Görüntülenen veriler zaman aşımına uğramış olabilir. Bağlantı kurulduğunda cüzdanınız otomatik olarak şebeke ile eşleşir ancak bu işlem henüz tamamlanmamıştır.</translation> + <translation>Görüntülenen bilgiler güncel olmayabilir. Bağlantı kurulduğunda cüzdanınız otomatik olarak Bitcoin ağı ile senkronize olur ancak bu işlem henüz tamamlanmamıştır.</translation> </message> <message> <source>Watch-only:</source> @@ -984,7 +1216,7 @@ </message> <message> <source>Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</source> - <translation>Henüz teyit edilmemiş ve harcanabilir bakiyeye eklenmemiş muamelelerin toplamı</translation> + <translation>Henüz doğrulanmamış ve harcanabilir bakiyeye eklenmemiş işlemlerin toplamı</translation> </message> <message> <source>Immature:</source> @@ -1016,11 +1248,11 @@ </message> <message> <source>Recent transactions</source> - <translation>Son muameleler</translation> + <translation>Son işlemler</translation> </message> <message> <source>Unconfirmed transactions to watch-only addresses</source> - <translation>Sadece izlenen adreslere gelen teyit edilmemiş muameleler</translation> + <translation>Sadece izlenen adreslere gelen doğrulanmamış işlemler</translation> </message> <message> <source>Mined balance in watch-only addresses that has not yet matured</source> @@ -1033,7 +1265,95 @@ </context> <context> <name>PaymentServer</name> - </context> + <message> + <source>Payment request error</source> + <translation>Ödeme talebi hatası</translation> + </message> + <message> + <source>Cannot start bitcoin: click-to-pay handler</source> + <translation>Bitcoin başlatılamadı: tıkla-ve-öde yöneticisi</translation> + </message> + <message> + <source>URI handling</source> + <translation>URI yönetimi</translation> + </message> + <message> + <source>Payment request fetch URL is invalid: %1</source> + <translation>Ödeme talebini alma URL'i geçersiz: %1</translation> + </message> + <message> + <source>Invalid payment address %1</source> + <translation>%1 ödeme adresi geçersizdir</translation> + </message> + <message> + <source>URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters.</source> + <translation>URI ayrıştırılamıyor! Bunun nedeni geçersiz bir Bitcoin adresi veya hatalı biçimlendirilmiş URI değişkenleri olabilir.</translation> + </message> + <message> + <source>Payment request file handling</source> + <translation>Ödeme talebi dosyası yönetimi</translation> + </message> + <message> + <source>Payment request file cannot be read! This can be caused by an invalid payment request file.</source> + <translation>Ödeme talebi dosyası okunamıyor! Bunun nedeni geçersiz bir ödeme talebi dosyası olabilir.</translation> + </message> + <message> + <source>Payment request rejected</source> + <translation>Ödeme talebi reddedildi</translation> + </message> + <message> + <source>Payment request network doesn't match client network.</source> + <translation>Ödeme talebi ağı, istemci ağıyla eşleşmiyor.</translation> + </message> + <message> + <source>Payment request expired.</source> + <translation>Ödeme talebinin geçerlilik süresi bitti.</translation> + </message> + <message> + <source>Payment request is not initialized.</source> + <translation>Ödeme talebi başlatılmadı.</translation> + </message> + <message> + <source>Unverified payment requests to custom payment scripts are unsupported.</source> + <translation>Özel ödeme betiklerine, doğrulanmamış ödeme talepleri desteklenmez.</translation> + </message> + <message> + <source>Invalid payment request.</source> + <translation>Geçersiz ödeme talebi.</translation> + </message> + <message> + <source>Requested payment amount of %1 is too small (considered dust).</source> + <translation>Talep edilen %1 ödeme tutarı çok küçüktür (toz olarak kabul edilir).</translation> + </message> + <message> + <source>Refund from %1</source> + <translation>%1 adresinden geri ödeme</translation> + </message> + <message> + <source>Payment request %1 is too large (%2 bytes, allowed %3 bytes).</source> + <translation>%1 ödeme talebi çok büyük (%2 bayt, üst sınır %3 bayt).</translation> + </message> + <message> + <source>Error communicating with %1: %2</source> + <translation>%1 ile iletişimde hata: %2</translation> + </message> + <message> + <source>Payment request cannot be parsed!</source> + <translation>Ödeme talebi ayrıştırılamaz!</translation> + </message> + <message> + <source>Bad response from server %1</source> + <translation>%1 sunucusundan hatalı yanıt</translation> + </message> + <message> + <source>Network request error</source> + <translation>Ağ talebi hatası</translation> + </message> + <message> + <source>Payment acknowledged</source> + <translation>Ödeme kabul edildi</translation> + </message> +</context> <context> <name>PeerTableModel</name> <message> @@ -1044,12 +1364,20 @@ <source>Node/Service</source> <translation>Düğüm/Servis</translation> </message> - </context> + <message> + <source>NodeId</source> + <translation>Düğüm ID'si</translation> + </message> + <message> + <source>Ping</source> + <translation>Ping</translation> + </message> +</context> <context> <name>QObject</name> <message> <source>Amount</source> - <translation>Meblağ</translation> + <translation>Tutar</translation> </message> <message> <source>Enter a Bitcoin address (e.g. %1)</source> @@ -1083,21 +1411,73 @@ <source>%1 ms</source> <translation>%1 ms</translation> </message> + <message numerus="yes"> + <source>%n second(s)</source> + <translation><numerusform>%n saniye</numerusform><numerusform>%n saniye</numerusform></translation> + </message> + <message numerus="yes"> + <source>%n minute(s)</source> + <translation><numerusform>%n dakika</numerusform><numerusform>%n dakika</numerusform></translation> + </message> + <message numerus="yes"> + <source>%n hour(s)</source> + <translation><numerusform>%n saat</numerusform><numerusform>%n saat</numerusform></translation> + </message> + <message numerus="yes"> + <source>%n day(s)</source> + <translation><numerusform>%n gün</numerusform><numerusform>%n gün</numerusform></translation> + </message> + <message numerus="yes"> + <source>%n week(s)</source> + <translation><numerusform>%n hafta</numerusform><numerusform>%n hafta</numerusform></translation> + </message> <message> <source>%1 and %2</source> <translation>%1 ve %2</translation> </message> - </context> + <message numerus="yes"> + <source>%n year(s)</source> + <translation><numerusform>%n yıl</numerusform><numerusform>%n yıl</numerusform></translation> + </message> + <message> + <source>%1 didn't yet exit safely...</source> + <translation>%1 henüz güvenli bir şekilde çıkış yapmamıştır...</translation> + </message> +</context> <context> <name>QObject::QObject</name> - </context> + <message> + <source>Error: Specified data directory "%1" does not exist.</source> + <translation>Hata: Belirtilen "%1" veri klasörü yoktur.</translation> + </message> + <message> + <source>Error: Cannot parse configuration file: %1. Only use key=value syntax.</source> + <translation>Hata: %1 yapılandırma dosyası ayrıştırılamadı. Sadece anahtar=değer dizimini kullanınız.</translation> + </message> + <message> + <source>Error: %1</source> + <translation>Hata: %1</translation> + </message> +</context> <context> <name>QRImageWidget</name> <message> <source>&Save Image...</source> <translation>Resmi ka&ydet...</translation> </message> - </context> + <message> + <source>&Copy Image</source> + <translation>Resmi &Kopyala</translation> + </message> + <message> + <source>Save QR Code</source> + <translation>QR Kodu Kaydet</translation> + </message> + <message> + <source>PNG Image (*.png)</source> + <translation>PNG Resim (*.png)</translation> + </message> +</context> <context> <name>RPCConsole</name> <message> @@ -1110,7 +1490,7 @@ </message> <message> <source>&Information</source> - <translation>&Malumat</translation> + <translation>&Bilgi</translation> </message> <message> <source>Debug window</source> @@ -1134,7 +1514,7 @@ </message> <message> <source>Network</source> - <translation>Şebeke</translation> + <translation>Ağ</translation> </message> <message> <source>Name</source> @@ -1158,7 +1538,7 @@ </message> <message> <source>Current number of transactions</source> - <translation>Güncel muamele sayısı</translation> + <translation>Güncel işlem sayısı</translation> </message> <message> <source>Memory usage</source> @@ -1202,7 +1582,7 @@ </message> <message> <source>Synced Headers</source> - <translation>Eşleşmiş Başlıklar</translation> + <translation>Eşleşmiş Üstbilgiler</translation> </message> <message> <source>Synced Blocks</source> @@ -1257,6 +1637,10 @@ <translation>Ping Beklemesi</translation> </message> <message> + <source>Min Ping</source> + <translation>En Düşük Ping</translation> + </message> + <message> <source>Time Offset</source> <translation>Saat Farkı</translation> </message> @@ -1274,7 +1658,7 @@ </message> <message> <source>&Network Traffic</source> - <translation>&Şebeke trafiği</translation> + <translation>&Ağ trafiği</translation> </message> <message> <source>&Clear</source> @@ -1317,18 +1701,38 @@ <translation>1 &yıl</translation> </message> <message> + <source>&Disconnect</source> + <translation>&Bağlantıyı Kes</translation> + </message> + <message> + <source>Ban for</source> + <translation>Yasakla</translation> + </message> + <message> + <source>&Unban</source> + <translation>&Yasaklamayı Kaldır</translation> + </message> + <message> <source>Welcome to the %1 RPC console.</source> <translation>%1 RPC konsoluna hoş geldiniz.</translation> </message> <message> <source>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</source> - <translation>Tarihçede gezinmek için imleç tuşlarını kullanınız, <b>Ctrl-L</b> ile de ekranı temizleyebilirsiniz.</translation> + <translation>Tarihçede gezinmek için aşağı ve yukarı ok tuşlarını kullanınız, <b>Ctrl-L</b> ile de ekranı temizleyebilirsiniz.</translation> </message> <message> <source>Type <b>help</b> for an overview of available commands.</source> <translation>Mevcut komutların listesi için <b>help</b> yazınız.</translation> </message> <message> + <source>WARNING: Scammers have been active, telling users to type commands here, stealing their wallet contents. Do not use this console without fully understanding the ramification of a command.</source> + <translation>UYARI: Bitcoin dolandırıcılarının çok fazla etkin olduğu zamanlarda, dolandırıcılar bazı kullanıcılara buraya komutlar yazmalarını söylerek onların cüzdanlarındaki bitcoinleri çalmışlardır. Bir komutun sonuçlarını tam olarak anlamadan bu konsolu kullanmayın.</translation> + </message> + <message> + <source>Network activity disabled</source> + <translation>Ağ etkinliği devre dışı bırakıldı</translation> + </message> + <message> <source>%1 B</source> <translation>%1 B</translation> </message> @@ -1381,7 +1785,7 @@ <name>ReceiveCoinsDialog</name> <message> <source>&Amount:</source> - <translation>&Meblağ:</translation> + <translation>&Tutar:</translation> </message> <message> <source>&Label:</source> @@ -1389,7 +1793,7 @@ </message> <message> <source>&Message:</source> - <translation>Me&saj:</translation> + <translation>&İleti:</translation> </message> <message> <source>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.</source> @@ -1401,7 +1805,7 @@ </message> <message> <source>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.</source> - <translation>Talep açıldığında gösterilecek, isteğinize dayalı, ödeme talebi ile ilişkilendirilecek bir mesaj. Not: Bu mesaj ödeme ile birlikte Bitcoin şebekesi üzerinden gönderilmeyecektir.</translation> + <translation>Talep açıldığında gösterilecek, isteğinize dayalı, ödeme talebi ile ilişkilendirilecek bir ileti. Not: Bu ileti ödeme ile birlikte Bitcoin ağı üzerinden gönderilmeyecektir.</translation> </message> <message> <source>An optional label to associate with the new receiving address.</source> @@ -1413,7 +1817,7 @@ </message> <message> <source>An optional amount to request. Leave this empty or zero to not request a specific amount.</source> - <translation>Seçiminize dayalı talep edilecek meblağ. Belli bir meblağ talep etmemek için bunu boş bırakın veya sıfır değerini kullanın.</translation> + <translation>Seçiminize dayalı talep edilecek tutar. Belli bir tutar talep etmemek için bunu boş bırakın veya sıfır değerini kullanın.</translation> </message> <message> <source>Clear all fields of the form.</source> @@ -1448,12 +1852,20 @@ <translation>Kaldır</translation> </message> <message> + <source>Copy URI</source> + <translation>URI'yi kopyala</translation> + </message> + <message> <source>Copy label</source> <translation>Etiket kopyala</translation> </message> <message> + <source>Copy message</source> + <translation>İletiyi kopyala</translation> + </message> + <message> <source>Copy amount</source> - <translation>Miktarı kopyala</translation> + <translation>Tutarı kopyala</translation> </message> </context> <context> @@ -1475,25 +1887,73 @@ <translation>Resmi ka&ydet...</translation> </message> <message> + <source>Request payment to %1</source> + <translation>%1 unsuruna ödeme talep et</translation> + </message> + <message> + <source>Payment information</source> + <translation>Ödeme bilgisi</translation> + </message> + <message> + <source>URI</source> + <translation>URI</translation> + </message> + <message> <source>Address</source> <translation>Adres</translation> </message> <message> + <source>Amount</source> + <translation>Tutar</translation> + </message> + <message> <source>Label</source> <translation>Etiket</translation> </message> - </context> + <message> + <source>Message</source> + <translation>İleti</translation> + </message> + <message> + <source>Resulting URI too long, try to reduce the text for label / message.</source> + <translation>Sonuç URI çok uzun, etiket ya da ileti metnini kısaltmayı deneyiniz.</translation> + </message> + <message> + <source>Error encoding URI into QR Code.</source> + <translation>URI'nin QR koduna kodlanmasında hata oluştu.</translation> + </message> +</context> <context> <name>RecentRequestsTableModel</name> <message> + <source>Date</source> + <translation>Tarih</translation> + </message> + <message> <source>Label</source> <translation>Etiket</translation> </message> <message> + <source>Message</source> + <translation>İleti</translation> + </message> + <message> <source>(no label)</source> <translation>(etiket yok)</translation> </message> - </context> + <message> + <source>(no message)</source> + <translation>(ileti yok)</translation> + </message> + <message> + <source>(no amount requested)</source> + <translation>(tutar talep edilmedi)</translation> + </message> + <message> + <source>Requested</source> + <translation>Talep edilen</translation> + </message> +</context> <context> <name>SendCoinsDialog</name> <message> @@ -1526,7 +1986,7 @@ </message> <message> <source>Amount:</source> - <translation>Meblağ:</translation> + <translation>Tutar:</translation> </message> <message> <source>Fee:</source> @@ -1550,7 +2010,7 @@ </message> <message> <source>Transaction Fee:</source> - <translation>Muamele ücreti:</translation> + <translation>İşlem ücreti:</translation> </message> <message> <source>Choose...</source> @@ -1566,11 +2026,11 @@ </message> <message> <source>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.</source> - <translation>Eğer özel ücret 1000 satoşi olarak ayarlandıysa ve muamele sadece 250 baytsa, "kilobayt başı" ücret olarak sadece 250 satoşi öder ve "toplam asgari" 1000 satoşi öder. Bir kilobayttan yüksek muameleler için ikisi de kilobayt başı ödeme yapar.</translation> + <translation>Eğer özel ücret 1000 satoşi olarak ayarlandıysa ve işlem sadece 250 baytsa, "kilobayt başı" ücret olarak sadece 250 satoşi öder ve "toplam asgari" 1000 satoşi öder. Bir kilobayttan yüksek işlemler için ikisi de kilobayt başı ödeme yapar.</translation> </message> <message> <source>Hide</source> - <translation>Sakla</translation> + <translation>Gizle</translation> </message> <message> <source>total at least</source> @@ -1578,7 +2038,7 @@ </message> <message> <source>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.</source> - <translation>Asgari ücreti ödemek, bloklarda boşluktan daha az muamele hacmi olduğu sürece bir sorun çıkarmaz. Fakat şebekenin işleyecebileceğinden daha çok bitcoin muameleleri talebi olduğunda bunun asla teyit edilmeyen bir muamele olabileceğinin farkında olmalısınız.</translation> + <translation>Gerekli olan en az ücreti ödemek, bloklarda boşluktan daha az işlem hacmi olduğu sürece bir sorun çıkarmaz. Fakat ağın işleyecebileceğinden daha çok bitcoin işlemi talebi olduğunda bunun asla doğrulanmayan bir işlem olabileceğinin farkında olmalısınız.</translation> </message> <message> <source>(read the tooltip)</source> @@ -1621,6 +2081,10 @@ <translation>Toz:</translation> </message> <message> + <source>Confirmation time target:</source> + <translation>Doğrulama süresi hedefi:</translation> + </message> + <message> <source>Clear &All</source> <translation>Tümünü &temizle</translation> </message> @@ -1637,10 +2101,118 @@ <translation>G&önder</translation> </message> <message> - <source>Copy amount</source> + <source>Copy quantity</source> <translation>Miktarı kopyala</translation> </message> <message> + <source>Copy amount</source> + <translation>Tutarı kopyala</translation> + </message> + <message> + <source>Copy fee</source> + <translation>Ücreti kopyala</translation> + </message> + <message> + <source>Copy after fee</source> + <translation>Ücretten sonrasını kopyala</translation> + </message> + <message> + <source>Copy bytes</source> + <translation>Baytları kopyala</translation> + </message> + <message> + <source>Copy dust</source> + <translation>Tozu kopyala</translation> + </message> + <message> + <source>Copy change</source> + <translation>Para üstünü kopyala</translation> + </message> + <message> + <source>%1 to %2</source> + <translation>%1 ögesinden %2 unsuruna</translation> + </message> + <message> + <source>Are you sure you want to send?</source> + <translation>Göndermek istediğinizden emin misiniz?</translation> + </message> + <message> + <source>added as transaction fee</source> + <translation>işlem ücreti olarak eklendi</translation> + </message> + <message> + <source>Total Amount %1</source> + <translation>Toplam Tutar %1</translation> + </message> + <message> + <source>or</source> + <translation>veya</translation> + </message> + <message> + <source>Confirm send coins</source> + <translation>Bitcoin gönderimini onaylayın</translation> + </message> + <message> + <source>The recipient address is not valid. Please recheck.</source> + <translation>Alıcı adresi geçerli değildir. Lütfen tekrar kontrol ediniz.</translation> + </message> + <message> + <source>The amount to pay must be larger than 0.</source> + <translation>Ödeyeceğiniz tutarın 0'dan yüksek olması gerekir.</translation> + </message> + <message> + <source>The amount exceeds your balance.</source> + <translation>Tutar bakiyenizden yüksektir.</translation> + </message> + <message> + <source>The total exceeds your balance when the %1 transaction fee is included.</source> + <translation>Toplam, %1 işlem ücreti eklendiğinde bakiyenizi geçmektedir.</translation> + </message> + <message> + <source>Duplicate address found: addresses should only be used once each.</source> + <translation>Tekrarlayan adres bulundu: adresler sadece bir kez kullanılmalıdır.</translation> + </message> + <message> + <source>Transaction creation failed!</source> + <translation>İşlem oluşturma başarısız!</translation> + </message> + <message> + <source>The transaction was rejected with the following reason: %1</source> + <translation>İşlem şu nedenden dolayı reddedildi: %1</translation> + </message> + <message> + <source>A fee higher than %1 is considered an absurdly high fee.</source> + <translation>%1 tutarından yüksek bir ücret saçma derecede yüksek bir ücret olarak kabul edilir.</translation> + </message> + <message> + <source>Payment request expired.</source> + <translation>Ödeme talebinin geçerlilik süresi bitti.</translation> + </message> + <message numerus="yes"> + <source>%n block(s)</source> + <translation><numerusform>%n blok</numerusform><numerusform>%n blok</numerusform></translation> + </message> + <message> + <source>Pay only the required fee of %1</source> + <translation>Sadece asgari ücret olan %1 tutarını öde</translation> + </message> + <message> + <source>Warning: Invalid Bitcoin address</source> + <translation>Uyarı: geçersiz Bitcoin adresi</translation> + </message> + <message> + <source>Warning: Unknown change address</source> + <translation>Uyarı: Bilinmeyen para üstü adresi</translation> + </message> + <message> + <source>Confirm custom change address</source> + <translation>Özel para üstü adresini onayla</translation> + </message> + <message> + <source>The address you selected for change is not part of this wallet. Any or all funds in your wallet may be sent to this address. Are you sure?</source> + <translation>Para üstü için seçtiğiniz adres bu cüzdanın bir parçası değil. Cüzdanınızdaki bir miktar veya tüm para bu adrese gönderilebilir. Emin misiniz?</translation> + </message> + <message> <source>(no label)</source> <translation>(etiket yok)</translation> </message> @@ -1649,7 +2221,7 @@ <name>SendCoinsEntry</name> <message> <source>A&mount:</source> - <translation>Mebla&ğ:</translation> + <translation>T&utar:</translation> </message> <message> <source>Pay &To:</source> @@ -1685,19 +2257,19 @@ </message> <message> <source>Remove this entry</source> - <translation>Bu unsuru kaldır</translation> + <translation>Bu ögeyi kaldır</translation> </message> <message> <source>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.</source> - <translation>Ücret yollanan meblağdan alınacaktır. Alıcı meblağ alanında girdiğinizden daha az bitcoin alacaktır. Eğer birden çok alıcı seçiliyse ücret eşit olarak bölünecektir.</translation> + <translation>Ücret yollanan tutardan alınacaktır. Alıcı tutar alanına girdiğinizden daha az bitcoin alacaktır. Eğer birden çok alıcı seçiliyse ücret eşit olarak bölünecektir.</translation> </message> <message> <source>S&ubtract fee from amount</source> - <translation>Ücreti meblağdan düş</translation> + <translation>Ücreti tutardan düş</translation> </message> <message> <source>Message:</source> - <translation>Mesaj:</translation> + <translation>İleti:</translation> </message> <message> <source>This is an unauthenticated payment request.</source> @@ -1713,7 +2285,7 @@ </message> <message> <source>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.</source> - <translation>Bitcoin: URI'siyle ilişkili ve bilginiz için muameleyle saklanacak bir mesaj. Not: Bu mesaj Bitcoin şebekesi üzerinden gönderilmeyecektir.</translation> + <translation>Referans için bitcoin: URI'siyle iliştirilmiş işlemle birlikte depolanacak bir ileti. Not: Bu mesaj Bitcoin ağı üzerinden gönderilmeyecektir.</translation> </message> <message> <source>Pay To:</source> @@ -1723,10 +2295,18 @@ <source>Memo:</source> <translation>Not:</translation> </message> - </context> + <message> + <source>Enter a label for this address to add it to your address book</source> + <translation>Adres defterinize eklemek için bu adrese bir etiket giriniz</translation> + </message> +</context> <context> <name>SendConfirmationDialog</name> - </context> + <message> + <source>Yes</source> + <translation>Evet</translation> + </message> +</context> <context> <name>ShutdownWindow</name> <message> @@ -1742,19 +2322,19 @@ <name>SignVerifyMessageDialog</name> <message> <source>Signatures - Sign / Verify a Message</source> - <translation>İmzalar - Mesaj İmzala / Kontrol et</translation> + <translation>İmzalar - İleti İmzala / Kontrol et</translation> </message> <message> <source>&Sign Message</source> - <translation>Mesaj &imzala</translation> + <translation>İleti &imzala</translation> </message> <message> <source>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.</source> - <translation>Adreslerinize yollanan bitcoinleri alabileceğiniz ispatlamak için adreslerinizle mesaj/anlaşma imzalayabilirsiniz. Oltalama saldırılarının kimliğinizi imzanızla elde etmeyi deneyebilecekleri için belirsiz ya da rastgele hiçbir şey imzalamamaya dikkat ediniz. Sadece ayrıntılı açıklaması olan ve tümüne katıldığınız ifadeleri imzalayınız.</translation> + <translation>Adreslerinize yollanan bitcoinleri alabileceğiniz ispatlamak için adreslerinizle iletiler/anlaşmalar imzalayabilirsiniz. Oltalama saldırılarının kimliğinizi imzanızla elde etmeyi deneyebilecekleri için belirsiz ya da rastgele hiçbir şey imzalamamaya dikkat ediniz. Sadece ayrıntılı açıklaması olan ve tümüne katıldığınız ifadeleri imzalayınız.</translation> </message> <message> <source>The Bitcoin address to sign the message with</source> - <translation>Mesajın imzalanmasında kullanılacak Bitcoin adresi</translation> + <translation>İletinin imzalanmasında kullanılacak Bitcoin adresi</translation> </message> <message> <source>Choose previously used address</source> @@ -1774,7 +2354,7 @@ </message> <message> <source>Enter the message you want to sign here</source> - <translation>İmzalamak istediğiniz mesajı burada giriniz</translation> + <translation>İmzalamak istediğiniz iletiyi burada giriniz</translation> </message> <message> <source>Signature</source> @@ -1786,15 +2366,15 @@ </message> <message> <source>Sign the message to prove you own this Bitcoin address</source> - <translation>Bu Bitcoin adresinin sizin olduğunu ispatlamak için mesajı imzalayın</translation> + <translation>Bu Bitcoin adresinin sizin olduğunu ispatlamak için iletiyi imzalayın</translation> </message> <message> <source>Sign &Message</source> - <translation>&Mesajı imzala</translation> + <translation>&İletiyi imzala</translation> </message> <message> <source>Reset all sign message fields</source> - <translation>Tüm mesaj alanlarını sıfırla</translation> + <translation>Tüm ileti alanlarını sıfırla</translation> </message> <message> <source>Clear &All</source> @@ -1802,29 +2382,81 @@ </message> <message> <source>&Verify Message</source> - <translation>Mesaj &kontrol et</translation> + <translation>İletiyi &kontrol et</translation> </message> <message> <source>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!</source> - <translation>Alıcının adresini, mesajı (satır sonları, boşluklar, sekmeler vs. karakterleri tam olarak kopyaladığınızdan emin olunuz) ve imzayı aşağıda giriniz. Bir ortadaki adam saldırısı tarafından kandırılmaya mâni olmak için imzadan, imzalı mesajın içeriğini aşan bir anlam çıkarmamaya dikkat ediniz. Bunun sadece imzalayan tarafın adres ile alım yapabildiğini ispatladığını ve herhangi bir muamelenin gönderi tarafını kanıtlayamayacağını unutmayınız!</translation> + <translation>Alıcının adresini, iletiyi (satır sonları, boşluklar, sekmeler vs. karakterleri tam olarak kopyaladığınızdan emin olunuz) ve imzayı aşağıya giriniz. Bir ortadaki adam saldırısı tarafından kandırılmaya engel olmak için imzadan, imzalı iletinin içeriğini aşan bir anlam çıkarmamaya dikkat ediniz. Bunun sadece imzalayan tarafın adres ile alım yapabildiğini ispatladığını ve herhangi bir işlemin gönderi tarafını kanıtlayamayacağını unutmayınız!</translation> </message> <message> <source>The Bitcoin address the message was signed with</source> - <translation>Mesajın imzalanmasında kullanılan Bitcoin adresi</translation> + <translation>İletinin imzalanmasında kullanılan Bitcoin adresi</translation> </message> <message> <source>Verify the message to ensure it was signed with the specified Bitcoin address</source> - <translation>Belirtilen Bitcoin adresi ile imzalandığını doğrulamak için mesajı kontrol et</translation> + <translation>Belirtilen Bitcoin adresi ile imzalandığını doğrulamak için iletiyi kontrol et</translation> </message> <message> <source>Verify &Message</source> - <translation>&Mesaj kontrol et</translation> + <translation>&İletiyi kontrol et</translation> </message> <message> <source>Reset all verify message fields</source> - <translation>Tüm mesaj kontrolü alanlarını sıfırla</translation> + <translation>Tüm ileti kontrolü alanlarını sıfırla</translation> + </message> + <message> + <source>Click "Sign Message" to generate signature</source> + <translation>İmzayı oluşturmak için "İletiyi İmzala"ya tıklayın</translation> + </message> + <message> + <source>The entered address is invalid.</source> + <translation>Girilen adres geçersizdir.</translation> + </message> + <message> + <source>Please check the address and try again.</source> + <translation>Lütfen adresi kontrol edip tekrar deneyiniz.</translation> </message> - </context> + <message> + <source>The entered address does not refer to a key.</source> + <translation>Girilen adres herhangi bir anahtara işaret etmemektedir.</translation> + </message> + <message> + <source>Wallet unlock was cancelled.</source> + <translation>Cüzdan kilidinin açılması iptal edildi.</translation> + </message> + <message> + <source>Private key for the entered address is not available.</source> + <translation>Girilen adres için özel anahtar mevcut değildir.</translation> + </message> + <message> + <source>Message signing failed.</source> + <translation>İleti imzalaması başarısız oldu.</translation> + </message> + <message> + <source>Message signed.</source> + <translation>İleti imzalandı.</translation> + </message> + <message> + <source>The signature could not be decoded.</source> + <translation>İmzanın kodu çözülemedi.</translation> + </message> + <message> + <source>Please check the signature and try again.</source> + <translation>Lütfen imzayı kontrol edip tekrar deneyiniz.</translation> + </message> + <message> + <source>The signature did not match the message digest.</source> + <translation>İmza iletinin özeti ile eşleşmedi.</translation> + </message> + <message> + <source>Message verification failed.</source> + <translation>İleti doğrulaması başarısız oldu.</translation> + </message> + <message> + <source>Message verified.</source> + <translation>İleti doğrulandı.</translation> + </message> +</context> <context> <name>SplashScreen</name> <message> @@ -1841,28 +2473,368 @@ </context> <context> <name>TransactionDesc</name> - </context> + <message numerus="yes"> + <source>Open for %n more block(s)</source> + <translation><numerusform>%n taneden daha fazla blok için açık</numerusform><numerusform>%n taneden daha fazla blok için açık</numerusform></translation> + </message> + <message> + <source>Open until %1</source> + <translation>%1 değerine dek açık</translation> + </message> + <message> + <source>conflicted with a transaction with %1 confirmations</source> + <translation>%1 doğrulamalı bir işlem ile çelişti</translation> + </message> + <message> + <source>%1/offline</source> + <translation>%1/çevrim dışı</translation> + </message> + <message> + <source>0/unconfirmed, %1</source> + <translation>0/doğrulanmamış, %1</translation> + </message> + <message> + <source>in memory pool</source> + <translation>bellek alanında</translation> + </message> + <message> + <source>not in memory pool</source> + <translation>bellek alanında değil</translation> + </message> + <message> + <source>abandoned</source> + <translation>terk edilmiş</translation> + </message> + <message> + <source>%1/unconfirmed</source> + <translation>%1/doğrulanmadı</translation> + </message> + <message> + <source>%1 confirmations</source> + <translation>%1 doğrulama</translation> + </message> + <message> + <source>Status</source> + <translation>Durum</translation> + </message> + <message> + <source>, has not been successfully broadcast yet</source> + <translation>, henüz başarılı bir şekilde yayınlanmadı</translation> + </message> + <message numerus="yes"> + <source>, broadcast through %n node(s)</source> + <translation><numerusform>, %n düğüm aracılığıyla yayınlandı</numerusform><numerusform>, %n düğüm aracılığıyla yayınlandı</numerusform></translation> + </message> + <message> + <source>Date</source> + <translation>Tarih</translation> + </message> + <message> + <source>Source</source> + <translation>Kaynak</translation> + </message> + <message> + <source>Generated</source> + <translation>Oluşturuldu</translation> + </message> + <message> + <source>From</source> + <translation>Gönderen</translation> + </message> + <message> + <source>unknown</source> + <translation>bilinmiyor</translation> + </message> + <message> + <source>To</source> + <translation>Alıcı</translation> + </message> + <message> + <source>own address</source> + <translation>kendi adresiniz</translation> + </message> + <message> + <source>watch-only</source> + <translation>sadece-izlenen</translation> + </message> + <message> + <source>label</source> + <translation>etiket</translation> + </message> + <message> + <source>Credit</source> + <translation>Alınan Tutar</translation> + </message> + <message numerus="yes"> + <source>matures in %n more block(s)</source> + <translation><numerusform>%n ek blok sonrasında olgunlaşacak</numerusform><numerusform>%n ek blok sonrasında olgunlaşacak</numerusform></translation> + </message> + <message> + <source>not accepted</source> + <translation>kabul edilmedi</translation> + </message> + <message> + <source>Debit</source> + <translation>Çekilen Tutar</translation> + </message> + <message> + <source>Total debit</source> + <translation>Toplam çekilen tutar</translation> + </message> + <message> + <source>Total credit</source> + <translation>Toplam alınan tutar</translation> + </message> + <message> + <source>Transaction fee</source> + <translation>İşlem ücreti</translation> + </message> + <message> + <source>Net amount</source> + <translation>Net tutar</translation> + </message> + <message> + <source>Message</source> + <translation>İleti</translation> + </message> + <message> + <source>Comment</source> + <translation>Yorum</translation> + </message> + <message> + <source>Transaction ID</source> + <translation>İşlem ID'si</translation> + </message> + <message> + <source>Transaction total size</source> + <translation>İşlemin toplam boyutu</translation> + </message> + <message> + <source>Output index</source> + <translation>Çıktı indeksi</translation> + </message> + <message> + <source>Merchant</source> + <translation>Tüccar</translation> + </message> + <message> + <source>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.</source> + <translation>Oluşturulan bitcoin'lerin harcanabilmelerinden önce %1 blok beklemeleri gerekmektedir. Bu blok, oluşturduğunuzda, blok zincirine eklenmesi için ağda yayınlandı. Zincire eklenmesi başarısız olursa, durumu "kabul edilmedi" olarak değiştirilecek ve harcanamayacaktır. Bu, bazen başka bir düğüm sizden birkaç saniye önce ya da sonra blok oluşturursa meydana gelebilir.</translation> + </message> + <message> + <source>Debug information</source> + <translation>Hata ayıklama bilgisi</translation> + </message> + <message> + <source>Transaction</source> + <translation>İşlem</translation> + </message> + <message> + <source>Inputs</source> + <translation>Girdiler</translation> + </message> + <message> + <source>Amount</source> + <translation>Tutar</translation> + </message> + <message> + <source>true</source> + <translation>doğru</translation> + </message> + <message> + <source>false</source> + <translation>yanlış</translation> + </message> +</context> <context> <name>TransactionDescDialog</name> <message> <source>This pane shows a detailed description of the transaction</source> - <translation>Bu pano muamelenin ayrıntılı açıklamasını gösterir</translation> + <translation>Bu pano işlemin ayrıntılı açıklamasını gösterir</translation> + </message> + <message> + <source>Details for %1</source> + <translation>%1 için ayrıntılar</translation> </message> - </context> +</context> <context> <name>TransactionTableModel</name> <message> + <source>Date</source> + <translation>Tarih</translation> + </message> + <message> + <source>Type</source> + <translation>Tür</translation> + </message> + <message> <source>Label</source> <translation>Etiket</translation> </message> + <message numerus="yes"> + <source>Open for %n more block(s)</source> + <translation><numerusform>%n taneden daha fazla blok için açık</numerusform><numerusform>%n taneden daha fazla blok için açık</numerusform></translation> + </message> + <message> + <source>Open until %1</source> + <translation>%1 değerine dek açık</translation> + </message> + <message> + <source>Offline</source> + <translation>Çevrim dışı</translation> + </message> + <message> + <source>Unconfirmed</source> + <translation>Doğrulanmamış</translation> + </message> + <message> + <source>Abandoned</source> + <translation>Terk edilmiş</translation> + </message> + <message> + <source>Confirming (%1 of %2 recommended confirmations)</source> + <translation>Doğrulanıyor (%1 kere doğrulandı, önerilen doğrulama sayısı %2)</translation> + </message> + <message> + <source>Confirmed (%1 confirmations)</source> + <translation>Doğrulandı (%1 doğrulama)</translation> + </message> + <message> + <source>Conflicted</source> + <translation>Uyuşmadı</translation> + </message> + <message> + <source>Immature (%1 confirmations, will be available after %2)</source> + <translation>Olgunlaşmamış (%1 doğrulama, %2 doğrulama sonra kullanılabilir olacaktır)</translation> + </message> + <message> + <source>This block was not received by any other nodes and will probably not be accepted!</source> + <translation>Bu blok başka hiçbir düğüm tarafından alınmamıştır ve muhtemelen kabul edilmeyecektir!</translation> + </message> + <message> + <source>Generated but not accepted</source> + <translation>Oluşturuldu ama kabul edilmedi</translation> + </message> + <message> + <source>Received with</source> + <translation>Şununla alındı</translation> + </message> + <message> + <source>Received from</source> + <translation>Alındığı kişi</translation> + </message> + <message> + <source>Sent to</source> + <translation>Gönderildiği adres</translation> + </message> + <message> + <source>Payment to yourself</source> + <translation>Kendinize ödeme</translation> + </message> + <message> + <source>Mined</source> + <translation>Madenden çıkarılan</translation> + </message> + <message> + <source>watch-only</source> + <translation>sadece-izlenen</translation> + </message> + <message> + <source>(n/a)</source> + <translation>(mevcut değil)</translation> + </message> <message> <source>(no label)</source> <translation>(etiket yok)</translation> </message> - </context> + <message> + <source>Transaction status. Hover over this field to show number of confirmations.</source> + <translation>İşlem durumu. Doğrulama sayısını görüntülemek için fare imlecini bu alanın üzerinde tutunuz.</translation> + </message> + <message> + <source>Date and time that the transaction was received.</source> + <translation>İşlemin alındığı tarih ve zaman.</translation> + </message> + <message> + <source>Type of transaction.</source> + <translation>İşlemin türü.</translation> + </message> + <message> + <source>Whether or not a watch-only address is involved in this transaction.</source> + <translation>Bu işleme sadece-izlenen bir adresin dahil edilip, edilmediği.</translation> + </message> + <message> + <source>User-defined intent/purpose of the transaction.</source> + <translation>İşlemin kullanıcı tanımlı amacı.</translation> + </message> + <message> + <source>Amount removed from or added to balance.</source> + <translation>Bakiyeden kaldırılan ya da bakiyeye eklenen tutar.</translation> + </message> +</context> <context> <name>TransactionView</name> <message> + <source>All</source> + <translation>Hepsi</translation> + </message> + <message> + <source>Today</source> + <translation>Bugün</translation> + </message> + <message> + <source>This week</source> + <translation>Bu hafta</translation> + </message> + <message> + <source>This month</source> + <translation>Bu ay</translation> + </message> + <message> + <source>Last month</source> + <translation>Geçen ay</translation> + </message> + <message> + <source>This year</source> + <translation>Bu yıl</translation> + </message> + <message> + <source>Range...</source> + <translation>Tarih Aralığı</translation> + </message> + <message> + <source>Received with</source> + <translation>Şununla alındı</translation> + </message> + <message> + <source>Sent to</source> + <translation>Gönderildiği adres</translation> + </message> + <message> + <source>To yourself</source> + <translation>Kendinize</translation> + </message> + <message> + <source>Mined</source> + <translation>Madenden çıkarılan</translation> + </message> + <message> + <source>Other</source> + <translation>Diğer</translation> + </message> + <message> + <source>Enter address or label to search</source> + <translation>Aranacak adres ya da etiket giriniz</translation> + </message> + <message> + <source>Min amount</source> + <translation>En düşük tutar</translation> + </message> + <message> + <source>Abandon transaction</source> + <translation>İşlemden vazgeç</translation> + </message> + <message> <source>Copy address</source> <translation>Adres kopyala</translation> </message> @@ -1872,7 +2844,51 @@ </message> <message> <source>Copy amount</source> - <translation>Miktarı kopyala</translation> + <translation>Tutarı kopyala</translation> + </message> + <message> + <source>Copy transaction ID</source> + <translation>İşlem ID'sini kopyala</translation> + </message> + <message> + <source>Copy raw transaction</source> + <translation>Ham işlemi kopyala</translation> + </message> + <message> + <source>Copy full transaction details</source> + <translation>Tüm işlem ayrıntılarını kopyala</translation> + </message> + <message> + <source>Edit label</source> + <translation>Etiketi düzenle</translation> + </message> + <message> + <source>Show transaction details</source> + <translation>İşlem ayrıntılarını göster</translation> + </message> + <message> + <source>Export Transaction History</source> + <translation>İşlem Tarihçesini Dışarı Aktar</translation> + </message> + <message> + <source>Comma separated file (*.csv)</source> + <translation>Virgülle ayrılmış değerler dosyası (*.csv)</translation> + </message> + <message> + <source>Confirmed</source> + <translation>Doğrulandı</translation> + </message> + <message> + <source>Watch-only</source> + <translation>Sadece izlenen</translation> + </message> + <message> + <source>Date</source> + <translation>Tarih</translation> + </message> + <message> + <source>Type</source> + <translation>Tür</translation> </message> <message> <source>Label</source> @@ -1883,26 +2899,90 @@ <translation>Adres</translation> </message> <message> + <source>ID</source> + <translation>ID</translation> + </message> + <message> <source>Exporting Failed</source> <translation>Dışarı aktarmada hata</translation> </message> - </context> + <message> + <source>There was an error trying to save the transaction history to %1.</source> + <translation>İşlem tarihçesinin %1 konumuna kaydedilmeye çalışıldığı sırada bir hata meydana geldi.</translation> + </message> + <message> + <source>Exporting Successful</source> + <translation>Dışarı Aktarma Başarılı</translation> + </message> + <message> + <source>The transaction history was successfully saved to %1.</source> + <translation>İşlem tarihçesi %1 konumuna başarıyla kaydedildi.</translation> + </message> + <message> + <source>Range:</source> + <translation>Tarih Aralığı:</translation> + </message> + <message> + <source>to</source> + <translation>Alıcı</translation> + </message> +</context> <context> <name>UnitDisplayStatusBarControl</name> <message> <source>Unit to show amounts in. Click to select another unit.</source> - <translation>Meblağları göstermek için birim. Başka bir birim seçmek için tıklayınız.</translation> + <translation>Tutarı göstermek için birim. Başka bir birim seçmek için tıklayınız.</translation> </message> </context> <context> <name>WalletFrame</name> - </context> + <message> + <source>No wallet has been loaded.</source> + <translation>Hiçbir cüzdan yüklenmedi.</translation> + </message> +</context> <context> <name>WalletModel</name> - </context> + <message> + <source>Send Coins</source> + <translation>Bitcoini Gönder</translation> + </message> +</context> <context> <name>WalletView</name> - </context> + <message> + <source>&Export</source> + <translation>&Dışarı aktar</translation> + </message> + <message> + <source>Export the data in the current tab to a file</source> + <translation>Mevcut sekmedeki verileri bir dosyaya aktar</translation> + </message> + <message> + <source>Backup Wallet</source> + <translation>Cüzdanı Yedekle</translation> + </message> + <message> + <source>Wallet Data (*.dat)</source> + <translation>Cüzdan Verileri (*.dat)</translation> + </message> + <message> + <source>Backup Failed</source> + <translation>Yedekleme Başarısız Oldu</translation> + </message> + <message> + <source>There was an error trying to save the wallet data to %1.</source> + <translation>Cüzdan verilerinin %1 konumuna kaydedilmesi sırasında bir hata meydana geldi.</translation> + </message> + <message> + <source>Backup Successful</source> + <translation>Yedekleme Başarılı</translation> + </message> + <message> + <source>The wallet data was successfully saved to %1.</source> + <translation>Cüzdan verileri %1 konumuna başarıyla kaydedildi.</translation> + </message> +</context> <context> <name>bitcoin-core</name> <message> @@ -1926,12 +3006,24 @@ <translation>Komut satırı ve JSON-RPC komutlarını kabul et</translation> </message> <message> + <source>Accept connections from outside (default: 1 if no -proxy or -connect/-noconnect)</source> + <translation>Dışarıdan gelen bağlantıları kabul et (varsayılan: 1 eğer -proxy veya -connect/-noconnect yoksa)</translation> + </message> + <message> + <source>Connect only to the specified node(s); -noconnect or -connect=0 alone to disable automatic connections</source> + <translation>-noconnect ile yalnızca belirtilen düğümleri bağlayın veya yalnız otomatik bağlantıları devre dışı bırakmak için -connect=0 kullanın.</translation> + </message> + <message> + <source>Distributed under the MIT software license, see the accompanying file %s or %s</source> + <translation>MIT yazılım lisansı altında dağıtılmıştır, beraberindeki %s ya da %s dosyasına bakınız.</translation> + </message> + <message> <source>If <category> is not supplied or if <category> = 1, output all debugging information.</source> - <translation>Eğer <kategori> belirtilmemişse ya da <kategori> = 1 ise, tüm hata ayıklama verilerini dök.</translation> + <translation>Eğer <kategori> belirtilmemişse ya da <kategori> = 1 ise, tüm hata ayıklama verilerini çıktı al.</translation> </message> <message> <source>Prune configured below the minimum of %d MiB. Please use a higher number.</source> - <translation>Budama, asgari değer olan %d MiB'den düşük olarak ayarlanmıştır. Lütfen daha yüksek bir sayı kullanınız.</translation> + <translation>Budama, en düşük değer olan %d MiB'den düşük olarak ayarlanmıştır. Lütfen daha yüksek bir sayı kullanınız.</translation> </message> <message> <source>Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node)</source> @@ -1947,7 +3039,7 @@ </message> <message> <source>Fee (in %s/kB) to add to transactions you send (default: %s)</source> - <translation>Yolladığınız muamelelere eklenecek ücret (%s/kB olarak) (varsayılan: %s)</translation> + <translation>Yolladığınız işlemlere eklenecek ücret (%s/kB olarak) (varsayılan: %s)</translation> </message> <message> <source>Pruning blockstore...</source> @@ -1975,7 +3067,7 @@ </message> <message> <source>Accept relayed transactions received from whitelisted peers even when not relaying transactions (default: %d)</source> - <translation>Muameleler aktarılmadığında dahi beyaz listedeki eşlerden aktarılan muameleleri kabul et (varsayılan: %d)</translation> + <translation>İşlemler aktarılmadığında dahi beyaz listedeki eşlerden aktarılan işlemleri kabul et (varsayılan: %d)</translation> </message> <message> <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source> @@ -1987,7 +3079,7 @@ </message> <message> <source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source> - <translation>Tüm cüzdan muamelelerini sil ve başlangıçta -rescan ile sadece blok zincirinin parçası olanları geri getir</translation> + <translation>Tüm cüzdan işlemlerini sil ve başlangıçta -rescan ile sadece blok zincirinin parçası olanları geri getir</translation> </message> <message> <source>Error loading %s: You can't enable HD on a already existing non-HD wallet</source> @@ -1995,19 +3087,27 @@ </message> <message> <source>Error reading %s! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source> - <translation>%s 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.</translation> + <translation>%s dosyasının okunması sırasında bir hata meydana geldi! Tüm anahtarlar doğru bir şekilde okundu, ancak işlem verileri ya da adres defteri ögeleri hatalı veya eksik olabilir.</translation> </message> <message> <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> - <translation>Bir cüzdan muamelesi değiştiğinde komutu çalıştır (komuttaki %s muamele kimliği ile değiştirilecektir)</translation> + <translation>Bir cüzdan işlemi değiştiğinde komutu çalıştır (komuttaki %s işlem kimliği ile değiştirilecektir)</translation> + </message> + <message> + <source>Extra transactions to keep in memory for compact block reconstructions (default: %u)</source> + <translation>Daha küçük boyutlu blok yeniden yapılandırması için fazladan işlemleri bellekte tut. (varsayılan: %u)</translation> + </message> + <message> + <source>If this block is in the chain assume that it and its ancestors are valid and potentially skip their script verification (0 to verify all, default: %s, testnet: %s)</source> + <translation>Eğer bu blok zincirde yer alıyorsa onun ve atalarının geçerli olduğunu varsay ve potansiyel olarak onların betik doğrulamasını atla. (Tümünü doğrulamak için 0, varsayılan %s, testnet: %s)</translation> </message> <message> <source>Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds)</source> - <translation>Müsaade edilen azami medyan eş zamanı değişiklik sınırının ayarlaması. Zamanın yerel perspektifi bu miktar kadar ileri ya da geri eşler tarafından etkilenebilir. (Varsayılan %u saniye)</translation> + <translation>İzin verilen edilen en yüksek medyan eş zamanı değişiklik sınırının ayarlaması. Zamanın yerel perspektifi bu miktar kadar ileri ya da geri eşler tarafından etkilenebilir. (Varsayılan %u saniye)</translation> </message> <message> <source>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)</source> - <translation>Tek cüzdan muamelesinde ya da ham muamelede kullanılacak azami toplam ücret (%s olarak); bunu çok düşük olarak ayarlamak büyük muameleleri iptal edebilir (varsayılan: %s)</translation> + <translation>Tek bir cüzdan işleminde ya da ham işlemde kullanılacak en yüksek toplam ücret (%s olarak); bunu çok düşük olarak ayarlamak büyük işlemleri iptal edebilir (varsayılan: %s)</translation> </message> <message> <source>Please check that your computer's date and time are correct! If your clock is wrong, %s will not work properly.</source> @@ -2018,6 +3118,14 @@ <translation>%s programını faydalı buluyorsanız lütfen katkıda bulununuz. Yazılım hakkında daha fazla bilgi için %s adresini ziyaret ediniz.</translation> </message> <message> + <source>Reduce storage requirements by enabling pruning (deleting) of old blocks. This allows the pruneblockchain RPC to be called to delete specific blocks, and enables automatic pruning of old blocks if a target size in MiB is provided. This mode is incompatible with -txindex and -rescan. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, 1 = allow manual pruning via RPC, >%u = automatically prune block files to stay under the specified target size in MiB)</source> + <translation>Eski blokları budamayı (silme) etkinleştirerek depolama gereksinimlerini azaltın. Bu belirli blokları silmek için pruneblockchain uzak yordam çağrısına (RPC) izin verir. Eğer bloklar hedef mebibyte boyutuna ulaşırsa eski blokların otomatik olarak budanmasını sağlar. Bu kip, -txindex ve -rescan ile uyumsuzdur. Uyarı: Bu ayarı geri almak, blok zincirinin tamamını yeniden yüklemeyi gerektirir. (varsayılan: 0 = blok budaması devre dışı, 1 = RPC üzerinden manuel budamaya izin verir, >%u = mebibyte olarak belirtilen hedef boyutun altında kalması için blok dosyalarını otomatik olarak budar)</translation> + </message> + <message> + <source>Set lowest fee rate (in %s/kB) for transactions to be included in block creation. (default: %s)</source> + <translation>Blok oluşturmaya dahil olan işlemler için en düşük ücret oranını (%s/kB olarak) ayarla. (varsayılan: %s)</translation> + </message> + <message> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> <translation>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)</translation> </message> @@ -2026,6 +3134,10 @@ <translation>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.</translation> </message> <message> + <source>This is a pre-release test build - use at your own risk - do not use for mining or merchant applications</source> + <translation>Bu kararlı sürümden önceki bir deneme sürümüdür. - risklerini bilerek kullanma sorumluluğu sizdedir - bitcoin oluşturmak ya da ticari uygulamalar için kullanmayınız</translation> + </message> + <message> <source>Unable to rewind the database to a pre-fork state. You will need to redownload the blockchain</source> <translation>Veritabanını çatallama öncesi duruma geri sarmak mümkün değil. Blok zincirini tekrar indirmeniz gerekmektedir</translation> </message> @@ -2034,6 +3146,22 @@ <translation>Dinlenecek portu haritalamak için UPnP kullan (varsayılan: dinlenildiğinde ve -proxy olmadığında 1)</translation> </message> <message> + <source>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. The client then connects normally using the rpcuser=<USERNAME>/rpcpassword=<PASSWORD> pair of arguments. This option can be specified multiple times</source> + <translation>JSON-RPC bağlantıları için kullanıcı adı ve karmalanmış parola. <userpw> alanı şu biçimdedir: <KULLANICI ADI>:<SALT>$<HASH>. Kanonik bir Python betiği share/rpcuser klasöründe bulunabilir. Ardından istemci normal şekilde rpcuser=<KULLANICI ADI>/rpcpassword=<PAROLA> argüman çiftini kullanarak bağlanabilir. Bu seçenek birden çok kez belirtilebilir.</translation> + </message> + <message> + <source>Wallet will not create transactions that violate mempool chain limits (default: %u)</source> + <translation>Cüzdan, zincir bellek alanı limitlerini ihlal eden işlem oluşturmayacak. (varsayılan: %u)</translation> + </message> + <message> + <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source> + <translation>Uyarı: Ağ üyeleri aralarında tamamen anlaşmış gibi gözükmüyor! Bazı madenciler sorun yaşıyor gibi görünmektedir.</translation> + </message> + <message> + <source>Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade.</source> + <translation>Uyarı: Ağ eşlerimizle tamamen anlaşamamışız gibi görünüyor! Güncelleme yapmanız gerekebilir ya da diğer düğümlerin güncelleme yapmaları gerekebilir.</translation> + </message> + <message> <source>You need to rebuild the database using -reindex-chainstate to change -txindex</source> <translation>-txindex'i değiştirmek için veritabanını -reindex-chainstate kullanarak tekrar inşa etmeniz gerekmektedir</translation> </message> @@ -2043,7 +3171,7 @@ </message> <message> <source>-maxmempool must be at least %d MB</source> - <translation>-maxmempool asgari %d MB olmalıdır</translation> + <translation>-maxmempool en az %d MB olmalıdır</translation> </message> <message> <source><category> can be:</source> @@ -2066,8 +3194,12 @@ <translation>Çözümlenemedi - %s adres: '%s'</translation> </message> <message> + <source>Chain selection options:</source> + <translation>Blok zinciri seçim ayarları:</translation> + </message> + <message> <source>Change index out of range</source> - <translation>Aralık dışında değişiklik endeksi</translation> + <translation>Aralık dışında değişiklik indeksi</translation> </message> <message> <source>Connection options:</source> @@ -2099,7 +3231,7 @@ </message> <message> <source>Enable publish hash transaction in <address></source> - <translation>Karma değer muamelesinin <adres>te yayınlanmasını etkinleştir</translation> + <translation>Karma değer işleminin <adres>te yayınlanmasını etkinleştir</translation> </message> <message> <source>Enable publish raw block in <address></source> @@ -2107,11 +3239,11 @@ </message> <message> <source>Enable publish raw transaction in <address></source> - <translation>Ham muamelenin <adres>te yayınlanmasını etkinleştir</translation> + <translation>Ham işlemin <adres>te yayınlanmasını etkinleştir</translation> </message> <message> <source>Enable transaction replacement in the memory pool (default: %u)</source> - <translation>Bellek alanında muamele değiştirmeyi etkinleştir (varsayılan: %u)</translation> + <translation>Bellek alanında işlem değiştirmeyi etkinleştir (varsayılan: %u)</translation> </message> <message> <source>Error initializing block database</source> @@ -2159,7 +3291,7 @@ </message> <message> <source>Incorrect or no genesis block found. Wrong datadir for network?</source> - <translation>Yanlış ya da bulunamamış doğuş bloku. Şebeke için yanlış veri klasörü mü?</translation> + <translation>Yanlış ya da bulunamamış doğuş bloğu. Ağ için yanlış veri klasörü mü?</translation> </message> <message> <source>Initialization sanity check failed. %s is shutting down.</source> @@ -2171,15 +3303,15 @@ </message> <message> <source>Invalid amount for -%s=<amount>: '%s'</source> - <translation>-%s=<meblağ> için geçersiz meblağ: '%s'</translation> + <translation>-%s=<tutar> için geçersiz tutar: '%s'</translation> </message> <message> <source>Invalid amount for -fallbackfee=<amount>: '%s'</source> - <translation> -fallbackfee=<meblağ> için geçersiz meblağ: '%s'</translation> + <translation> -fallbackfee=<tutar> için geçersiz tutar: '%s'</translation> </message> <message> <source>Keep the transaction memory pool below <n> megabytes (default: %u)</source> - <translation>Muamele bellek alanını <n> megabayttan düşük tut (varsayılan: %u)</translation> + <translation>İşlem bellek alanını <n> megabayttan düşük tut (varsayılan: %u)</translation> </message> <message> <source>Loading banlist...</source> @@ -2195,7 +3327,7 @@ </message> <message> <source>Only connect to nodes in network <net> (ipv4, ipv6 or onion)</source> - <translation>Sadece <net> şebekesindeki düğümlere bağlan (ipv4, ipv6 veya onion)</translation> + <translation>Sadece <net> ağındaki düğümlere bağlan (ipv4, ipv6 veya onion)</translation> </message> <message> <source>Print this help message and exit</source> @@ -2215,11 +3347,11 @@ </message> <message> <source>Rebuild chain state and block index from the blk*.dat files on disk</source> - <translation>Zincir durumu ve blok endeksini diskteki blk*.dat dosyalarından yeniden derle</translation> + <translation>Zincir durumu ve blok indeksini diskteki blk*.dat dosyalarından yeniden derle</translation> </message> <message> <source>Rebuild chain state from the currently indexed blocks</source> - <translation>Zincir durumunu güncel olarak endekslenen bloklardan yeniden derle</translation> + <translation>Zincir durumunu güncel olarak indekslenen bloklardan yeniden derle</translation> </message> <message> <source>Rewinding blocks...</source> @@ -2231,7 +3363,7 @@ </message> <message> <source>Set maximum block size in bytes (default: %d)</source> - <translation>Azami blok boyutunu bayt olarak ayarla (varsayılan: %d)</translation> + <translation>En yüksek blok boyutunu bayt olarak ayarla (varsayılan: %d)</translation> </message> <message> <source>Specify wallet file (within data directory)</source> @@ -2262,6 +3394,10 @@ <translation>Dinleme portunu haritalamak için UPnP kullan (varsayılan: %u)</translation> </message> <message> + <source>Use the test chain</source> + <translation>Test blok zincirini kullan</translation> + </message> + <message> <source>User Agent comment (%s) contains unsafe characters.</source> <translation>Kullanıcı Aracı açıklaması (%s) güvensiz karakterler içermektedir.</translation> </message> @@ -2291,7 +3427,7 @@ </message> <message> <source>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</source> - <translation>Belirtilen kaynaktan JSON-RPC bağlantılarını kabul et. Bir <ip> için geçerli olanlar şunlardır: salt IP adresi (mesela 1.2.3.4), bir şebeke/ağ maskesi (örneğin 1.2.3.4/255.255.255.0) ya da bir şebeke/CIDR (mesela 1.2.3.4/24). Bu seçenek birden fazla kez belirtilebilir</translation> + <translation>Belirtilen kaynaktan JSON-RPC bağlantılarını kabul et. Bir <ip> için geçerli olanlar şunlardır: IP adresi (mesela 1.2.3.4), bir ağ/ağ maskesi (örneğin 1.2.3.4/255.255.255.0) ya da bir ağ/CIDR (mesela 1.2.3.4/24). Bu seçenek birden fazla kez belirtilebilir</translation> </message> <message> <source>Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6</source> @@ -2319,19 +3455,19 @@ </message> <message> <source>Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s)</source> - <translation>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)</translation> + <translation>Bundan düşük ücretler (%s/kB olarak) aktarma, oluşturma ve işlem yaratma için sıfır değerinde ücret olarak kabul edilir (varsayılan: %s)</translation> </message> <message> <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> - <translation>Eğer paytxfee ayarlanmadıysa kafi derecede ücret ekleyin ki muameleler teyite vasati n blok içinde başlasın (varsayılan: %u)</translation> + <translation>Eğer paytxfee ayarlanmadıysa kafi derecede ücret ekleyin ki işlemler teyite vasati n blok içinde başlasın (varsayılan: %u)</translation> </message> <message> <source>Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)</source> - <translation>-maxtxfee=<tutar> için geçersiz tutar: '%s' (Sıkışmış muameleleri önlemek için en az %s değerinde asgari aktarım ücretine eşit olmalıdır)</translation> + <translation>-maxtxfee=<tutar> için geçersiz tutar: '%s' (Sıkışmış işlemleri önlemek için en az %s değerinde en düşük aktarım ücretine eşit olmalıdır)</translation> </message> <message> <source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source> - <translation>Aktardığımız ve oluşturduğumuz veri taşıyıcı muamelelerindeki azami veri boyutu (varsayılan: %u)</translation> + <translation>Aktardığımız ve oluşturduğumuz veri taşıyıcı işlemlerindeki en yüksek veri boyutu (varsayılan: %u)</translation> </message> <message> <source>Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)</source> @@ -2339,11 +3475,11 @@ </message> <message> <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source> - <translation>Yüksek öncelikli/düşük ücretli muamelelerin azami boyutunu bayt olarak ayarla (varsayılan: %d)</translation> + <translation>Yüksek öncelikli/düşük ücretli işlemlerin en yüksek boyutunu bayt olarak ayarla (varsayılan: %d)</translation> </message> <message> <source>The transaction amount is too small to send after the fee has been deducted</source> - <translation>Bu muamele, ücret düşüldükten sonra göndermek için çok düşük</translation> + <translation>Bu işlem, tutar düşüldükten sonra göndermek için çok düşük</translation> </message> <message> <source>Use hierarchical deterministic key generation (HD) after BIP32. Only has effect during wallet creation/first start</source> @@ -2351,7 +3487,7 @@ </message> <message> <source>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</source> - <translation>Beyaz listeye alınan eşler DoS yasaklamasına uğramazlar ve muameleleri zaten mempool'da olsalar da daima aktarılır, bu mesela bir geçit için kullanışlıdır</translation> + <translation>Beyaz listeye alınan eşler DoS yasaklamasına uğramazlar ve işlemleri zaten mempool'da olsalar da daima aktarılır, bu mesela bir geçit için kullanışlıdır</translation> </message> <message> <source>You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source> @@ -2395,7 +3531,7 @@ </message> <message> <source>Keep at most <n> unconnectable transactions in memory (default: %u)</source> - <translation>Hafızada en çok <n> bağlanılamaz muamele tut (varsayılan: %u)</translation> + <translation>Hafızada en çok <n> bağlanılamaz işlem tut (varsayılan: %u)</translation> </message> <message> <source>Need to specify a port with -whitebind: '%s'</source> @@ -2403,7 +3539,7 @@ </message> <message> <source>Node relay options:</source> - <translation>Düğüm röle seçenekleri:</translation> + <translation>Düğüm aktarma seçenekleri:</translation> </message> <message> <source>RPC server options:</source> @@ -2415,15 +3551,15 @@ </message> <message> <source>Rescan the block chain for missing wallet transactions on startup</source> - <translation>Başlangıçta blok zincirini eksik cüzdan muameleleri için tekrar tara</translation> + <translation>Başlangıçta blok zincirini eksik cüzdan işlemleri için tekrar tara</translation> </message> <message> <source>Send trace/debug info to console instead of debug.log file</source> - <translation>Trace/hata ayıklama verilerini debug.log dosyası yerine konsola gönder</translation> + <translation>İzleme/hata ayıklama verilerini debug.log dosyası yerine konsola gönder</translation> </message> <message> <source>Send transactions as zero-fee transactions if possible (default: %u)</source> - <translation>Muameleleri mümkünse ücretsiz olarak gönder (varsayılan: %u)</translation> + <translation>İşlemleri mümkünse ücretsiz olarak gönder (varsayılan: %u)</translation> </message> <message> <source>Show all debugging options (usage: --help -help-debug)</source> @@ -2435,11 +3571,11 @@ </message> <message> <source>Signing transaction failed</source> - <translation>Muamelenin imzalanması başarısız oldu</translation> + <translation>İşlemin imzalanması başarısız oldu</translation> </message> <message> <source>The transaction amount is too small to pay the fee</source> - <translation>Muamele meblağı ücreti ödemek için çok düşük</translation> + <translation>İşlemdeki bitcoin tutarı ücreti ödemek için çok düşük</translation> </message> <message> <source>This is experimental software.</source> @@ -2451,23 +3587,23 @@ </message> <message> <source>Tor control port to use if onion listening enabled (default: %s)</source> - <translation>Eğer onion dinlenmesi etkinse kullanılacak Tor kontrol portu (varsayılan: %s)</translation> + <translation>Eğer onion dinlemesi etkinse kullanılacak Tor kontrol portu (varsayılan: %s)</translation> </message> <message> <source>Transaction amount too small</source> - <translation>Muamele meblağı çok düşük</translation> + <translation>İşlem tutarı çok düşük</translation> </message> <message> <source>Transaction too large for fee policy</source> - <translation>Ücret politikası için çok büyük muamele</translation> + <translation>Ücret politikası için işlem çok büyük</translation> </message> <message> <source>Transaction too large</source> - <translation>Muamele çok büyük</translation> + <translation>İşlem çok büyük</translation> </message> <message> <source>Unable to bind to %s on this computer (bind returned error %s)</source> - <translation>Bu bilgisayarda %s unsuruna bağlanılamadı (bağlanma %s hatasını verdi)</translation> + <translation>Bu bilgisayarda %s ögesine bağlanılamadı (bağlanma %s hatasını verdi)</translation> </message> <message> <source>Upgrade wallet to latest format on startup</source> @@ -2483,15 +3619,15 @@ </message> <message> <source>Warning: unknown new rules activated (versionbit %i)</source> - <translation>İkaz: bilinmeyen yeni kurallar etkinleştirilmiştir (versionbit %i)</translation> + <translation>Uyarı: bilinmeyen yeni kurallar etkinleştirilmiştir (versionbit %i)</translation> </message> <message> <source>Whether to operate in a blocks only mode (default: %u)</source> - <translation>Salt blok kipinde çalışılıp çalışılmayacağı (varsayılan: %u)</translation> + <translation>Sadece blok kipinde çalışılıp çalışılmayacağı (varsayılan: %u)</translation> </message> <message> <source>Zapping all transactions from wallet...</source> - <translation>Cüzdandaki tüm muameleler kaldırılıyor...</translation> + <translation>Cüzdandaki tüm işlemler kaldırılıyor...</translation> </message> <message> <source>ZeroMQ notification options:</source> @@ -2519,19 +3655,23 @@ </message> <message> <source>-maxtxfee is set very high! Fees this large could be paid on a single transaction.</source> - <translation>-maxtxfee çok yüksek bir değere ayarlanmış! Bu denli yüksek ücretler tek bir muamelede ödenebilir.</translation> + <translation>-maxtxfee çok yüksek bir değere ayarlanmış! Bu denli yüksek ücretler tek bir işlemde ödenebilir.</translation> </message> <message> <source>Do not keep transactions in the mempool longer than <n> hours (default: %u)</source> - <translation>Muameleleri bellek alanında <n> saatten fazla tutma (varsayılan: %u)</translation> + <translation>İşlemleri bellek alanında <n> saatten fazla tutma (varsayılan: %u)</translation> </message> <message> <source>Equivalent bytes per sigop in transactions for relay and mining (default: %u)</source> - <translation>Oluşturma ve aktarşa muamelelerinde sigop başına eşdeğer bayt (varsayılan: %u)</translation> + <translation>Oluşturma ve aktarma işlemlerinde sigop başına eşdeğer bayt (varsayılan: %u)</translation> </message> <message> <source>Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s)</source> - <translation>Bundan düşük ücretler (%s/kB olarak) muamele oluşturulması için sıfır değerinde ücret olarak kabul edilir (varsayılan: %s)</translation> + <translation>Bundan düşük ücretler (%s/kB olarak) işlem oluşturulması için sıfır değerinde ücret olarak kabul edilir (varsayılan: %s)</translation> + </message> + <message> + <source>Force relay of transactions from whitelisted peers even if they violate local relay policy (default: %d)</source> + <translation>Yerel aktarma politikasını ihlal etseler bile beyaz listedeki eşlerden gelen işlemlerin aktarılmasını zorla (varsayılan: %d)</translation> </message> <message> <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source> @@ -2539,7 +3679,7 @@ </message> <message> <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source> - <translation>Muamelelerin tamamının indeksini tut, getrawtransaction rpc çağrısı tarafından kullanılır (varsayılan: %u)</translation> + <translation>İşlemlerin tamamının indeksini tut, getrawtransaction rpc çağrısı tarafından kullanılır (varsayılan: %u)</translation> </message> <message> <source>Number of seconds to keep misbehaving peers from reconnecting (default: %u)</source> @@ -2547,15 +3687,31 @@ </message> <message> <source>Output debugging information (default: %u, supplying <category> is optional)</source> - <translation>Hata ayıklama bilgisi dök (varsayılan: %u, <kategori> sağlanması seçime dayalıdır)</translation> + <translation>Hata ayıklama bilgisini dök (varsayılan: %u, <kategori> sağlanması seçime dayalıdır)</translation> + </message> + <message> + <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect/-noconnect)</source> + <translation>Adres sayısı azaldıysa DNS sorgulamasıyla eş adresleri ara (varsayılan: 1 -connect/-noconnect kullanılmadıysa)</translation> + </message> + <message> + <source>Sets the serialization of raw transaction or block hex returned in non-verbose mode, non-segwit(0) or segwit(1) (default: %d)</source> + <translation>Ham işlemin serileştirilmesini ayarlar veya blok non-verbose, non-segwit(0) veya segwit(1) kipinde onaltılık değeri döndürür (default: %d)</translation> </message> <message> <source>Support filtering of blocks and transaction with bloom filters (default: %u)</source> - <translation>Blokların ve muamelelerin bloom filtreleri ile süzülmesini destekle (varsayılan: %u)</translation> + <translation>Blokların ve işlemlerin bloom filtreleri ile süzülmesini destekle (varsayılan: %u)</translation> + </message> + <message> + <source>This is the transaction fee you may pay when fee estimates are not available.</source> + <translation>İşlem ücret tahminleri mevcut olmadığında ödeyebileceğiniz işlem ücreti budur.</translation> + </message> + <message> + <source>This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit %s and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.</source> + <translation>Bu ürün OpenSSL Projesi tarafından geliştirilen OpenSSL araç takımınında kullanılmak üzere yazılan yazılımları %s Eric Young tarafından yazılmış şifreleme yazılımını ve Thomas Bernard tarafından yazılmış UPnP yazılımını içerir.</translation> </message> <message> <source>Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments.</source> - <translation>Ş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.</translation> + <translation>Ağ sürümü zincirinin toplam boyutu (%i) en yüksek boyutu geçmektedir (%i). Kullanıcı aracı açıklamasının sayısı veya boyutunu azaltınız.</translation> </message> <message> <source>Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d)</source> @@ -2575,11 +3731,19 @@ </message> <message> <source>Warning: Unknown block versions being mined! It's possible unknown rules are in effect</source> - <translation>İkaz: bilinmeyen blok sürümü oluşturulmaya çalışılıyor. Bilinmeyen kuralların işlemesi mümkündür.</translation> + <translation>Uyarı: Bilinmeyen blok sürümü oluşturulmaya çalışılıyor. Bilinmeyen kuralların işlemesi mümkündür.</translation> </message> <message> <source>Warning: Wallet file corrupt, data salvaged! Original %s saved as %s in %s; if your balance or transactions are incorrect you should restore from a backup.</source> - <translation>Uyarı: wallet.dat bozuk, veriler geri kazanıldı! Özgün %s, %s olarak %s klasörüne kaydedildi; bakiyeniz ya da muameleleriniz yanlışsa bir yedeklemeden tekrar yüklemeniz gerekir.</translation> + <translation>Uyarı: wallet.dat bozuk, veriler geri kazanıldı! Özgün %s, %s olarak %s klasörüne kaydedildi; bakiyeniz ya da işlemleriniz yanlışsa bir yedeklemeden tekrar yüklemeniz gerekir.</translation> + </message> + <message> + <source>Whitelist peers connecting from the given IP address (e.g. 1.2.3.4) or CIDR notated network (e.g. 1.2.3.0/24). Can be specified multiple times.</source> + <translation>Beyaz listeye eklenen eşler verilen IP adresinden (ör. 1.2.3.4) veya CIDR ağından (ör. 1.2.3.0/24) bağlanabilir. Değerler birden çok kez kullanılabilir.</translation> + </message> + <message> + <source>%s is set very high!</source> + <translation>%s çok yüksek ayarlanmış!</translation> </message> <message> <source>(default: %s)</source> @@ -2602,6 +3766,10 @@ <translation>Geçersiz -proxy adresi: '%s'</translation> </message> <message> + <source>Keypool ran out, please call keypoolrefill first</source> + <translation>Keypool tükendi, lütfen önce keypoolrefill'i çağırın</translation> + </message> + <message> <source>Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)</source> <translation>JSON-RPC bağlantılarını <port> üzerinde dinle (varsayılan: %u veya tesnet: %u)</translation> </message> @@ -2615,15 +3783,15 @@ </message> <message> <source>Make the wallet broadcast transactions</source> - <translation>Cüzdanın muameleleri yayınlamasını sağla</translation> + <translation>Cüzdanın işlemleri yayınlamasını sağla</translation> </message> <message> <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)</source> - <translation>Her bağlantı için azami alım tamponu, <n>*1000 bayt (varsayılan: %u)</translation> + <translation>Her bağlantı için en yüksek alım tamponu, <n>*1000 bayt (varsayılan: %u)</translation> </message> <message> <source>Maximum per-connection send buffer, <n>*1000 bytes (default: %u)</source> - <translation>Her bağlantı için azami yollama tamponu, <n>*1000 bayt (varsayılan: %u)</translation> + <translation>Her bağlantı için çok gönderme tamponu, <n>*1000 bayt (varsayılan: %u)</translation> </message> <message> <source>Prepend debug output with timestamp (default: %u)</source> @@ -2631,19 +3799,23 @@ </message> <message> <source>Relay and mine data carrier transactions (default: %u)</source> - <translation>Veri taşıyıcı muameleleri oluştur ve aktar (varsayılan: %u)</translation> + <translation>Veri taşıyıcı işlemleri oluştur ve aktar (varsayılan: %u)</translation> </message> <message> <source>Relay non-P2SH multisig (default: %u)</source> <translation>P2SH olmayan çoklu imzaları aktar (varsayılan: %u)</translation> </message> <message> + <source>Send transactions with full-RBF opt-in enabled (default: %u)</source> + <translation>İşlemleri full-RBF opt-in ile gönder etkinleştirildi (default: %u)</translation> + </message> + <message> <source>Set key pool size to <n> (default: %u)</source> <translation>Anahtar alan boyutunu <n> değerine ayarla (varsayılan: %u)</translation> </message> <message> <source>Set maximum BIP141 block weight (default: %d)</source> - <translation>Azami BIP141 blok ağırlığını ayarla (varsayılan: %d)</translation> + <translation>En yüksek BIP141 blok ağırlığını ayarla (varsayılan: %d)</translation> </message> <message> <source>Set the number of threads to service RPC calls (default: %d)</source> @@ -2655,7 +3827,7 @@ </message> <message> <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source> - <translation>Bağlantı zaman aşım süresini milisaniye olarak belirt (asgari: 1, varsayılan: %d)</translation> + <translation>Bağlantı zaman aşım süresini milisaniye olarak belirt (en düşüki: 1, varsayılan: %d)</translation> </message> <message> <source>Specify pid file (default: %s)</source> @@ -2663,15 +3835,43 @@ </message> <message> <source>Spend unconfirmed change when sending transactions (default: %u)</source> - <translation>Gönderme muamelelerinde teyit edilmemiş para üstünü harca (varsayılan: %u)</translation> + <translation>Gönderme işlemlerinde doğrulanmamış para üstünü harca (varsayılan: %u)</translation> + </message> + <message> + <source>Starting network threads...</source> + <translation>Ağ iş parçacıkları başlatılıyor...</translation> + </message> + <message> + <source>The wallet will avoid paying less than the minimum relay fee.</source> + <translation>Cüzdan en az aktarma ücretinden daha az ödeme yapmaktan sakınacaktır.</translation> + </message> + <message> + <source>This is the minimum transaction fee you pay on every transaction.</source> + <translation>Bu her işlemde ödeceğiniz en düşük işlem ücretidir.</translation> + </message> + <message> + <source>This is the transaction fee you will pay if you send a transaction.</source> + <translation>Eğer bir gönderme işlemi yaparsanız bu ödeyeceğiniz işlem ücretidir.</translation> </message> <message> <source>Threshold for disconnecting misbehaving peers (default: %u)</source> <translation>Aksaklık gösteren eşlerle bağlantıyı kesme sınırı (varsayılan: %u)</translation> </message> <message> + <source>Transaction amounts must not be negative</source> + <translation>İşlem tutarı negatif olmamalıdır</translation> + </message> + <message> + <source>Transaction has too long of a mempool chain</source> + <translation>İşlem çok uzun bir mempool zincirine sahip</translation> + </message> + <message> + <source>Transaction must have at least one recipient</source> + <translation>İşlemin en az bir alıcısı olması gerekir</translation> + </message> + <message> <source>Unknown network specified in -onlynet: '%s'</source> - <translation>-onlynet için bilinmeyen bir şebeke belirtildi: '%s'</translation> + <translation>-onlynet için bilinmeyen bir ağ belirtildi: '%s'</translation> </message> <message> <source>Insufficient funds</source> @@ -2683,7 +3883,7 @@ </message> <message> <source>Add a node to connect to and attempt to keep the connection open</source> - <translation>Bağlanılacak düğüm ekle ve bağlantıyı zinde tutmaya çalış</translation> + <translation>Bağlanılacak düğüm ekle ve bağlantıyı sürekli açık tutmaya çalış</translation> </message> <message> <source>Loading wallet...</source> @@ -2699,7 +3899,7 @@ </message> <message> <source>Rescanning...</source> - <translation>Yeniden tarama...</translation> + <translation>Yeniden taranıyor...</translation> </message> <message> <source>Done loading</source> diff --git a/src/qt/locale/bitcoin_uk.ts b/src/qt/locale/bitcoin_uk.ts index a817c1baf2..2c017fc52e 100644 --- a/src/qt/locale/bitcoin_uk.ts +++ b/src/qt/locale/bitcoin_uk.ts @@ -257,10 +257,6 @@ <source>%n active connection(s) to Bitcoin network</source> <translation><numerusform>%n активне з'єднання з мережею Bitcoin</numerusform><numerusform>%n активні з'єднання з мережею Bitcoin</numerusform><numerusform>%n активних з'єднань з мережею Bitcoin</numerusform></translation> </message> - <message> - <source>No block source available...</source> - <translation>Недоступно жодного джерела блоків...</translation> - </message> <message numerus="yes"> <source>Processed %n block(s) of transaction history.</source> <translation><numerusform>Оброблено %n блок історії транзакцій.</numerusform><numerusform>Оброблено %n блоки історії транзакцій.</numerusform><numerusform>Оброблено %n блоків історії транзакцій.</numerusform></translation> diff --git a/src/qt/locale/bitcoin_uz@Cyrl.ts b/src/qt/locale/bitcoin_uz@Cyrl.ts index fe10a8a8e7..3898c441af 100644 --- a/src/qt/locale/bitcoin_uz@Cyrl.ts +++ b/src/qt/locale/bitcoin_uz@Cyrl.ts @@ -246,10 +246,6 @@ <translation><numerusform>%n та Bitcoin тармоғига фаол уланиш мавжуд</numerusform></translation> </message> <message> - <source>No block source available...</source> - <translation>Блок манбалари мавжуд эмас...</translation> - </message> - <message> <source>%1 behind</source> <translation>%1 орқада</translation> </message> diff --git a/src/qt/locale/bitcoin_zh_CN.ts b/src/qt/locale/bitcoin_zh_CN.ts index e76d605a80..20875c2327 100644 --- a/src/qt/locale/bitcoin_zh_CN.ts +++ b/src/qt/locale/bitcoin_zh_CN.ts @@ -441,10 +441,6 @@ <source>Processing blocks on disk...</source> <translation>正在处理数据块...</translation> </message> - <message> - <source>No block source available...</source> - <translation>沒有可用的区块来源...</translation> - </message> <message numerus="yes"> <source>Processed %n block(s) of transaction history.</source> <translation><numerusform>已处理 %n 个交易历史数据块。</numerusform></translation> @@ -486,6 +482,10 @@ <translation>%1 客戶</translation> </message> <message> + <source>Connecting to peers...</source> + <translation>正在连接到节点……</translation> + </message> + <message> <source>Catching up...</source> <translation>更新中...</translation> </message> @@ -1931,7 +1931,11 @@ <source>(no amount requested)</source> <translation>(无请求金额)</translation> </message> - </context> + <message> + <source>Requested</source> + <translation>总额</translation> + </message> +</context> <context> <name>SendCoinsDialog</name> <message> @@ -2183,6 +2187,10 @@ <translation>警告:未知的更改地址</translation> </message> <message> + <source>The address you selected for change is not part of this wallet. Any or all funds in your wallet may be sent to this address. Are you sure?</source> + <translation>你选择的找零地址未被包含在本钱包中,你钱包中的部分或全部金额将被发送至该地址。你确定要这样做吗?</translation> + </message> + <message> <source>(no label)</source> <translation>(无标签)</translation> </message> @@ -2464,6 +2472,14 @@ <translation>0/未确认,%1</translation> </message> <message> + <source>in memory pool</source> + <translation>在内存池中</translation> + </message> + <message> + <source>not in memory pool</source> + <translation>不在内存池中</translation> + </message> + <message> <source>abandoned</source> <translation>已抛弃</translation> </message> @@ -3205,6 +3221,10 @@ <translation>使用UPnp映射监听端口 (默认: %u) </translation> </message> <message> + <source>Use the test chain</source> + <translation>使用测试链</translation> + </message> + <message> <source>User Agent comment (%s) contains unsafe characters.</source> <translation>用户代理评论(%s)包含不安全的字符。</translation> </message> diff --git a/src/qt/locale/bitcoin_zh_TW.ts b/src/qt/locale/bitcoin_zh_TW.ts index 4a8b1474d8..bd0533a83e 100644 --- a/src/qt/locale/bitcoin_zh_TW.ts +++ b/src/qt/locale/bitcoin_zh_TW.ts @@ -330,6 +330,10 @@ <translation>按一下就又會使用網路。</translation> </message> <message> + <source>Syncing Headers (%1%)...</source> + <translation>正在同步前導資料(%1%)中...</translation> + </message> + <message> <source>Reindexing blocks on disk...</source> <translation>正在為磁碟裡的區塊重建索引...</translation> </message> @@ -441,10 +445,6 @@ <source>Processing blocks on disk...</source> <translation>正在處理磁碟裡的區塊資料...</translation> </message> - <message> - <source>No block source available...</source> - <translation>沒有可用的區塊來源...</translation> - </message> <message numerus="yes"> <source>Processed %n block(s) of transaction history.</source> <translation><numerusform>已經處理了 %n 個區塊的交易紀錄。</numerusform></translation> @@ -486,6 +486,10 @@ <translation>%1 客戶端軟體</translation> </message> <message> + <source>Connecting to peers...</source> + <translation>正在跟其他節點連線中...</translation> + </message> + <message> <source>Catching up...</source> <translation>正在趕進度...</translation> </message> @@ -3091,6 +3095,14 @@ <translation>當錢包有交易改變時要執行的指令(指令中的 %s 會被取代成交易識別碼)</translation> </message> <message> + <source>Extra transactions to keep in memory for compact block reconstructions (default: %u)</source> + <translation>為了將摘要區塊完整回組而額外保留在記憶體中的交易數量(預設值: %u)</translation> + </message> + <message> + <source>If this block is in the chain assume that it and its ancestors are valid and potentially skip their script verification (0 to verify all, default: %s, testnet: %s)</source> + <translation>假設已經在區塊鏈中的區塊以及其先前的區塊都合法,因此對它們略過指令碼驗證(0 表示一律要驗證,預設值: %s, 測試網路: %s)</translation> + </message> + <message> <source>Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds)</source> <translation>跟其他節點的時間差最高可接受的中位數值。本機所認為的時間可能會被其他節點影響,往前或往後在這個值之內。(預設值: %u 秒)</translation> </message> @@ -3384,7 +3396,7 @@ </message> <message> <source>Use the test chain</source> - <translation>使用測試鏈</translation> + <translation>使用測試區塊鏈</translation> </message> <message> <source>User Agent comment (%s) contains unsafe characters.</source> diff --git a/src/qt/modaloverlay.cpp b/src/qt/modaloverlay.cpp index 89fb159956..4779ffa43f 100644 --- a/src/qt/modaloverlay.cpp +++ b/src/qt/modaloverlay.cpp @@ -7,6 +7,8 @@ #include "guiutil.h" +#include "chainparams.h" + #include <QResizeEvent> #include <QPropertyAnimation> @@ -125,11 +127,11 @@ void ModalOverlay::tipUpdate(int count, const QDateTime& blockDate, double nVeri // estimate the number of headers left based on nPowTargetSpacing // and check if the gui is not aware of the the best header (happens rarely) - int estimateNumHeadersLeft = bestHeaderDate.secsTo(currentDate) / 600; + int estimateNumHeadersLeft = bestHeaderDate.secsTo(currentDate) / Params().GetConsensus().nPowTargetSpacing; bool hasBestHeader = bestHeaderHeight >= count; // show remaining number of blocks - if (estimateNumHeadersLeft < 24 && hasBestHeader) { + if (estimateNumHeadersLeft < HEADER_HEIGHT_DELTA_SYNC && hasBestHeader) { ui->numberOfBlocksLeft->setText(QString::number(bestHeaderHeight - count)); } else { ui->numberOfBlocksLeft->setText(tr("Unknown. Syncing Headers (%1)...").arg(bestHeaderHeight)); diff --git a/src/qt/modaloverlay.h b/src/qt/modaloverlay.h index 6d1f12164e..21ccdbd839 100644 --- a/src/qt/modaloverlay.h +++ b/src/qt/modaloverlay.h @@ -9,7 +9,7 @@ #include <QWidget> //! The required delta of headers to the estimated number of available headers until we show the IBD progress -static const int REQ_HEADER_HEIGHT_DELTA_SYNC = 24; +static constexpr int HEADER_HEIGHT_DELTA_SYNC = 24; namespace Ui { class ModalOverlay; diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp index 89f633aa73..7ff00b1e9e 100644 --- a/src/qt/optionsdialog.cpp +++ b/src/qt/optionsdialog.cpp @@ -277,6 +277,9 @@ void OptionsDialog::showRestartWarning(bool fPersistent) void OptionsDialog::clearStatusLabel() { ui->statusLabel->clear(); + if (model && model->isRestartRequired()) { + showRestartWarning(true); + } } void OptionsDialog::updateProxyValidationState() @@ -286,7 +289,7 @@ void OptionsDialog::updateProxyValidationState() if (pUiProxyIp->isValid() && (!ui->proxyPort->isEnabled() || ui->proxyPort->text().toInt() > 0) && (!ui->proxyPortTor->isEnabled() || ui->proxyPortTor->text().toInt() > 0)) { setOkButtonState(otherProxyWidget->isValid()); //only enable ok button if both proxys are valid - ui->statusLabel->clear(); + clearStatusLabel(); } else { diff --git a/src/qt/paymentrequestplus.h b/src/qt/paymentrequestplus.h index ee1a37d83c..a2fea3fdc6 100644 --- a/src/qt/paymentrequestplus.h +++ b/src/qt/paymentrequestplus.h @@ -5,7 +5,10 @@ #ifndef BITCOIN_QT_PAYMENTREQUESTPLUS_H #define BITCOIN_QT_PAYMENTREQUESTPLUS_H +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" #include "paymentrequest.pb.h" +#pragma GCC diagnostic pop #include "base58.h" diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp index 688e8123af..dd75f12076 100644 --- a/src/qt/paymentserver.cpp +++ b/src/qt/paymentserver.cpp @@ -55,8 +55,6 @@ const char* BIP70_MESSAGE_PAYMENTREQUEST = "PaymentRequest"; const char* BIP71_MIMETYPE_PAYMENT = "application/bitcoin-payment"; const char* BIP71_MIMETYPE_PAYMENTACK = "application/bitcoin-paymentack"; const char* BIP71_MIMETYPE_PAYMENTREQUEST = "application/bitcoin-paymentrequest"; -// BIP70 max payment request size in bytes (DoS protection) -const qint64 BIP70_MAX_PAYMENTREQUEST_SIZE = 50000; struct X509StoreDeleter { void operator()(X509_STORE* b) { diff --git a/src/qt/paymentserver.h b/src/qt/paymentserver.h index 37ee522d54..7c6d4507fe 100644 --- a/src/qt/paymentserver.h +++ b/src/qt/paymentserver.h @@ -21,10 +21,10 @@ // // When startup is finished and the main window is // shown, a signal is sent to slot uiReady(), which -// emits a receivedURL() signal for any payment +// emits a receivedURI() signal for any payment // requests that happened during startup. // -// After startup, receivedURL() happens as usual. +// After startup, receivedURI() happens as usual. // // This class has one more feature: a static // method that finds URIs passed in the command line @@ -53,7 +53,7 @@ class QUrl; QT_END_NAMESPACE // BIP70 max payment request size in bytes (DoS protection) -extern const qint64 BIP70_MAX_PAYMENTREQUEST_SIZE; +static const qint64 BIP70_MAX_PAYMENTREQUEST_SIZE = 50000; class PaymentServer : public QObject { diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index 87d73b5f08..60406c2059 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -1023,11 +1023,11 @@ void RPCConsole::updateNodeDetail(const CNodeCombinedStats *stats) peerAddrDetails += "<br />" + tr("via %1").arg(QString::fromStdString(stats->nodeStats.addrLocal)); ui->peerHeading->setText(peerAddrDetails); ui->peerServices->setText(GUIUtil::formatServicesStr(stats->nodeStats.nServices)); - ui->peerLastSend->setText(stats->nodeStats.nLastSend ? GUIUtil::formatDurationStr(GetTime() - stats->nodeStats.nLastSend) : tr("never")); - ui->peerLastRecv->setText(stats->nodeStats.nLastRecv ? GUIUtil::formatDurationStr(GetTime() - stats->nodeStats.nLastRecv) : tr("never")); + ui->peerLastSend->setText(stats->nodeStats.nLastSend ? GUIUtil::formatDurationStr(GetSystemTimeInSeconds() - stats->nodeStats.nLastSend) : tr("never")); + ui->peerLastRecv->setText(stats->nodeStats.nLastRecv ? GUIUtil::formatDurationStr(GetSystemTimeInSeconds() - stats->nodeStats.nLastRecv) : tr("never")); ui->peerBytesSent->setText(FormatBytes(stats->nodeStats.nSendBytes)); ui->peerBytesRecv->setText(FormatBytes(stats->nodeStats.nRecvBytes)); - ui->peerConnTime->setText(GUIUtil::formatDurationStr(GetTime() - stats->nodeStats.nTimeConnected)); + ui->peerConnTime->setText(GUIUtil::formatDurationStr(GetSystemTimeInSeconds() - stats->nodeStats.nTimeConnected)); ui->peerPingTime->setText(GUIUtil::formatPingTime(stats->nodeStats.dPingTime)); ui->peerPingWait->setText(GUIUtil::formatPingTime(stats->nodeStats.dPingWait)); ui->peerMinPing->setText(GUIUtil::formatPingTime(stats->nodeStats.dMinPing)); diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index 5aeda7a30d..1c0ed663c1 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -16,6 +16,7 @@ #include "walletmodel.h" #include "base58.h" +#include "chainparams.h" #include "wallet/coincontrol.h" #include "validation.h" // mempool and minRelayTxFee #include "ui_interface.h" @@ -607,8 +608,8 @@ void SendCoinsDialog::updateGlobalFeeVariables() // set nMinimumTotalFee to 0 to not accidentally pay a custom fee CoinControlDialog::coinControl->nMinimumTotalFee = 0; - // show the estimated reuquired time for confirmation - ui->confirmationTargetLabel->setText(GUIUtil::formatDurationStr(nConfirmTarget*600)+" / "+tr("%n block(s)", "", nConfirmTarget)); + // show the estimated required time for confirmation + ui->confirmationTargetLabel->setText(GUIUtil::formatDurationStr(nConfirmTarget * Params().GetConsensus().nPowTargetSpacing) + " / " + tr("%n block(s)", "", nConfirmTarget)); } else { diff --git a/src/qt/transactionrecord.cpp b/src/qt/transactionrecord.cpp index cbdedbf68b..a9d9b6887e 100644 --- a/src/qt/transactionrecord.cpp +++ b/src/qt/transactionrecord.cpp @@ -47,14 +47,15 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet * // // Credit // - BOOST_FOREACH(const CTxOut& txout, wtx.tx->vout) + for(unsigned int i = 0; i < wtx.tx->vout.size(); i++) { + const CTxOut& txout = wtx.tx->vout[i]; isminetype mine = wallet->IsMine(txout); if(mine) { TransactionRecord sub(hash, nTime); CTxDestination address; - sub.idx = parts.size(); // sequence number + sub.idx = i; // vout index sub.credit = txout.nValue; sub.involvesWatchAddress = mine & ISMINE_WATCH_ONLY; if (ExtractDestination(txout.scriptPubKey, address) && IsMine(*wallet, address)) @@ -118,7 +119,7 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet * { const CTxOut& txout = wtx.tx->vout[nOut]; TransactionRecord sub(hash, nTime); - sub.idx = parts.size(); + sub.idx = nOut; sub.involvesWatchAddress = involvesWatchAddress; if(wallet->IsMine(txout)) diff --git a/src/qt/utilitydialog.cpp b/src/qt/utilitydialog.cpp index 70efe27990..7ab4125284 100644 --- a/src/qt/utilitydialog.cpp +++ b/src/qt/utilitydialog.cpp @@ -39,7 +39,7 @@ HelpMessageDialog::HelpMessageDialog(QWidget *parent, bool about) : QString version = tr(PACKAGE_NAME) + " " + tr("version") + " " + QString::fromStdString(FormatFullVersion()); /* On x86 add a bit specifier to the version so that users can distinguish between - * 32 and 64 bit builds. On other architectures, 32/64 bit may be more ambigious. + * 32 and 64 bit builds. On other architectures, 32/64 bit may be more ambiguous. */ #if defined(__x86_64__) version += " " + tr("(%1-bit)").arg(64); diff --git a/src/random.cpp b/src/random.cpp index 6634019bea..8284f457c9 100644 --- a/src/random.cpp +++ b/src/random.cpp @@ -21,6 +21,17 @@ #include <sys/time.h> #endif +#ifdef HAVE_SYS_GETRANDOM +#include <sys/syscall.h> +#include <linux/random.h> +#endif +#ifdef HAVE_GETENTROPY +#include <unistd.h> +#endif +#ifdef HAVE_SYSCTL_ARND +#include <sys/sysctl.h> +#endif + #include <openssl/err.h> #include <openssl/rand.h> @@ -91,34 +102,86 @@ static void RandAddSeedPerfmon() #endif } +#ifndef WIN32 +/** Fallback: get 32 bytes of system entropy from /dev/urandom. The most + * compatible way to get cryptographic randomness on UNIX-ish platforms. + */ +void GetDevURandom(unsigned char *ent32) +{ + int f = open("/dev/urandom", O_RDONLY); + if (f == -1) { + RandFailure(); + } + int have = 0; + do { + ssize_t n = read(f, ent32 + have, NUM_OS_RANDOM_BYTES - have); + if (n <= 0 || n + have > NUM_OS_RANDOM_BYTES) { + RandFailure(); + } + have += n; + } while (have < NUM_OS_RANDOM_BYTES); + close(f); +} +#endif + /** Get 32 bytes of system entropy. */ -static void GetOSRand(unsigned char *ent32) +void GetOSRand(unsigned char *ent32) { -#ifdef WIN32 +#if defined(WIN32) HCRYPTPROV hProvider; int ret = CryptAcquireContextW(&hProvider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); if (!ret) { RandFailure(); } - ret = CryptGenRandom(hProvider, 32, ent32); + ret = CryptGenRandom(hProvider, NUM_OS_RANDOM_BYTES, ent32); if (!ret) { RandFailure(); } CryptReleaseContext(hProvider, 0); -#else - int f = open("/dev/urandom", O_RDONLY); - if (f == -1) { +#elif defined(HAVE_SYS_GETRANDOM) + /* Linux. From the getrandom(2) man page: + * "If the urandom source has been initialized, reads of up to 256 bytes + * will always return as many bytes as requested and will not be + * interrupted by signals." + */ + int rv = syscall(SYS_getrandom, ent32, NUM_OS_RANDOM_BYTES, 0); + if (rv != NUM_OS_RANDOM_BYTES) { + if (rv < 0 && errno == ENOSYS) { + /* Fallback for kernel <3.17: the return value will be -1 and errno + * ENOSYS if the syscall is not available, in that case fall back + * to /dev/urandom. + */ + GetDevURandom(ent32); + } else { + RandFailure(); + } + } +#elif defined(HAVE_GETENTROPY) + /* On OpenBSD this can return up to 256 bytes of entropy, will return an + * error if more are requested. + * The call cannot return less than the requested number of bytes. + */ + if (getentropy(ent32, NUM_OS_RANDOM_BYTES) != 0) { RandFailure(); } +#elif defined(HAVE_SYSCTL_ARND) + /* FreeBSD and similar. It is possible for the call to return less + * bytes than requested, so need to read in a loop. + */ + static const int name[2] = {CTL_KERN, KERN_ARND}; int have = 0; do { - ssize_t n = read(f, ent32 + have, 32 - have); - if (n <= 0 || n + have > 32) { + size_t len = NUM_OS_RANDOM_BYTES - have; + if (sysctl(name, ARRAYLEN(name), ent32 + have, &len, NULL, 0) != 0) { RandFailure(); } - have += n; - } while (have < 32); - close(f); + have += len; + } while (have < NUM_OS_RANDOM_BYTES); +#else + /* Fall back to /dev/urandom if there is no specific method implemented to + * get system entropy for this OS. + */ + GetDevURandom(ent32); #endif } @@ -195,3 +258,33 @@ FastRandomContext::FastRandomContext(bool fDeterministic) } } +bool Random_SanityCheck() +{ + /* This does not measure the quality of randomness, but it does test that + * OSRandom() overwrites all 32 bytes of the output given a maximum + * number of tries. + */ + static const ssize_t MAX_TRIES = 1024; + uint8_t data[NUM_OS_RANDOM_BYTES]; + bool overwritten[NUM_OS_RANDOM_BYTES] = {}; /* Tracks which bytes have been overwritten at least once */ + int num_overwritten; + int tries = 0; + /* Loop until all bytes have been overwritten at least once, or max number tries reached */ + do { + memset(data, 0, NUM_OS_RANDOM_BYTES); + GetOSRand(data); + for (int x=0; x < NUM_OS_RANDOM_BYTES; ++x) { + overwritten[x] |= (data[x] != 0); + } + + num_overwritten = 0; + for (int x=0; x < NUM_OS_RANDOM_BYTES; ++x) { + if (overwritten[x]) { + num_overwritten += 1; + } + } + + tries += 1; + } while (num_overwritten < NUM_OS_RANDOM_BYTES && tries < MAX_TRIES); + return (num_overwritten == NUM_OS_RANDOM_BYTES); /* If this failed, bailed out after too many tries */ +} diff --git a/src/random.h b/src/random.h index 664f030eba..0464bdce14 100644 --- a/src/random.h +++ b/src/random.h @@ -46,4 +46,21 @@ public: uint32_t Rw; }; +/* Number of random bytes returned by GetOSRand. + * When changing this constant make sure to change all call sites, and make + * sure that the underlying OS APIs for all platforms support the number. + * (many cap out at 256 bytes). + */ +static const ssize_t NUM_OS_RANDOM_BYTES = 32; + +/** Get 32 bytes of system entropy. Do not use this in application code: use + * GetStrongRandBytes instead. + */ +void GetOSRand(unsigned char *ent32); + +/** Check that OS randomness is available and returning the requested number + * of bytes. + */ +bool Random_SanityCheck(); + #endif // BITCOIN_RANDOM_H diff --git a/src/rest.cpp b/src/rest.cpp index a8f8e753c6..54eefcafe3 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -20,8 +20,6 @@ #include <univalue.h> -using namespace std; - static const size_t MAX_GETUTXOS_OUTPOINTS = 15; //allow a max of 15 outpoints to be queried at once enum RetFormat { @@ -64,7 +62,7 @@ extern UniValue mempoolToJSON(bool fVerbose = false); extern void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex); extern UniValue blockheaderToJSON(const CBlockIndex* blockindex); -static bool RESTERR(HTTPRequest* req, enum HTTPStatusCode status, string message) +static bool RESTERR(HTTPRequest* req, enum HTTPStatusCode status, std::string message) { req->WriteHeader("Content-Type", "text/plain"); req->WriteReply(status, message + "\r\n"); @@ -92,9 +90,9 @@ static enum RetFormat ParseDataFormat(std::string& param, const std::string& str return rf_names[0].rf; } -static string AvailableDataFormatsString() +static std::string AvailableDataFormatsString() { - string formats = ""; + std::string formats = ""; for (unsigned int i = 0; i < ARRAYLEN(rf_names); i++) if (strlen(rf_names[i].name) > 0) { formats.append("."); @@ -108,7 +106,7 @@ static string AvailableDataFormatsString() return formats; } -static bool ParseHashStr(const string& strReq, uint256& v) +static bool ParseHashStr(const std::string& strReq, uint256& v) { if (!IsHex(strReq) || (strReq.size() != 64)) return false; @@ -132,7 +130,7 @@ static bool rest_headers(HTTPRequest* req, return false; std::string param; const RetFormat rf = ParseDataFormat(param, strURIPart); - vector<string> path; + std::vector<std::string> path; boost::split(path, param, boost::is_any_of("/")); if (path.size() != 2) @@ -142,7 +140,7 @@ static bool rest_headers(HTTPRequest* req, if (count < 1 || count > 2000) return RESTERR(req, HTTP_BAD_REQUEST, "Header count out of range: " + path[0]); - string hashStr = path[1]; + std::string hashStr = path[1]; uint256 hash; if (!ParseHashStr(hashStr, hash)) return RESTERR(req, HTTP_BAD_REQUEST, "Invalid hash: " + hashStr); @@ -168,14 +166,14 @@ static bool rest_headers(HTTPRequest* req, switch (rf) { case RF_BINARY: { - string binaryHeader = ssHeader.str(); + std::string binaryHeader = ssHeader.str(); req->WriteHeader("Content-Type", "application/octet-stream"); req->WriteReply(HTTP_OK, binaryHeader); return true; } case RF_HEX: { - string strHex = HexStr(ssHeader.begin(), ssHeader.end()) + "\n"; + std::string strHex = HexStr(ssHeader.begin(), ssHeader.end()) + "\n"; req->WriteHeader("Content-Type", "text/plain"); req->WriteReply(HTTP_OK, strHex); return true; @@ -185,7 +183,7 @@ static bool rest_headers(HTTPRequest* req, BOOST_FOREACH(const CBlockIndex *pindex, headers) { jsonHeaders.push_back(blockheaderToJSON(pindex)); } - string strJSON = jsonHeaders.write() + "\n"; + std::string strJSON = jsonHeaders.write() + "\n"; req->WriteHeader("Content-Type", "application/json"); req->WriteReply(HTTP_OK, strJSON); return true; @@ -232,14 +230,14 @@ static bool rest_block(HTTPRequest* req, switch (rf) { case RF_BINARY: { - string binaryBlock = ssBlock.str(); + std::string binaryBlock = ssBlock.str(); req->WriteHeader("Content-Type", "application/octet-stream"); req->WriteReply(HTTP_OK, binaryBlock); return true; } case RF_HEX: { - string strHex = HexStr(ssBlock.begin(), ssBlock.end()) + "\n"; + std::string strHex = HexStr(ssBlock.begin(), ssBlock.end()) + "\n"; req->WriteHeader("Content-Type", "text/plain"); req->WriteReply(HTTP_OK, strHex); return true; @@ -247,7 +245,7 @@ static bool rest_block(HTTPRequest* req, case RF_JSON: { UniValue objBlock = blockToJSON(block, pblockindex, showTxDetails); - string strJSON = objBlock.write() + "\n"; + std::string strJSON = objBlock.write() + "\n"; req->WriteHeader("Content-Type", "application/json"); req->WriteReply(HTTP_OK, strJSON); return true; @@ -287,7 +285,7 @@ static bool rest_chaininfo(HTTPRequest* req, const std::string& strURIPart) JSONRPCRequest jsonRequest; jsonRequest.params = UniValue(UniValue::VARR); UniValue chainInfoObject = getblockchaininfo(jsonRequest); - string strJSON = chainInfoObject.write() + "\n"; + std::string strJSON = chainInfoObject.write() + "\n"; req->WriteHeader("Content-Type", "application/json"); req->WriteReply(HTTP_OK, strJSON); return true; @@ -312,7 +310,7 @@ static bool rest_mempool_info(HTTPRequest* req, const std::string& strURIPart) case RF_JSON: { UniValue mempoolInfoObject = mempoolInfoToJSON(); - string strJSON = mempoolInfoObject.write() + "\n"; + std::string strJSON = mempoolInfoObject.write() + "\n"; req->WriteHeader("Content-Type", "application/json"); req->WriteReply(HTTP_OK, strJSON); return true; @@ -337,7 +335,7 @@ static bool rest_mempool_contents(HTTPRequest* req, const std::string& strURIPar case RF_JSON: { UniValue mempoolObject = mempoolToJSON(true); - string strJSON = mempoolObject.write() + "\n"; + std::string strJSON = mempoolObject.write() + "\n"; req->WriteHeader("Content-Type", "application/json"); req->WriteReply(HTTP_OK, strJSON); return true; @@ -372,14 +370,14 @@ static bool rest_tx(HTTPRequest* req, const std::string& strURIPart) switch (rf) { case RF_BINARY: { - string binaryTx = ssTx.str(); + std::string binaryTx = ssTx.str(); req->WriteHeader("Content-Type", "application/octet-stream"); req->WriteReply(HTTP_OK, binaryTx); return true; } case RF_HEX: { - string strHex = HexStr(ssTx.begin(), ssTx.end()) + "\n"; + std::string strHex = HexStr(ssTx.begin(), ssTx.end()) + "\n"; req->WriteHeader("Content-Type", "text/plain"); req->WriteReply(HTTP_OK, strHex); return true; @@ -388,7 +386,7 @@ static bool rest_tx(HTTPRequest* req, const std::string& strURIPart) case RF_JSON: { UniValue objTx(UniValue::VOBJ); TxToJSON(*tx, hashBlock, objTx); - string strJSON = objTx.write() + "\n"; + std::string strJSON = objTx.write() + "\n"; req->WriteHeader("Content-Type", "application/json"); req->WriteReply(HTTP_OK, strJSON); return true; @@ -410,7 +408,7 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart) std::string param; const RetFormat rf = ParseDataFormat(param, strURIPart); - vector<string> uriParts; + std::vector<std::string> uriParts; if (param.length() > 1) { std::string strUriParams = param.substr(1); @@ -424,7 +422,7 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart) bool fInputParsed = false; bool fCheckMemPool = false; - vector<COutPoint> vOutPoints; + std::vector<COutPoint> vOutPoints; // parse/deserialize input // input-format = output-format, rest/getutxos/bin requires binary input, gives binary output, ... @@ -498,8 +496,8 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart) return RESTERR(req, HTTP_BAD_REQUEST, 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-readable string representation) - vector<unsigned char> bitmap; - vector<CCoin> outs; + std::vector<unsigned char> bitmap; + std::vector<CCoin> outs; std::string bitmapStringRepresentation; std::vector<bool> hits; bitmap.resize((vOutPoints.size() + 7) / 8); @@ -546,7 +544,7 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart) // use exact same output as mentioned in Bip64 CDataStream ssGetUTXOResponse(SER_NETWORK, PROTOCOL_VERSION); ssGetUTXOResponse << chainActive.Height() << chainActive.Tip()->GetBlockHash() << bitmap << outs; - string ssGetUTXOResponseString = ssGetUTXOResponse.str(); + std::string ssGetUTXOResponseString = ssGetUTXOResponse.str(); req->WriteHeader("Content-Type", "application/octet-stream"); req->WriteReply(HTTP_OK, ssGetUTXOResponseString); @@ -556,7 +554,7 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart) case RF_HEX: { CDataStream ssGetUTXOResponse(SER_NETWORK, PROTOCOL_VERSION); ssGetUTXOResponse << chainActive.Height() << chainActive.Tip()->GetBlockHash() << bitmap << outs; - string strHex = HexStr(ssGetUTXOResponse.begin(), ssGetUTXOResponse.end()) + "\n"; + std::string strHex = HexStr(ssGetUTXOResponse.begin(), ssGetUTXOResponse.end()) + "\n"; req->WriteHeader("Content-Type", "text/plain"); req->WriteReply(HTTP_OK, strHex); @@ -588,7 +586,7 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart) objGetUTXOResponse.push_back(Pair("utxos", utxos)); // return json string - string strJSON = objGetUTXOResponse.write() + "\n"; + std::string strJSON = objGetUTXOResponse.write() + "\n"; req->WriteHeader("Content-Type", "application/json"); req->WriteReply(HTTP_OK, strJSON); return true; diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 368654bfa6..6826ce4a79 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -43,10 +43,15 @@ static CUpdatedBlock latestblock; extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry); void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex); +/** + * Get the difficulty of the net wrt to the given block index, or the chain tip if + * not provided. + * + * @return A floating point number that is a multiple of the main net minimum + * difficulty (4295032833 hashes). + */ double GetDifficulty(const CBlockIndex* blockindex) { - // Floating point number that is a multiple of the minimum difficulty, - // minimum difficulty = 1.0. if (blockindex == NULL) { if (chainActive.Tip() == NULL) @@ -820,7 +825,8 @@ UniValue pruneblockchain(const JSONRPCRequest& request) throw runtime_error( "pruneblockchain\n" "\nArguments:\n" - "1. \"height\" (numeric, required) The block height to prune up to. May be set to a discrete height, or to a unix timestamp to prune based on block time.\n" + "1. \"height\" (numeric, required) The block height to prune up to. May be set to a discrete height, or a unix timestamp\n" + " to prune blocks whose block time is at least 2 hours older than the provided timestamp.\n" "\nResult:\n" "n (numeric) Height of the last block pruned.\n" "\nExamples:\n" @@ -839,7 +845,8 @@ UniValue pruneblockchain(const JSONRPCRequest& request) // Height value more than a billion is too high to be a block height, and // too low to be a block time (corresponds to timestamp from Sep 2001). if (heightParam > 1000000000) { - CBlockIndex* pindex = chainActive.FindEarliestAtLeast(heightParam); + // Add a 2 hour buffer to include blocks which might have had old timestamps + CBlockIndex* pindex = chainActive.FindEarliestAtLeast(heightParam - 7200); if (!pindex) { throw JSONRPCError(RPC_INTERNAL_ERROR, "Could not find block with at least the specified timestamp."); } diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp index 5bdd84e555..29bdb37682 100644 --- a/src/rpc/client.cpp +++ b/src/rpc/client.cpp @@ -24,7 +24,7 @@ public: }; /** - * Specifiy a (method, idx, name) here if the argument is a non-string RPC + * Specify a (method, idx, name) here if the argument is a non-string RPC * argument and needs to be converted from JSON. * * @note Parameter indexes start from 0. diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index e46f55a8aa..7708771d00 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -282,7 +282,7 @@ UniValue prioritisetransaction(const JSONRPCRequest& request) uint256 hash = ParseHashStr(request.params[0].get_str(), "txid"); CAmount nAmount = request.params[2].get_int64(); - mempool.PrioritiseTransaction(hash, request.params[0].get_str(), request.params[1].get_real(), nAmount); + mempool.PrioritiseTransaction(hash, request.params[1].get_real(), nAmount); return true; } @@ -676,8 +676,12 @@ UniValue getblocktemplate(const JSONRPCRequest& request) nSigOpLimit /= WITNESS_SCALE_FACTOR; } result.push_back(Pair("sigoplimit", nSigOpLimit)); - result.push_back(Pair("sizelimit", (int64_t)MAX_BLOCK_SERIALIZED_SIZE)); - result.push_back(Pair("weightlimit", (int64_t)MAX_BLOCK_WEIGHT)); + if (fPreSegWit) { + result.push_back(Pair("sizelimit", (int64_t)MAX_BLOCK_BASE_SIZE)); + } else { + result.push_back(Pair("sizelimit", (int64_t)MAX_BLOCK_SERIALIZED_SIZE)); + result.push_back(Pair("weightlimit", (int64_t)MAX_BLOCK_WEIGHT)); + } result.push_back(Pair("curtime", pblock->GetBlockTime())); result.push_back(Pair("bits", strprintf("%08x", pblock->nBits))); result.push_back(Pair("height", (int64_t)(pindexPrev->nHeight+1))); @@ -697,7 +701,7 @@ public: bool found; CValidationState state; - submitblock_StateCatcher(const uint256 &hashIn) : hash(hashIn), found(false), state() {}; + submitblock_StateCatcher(const uint256 &hashIn) : hash(hashIn), found(false), state() {} protected: virtual void BlockChecked(const CBlock& block, const CValidationState& stateIn) { @@ -705,7 +709,7 @@ protected: return; found = true; state = stateIn; - }; + } }; UniValue submitblock(const JSONRPCRequest& request) diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 54d8c3e035..c84eab7d23 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -167,6 +167,7 @@ UniValue validateaddress(const JSONRPCRequest& request) " \"pubkey\" : \"publickeyhex\", (string) The hex value of the raw public key\n" " \"iscompressed\" : true|false, (boolean) If the address is compressed\n" " \"account\" : \"account\" (string) DEPRECATED. The account associated with the address, \"\" is the default account\n" + " \"timestamp\" : timestamp, (number, optional) The creation time of the key if available in seconds since epoch (Jan 1 1970 GMT)\n" " \"hdkeypath\" : \"keypath\" (string, optional) The HD keypath if the key is HD and available\n" " \"hdmasterkeyid\" : \"<hash160>\" (string, optional) The Hash160 of the HD master pubkey\n" "}\n" @@ -204,10 +205,19 @@ UniValue validateaddress(const JSONRPCRequest& request) if (pwalletMain && pwalletMain->mapAddressBook.count(dest)) ret.push_back(Pair("account", pwalletMain->mapAddressBook[dest].name)); CKeyID keyID; - if (pwalletMain && address.GetKeyID(keyID) && pwalletMain->mapKeyMetadata.count(keyID) && !pwalletMain->mapKeyMetadata[keyID].hdKeypath.empty()) - { - ret.push_back(Pair("hdkeypath", pwalletMain->mapKeyMetadata[keyID].hdKeypath)); - ret.push_back(Pair("hdmasterkeyid", pwalletMain->mapKeyMetadata[keyID].hdMasterKeyID.GetHex())); + if (pwalletMain) { + const auto& meta = pwalletMain->mapKeyMetadata; + auto it = address.GetKeyID(keyID) ? meta.find(keyID) : meta.end(); + if (it == meta.end()) { + it = meta.find(CScriptID(scriptPubKey)); + } + if (it != meta.end()) { + ret.push_back(Pair("timestamp", it->second.nCreateTime)); + if (!it->second.hdKeypath.empty()) { + ret.push_back(Pair("hdkeypath", it->second.hdKeypath)); + ret.push_back(Pair("hdmasterkeyid", it->second.hdMasterKeyID.GetHex())); + } + } } #endif } @@ -337,11 +347,11 @@ UniValue verifymessage(const JSONRPCRequest& request) "\nUnlock the wallet for 30 seconds\n" + HelpExampleCli("walletpassphrase", "\"mypassphrase\" 30") + "\nCreate the signature\n" - + HelpExampleCli("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" \"my message\"") + + + HelpExampleCli("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"my message\"") + "\nVerify the signature\n" - + HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" \"signature\" \"my message\"") + + + HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"signature\" \"my message\"") + "\nAs json rpc\n" - + HelpExampleRpc("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\", \"signature\", \"my message\"") + + HelpExampleRpc("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\", \"signature\", \"my message\"") ); LOCK(cs_main); @@ -390,7 +400,7 @@ UniValue signmessagewithprivkey(const JSONRPCRequest& request) "\nCreate the signature\n" + HelpExampleCli("signmessagewithprivkey", "\"privkey\" \"my message\"") + "\nVerify the signature\n" - + HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" \"signature\" \"my message\"") + + + HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"signature\" \"my message\"") + "\nAs json rpc\n" + HelpExampleRpc("signmessagewithprivkey", "\"privkey\", \"my message\"") ); @@ -431,22 +441,16 @@ UniValue setmocktime(const JSONRPCRequest& request) if (!Params().MineBlocksOnDemand()) throw runtime_error("setmocktime for regression testing (-regtest mode) only"); - // cs_vNodes is locked and node send/receive times are updated - // atomically with the time change to prevent peers from being - // disconnected because we think we haven't communicated with them - // in a long time. + // For now, don't change mocktime if we're in the middle of validation, as + // this could have an effect on mempool time-based eviction, as well as + // IsCurrentForFeeEstimation() and IsInitialBlockDownload(). + // TODO: figure out the right way to synchronize around mocktime, and + // ensure all call sites of GetTime() are accessing this safely. LOCK(cs_main); RPCTypeCheck(request.params, boost::assign::list_of(UniValue::VNUM)); SetMockTime(request.params[0].get_int64()); - uint64_t t = GetTime(); - if(g_connman) { - g_connman->ForEachNode([t](CNode* pnode) { - pnode->nLastSend = pnode->nLastRecv = t; - }); - } - return NullUniValue; } diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp index 27b9963a10..f590db5efa 100644 --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -10,6 +10,7 @@ #include "net.h" #include "net_processing.h" #include "netbase.h" +#include "policy/policy.h" #include "protocol.h" #include "sync.h" #include "timedata.h" @@ -150,7 +151,7 @@ UniValue getpeerinfo(const JSONRPCRequest& request) obj.push_back(Pair("pingwait", stats.dPingWait)); obj.push_back(Pair("version", stats.nVersion)); // Use the sanitized form of subver here, to avoid tricksy remote peers from - // corrupting or modifiying the JSON output by putting special characters in + // corrupting or modifying the JSON output by putting special characters in // their ver message. obj.push_back(Pair("subver", stats.cleanSubVer)); obj.push_back(Pair("inbound", stats.fInbound)); @@ -417,6 +418,7 @@ UniValue getnetworkinfo(const JSONRPCRequest& request) " ,...\n" " ],\n" " \"relayfee\": x.xxxxxxxx, (numeric) minimum relay fee for non-free transactions in " + CURRENCY_UNIT + "/kB\n" + " \"incrementalfee\": x.xxxxxxxx, (numeric) minimum fee increment for mempool limiting or BIP 125 replacement in " + CURRENCY_UNIT + "/kB\n" " \"localaddresses\": [ (array) list of local addresses\n" " {\n" " \"address\": \"xxxx\", (string) network address\n" @@ -447,6 +449,7 @@ UniValue getnetworkinfo(const JSONRPCRequest& request) } obj.push_back(Pair("networks", GetNetworksInfo())); obj.push_back(Pair("relayfee", ValueFromAmount(::minRelayTxFee.GetFeePerK()))); + obj.push_back(Pair("incrementalfee", ValueFromAmount(::incrementalRelayFee.GetFeePerK()))); UniValue localAddresses(UniValue::VARR); { LOCK(cs_mapLocalHost); diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index c10de45f8b..bf16f27498 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -245,7 +245,6 @@ UniValue gettxoutproof(const JSONRPCRequest& request) "unspent output in the utxo for this transaction. To make it always work,\n" "you need to maintain a transaction index, using the -txindex command line option or\n" "specify the block in which the transaction is included manually (by blockhash).\n" - "\nReturn the raw transaction data.\n" "\nArguments:\n" "1. \"txids\" (string) A json array of txids to filter\n" " [\n" @@ -835,7 +834,9 @@ UniValue signrawtransaction(const JSONRPCRequest& request) // ... and merge in other signatures: BOOST_FOREACH(const CMutableTransaction& txv, txVariants) { - sigdata = CombineSignatures(prevPubKey, TransactionSignatureChecker(&txConst, i, amount), sigdata, DataFromTransaction(txv, i)); + if (txv.vin.size() > i) { + sigdata = CombineSignatures(prevPubKey, TransactionSignatureChecker(&txConst, i, amount), sigdata, DataFromTransaction(txv, i)); + } } UpdateTransaction(mergedTx, i, sigdata); diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 283d458c8d..0d29f245ae 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -18,8 +18,6 @@ #include <boost/bind.hpp> #include <boost/filesystem.hpp> #include <boost/foreach.hpp> -#include <boost/iostreams/concepts.hpp> -#include <boost/iostreams/stream.hpp> #include <boost/shared_ptr.hpp> #include <boost/signals2/signal.hpp> #include <boost/thread.hpp> @@ -195,9 +193,6 @@ std::string CRPCTable::help(const std::string& strCommand) const { const CRPCCommand *pcmd = command.second; string strMethod = pcmd->name; - // We already filter duplicates, but these deprecated screw up the sort order - if (strMethod.find("label") != string::npos) - continue; if ((strCommand != "" || pcmd->category == "hidden") && strMethod != strCommand) continue; try diff --git a/src/script/script.cpp b/src/script/script.cpp index 828ce1a056..9f4741b1cd 100644 --- a/src/script/script.cpp +++ b/src/script/script.cpp @@ -129,7 +129,7 @@ const char* GetOpName(opcodetype opcode) case OP_CHECKMULTISIG : return "OP_CHECKMULTISIG"; case OP_CHECKMULTISIGVERIFY : return "OP_CHECKMULTISIGVERIFY"; - // expanson + // expansion case OP_NOP1 : return "OP_NOP1"; case OP_CHECKLOCKTIMEVERIFY : return "OP_CHECKLOCKTIMEVERIFY"; case OP_CHECKSEQUENCEVERIFY : return "OP_CHECKSEQUENCEVERIFY"; diff --git a/src/script/sigcache.cpp b/src/script/sigcache.cpp index 09bedc5460..6f47b725fb 100644 --- a/src/script/sigcache.cpp +++ b/src/script/sigcache.cpp @@ -90,11 +90,13 @@ public: static CSignatureCache signatureCache; } -// To be called once in AppInit2/TestingSetup to initialize the signatureCache +// To be called once in AppInitMain/BasicTestingSetup to initialize the +// signatureCache. void InitSignatureCache() { - size_t nMaxCacheSize = GetArg("-maxsigcachesize", DEFAULT_MAX_SIG_CACHE_SIZE) * ((size_t) 1 << 20); - if (nMaxCacheSize <= 0) return; + // nMaxCacheSize is unsigned. If -maxsigcachesize is set to zero, + // setup_bytes creates the minimum possible cache (2 elements). + size_t nMaxCacheSize = std::min(std::max((int64_t)0, GetArg("-maxsigcachesize", DEFAULT_MAX_SIG_CACHE_SIZE)), MAX_MAX_SIG_CACHE_SIZE) * ((size_t) 1 << 20); size_t nElems = signatureCache.setup_bytes(nMaxCacheSize); LogPrintf("Using %zu MiB out of %zu requested for signature cache, able to store %zu elements\n", (nElems*sizeof(uint256)) >>20, nMaxCacheSize>>20, nElems); diff --git a/src/script/sigcache.h b/src/script/sigcache.h index c123a9ba0f..238952bb95 100644 --- a/src/script/sigcache.h +++ b/src/script/sigcache.h @@ -14,6 +14,8 @@ // systems). Due to how we count cache size, actual memory usage is slightly // more (~32.25 MB) static const unsigned int DEFAULT_MAX_SIG_CACHE_SIZE = 32; +// Maximum sig cache size allowed +static const int64_t MAX_MAX_SIG_CACHE_SIZE = 16384; class CPubKey; diff --git a/src/sync.cpp b/src/sync.cpp index a18d0f1485..fce57f1df9 100644 --- a/src/sync.cpp +++ b/src/sync.cpp @@ -77,52 +77,28 @@ boost::thread_specific_ptr<LockStack> lockstack; static void potential_deadlock_detected(const std::pair<void*, void*>& mismatch, const LockStack& s1, const LockStack& s2) { - // We attempt to not assert on probably-not deadlocks by assuming that - // a try lock will immediately have otherwise bailed if it had - // failed to get the lock - // We do this by, for the locks which triggered the potential deadlock, - // in either lockorder, checking that the second of the two which is locked - // is only a TRY_LOCK, ignoring locks if they are reentrant. - bool firstLocked = false; - bool secondLocked = false; - bool onlyMaybeDeadlock = false; - LogPrintf("POTENTIAL DEADLOCK DETECTED\n"); LogPrintf("Previous lock order was:\n"); BOOST_FOREACH (const PAIRTYPE(void*, CLockLocation) & i, s2) { if (i.first == mismatch.first) { LogPrintf(" (1)"); - if (!firstLocked && secondLocked && i.second.fTry) - onlyMaybeDeadlock = true; - firstLocked = true; } if (i.first == mismatch.second) { LogPrintf(" (2)"); - if (!secondLocked && firstLocked && i.second.fTry) - onlyMaybeDeadlock = true; - secondLocked = true; } LogPrintf(" %s\n", i.second.ToString()); } - firstLocked = false; - secondLocked = false; LogPrintf("Current lock order is:\n"); BOOST_FOREACH (const PAIRTYPE(void*, CLockLocation) & i, s1) { if (i.first == mismatch.first) { LogPrintf(" (1)"); - if (!firstLocked && secondLocked && i.second.fTry) - onlyMaybeDeadlock = true; - firstLocked = true; } if (i.first == mismatch.second) { LogPrintf(" (2)"); - if (!secondLocked && firstLocked && i.second.fTry) - onlyMaybeDeadlock = true; - secondLocked = true; } LogPrintf(" %s\n", i.second.ToString()); } - assert(onlyMaybeDeadlock); + assert(false); } static void push_lock(void* c, const CLockLocation& locklocation, bool fTry) @@ -134,21 +110,19 @@ static void push_lock(void* c, const CLockLocation& locklocation, bool fTry) (*lockstack).push_back(std::make_pair(c, locklocation)); - if (!fTry) { - BOOST_FOREACH (const PAIRTYPE(void*, CLockLocation) & i, (*lockstack)) { - if (i.first == c) - break; + BOOST_FOREACH (const PAIRTYPE(void*, CLockLocation) & i, (*lockstack)) { + if (i.first == c) + break; - std::pair<void*, void*> p1 = std::make_pair(i.first, c); - if (lockdata.lockorders.count(p1)) - continue; - lockdata.lockorders[p1] = (*lockstack); + std::pair<void*, void*> p1 = std::make_pair(i.first, c); + if (lockdata.lockorders.count(p1)) + continue; + lockdata.lockorders[p1] = (*lockstack); - std::pair<void*, void*> p2 = std::make_pair(c, i.first); - lockdata.invlockorders.insert(p2); - if (lockdata.lockorders.count(p2)) - potential_deadlock_detected(p1, lockdata.lockorders[p2], lockdata.lockorders[p1]); - } + std::pair<void*, void*> p2 = std::make_pair(c, i.first); + lockdata.invlockorders.insert(p2); + if (lockdata.lockorders.count(p2)) + potential_deadlock_detected(p1, lockdata.lockorders[p2], lockdata.lockorders[p1]); } } diff --git a/src/test/DoS_tests.cpp b/src/test/DoS_tests.cpp index 9345a44fb0..c62e6ae838 100644 --- a/src/test/DoS_tests.cpp +++ b/src/test/DoS_tests.cpp @@ -23,7 +23,7 @@ #include <boost/foreach.hpp> #include <boost/test/unit_test.hpp> -// Tests this internal-to-main.cpp method: +// Tests these internal-to-net_processing.cpp methods: extern bool AddOrphanTx(const CTransactionRef& tx, NodeId peer); extern void EraseOrphansFor(NodeId peer); extern unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans); @@ -55,6 +55,7 @@ BOOST_AUTO_TEST_CASE(DoS_banning) dummyNode1.SetSendVersion(PROTOCOL_VERSION); GetNodeSignals().InitializeNode(&dummyNode1, *connman); dummyNode1.nVersion = 1; + dummyNode1.fSuccessfullyConnected = true; Misbehaving(dummyNode1.GetId(), 100); // Should get banned SendMessages(&dummyNode1, *connman, interruptDummy); BOOST_CHECK(connman->IsBanned(addr1)); @@ -65,6 +66,7 @@ BOOST_AUTO_TEST_CASE(DoS_banning) dummyNode2.SetSendVersion(PROTOCOL_VERSION); GetNodeSignals().InitializeNode(&dummyNode2, *connman); dummyNode2.nVersion = 1; + dummyNode2.fSuccessfullyConnected = true; Misbehaving(dummyNode2.GetId(), 50); SendMessages(&dummyNode2, *connman, interruptDummy); BOOST_CHECK(!connman->IsBanned(addr2)); // 2 not banned yet... @@ -85,6 +87,7 @@ BOOST_AUTO_TEST_CASE(DoS_banscore) dummyNode1.SetSendVersion(PROTOCOL_VERSION); GetNodeSignals().InitializeNode(&dummyNode1, *connman); dummyNode1.nVersion = 1; + dummyNode1.fSuccessfullyConnected = true; Misbehaving(dummyNode1.GetId(), 100); SendMessages(&dummyNode1, *connman, interruptDummy); BOOST_CHECK(!connman->IsBanned(addr1)); @@ -110,6 +113,7 @@ BOOST_AUTO_TEST_CASE(DoS_bantime) dummyNode.SetSendVersion(PROTOCOL_VERSION); GetNodeSignals().InitializeNode(&dummyNode, *connman); dummyNode.nVersion = 1; + dummyNode.fSuccessfullyConnected = true; Misbehaving(dummyNode.GetId(), 100); SendMessages(&dummyNode, *connman, interruptDummy); diff --git a/src/test/bip32_tests.cpp b/src/test/bip32_tests.cpp index 7f1c2a32dd..c148ad6d82 100644 --- a/src/test/bip32_tests.cpp +++ b/src/test/bip32_tests.cpp @@ -78,6 +78,15 @@ TestVector test2 = "xprvA2nrNbFZABcdryreWet9Ea4LvTJcGsqrMzxHx98MMrotbir7yrKCEXw7nadnHM8Dq38EGfSh6dqA9QWTyefMLEcBYJUuekgW4BYPJcr9E7j", 0); +TestVector test3 = + TestVector("4b381541583be4423346c643850da4b320e46a87ae3d2a4e6da11eba819cd4acba45d239319ac14f863b8d5ab5a0d0c64d2e8a1e7d1457df2e5a3c51c73235be") + ("xpub661MyMwAqRbcEZVB4dScxMAdx6d4nFc9nvyvH3v4gJL378CSRZiYmhRoP7mBy6gSPSCYk6SzXPTf3ND1cZAceL7SfJ1Z3GC8vBgp2epUt13", + "xprv9s21ZrQH143K25QhxbucbDDuQ4naNntJRi4KUfWT7xo4EKsHt2QJDu7KXp1A3u7Bi1j8ph3EGsZ9Xvz9dGuVrtHHs7pXeTzjuxBrCmmhgC6", + 0x80000000) + ("xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y", + "xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L", + 0); + void RunTest(const TestVector &test) { std::vector<unsigned char> seed = ParseHex(test.strHexMaster); CExtKey key; @@ -146,4 +155,8 @@ BOOST_AUTO_TEST_CASE(bip32_test2) { RunTest(test2); } +BOOST_AUTO_TEST_CASE(bip32_test3) { + RunTest(test3); +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/data/tx_invalid.json b/src/test/data/tx_invalid.json index f7d9e1847f..2235bd0ae7 100644 --- a/src/test/data/tx_invalid.json +++ b/src/test/data/tx_invalid.json @@ -1,7 +1,7 @@ [ ["The following are deserialized transactions which are invalid."], ["They are in the form"], -["[[[prevout hash, prevout index, prevout scriptPubKey], [input 2], ...],"], +["[[[prevout hash, prevout index, prevout scriptPubKey, amount?], [input 2], ...],"], ["serializedTransaction, verifyFlags]"], ["Objects that are only a single string (like this one) are ignored"], diff --git a/src/test/data/tx_valid.json b/src/test/data/tx_valid.json index a3f47fcee2..d70fa54333 100644 --- a/src/test/data/tx_valid.json +++ b/src/test/data/tx_valid.json @@ -1,7 +1,7 @@ [ ["The following are deserialized transactions which are valid."], ["They are in the form"], -["[[[prevout hash, prevout index, prevout scriptPubKey], [input 2], ...],"], +["[[[prevout hash, prevout index, prevout scriptPubKey, amount?], [input 2], ...],"], ["serializedTransaction, verifyFlags]"], ["Objects that are only a single string (like this one) are ignored"], diff --git a/src/test/dbwrapper_tests.cpp b/src/test/dbwrapper_tests.cpp index d5d158027b..22c90bd95b 100644 --- a/src/test/dbwrapper_tests.cpp +++ b/src/test/dbwrapper_tests.cpp @@ -277,7 +277,7 @@ BOOST_AUTO_TEST_CASE(iterator_string_ordering) CDBWrapper dbw(ph, (1 << 20), true, false, false); for (int x=0x00; x<10; ++x) { for (int y = 0; y < 10; y++) { - sprintf(buf, "%d", x); + snprintf(buf, sizeof(buf), "%d", x); StringContentsSerializer key(buf); for (int z = 0; z < y; z++) key += key; @@ -293,12 +293,12 @@ BOOST_AUTO_TEST_CASE(iterator_string_ordering) seek_start = 0; else seek_start = 5; - sprintf(buf, "%d", seek_start); + snprintf(buf, sizeof(buf), "%d", seek_start); StringContentsSerializer seek_key(buf); it->Seek(seek_key); for (int x=seek_start; x<10; ++x) { for (int y = 0; y < 10; y++) { - sprintf(buf, "%d", x); + snprintf(buf, sizeof(buf), "%d", x); std::string exp_key(buf); for (int z = 0; z < y; z++) exp_key += exp_key; diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp index 2f74f57d00..5dbbb1b634 100644 --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -9,6 +9,7 @@ #include "consensus/validation.h" #include "validation.h" #include "miner.h" +#include "policy/policy.h" #include "pubkey.h" #include "script/standard.h" #include "txmempool.h" @@ -24,6 +25,17 @@ BOOST_FIXTURE_TEST_SUITE(miner_tests, TestingSetup) +static CFeeRate blockMinFeeRate = CFeeRate(DEFAULT_BLOCK_MIN_TX_FEE); + +static BlockAssembler AssemblerForTest(const CChainParams& params) { + BlockAssembler::Options options; + + options.nBlockMaxWeight = MAX_BLOCK_WEIGHT; + options.nBlockMaxSize = MAX_BLOCK_SERIALIZED_SIZE; + options.blockMinFeeRate = blockMinFeeRate; + return BlockAssembler(params, options); +} + static struct { unsigned char extranonce; @@ -107,12 +119,12 @@ void TestPackageSelection(const CChainParams& chainparams, CScript scriptPubKey, uint256 hashHighFeeTx = tx.GetHash(); mempool.addUnchecked(hashHighFeeTx, entry.Fee(50000).Time(GetTime()).SpendsCoinbase(false).FromTx(tx)); - std::unique_ptr<CBlockTemplate> pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey); + std::unique_ptr<CBlockTemplate> pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey); BOOST_CHECK(pblocktemplate->block.vtx[1]->GetHash() == hashParentTx); BOOST_CHECK(pblocktemplate->block.vtx[2]->GetHash() == hashHighFeeTx); BOOST_CHECK(pblocktemplate->block.vtx[3]->GetHash() == hashMediumFeeTx); - // Test that a package below the min relay fee doesn't get included + // Test that a package below the block min tx fee doesn't get included tx.vin[0].prevout.hash = hashHighFeeTx; tx.vout[0].nValue = 5000000000LL - 1000 - 50000; // 0 fee uint256 hashFreeTx = tx.GetHash(); @@ -120,14 +132,14 @@ void TestPackageSelection(const CChainParams& chainparams, CScript scriptPubKey, size_t freeTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); // Calculate a fee on child transaction that will put the package just - // below the min relay fee (assuming 1 child tx of the same size). - CAmount feeToUse = minRelayTxFee.GetFee(2*freeTxSize) - 1; + // below the block min tx fee (assuming 1 child tx of the same size). + CAmount feeToUse = blockMinFeeRate.GetFee(2*freeTxSize) - 1; tx.vin[0].prevout.hash = hashFreeTx; tx.vout[0].nValue = 5000000000LL - 1000 - 50000 - feeToUse; uint256 hashLowFeeTx = tx.GetHash(); mempool.addUnchecked(hashLowFeeTx, entry.Fee(feeToUse).FromTx(tx)); - pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey); + pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey); // Verify that the free tx and the low fee tx didn't get selected for (size_t i=0; i<pblocktemplate->block.vtx.size(); ++i) { BOOST_CHECK(pblocktemplate->block.vtx[i]->GetHash() != hashFreeTx); @@ -141,7 +153,7 @@ void TestPackageSelection(const CChainParams& chainparams, CScript scriptPubKey, tx.vout[0].nValue -= 2; // Now we should be just over the min relay fee hashLowFeeTx = tx.GetHash(); mempool.addUnchecked(hashLowFeeTx, entry.Fee(feeToUse+2).FromTx(tx)); - pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey); + pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey); BOOST_CHECK(pblocktemplate->block.vtx[4]->GetHash() == hashFreeTx); BOOST_CHECK(pblocktemplate->block.vtx[5]->GetHash() == hashLowFeeTx); @@ -158,11 +170,11 @@ void TestPackageSelection(const CChainParams& chainparams, CScript scriptPubKey, // This tx can't be mined by itself tx.vin[0].prevout.hash = hashFreeTx2; tx.vout.resize(1); - feeToUse = minRelayTxFee.GetFee(freeTxSize); + feeToUse = blockMinFeeRate.GetFee(freeTxSize); tx.vout[0].nValue = 5000000000LL - 100000000 - feeToUse; uint256 hashLowFeeTx2 = tx.GetHash(); mempool.addUnchecked(hashLowFeeTx2, entry.Fee(feeToUse).SpendsCoinbase(false).FromTx(tx)); - pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey); + pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey); // Verify that this tx isn't selected. for (size_t i=0; i<pblocktemplate->block.vtx.size(); ++i) { @@ -175,7 +187,7 @@ void TestPackageSelection(const CChainParams& chainparams, CScript scriptPubKey, tx.vin[0].prevout.n = 1; tx.vout[0].nValue = 100000000 - 10000; // 10k satoshi fee mempool.addUnchecked(tx.GetHash(), entry.Fee(10000).FromTx(tx)); - pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey); + pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey); BOOST_CHECK(pblocktemplate->block.vtx[8]->GetHash() == hashLowFeeTx2); } @@ -198,7 +210,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) fCheckpointsEnabled = false; // Simple block creation, nothing special yet: - BOOST_CHECK(pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey)); // We can't make transactions until we have inputs // Therefore, load 100 blocks :) @@ -229,7 +241,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) } // Just to make sure we can still make simple blocks - BOOST_CHECK(pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey)); const CAmount BLOCKSUBSIDY = 50*COIN; const CAmount LOWFEE = CENT; @@ -253,7 +265,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) mempool.addUnchecked(hash, entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(spendsCoinbase).FromTx(tx)); tx.vin[0].prevout.hash = hash; } - BOOST_CHECK_THROW(BlockAssembler(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error); + BOOST_CHECK_THROW(AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error); mempool.clear(); tx.vin[0].prevout.hash = txFirst[0]->GetHash(); @@ -267,7 +279,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) mempool.addUnchecked(hash, entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(spendsCoinbase).SigOpsCost(80).FromTx(tx)); tx.vin[0].prevout.hash = hash; } - BOOST_CHECK(pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey)); mempool.clear(); // block size > limit @@ -287,13 +299,13 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) mempool.addUnchecked(hash, entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(spendsCoinbase).FromTx(tx)); tx.vin[0].prevout.hash = hash; } - BOOST_CHECK(pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey)); mempool.clear(); // orphan in mempool, template creation fails hash = tx.GetHash(); mempool.addUnchecked(hash, entry.Fee(LOWFEE).Time(GetTime()).FromTx(tx)); - BOOST_CHECK_THROW(BlockAssembler(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error); + BOOST_CHECK_THROW(AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error); mempool.clear(); // child with higher priority than parent @@ -310,7 +322,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vout[0].nValue = tx.vout[0].nValue+BLOCKSUBSIDY-HIGHERFEE; //First txn output + fresh coinbase - new txn fee hash = tx.GetHash(); mempool.addUnchecked(hash, entry.Fee(HIGHERFEE).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); - BOOST_CHECK(pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey)); mempool.clear(); // coinbase in mempool, template creation fails @@ -321,7 +333,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) hash = tx.GetHash(); // give it a fee so it'll get mined mempool.addUnchecked(hash, entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(false).FromTx(tx)); - BOOST_CHECK_THROW(BlockAssembler(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error); + BOOST_CHECK_THROW(AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error); mempool.clear(); // invalid (pre-p2sh) txn in mempool, template creation fails @@ -338,7 +350,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vout[0].nValue -= LOWFEE; hash = tx.GetHash(); mempool.addUnchecked(hash, entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(false).FromTx(tx)); - BOOST_CHECK_THROW(BlockAssembler(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error); + BOOST_CHECK_THROW(AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error); mempool.clear(); // double spend txn pair in mempool, template creation fails @@ -351,7 +363,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vout[0].scriptPubKey = CScript() << OP_2; hash = tx.GetHash(); mempool.addUnchecked(hash, entry.Fee(HIGHFEE).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); - BOOST_CHECK_THROW(BlockAssembler(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error); + BOOST_CHECK_THROW(AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error); mempool.clear(); // subsidy changing @@ -367,7 +379,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) next->BuildSkip(); chainActive.SetTip(next); } - BOOST_CHECK(pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey)); // Extend to a 210000-long block chain. while (chainActive.Tip()->nHeight < 210000) { CBlockIndex* prev = chainActive.Tip(); @@ -379,7 +391,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) next->BuildSkip(); chainActive.SetTip(next); } - BOOST_CHECK(pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey)); // Delete the dummy blocks again. while (chainActive.Tip()->nHeight > nHeight) { CBlockIndex* del = chainActive.Tip(); @@ -465,7 +477,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vin[0].nSequence = CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG | 1; BOOST_CHECK(!TestSequenceLocks(tx, flags)); // Sequence locks fail - BOOST_CHECK(pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey)); // None of the of the absolute height/time locked tx should have made // it into the template because we still check IsFinalTx in CreateNewBlock, @@ -478,7 +490,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) chainActive.Tip()->nHeight++; SetMockTime(chainActive.Tip()->GetMedianTimePast() + 1); - BOOST_CHECK(pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey)); BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 5); chainActive.Tip()->nHeight--; diff --git a/src/test/raii_event_tests.cpp b/src/test/raii_event_tests.cpp index 87d25c0e2c..0f40874f55 100644 --- a/src/test/raii_event_tests.cpp +++ b/src/test/raii_event_tests.cpp @@ -3,6 +3,10 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include <event2/event.h> + +#ifdef EVENT_SET_MEM_FUNCTIONS_IMPLEMENTED +// It would probably be ideal to define dummy test(s) that report skipped, but boost::test doesn't seem to make that practical (at least not in versions available with common distros) + #include <map> #include <stdlib.h> @@ -86,3 +90,5 @@ BOOST_AUTO_TEST_CASE(raii_event_order) } BOOST_AUTO_TEST_SUITE_END() + +#endif // EVENT_SET_MEM_FUNCTIONS_IMPLEMENTED diff --git a/src/test/random_tests.cpp b/src/test/random_tests.cpp new file mode 100644 index 0000000000..d2c46c0daa --- /dev/null +++ b/src/test/random_tests.cpp @@ -0,0 +1,19 @@ +// Copyright (c) 2017 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 "random.h" + +#include "test/test_bitcoin.h" + +#include <boost/test/unit_test.hpp> + +BOOST_FIXTURE_TEST_SUITE(random_tests, BasicTestingSetup) + +BOOST_AUTO_TEST_CASE(osrandom_tests) +{ + BOOST_CHECK(Random_SanityCheck()); +} + +BOOST_AUTO_TEST_SUITE_END() + diff --git a/src/test/serialize_tests.cpp b/src/test/serialize_tests.cpp index 2d54668eaf..9661a66514 100644 --- a/src/test/serialize_tests.cpp +++ b/src/test/serialize_tests.cpp @@ -90,7 +90,7 @@ BOOST_AUTO_TEST_CASE(sizes) BOOST_AUTO_TEST_CASE(floats_conversion) { - // Choose values that map unambigiously to binary floating point to avoid + // Choose values that map unambiguously to binary floating point to avoid // rounding issues at the compiler side. BOOST_CHECK_EQUAL(ser_uint32_to_float(0x00000000), 0.0F); BOOST_CHECK_EQUAL(ser_uint32_to_float(0x3f000000), 0.5F); @@ -109,7 +109,7 @@ BOOST_AUTO_TEST_CASE(floats_conversion) BOOST_AUTO_TEST_CASE(doubles_conversion) { - // Choose values that map unambigiously to binary floating point to avoid + // Choose values that map unambiguously to binary floating point to avoid // rounding issues at the compiler side. BOOST_CHECK_EQUAL(ser_uint64_to_double(0x0000000000000000ULL), 0.0); BOOST_CHECK_EQUAL(ser_uint64_to_double(0x3fe0000000000000ULL), 0.5); diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp index 4785415e3c..51fc6ae0ba 100644 --- a/src/test/test_bitcoin.cpp +++ b/src/test/test_bitcoin.cpp @@ -156,12 +156,12 @@ CTxMemPoolEntry TestMemPoolEntryHelper::FromTx(const CTransaction &txn, CTxMemPo void Shutdown(void* parg) { - exit(0); + exit(EXIT_SUCCESS); } void StartShutdown() { - exit(0); + exit(EXIT_SUCCESS); } bool ShutdownRequested() diff --git a/src/test/test_bitcoin_fuzzy.cpp b/src/test/test_bitcoin_fuzzy.cpp index 376d8e428a..c4983f6f5c 100644 --- a/src/test/test_bitcoin_fuzzy.cpp +++ b/src/test/test_bitcoin_fuzzy.cpp @@ -18,6 +18,7 @@ #include "streams.h" #include "undo.h" #include "version.h" +#include "pubkey.h" #include <stdint.h> #include <unistd.h> @@ -60,6 +61,7 @@ bool read_stdin(std::vector<char> &data) { int main(int argc, char **argv) { + ECCVerifyHandle globalVerifyHandle; std::vector<char> buffer; if (!read_stdin(buffer)) return 0; diff --git a/src/test/testutil.cpp b/src/test/testutil.cpp index 304cffb798..e6d8622979 100644 --- a/src/test/testutil.cpp +++ b/src/test/testutil.cpp @@ -11,23 +11,5 @@ #include <boost/filesystem.hpp> boost::filesystem::path GetTempPath() { -#if BOOST_FILESYSTEM_VERSION == 3 return boost::filesystem::temp_directory_path(); -#else - // TODO: remove when we don't support filesystem v2 anymore - boost::filesystem::path path; -#ifdef WIN32 - char pszPath[MAX_PATH] = ""; - - if (GetTempPathA(MAX_PATH, pszPath)) - path = boost::filesystem::path(pszPath); -#else - path = boost::filesystem::path("/tmp"); -#endif - if (path.empty() || !boost::filesystem::is_directory(path)) { - LogPrintf("GetTempPath(): failed to find temp path\n"); - return boost::filesystem::path(""); - } - return path; -#endif } diff --git a/src/test/versionbits_tests.cpp b/src/test/versionbits_tests.cpp index bae0eff7e5..e2b5573abd 100644 --- a/src/test/versionbits_tests.cpp +++ b/src/test/versionbits_tests.cpp @@ -292,7 +292,7 @@ BOOST_AUTO_TEST_CASE(versionbits_computeblockversion) blocksToMine--; nTime += 600; nHeight += 1; - }; + } nTime = nTimeout; // FAILED is only triggered at the end of a period, so CBV should be setting diff --git a/src/timedata.cpp b/src/timedata.cpp index c72252e6d8..2ff6437c73 100644 --- a/src/timedata.cpp +++ b/src/timedata.cpp @@ -17,8 +17,6 @@ #include <boost/foreach.hpp> -using namespace std; - static CCriticalSection cs_nTimeOffset; static int64_t nTimeOffset = 0; @@ -51,7 +49,7 @@ void AddTimeData(const CNetAddr& ip, int64_t nOffsetSample) { LOCK(cs_nTimeOffset); // Ignore duplicates - static set<CNetAddr> setKnown; + static std::set<CNetAddr> setKnown; if (setKnown.size() == BITCOIN_TIMEDATA_MAX_SAMPLES) return; if (!setKnown.insert(ip).second) diff --git a/src/torcontrol.cpp b/src/torcontrol.cpp index 5571b7de44..c49c5d9eb2 100644 --- a/src/torcontrol.cpp +++ b/src/torcontrol.cpp @@ -372,7 +372,7 @@ private: struct event *reconnect_ev; float reconnect_timeout; CService service; - /** Cooie for SAFECOOKIE auth */ + /** Cookie for SAFECOOKIE auth */ std::vector<uint8_t> cookie; /** ClientNonce for SAFECOOKIE auth */ std::vector<uint8_t> clientNonce; diff --git a/src/txdb.cpp b/src/txdb.cpp index c223abd590..1a30bb58ad 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -14,8 +14,6 @@ #include <boost/thread.hpp> -using namespace std; - static const char DB_COINS = 'c'; static const char DB_BLOCK_FILES = 'f'; static const char DB_TXINDEX = 't'; @@ -32,11 +30,11 @@ CCoinsViewDB::CCoinsViewDB(size_t nCacheSize, bool fMemory, bool fWipe) : db(Get } bool CCoinsViewDB::GetCoins(const uint256 &txid, CCoins &coins) const { - return db.Read(make_pair(DB_COINS, txid), coins); + return db.Read(std::make_pair(DB_COINS, txid), coins); } bool CCoinsViewDB::HaveCoins(const uint256 &txid) const { - return db.Exists(make_pair(DB_COINS, txid)); + return db.Exists(std::make_pair(DB_COINS, txid)); } uint256 CCoinsViewDB::GetBestBlock() const { @@ -53,9 +51,9 @@ bool CCoinsViewDB::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { for (CCoinsMap::iterator it = mapCoins.begin(); it != mapCoins.end();) { if (it->second.flags & CCoinsCacheEntry::DIRTY) { if (it->second.coins.IsPruned()) - batch.Erase(make_pair(DB_COINS, it->first)); + batch.Erase(std::make_pair(DB_COINS, it->first)); else - batch.Write(make_pair(DB_COINS, it->first), it->second.coins); + batch.Write(std::make_pair(DB_COINS, it->first), it->second.coins); changed++; } count++; @@ -73,7 +71,7 @@ CBlockTreeDB::CBlockTreeDB(size_t nCacheSize, bool fMemory, bool fWipe) : CDBWra } bool CBlockTreeDB::ReadBlockFileInfo(int nFile, CBlockFileInfo &info) { - return Read(make_pair(DB_BLOCK_FILES, nFile), info); + return Read(std::make_pair(DB_BLOCK_FILES, nFile), info); } bool CBlockTreeDB::WriteReindexing(bool fReindexing) { @@ -139,23 +137,23 @@ void CCoinsViewDBCursor::Next() bool CBlockTreeDB::WriteBatchSync(const std::vector<std::pair<int, const CBlockFileInfo*> >& fileInfo, int nLastFile, const std::vector<const CBlockIndex*>& blockinfo) { CDBBatch batch(*this); for (std::vector<std::pair<int, const CBlockFileInfo*> >::const_iterator it=fileInfo.begin(); it != fileInfo.end(); it++) { - batch.Write(make_pair(DB_BLOCK_FILES, it->first), *it->second); + batch.Write(std::make_pair(DB_BLOCK_FILES, it->first), *it->second); } batch.Write(DB_LAST_BLOCK, nLastFile); for (std::vector<const CBlockIndex*>::const_iterator it=blockinfo.begin(); it != blockinfo.end(); it++) { - batch.Write(make_pair(DB_BLOCK_INDEX, (*it)->GetBlockHash()), CDiskBlockIndex(*it)); + batch.Write(std::make_pair(DB_BLOCK_INDEX, (*it)->GetBlockHash()), CDiskBlockIndex(*it)); } return WriteBatch(batch, true); } bool CBlockTreeDB::ReadTxIndex(const uint256 &txid, CDiskTxPos &pos) { - return Read(make_pair(DB_TXINDEX, txid), pos); + return Read(std::make_pair(DB_TXINDEX, txid), pos); } bool CBlockTreeDB::WriteTxIndex(const std::vector<std::pair<uint256, CDiskTxPos> >&vect) { CDBBatch batch(*this); for (std::vector<std::pair<uint256,CDiskTxPos> >::const_iterator it=vect.begin(); it!=vect.end(); it++) - batch.Write(make_pair(DB_TXINDEX, it->first), it->second); + batch.Write(std::make_pair(DB_TXINDEX, it->first), it->second); return WriteBatch(batch); } @@ -175,7 +173,7 @@ bool CBlockTreeDB::LoadBlockIndexGuts(boost::function<CBlockIndex*(const uint256 { std::unique_ptr<CDBIterator> pcursor(NewIterator()); - pcursor->Seek(make_pair(DB_BLOCK_INDEX, uint256())); + pcursor->Seek(std::make_pair(DB_BLOCK_INDEX, uint256())); // Load mapBlockIndex while (pcursor->Valid()) { diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 5b085f492d..942a6fcce7 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -18,8 +18,6 @@ #include "utiltime.h" #include "version.h" -using namespace std; - CTxMemPoolEntry::CTxMemPoolEntry(const CTransactionRef& _tx, const CAmount& _nFee, int64_t _nTime, double _entryPriority, unsigned int _entryHeight, CAmount _inChainInputValue, @@ -173,6 +171,8 @@ void CTxMemPool::UpdateTransactionsFromBlock(const std::vector<uint256> &vHashes bool CTxMemPool::CalculateMemPoolAncestors(const CTxMemPoolEntry &entry, setEntries &setAncestors, uint64_t limitAncestorCount, uint64_t limitAncestorSize, uint64_t limitDescendantCount, uint64_t limitDescendantSize, std::string &errString, bool fSearchForParents /* = true */) const { + LOCK(cs); + setEntries parentHashes; const CTransaction &tx = entry.GetTx(); @@ -393,8 +393,9 @@ void CTxMemPool::AddTransactionsUpdated(unsigned int n) bool CTxMemPool::addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, setEntries &setAncestors, bool validFeeEstimate) { + NotifyEntryAdded(entry.GetSharedTx()); // Add to memory pool without checking anything. - // Used by main.cpp AcceptToMemoryPool(), which DOES do + // Used by AcceptToMemoryPool(), which DOES do // all the appropriate checks. LOCK(cs); indexed_transaction_set::iterator newit = mapTx.insert(entry).first; @@ -449,8 +450,9 @@ bool CTxMemPool::addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, return true; } -void CTxMemPool::removeUnchecked(txiter it) +void CTxMemPool::removeUnchecked(txiter it, MemPoolRemovalReason reason) { + NotifyEntryRemoved(it->GetSharedTx(), reason); const uint256 hash = it->GetTx().GetHash(); BOOST_FOREACH(const CTxIn& txin, it->GetTx().vin) mapNextTx.erase(txin.prevout); @@ -502,7 +504,7 @@ void CTxMemPool::CalculateDescendants(txiter entryit, setEntries &setDescendants } } -void CTxMemPool::removeRecursive(const CTransaction &origTx) +void CTxMemPool::removeRecursive(const CTransaction &origTx, MemPoolRemovalReason reason) { // Remove transaction from memory pool { @@ -529,7 +531,8 @@ void CTxMemPool::removeRecursive(const CTransaction &origTx) BOOST_FOREACH(txiter it, txToRemove) { CalculateDescendants(it, setAllRemoves); } - RemoveStaged(setAllRemoves, false); + + RemoveStaged(setAllRemoves, false, reason); } } @@ -567,7 +570,7 @@ void CTxMemPool::removeForReorg(const CCoinsViewCache *pcoins, unsigned int nMem for (txiter it : txToRemove) { CalculateDescendants(it, setAllRemoves); } - RemoveStaged(setAllRemoves, false); + RemoveStaged(setAllRemoves, false, MemPoolRemovalReason::REORG); } void CTxMemPool::removeConflicts(const CTransaction &tx) @@ -581,7 +584,7 @@ void CTxMemPool::removeConflicts(const CTransaction &tx) if (txConflict != tx) { ClearPrioritisation(txConflict.GetHash()); - removeRecursive(txConflict); + removeRecursive(txConflict, MemPoolRemovalReason::CONFLICT); } } } @@ -610,7 +613,7 @@ void CTxMemPool::removeForBlock(const std::vector<CTransactionRef>& vtx, unsigne if (it != mapTx.end()) { setEntries stage; stage.insert(it); - RemoveStaged(stage, true); + RemoveStaged(stage, true, MemPoolRemovalReason::BLOCK); } removeConflicts(*tx); ClearPrioritisation(tx->GetHash()); @@ -655,7 +658,7 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const const int64_t nSpendHeight = GetSpendHeight(mempoolDuplicate); LOCK(cs); - list<const CTxMemPoolEntry*> waitingOnDependants; + std::list<const CTxMemPoolEntry*> waitingOnDependants; for (indexed_transaction_set::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) { unsigned int i = 0; checkTotal += it->GetTxSize(); @@ -813,7 +816,7 @@ std::vector<CTxMemPool::indexed_transaction_set::const_iterator> CTxMemPool::Get return iters; } -void CTxMemPool::queryHashes(vector<uint256>& vtxid) +void CTxMemPool::queryHashes(std::vector<uint256>& vtxid) { LOCK(cs); auto iters = GetSortedDepthAndScore(); @@ -917,7 +920,7 @@ CTxMemPool::ReadFeeEstimates(CAutoFile& filein) return true; } -void CTxMemPool::PrioritiseTransaction(const uint256 hash, const string strHash, double dPriorityDelta, const CAmount& nFeeDelta) +void CTxMemPool::PrioritiseTransaction(const uint256& hash, double dPriorityDelta, const CAmount& nFeeDelta) { { LOCK(cs); @@ -937,7 +940,7 @@ void CTxMemPool::PrioritiseTransaction(const uint256 hash, const string strHash, } } } - LogPrintf("PrioritiseTransaction: %s priority += %f, fee += %d\n", strHash, dPriorityDelta, FormatMoney(nFeeDelta)); + LogPrintf("PrioritiseTransaction: %s priority += %f, fee += %d\n", hash.ToString(), dPriorityDelta, FormatMoney(nFeeDelta)); } void CTxMemPool::ApplyDeltas(const uint256 hash, double &dPriorityDelta, CAmount &nFeeDelta) const @@ -989,11 +992,11 @@ size_t CTxMemPool::DynamicMemoryUsage() const { return memusage::MallocUsage(sizeof(CTxMemPoolEntry) + 15 * sizeof(void*)) * mapTx.size() + memusage::DynamicUsage(mapNextTx) + memusage::DynamicUsage(mapDeltas) + memusage::DynamicUsage(mapLinks) + memusage::DynamicUsage(vTxHashes) + cachedInnerUsage; } -void CTxMemPool::RemoveStaged(setEntries &stage, bool updateDescendants) { +void CTxMemPool::RemoveStaged(setEntries &stage, bool updateDescendants, MemPoolRemovalReason reason) { AssertLockHeld(cs); UpdateForRemoveFromMempool(stage, updateDescendants); BOOST_FOREACH(const txiter& it, stage) { - removeUnchecked(it); + removeUnchecked(it, reason); } } @@ -1009,7 +1012,7 @@ int CTxMemPool::Expire(int64_t time) { BOOST_FOREACH(txiter removeit, toremove) { CalculateDescendants(removeit, stage); } - RemoveStaged(stage, false); + RemoveStaged(stage, false, MemPoolRemovalReason::EXPIRY); return stage.size(); } @@ -1118,7 +1121,7 @@ void CTxMemPool::TrimToSize(size_t sizelimit, std::vector<uint256>* pvNoSpendsRe BOOST_FOREACH(txiter iter, stage) txn.push_back(iter->GetTx()); } - RemoveStaged(stage, false); + RemoveStaged(stage, false, MemPoolRemovalReason::SIZELIMIT); if (pvNoSpendsRemaining) { BOOST_FOREACH(const CTransaction& tx, txn) { BOOST_FOREACH(const CTxIn& txin, tx.vin) { diff --git a/src/txmempool.h b/src/txmempool.h index ffb1c1309b..8a8039ded1 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -20,11 +20,12 @@ #include "sync.h" #include "random.h" -#undef foreach #include "boost/multi_index_container.hpp" #include "boost/multi_index/ordered_index.hpp" #include "boost/multi_index/hashed_index.hpp" +#include <boost/signals2/signal.hpp> + class CAutoFile; class CBlockIndex; @@ -333,6 +334,19 @@ struct TxMempoolInfo int64_t nFeeDelta; }; +/** Reason why a transaction was removed from the mempool, + * this is passed to the notification signal. + */ +enum class MemPoolRemovalReason { + UNKNOWN = 0, //! Manually removed or unknown reason + EXPIRY, //! Expired from mempool + SIZELIMIT, //! Removed in size limiting + REORG, //! Removed for reorganization + BLOCK, //! Removed for block + CONFLICT, //! Removed for conflict with in-block transaction + REPLACED //! Removed for replacement +}; + /** * CTxMemPool stores valid-according-to-the-current-best-chain transactions * that may be included in the next block. @@ -340,7 +354,7 @@ struct TxMempoolInfo * Transactions are added when they are seen on the network (or created by the * local node), but not all transactions seen are added to the pool. For * example, the following new transactions will not be added to the mempool: - * - a transaction which doesn't make the mimimum fee requirements. + * - a transaction which doesn't meet the minimum fee requirements. * - a new transaction that double-spends an input of a transaction already in * the pool where the new transaction does not meet the Replace-By-Fee * requirements as defined in BIP 125. @@ -521,10 +535,11 @@ public: bool addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, bool validFeeEstimate = true); bool addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, setEntries &setAncestors, bool validFeeEstimate = true); - void removeRecursive(const CTransaction &tx); + void removeRecursive(const CTransaction &tx, MemPoolRemovalReason reason = MemPoolRemovalReason::UNKNOWN); void removeForReorg(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight, int flags); void removeConflicts(const CTransaction &tx); void removeForBlock(const std::vector<CTransactionRef>& vtx, unsigned int nBlockHeight); + void clear(); void _clear(); //lock free bool CompareDepthAndScore(const uint256& hasha, const uint256& hashb); @@ -539,7 +554,7 @@ public: bool HasNoInputsOf(const CTransaction& tx) const; /** Affect CreateNewBlock prioritisation of transactions */ - void PrioritiseTransaction(const uint256 hash, const std::string strHash, double dPriorityDelta, const CAmount& nFeeDelta); + void PrioritiseTransaction(const uint256& hash, double dPriorityDelta, const CAmount& nFeeDelta); void ApplyDeltas(const uint256 hash, double &dPriorityDelta, CAmount &nFeeDelta) const; void ClearPrioritisation(const uint256 hash); @@ -551,7 +566,7 @@ public: * Set updateDescendants to true when removing a tx that was in a block, so * that any in-mempool descendants have their ancestor state updated. */ - void RemoveStaged(setEntries &stage, bool updateDescendants); + void RemoveStaged(setEntries &stage, bool updateDescendants, MemPoolRemovalReason reason = MemPoolRemovalReason::UNKNOWN); /** When adding transactions from a disconnected block back to the mempool, * new mempool entries may have children in the mempool (which is generally @@ -647,6 +662,9 @@ public: size_t DynamicMemoryUsage() const; + boost::signals2::signal<void (CTransactionRef)> NotifyEntryAdded; + boost::signals2::signal<void (CTransactionRef, MemPoolRemovalReason)> NotifyEntryRemoved; + private: /** UpdateForDescendants is used by UpdateTransactionsFromBlock to update * the descendants for a single transaction that has been added to the @@ -683,7 +701,7 @@ private: * transactions in a chain before we've updated all the state for the * removal. */ - void removeUnchecked(txiter entry); + void removeUnchecked(txiter entry, MemPoolRemovalReason reason = MemPoolRemovalReason::UNKNOWN); }; /** diff --git a/src/uint256.cpp b/src/uint256.cpp index bd3d017085..c4c7b716fe 100644 --- a/src/uint256.cpp +++ b/src/uint256.cpp @@ -20,10 +20,7 @@ base_blob<BITS>::base_blob(const std::vector<unsigned char>& vch) template <unsigned int BITS> std::string base_blob<BITS>::GetHex() const { - char psz[sizeof(data) * 2 + 1]; - for (unsigned int i = 0; i < sizeof(data); i++) - sprintf(psz + i * 2, "%02x", data[sizeof(data) - i - 1]); - return std::string(psz, psz + sizeof(data) * 2); + return HexStr(std::reverse_iterator<const uint8_t*>(data + sizeof(data)), std::reverse_iterator<const uint8_t*>(data)); } template <unsigned int BITS> diff --git a/src/util.cpp b/src/util.cpp index 08ee6b8b87..78c353dfe5 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -214,12 +214,13 @@ void OpenDebugLog() assert(vMsgsBeforeOpenLog); boost::filesystem::path pathDebug = GetDataDir() / "debug.log"; fileout = fopen(pathDebug.string().c_str(), "a"); - if (fileout) setbuf(fileout, NULL); // unbuffered - - // dump buffered messages from before we opened the log - while (!vMsgsBeforeOpenLog->empty()) { - FileWriteStr(vMsgsBeforeOpenLog->front(), fileout); - vMsgsBeforeOpenLog->pop_front(); + if (fileout) { + setbuf(fileout, NULL); // unbuffered + // dump buffered messages from before we opened the log + while (!vMsgsBeforeOpenLog->empty()) { + FileWriteStr(vMsgsBeforeOpenLog->front(), fileout); + vMsgsBeforeOpenLog->pop_front(); + } } delete vMsgsBeforeOpenLog; @@ -723,13 +724,17 @@ void AllocateFileRange(FILE *file, unsigned int offset, unsigned int length) { void ShrinkDebugFile() { + // Amount of debug.log to save at end when shrinking (must fit in memory) + constexpr size_t RECENT_DEBUG_HISTORY_SIZE = 10 * 1000000; // Scroll debug.log if it's getting too big boost::filesystem::path pathLog = GetDataDir() / "debug.log"; FILE* file = fopen(pathLog.string().c_str(), "r"); - if (file && boost::filesystem::file_size(pathLog) > 10 * 1000000) + // If debug.log file is more than 10% bigger the RECENT_DEBUG_HISTORY_SIZE + // trim it down by saving only the last RECENT_DEBUG_HISTORY_SIZE bytes + if (file && boost::filesystem::file_size(pathLog) > 11 * (RECENT_DEBUG_HISTORY_SIZE / 10)) { // Restart the file with some of the end - std::vector <char> vch(200000,0); + std::vector<char> vch(RECENT_DEBUG_HISTORY_SIZE, 0); fseek(file, -((long)vch.size()), SEEK_END); int nBytes = fread(vch.data(), 1, vch.size(), file); fclose(file); @@ -834,4 +839,4 @@ std::string CopyrightHolders(const std::string& strPrefix) strCopyrightHolders += "\n" + strPrefix + "The Bitcoin Core developers"; } return strCopyrightHolders; -} +}
\ No newline at end of file diff --git a/src/utiltime.cpp b/src/utiltime.cpp index 7c5ee77265..c7b3e4f168 100644 --- a/src/utiltime.cpp +++ b/src/utiltime.cpp @@ -46,6 +46,11 @@ int64_t GetTimeMicros() return now; } +int64_t GetSystemTimeInSeconds() +{ + return GetTimeMicros()/1000000; +} + /** Return a time useful for the debug log */ int64_t GetLogTimeMicros() { @@ -58,7 +63,7 @@ void MilliSleep(int64_t n) { /** - * Boost's sleep_for was uninterruptable when backed by nanosleep from 1.50 + * Boost's sleep_for was uninterruptible when backed by nanosleep from 1.50 * until fixed in 1.52. Use the deprecated sleep method for the broken case. * See: https://svn.boost.org/trac/boost/ticket/7238 */ diff --git a/src/utiltime.h b/src/utiltime.h index b2807267db..cc3290c631 100644 --- a/src/utiltime.h +++ b/src/utiltime.h @@ -9,9 +9,20 @@ #include <stdint.h> #include <string> +/** + * GetTimeMicros() and GetTimeMillis() both return the system time, but in + * different units. GetTime() returns the system time in seconds, but also + * supports mocktime, where the time can be specified by the user, eg for + * testing (eg with the setmocktime rpc, or -mocktime argument). + * + * TODO: Rework these functions to be type-safe (so that we don't inadvertently + * compare numbers with different units, or compare a mocktime to system time). + */ + int64_t GetTime(); int64_t GetTimeMillis(); int64_t GetTimeMicros(); +int64_t GetSystemTimeInSeconds(); // Like GetTime(), but not mockable int64_t GetLogTimeMicros(); void SetMockTime(int64_t nMockTimeIn); void MilliSleep(int64_t n); diff --git a/src/validation.cpp b/src/validation.cpp index 881292d613..e84b1a7281 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -46,8 +46,6 @@ #include <boost/math/distributions/poisson.hpp> #include <boost/thread.hpp> -using namespace std; - #if defined(NDEBUG) # error "Bitcoin cannot be compiled without assertions." #endif @@ -90,7 +88,7 @@ static void CheckBlockIndex(const Consensus::Params& consensusParams); /** Constant stuff for coinbase transactions we create: */ CScript COINBASE_FLAGS; -const string strMessageMagic = "Bitcoin Signed Message:\n"; +const std::string strMessageMagic = "Bitcoin Signed Message:\n"; // Internal stuff namespace { @@ -123,11 +121,11 @@ namespace { * as good as our current tip or better. Entries may be failed, though, and pruning nodes may be * missing the data for the block. */ - set<CBlockIndex*, CBlockIndexWorkComparator> setBlockIndexCandidates; + std::set<CBlockIndex*, CBlockIndexWorkComparator> setBlockIndexCandidates; /** 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<CBlockIndex*, CBlockIndex*> mapBlocksUnlinked; + std::multimap<CBlockIndex*, CBlockIndex*> mapBlocksUnlinked; CCriticalSection cs_LastBlockFile; std::vector<CBlockFileInfo> vinfoBlockFile; @@ -151,12 +149,45 @@ namespace { arith_uint256 nLastPreciousChainwork = 0; /** Dirty block index entries. */ - set<CBlockIndex*> setDirtyBlockIndex; + std::set<CBlockIndex*> setDirtyBlockIndex; /** Dirty block file entries. */ - set<int> setDirtyFileInfo; + std::set<int> setDirtyFileInfo; } // anon namespace +/* Use this class to start tracking transactions that are removed from the + * mempool and pass all those transactions through SyncTransaction when the + * object goes out of scope. This is currently only used to call SyncTransaction + * on conflicts removed from the mempool during block connection. Applied in + * ActivateBestChain around ActivateBestStep which in turn calls: + * ConnectTip->removeForBlock->removeConflicts + */ +class MemPoolConflictRemovalTracker +{ +private: + std::vector<CTransactionRef> conflictedTxs; + CTxMemPool &pool; + +public: + MemPoolConflictRemovalTracker(CTxMemPool &_pool) : pool(_pool) { + pool.NotifyEntryRemoved.connect(boost::bind(&MemPoolConflictRemovalTracker::NotifyEntryRemoved, this, _1, _2)); + } + + void NotifyEntryRemoved(CTransactionRef txRemoved, MemPoolRemovalReason reason) { + if (reason == MemPoolRemovalReason::CONFLICT) { + conflictedTxs.push_back(txRemoved); + } + } + + ~MemPoolConflictRemovalTracker() { + pool.NotifyEntryRemoved.disconnect(boost::bind(&MemPoolConflictRemovalTracker::NotifyEntryRemoved, this, _1, _2)); + for (const auto& tx : conflictedTxs) { + GetMainSignals().SyncTransaction(*tx, NULL, CMainSignals::SYNC_TRANSACTION_NOT_IN_BLOCK); + } + conflictedTxs.clear(); + } +}; + CBlockIndex* FindForkInGlobalIndex(const CChain& chain, const CBlockLocator& locator) { // Find the first block the caller has in the main chain @@ -484,7 +515,7 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state, bool fChe // Check for duplicate inputs - note that this check is slow so we skip it in CheckBlock if (fCheckDuplicateInputs) { - set<COutPoint> vInOutPoints; + std::set<COutPoint> vInOutPoints; for (const auto& txin : tx.vin) { if (!vInOutPoints.insert(txin.prevout).second) @@ -563,7 +594,7 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C } // Rather not work on nonstandard transactions (unless -testnet/-regtest) - string reason; + std::string reason; if (fRequireStandard && !IsStandardTx(tx, reason, witnessEnabled)) return state.DoS(0, false, REJECT_NONSTANDARD, reason); @@ -578,7 +609,7 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C return state.Invalid(false, REJECT_ALREADY_KNOWN, "txn-already-in-mempool"); // Check for conflicts with in-memory transactions - set<uint256> setConflicts; + std::set<uint256> setConflicts; { LOCK(pool.cs); // protect pool.mapNextTx BOOST_FOREACH(const CTxIn &txin, tx.vin) @@ -794,10 +825,11 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C // subsequent RemoveStaged() and addUnchecked() calls don't guarantee // mempool consistency for us. LOCK(pool.cs); - if (setConflicts.size()) + const bool fReplacementTransaction = setConflicts.size(); + if (fReplacementTransaction) { CFeeRate newFeeRate(nModifiedFees, nSize); - set<uint256> setConflictsParents; + std::set<uint256> setConflictsParents; const int maxDescendantsToVisit = 100; CTxMemPool::setEntries setIterConflicting; BOOST_FOREACH(const uint256 &hashConflicting, setConflicts) @@ -898,14 +930,14 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C // 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)) + if (nDeltaFees < ::incrementalRelayFee.GetFee(nSize)) { return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "insufficient fee", false, strprintf("rejecting replacement %s, not enough additional fees to relay; %s < %s", hash.ToString(), FormatMoney(nDeltaFees), - FormatMoney(::minRelayTxFee.GetFee(nSize)))); + FormatMoney(::incrementalRelayFee.GetFee(nSize)))); } } @@ -956,12 +988,13 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C if (plTxnReplaced) plTxnReplaced->push_back(it->GetSharedTx()); } - pool.RemoveStaged(allConflicting, false); + pool.RemoveStaged(allConflicting, false, MemPoolRemovalReason::REPLACED); - // This transaction should only count for fee estimation if - // the node is not behind and it is not dependent on any other - // transactions in the mempool - bool validForFeeEstimation = IsCurrentForFeeEstimation() && pool.HasNoInputsOf(tx); + // This transaction should only count for fee estimation if it isn't a + // BIP 125 replacement transaction (may not be widely supported), the + // node is not behind, and the transaction is not dependent on any other + // transactions in the mempool. + bool validForFeeEstimation = !fReplacementTransaction && IsCurrentForFeeEstimation() && pool.HasNoInputsOf(tx); // Store transaction in memory pool.addUnchecked(hash, entry, setAncestors, validForFeeEstimation); @@ -1396,7 +1429,7 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi // Helps prevent CPU exhaustion attacks. // Skip script verification when connecting blocks under the - // assumedvalid block. Assuming the assumedvalid block is valid this + // assumevalid block. Assuming the assumevalid block is valid this // is safe because block merkle hashes are still computed and checked, // Of course, if an assumed valid block is invalid due to false scriptSigs // this optimization would allow an invalid chain to be accepted. @@ -1738,7 +1771,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin pindexBestHeader->GetAncestor(pindex->nHeight) == pindex && pindexBestHeader->nChainWork >= UintToArith256(chainparams.GetConsensus().nMinimumChainWork)) { // This block is a member of the assumed verified chain and an ancestor of the best header. - // The equivalent time check discourages hashpower from extorting the network via DOS attack + // The equivalent time check discourages hash power from extorting the network via DOS attack // into accepting an invalid block through telling users they must manually set assumevalid. // Requiring a software change or burying the invalid block, regardless of the setting, makes // it hard to hide the implication of the demand. This also avoids having release candidates @@ -2017,18 +2050,18 @@ bool static FlushStateToDisk(CValidationState &state, FlushStateMode mode, int n { std::vector<std::pair<int, const CBlockFileInfo*> > vFiles; vFiles.reserve(setDirtyFileInfo.size()); - for (set<int>::iterator it = setDirtyFileInfo.begin(); it != setDirtyFileInfo.end(); ) { - vFiles.push_back(make_pair(*it, &vinfoBlockFile[*it])); + for (std::set<int>::iterator it = setDirtyFileInfo.begin(); it != setDirtyFileInfo.end(); ) { + vFiles.push_back(std::make_pair(*it, &vinfoBlockFile[*it])); setDirtyFileInfo.erase(it++); } std::vector<const CBlockIndex*> vBlocks; vBlocks.reserve(setDirtyBlockIndex.size()); - for (set<CBlockIndex*>::iterator it = setDirtyBlockIndex.begin(); it != setDirtyBlockIndex.end(); ) { + for (std::set<CBlockIndex*>::iterator it = setDirtyBlockIndex.begin(); it != setDirtyBlockIndex.end(); ) { vBlocks.push_back(*it); setDirtyBlockIndex.erase(it++); } if (!pblocktree->WriteBatchSync(vFiles, nLastBlockFile, vBlocks)) { - return AbortNode(state, "Files to write to block index database"); + return AbortNode(state, "Failed to write to block index database"); } } // Finally remove any pruned files @@ -2166,7 +2199,7 @@ bool static DisconnectTip(CValidationState& state, const CChainParams& chainpara // ignore validation errors in resurrected transactions CValidationState stateDummy; if (tx.IsCoinBase() || !AcceptToMemoryPool(mempool, stateDummy, it, false, NULL, NULL, true)) { - mempool.removeRecursive(tx); + mempool.removeRecursive(tx, MemPoolRemovalReason::REORG); } else if (mempool.exists(tx.GetHash())) { vHashUpdate.push_back(tx.GetHash()); } @@ -2453,6 +2486,14 @@ bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams, bool fInitialDownload; { LOCK(cs_main); + { // TODO: Temporarily ensure that mempool removals are notified before + // connected transactions. This shouldn't matter, but the abandoned + // state of transactions in our wallet is currently cleared when we + // receive another notification and there is a race condition where + // notification of a connected conflict might cause an outside process + // to abandon a transaction and then have it inadvertently cleared by + // the notification that the conflicted transaction was evicted. + MemPoolConflictRemovalTracker mrt(mempool); CBlockIndex *pindexOldTip = chainActive.Tip(); if (pindexMostWork == NULL) { pindexMostWork = FindMostWorkChain(); @@ -2476,6 +2517,10 @@ bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams, fInitialDownload = IsInitialBlockDownload(); // throw all transactions though the signal-interface + + } // MemPoolConflictRemovalTracker destroyed and conflict evictions are notified + + // Transactions in the connected block are notified for (const auto& pair : connectTrace.blocksConnected) { assert(pair.second); const CBlock& block = *(pair.second); @@ -2623,7 +2668,7 @@ CBlockIndex* AddToBlockIndex(const CBlockHeader& block) // to avoid miners withholding blocks but broadcasting headers, to get a // competitive advantage. pindexNew->nSequenceId = 0; - BlockMap::iterator mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first; + BlockMap::iterator mi = mapBlockIndex.insert(std::make_pair(hash, pindexNew)).first; pindexNew->phashBlock = &((*mi).first); BlockMap::iterator miPrev = mapBlockIndex.find(block.hashPrevBlock); if (miPrev != mapBlockIndex.end()) @@ -2660,7 +2705,7 @@ bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBl if (pindexNew->pprev == NULL || pindexNew->pprev->nChainTx) { // If pindexNew is the genesis block or all parents are BLOCK_VALID_TRANSACTIONS. - deque<CBlockIndex*> queue; + std::deque<CBlockIndex*> queue; queue.push_back(pindexNew); // Recursively process any descendant blocks that now may be eligible to be connected. @@ -3142,7 +3187,7 @@ static bool AcceptBlock(const std::shared_ptr<const CBlock>& pblock, CValidation } if (fNewBlock) *fNewBlock = true; - if (!CheckBlock(block, state, chainparams.GetConsensus(), GetAdjustedTime()) || + if (!CheckBlock(block, state, chainparams.GetConsensus()) || !ContextualCheckBlock(block, state, chainparams.GetConsensus(), pindex->pprev)) { if (state.IsInvalid() && !state.CorruptionPossible()) { pindex->nStatus |= BLOCK_FAILED_VALID; @@ -3184,13 +3229,19 @@ static bool AcceptBlock(const std::shared_ptr<const CBlock>& pblock, CValidation bool ProcessNewBlock(const CChainParams& chainparams, const std::shared_ptr<const CBlock> pblock, bool fForceProcessing, bool *fNewBlock) { { - LOCK(cs_main); - - // Store to disk CBlockIndex *pindex = NULL; if (fNewBlock) *fNewBlock = false; CValidationState state; - bool ret = AcceptBlock(pblock, state, chainparams, &pindex, fForceProcessing, NULL, fNewBlock); + // Ensure that CheckBlock() passes before calling AcceptBlock, as + // belt-and-suspenders. + bool ret = CheckBlock(*pblock, state, chainparams.GetConsensus()); + + LOCK(cs_main); + + if (ret) { + // Store to disk + ret = AcceptBlock(pblock, state, chainparams, &pindex, fForceProcessing, NULL, fNewBlock); + } CheckBlockIndex(chainparams.GetConsensus()); if (!ret) { GetMainSignals().BlockChecked(*pblock, state); @@ -3280,9 +3331,9 @@ void PruneOneBlockFile(const int fileNumber) } -void UnlinkPrunedFiles(std::set<int>& setFilesToPrune) +void UnlinkPrunedFiles(const std::set<int>& setFilesToPrune) { - for (set<int>::iterator it = setFilesToPrune.begin(); it != setFilesToPrune.end(); ++it) { + for (std::set<int>::iterator it = setFilesToPrune.begin(); it != setFilesToPrune.end(); ++it) { CDiskBlockPos pos(*it, 0); boost::filesystem::remove(GetBlockPosFilename(pos, "blk")); boost::filesystem::remove(GetBlockPosFilename(pos, "rev")); @@ -3300,7 +3351,7 @@ void FindFilesToPruneManual(std::set<int>& setFilesToPrune, int nManualPruneHeig return; // last block to prune is the lesser of (user-specified height, MIN_BLOCKS_TO_KEEP from the tip) - unsigned int nLastBlockWeCanPrune = min((unsigned)nManualPruneHeight, chainActive.Tip()->nHeight - MIN_BLOCKS_TO_KEEP); + unsigned int nLastBlockWeCanPrune = std::min((unsigned)nManualPruneHeight, chainActive.Tip()->nHeight - MIN_BLOCKS_TO_KEEP); int count=0; for (int fileNumber = 0; fileNumber < nLastBlockFile; fileNumber++) { if (vinfoBlockFile[fileNumber].nSize == 0 || vinfoBlockFile[fileNumber].nHeightLast > nLastBlockWeCanPrune) @@ -3427,8 +3478,8 @@ CBlockIndex * InsertBlockIndex(uint256 hash) // Create new CBlockIndex* pindexNew = new CBlockIndex(); if (!pindexNew) - throw runtime_error(std::string(__func__) + ": new CBlockIndex failed"); - mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first; + throw std::runtime_error(std::string(__func__) + ": new CBlockIndex failed"); + mi = mapBlockIndex.insert(std::make_pair(hash, pindexNew)).first; pindexNew->phashBlock = &((*mi).first); return pindexNew; @@ -3442,12 +3493,12 @@ bool static LoadBlockIndexDB(const CChainParams& chainparams) boost::this_thread::interruption_point(); // Calculate nChainWork - vector<pair<int, CBlockIndex*> > vSortedByHeight; + std::vector<std::pair<int, CBlockIndex*> > vSortedByHeight; vSortedByHeight.reserve(mapBlockIndex.size()); BOOST_FOREACH(const PAIRTYPE(uint256, CBlockIndex*)& item, mapBlockIndex) { CBlockIndex* pindex = item.second; - vSortedByHeight.push_back(make_pair(pindex->nHeight, pindex)); + vSortedByHeight.push_back(std::make_pair(pindex->nHeight, pindex)); } sort(vSortedByHeight.begin(), vSortedByHeight.end()); BOOST_FOREACH(const PAIRTYPE(int, CBlockIndex*)& item, vSortedByHeight) @@ -3498,7 +3549,7 @@ bool static LoadBlockIndexDB(const CChainParams& chainparams) // Check presence of blk files LogPrintf("Checking all blk files are present...\n"); - set<int> setBlkDataFiles; + std::set<int> setBlkDataFiles; BOOST_FOREACH(const PAIRTYPE(uint256, CBlockIndex*)& item, mapBlockIndex) { CBlockIndex* pindex = item.second; @@ -3597,7 +3648,7 @@ bool CVerifyDB::VerifyDB(const CChainParams& chainparams, CCoinsView *coinsview, 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, chainparams.GetConsensus())) - return error("%s: *** found bad block at %d, hash=%s (%s)\n", __func__, + 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) { @@ -3768,7 +3819,7 @@ bool LoadBlockIndex(const CChainParams& chainparams) return true; } -bool InitBlockIndex(const CChainParams& chainparams) +bool InitBlockIndex(const CChainParams& chainparams) { LOCK(cs_main); @@ -3885,7 +3936,7 @@ bool LoadExternalBlockFile(const CChainParams& chainparams, FILE* fileIn, CDiskB NotifyHeaderTip(); // Recursively process earlier encountered successors of this block - deque<uint256> queue; + std::deque<uint256> queue; queue.push_back(hash); while (!queue.empty()) { uint256 head = queue.front(); @@ -4112,6 +4163,11 @@ std::string CBlockFileInfo::ToString() const return strprintf("CBlockFileInfo(blocks=%u, size=%u, heights=%u...%u, time=%s...%s)", nBlocks, nSize, nHeightFirst, nHeightLast, DateTimeStrFormat("%Y-%m-%d", nTimeFirst), DateTimeStrFormat("%Y-%m-%d", nTimeLast)); } +CBlockFileInfo* GetBlockFileInfo(size_t n) +{ + return &vinfoBlockFile.at(n); +} + ThresholdState VersionBitsTipState(const Consensus::Params& params, Consensus::DeploymentPos pos) { LOCK(cs_main); @@ -4129,7 +4185,7 @@ static const uint64_t MEMPOOL_DUMP_VERSION = 1; bool LoadMempool(void) { int64_t nExpiryTimeout = GetArg("-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY) * 60 * 60; - FILE* filestr = fopen((GetDataDir() / "mempool.dat").string().c_str(), "r"); + FILE* filestr = fopen((GetDataDir() / "mempool.dat").string().c_str(), "rb"); CAutoFile file(filestr, SER_DISK, CLIENT_VERSION); if (file.IsNull()) { LogPrintf("Failed to open mempool file from disk. Continuing anyway.\n"); @@ -4160,7 +4216,7 @@ bool LoadMempool(void) CAmount amountdelta = nFeeDelta; if (amountdelta) { - mempool.PrioritiseTransaction(tx->GetHash(), tx->GetHash().ToString(), prioritydummy, amountdelta); + mempool.PrioritiseTransaction(tx->GetHash(), prioritydummy, amountdelta); } CValidationState state; if (nTime + nExpiryTimeout > nNow) { @@ -4181,7 +4237,7 @@ bool LoadMempool(void) file >> mapDeltas; for (const auto& i : mapDeltas) { - mempool.PrioritiseTransaction(i.first, i.first.ToString(), prioritydummy, i.second); + mempool.PrioritiseTransaction(i.first, prioritydummy, i.second); } } catch (const std::exception& e) { LogPrintf("Failed to deserialize mempool data on disk: %s. Continuing anyway.\n", e.what()); @@ -4210,7 +4266,7 @@ void DumpMempool(void) int64_t mid = GetTimeMicros(); try { - FILE* filestr = fopen((GetDataDir() / "mempool.dat.new").string().c_str(), "w"); + FILE* filestr = fopen((GetDataDir() / "mempool.dat.new").string().c_str(), "wb"); if (!filestr) { return; } diff --git a/src/validation.h b/src/validation.h index 6fcbb1c108..9c606f2419 100644 --- a/src/validation.h +++ b/src/validation.h @@ -300,9 +300,14 @@ double GuessVerificationProgress(const ChainTxData& data, CBlockIndex* pindex); void FindFilesToPrune(std::set<int>& setFilesToPrune, uint64_t nPruneAfterHeight); /** + * Mark one block file as pruned. + */ +void PruneOneBlockFile(const int fileNumber); + +/** * Actually unlink the specified files */ -void UnlinkPrunedFiles(std::set<int>& setFilesToPrune); +void UnlinkPrunedFiles(const std::set<int>& setFilesToPrune); /** Create a new block index entry for a given block hash */ CBlockIndex * InsertBlockIndex(uint256 hash); @@ -562,6 +567,9 @@ static const unsigned int REJECT_ALREADY_KNOWN = 0x101; /** Transaction conflicts with a transaction already known */ static const unsigned int REJECT_CONFLICT = 0x102; +/** Get block file info entry for one block file */ +CBlockFileInfo* GetBlockFileInfo(size_t n); + /** Dump the mempool to disk. */ void DumpMempool(); diff --git a/src/validationinterface.h b/src/validationinterface.h index 594072719c..a494eb6990 100644 --- a/src/validationinterface.h +++ b/src/validationinterface.h @@ -50,9 +50,16 @@ protected: struct CMainSignals { /** Notifies listeners of updated block chain tip */ boost::signals2::signal<void (const CBlockIndex *, const CBlockIndex *, bool fInitialDownload)> UpdatedBlockTip; - /** A posInBlock value for SyncTransaction which indicates the transaction was conflicted, disconnected, or not in a block */ + /** A posInBlock value for SyncTransaction calls for transactions not + * included in connected blocks such as transactions removed from mempool, + * accepted to mempool or appearing in disconnected blocks.*/ static const int SYNC_TRANSACTION_NOT_IN_BLOCK = -1; - /** Notifies listeners of updated transaction data (transaction, and optionally the block it is found in. */ + /** Notifies listeners of updated transaction data (transaction, and + * optionally the block it is found in). Called with block data when + * transaction is included in a connected block, and without block data when + * transaction was accepted to mempool, removed from mempool (only when + * removal was due to conflict from connected block), or appeared in a + * disconnected block.*/ boost::signals2::signal<void (const CTransaction &, const CBlockIndex *pindex, int posInBlock)> SyncTransaction; /** Notifies listeners of an updated transaction without new data (for now: a coinbase potentially becoming visible). */ boost::signals2::signal<void (const uint256 &)> UpdatedTransaction; diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp index 800e1f4e29..7d1b429b30 100644 --- a/src/wallet/db.cpp +++ b/src/wallet/db.cpp @@ -24,9 +24,6 @@ using namespace std; -unsigned int nWalletDBUpdated; - - // // CDB // diff --git a/src/wallet/db.h b/src/wallet/db.h index bc15f2147f..b4ce044e7f 100644 --- a/src/wallet/db.h +++ b/src/wallet/db.h @@ -23,8 +23,6 @@ static const unsigned int DEFAULT_WALLET_DBLOGSIZE = 100; static const bool DEFAULT_WALLET_PRIVDB = true; -extern unsigned int nWalletDBUpdated; - class CDBEnv { private: diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index 7d4ed70ed9..20a3cbda1e 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -143,7 +143,7 @@ UniValue importprivkey(const JSONRPCRequest& request) throw JSONRPCError(RPC_WALLET_ERROR, "Error adding key to wallet"); // whenever a key is imported, we need to scan the whole chain - pwalletMain->nTimeFirstKey = 1; // 0 would be considered 'no value' + pwalletMain->UpdateTimeFirstKey(1); if (fRescan) { pwalletMain->ScanForWalletTransactions(chainActive.Genesis(), true); @@ -161,7 +161,7 @@ void ImportScript(const CScript& script, const string& strLabel, bool isRedeemSc pwalletMain->MarkDirty(); - if (!pwalletMain->HaveWatchOnly(script) && !pwalletMain->AddWatchOnly(script)) + if (!pwalletMain->HaveWatchOnly(script) && !pwalletMain->AddWatchOnly(script, 0 /* nCreateTime */)) throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet"); if (isRedeemScript) { @@ -500,8 +500,7 @@ UniValue importwallet(const JSONRPCRequest& request) while (pindex && pindex->pprev && pindex->GetBlockTime() > nTimeBegin - 7200) pindex = pindex->pprev; - if (!pwalletMain->nTimeFirstKey || nTimeBegin < pwalletMain->nTimeFirstKey) - pwalletMain->nTimeFirstKey = nTimeBegin; + pwalletMain->UpdateTimeFirstKey(nTimeBegin); LogPrintf("Rescanning last %i blocks\n", chainActive.Height() - pindex->nHeight + 1); pwalletMain->ScanForWalletTransactions(pindex); @@ -576,15 +575,17 @@ UniValue dumpwallet(const JSONRPCRequest& request) if (!file.is_open()) throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot open wallet dump file"); - std::map<CKeyID, int64_t> mapKeyBirth; + std::map<CTxDestination, int64_t> mapKeyBirth; std::set<CKeyID> setKeyPool; pwalletMain->GetKeyBirthTimes(mapKeyBirth); pwalletMain->GetAllReserveKeys(setKeyPool); // sort time/key pairs std::vector<std::pair<int64_t, CKeyID> > vKeyBirth; - for (std::map<CKeyID, int64_t>::const_iterator it = mapKeyBirth.begin(); it != mapKeyBirth.end(); it++) { - vKeyBirth.push_back(std::make_pair(it->second, it->first)); + for (const auto& entry : mapKeyBirth) { + if (const CKeyID* keyID = boost::get<CKeyID>(&entry.first)) { // set and test + vKeyBirth.push_back(std::make_pair(entry.second, *keyID)); + } } mapKeyBirth.clear(); std::sort(vKeyBirth.begin(), vKeyBirth.end()); @@ -640,7 +641,8 @@ UniValue dumpwallet(const JSONRPCRequest& request) } -UniValue processImport(const UniValue& data) { +UniValue ProcessImport(const UniValue& data, const int64_t timestamp) +{ try { bool success = false; @@ -659,7 +661,6 @@ UniValue processImport(const UniValue& data) { const bool& internal = data.exists("internal") ? data["internal"].get_bool() : false; const bool& watchOnly = data.exists("watchonly") ? data["watchonly"].get_bool() : false; const string& label = data.exists("label") && !internal ? data["label"].get_str() : ""; - const int64_t& timestamp = data.exists("timestamp") && data["timestamp"].get_int64() > 1 ? data["timestamp"].get_int64() : 1; bool isScript = scriptPubKey.getType() == UniValue::VSTR; bool isP2SH = strRedeemScript.length() > 0; @@ -671,6 +672,9 @@ UniValue processImport(const UniValue& data) { if (!isScript) { address = CBitcoinAddress(output); + if (!address.IsValid()) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address"); + } script = GetScriptForDestination(address.Get()); } else { if (!IsHex(output)) { @@ -721,7 +725,7 @@ UniValue processImport(const UniValue& data) { pwalletMain->MarkDirty(); - if (!pwalletMain->HaveWatchOnly(redeemScript) && !pwalletMain->AddWatchOnly(redeemScript)) { + if (!pwalletMain->HaveWatchOnly(redeemScript) && !pwalletMain->AddWatchOnly(redeemScript, timestamp)) { throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet"); } @@ -738,7 +742,7 @@ UniValue processImport(const UniValue& data) { pwalletMain->MarkDirty(); - if (!pwalletMain->HaveWatchOnly(redeemDestination) && !pwalletMain->AddWatchOnly(redeemDestination)) { + if (!pwalletMain->HaveWatchOnly(redeemDestination) && !pwalletMain->AddWatchOnly(redeemDestination, timestamp)) { throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet"); } @@ -782,9 +786,7 @@ UniValue processImport(const UniValue& data) { throw JSONRPCError(RPC_WALLET_ERROR, "Error adding key to wallet"); } - if (timestamp < pwalletMain->nTimeFirstKey) { - pwalletMain->nTimeFirstKey = timestamp; - } + pwalletMain->UpdateTimeFirstKey(timestamp); } } @@ -833,7 +835,7 @@ UniValue processImport(const UniValue& data) { pwalletMain->MarkDirty(); - if (!pwalletMain->HaveWatchOnly(pubKeyScript) && !pwalletMain->AddWatchOnly(pubKeyScript)) { + if (!pwalletMain->HaveWatchOnly(pubKeyScript) && !pwalletMain->AddWatchOnly(pubKeyScript, timestamp)) { throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet"); } @@ -851,7 +853,7 @@ UniValue processImport(const UniValue& data) { pwalletMain->MarkDirty(); - if (!pwalletMain->HaveWatchOnly(scriptRawPubKey) && !pwalletMain->AddWatchOnly(scriptRawPubKey)) { + if (!pwalletMain->HaveWatchOnly(scriptRawPubKey) && !pwalletMain->AddWatchOnly(scriptRawPubKey, timestamp)) { throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet"); } @@ -912,9 +914,7 @@ UniValue processImport(const UniValue& data) { throw JSONRPCError(RPC_WALLET_ERROR, "Error adding key to wallet"); } - if (timestamp < pwalletMain->nTimeFirstKey) { - pwalletMain->nTimeFirstKey = timestamp; - } + pwalletMain->UpdateTimeFirstKey(timestamp); success = true; } @@ -927,7 +927,7 @@ UniValue processImport(const UniValue& data) { pwalletMain->MarkDirty(); - if (!pwalletMain->HaveWatchOnly(script) && !pwalletMain->AddWatchOnly(script)) { + if (!pwalletMain->HaveWatchOnly(script) && !pwalletMain->AddWatchOnly(script, timestamp)) { throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet"); } @@ -958,6 +958,20 @@ UniValue processImport(const UniValue& data) { } } +int64_t GetImportTimestamp(const UniValue& data, int64_t now) +{ + if (data.exists("timestamp")) { + const UniValue& timestamp = data["timestamp"]; + if (timestamp.isNum()) { + return timestamp.get_int64(); + } else if (timestamp.isStr() && timestamp.get_str() == "now") { + return now; + } + throw JSONRPCError(RPC_TYPE_ERROR, strprintf("Expected number or \"now\" timestamp value for key. got type %s", uvTypeName(timestamp.type()))); + } + throw JSONRPCError(RPC_TYPE_ERROR, "Missing required timestamp field for key"); +} + UniValue importmulti(const JSONRPCRequest& mainRequest) { // clang-format off @@ -970,13 +984,18 @@ UniValue importmulti(const JSONRPCRequest& mainRequest) " [ (array of json objects)\n" " {\n" " \"scriptPubKey\": \"<script>\" | { \"address\":\"<address>\" }, (string / json, required) Type of scriptPubKey (string for script, json for address)\n" + " \"timestamp\": timestamp | \"now\" , (integer / string, required) Creation time of the key in seconds since epoch (Jan 1 1970 GMT),\n" + " or the string \"now\" to substitute the current synced blockchain time. The timestamp of the oldest\n" + " key will determine how far back blockchain rescans need to begin for missing wallet transactions.\n" + " \"now\" can be specified to bypass scanning, for keys which are known to never have been used, and\n" + " 0 can be specified to scan the entire blockchain. Blocks up to 2 hours before the earliest key\n" + " creation time of all keys being imported by the importmulti call will be scanned.\n" " \"redeemscript\": \"<script>\" , (string, optional) Allowed only if the scriptPubKey is a P2SH address or a P2SH scriptPubKey\n" " \"pubkeys\": [\"<pubKey>\", ... ] , (array, optional) Array of strings giving pubkeys that must occur in the output or redeemscript\n" " \"keys\": [\"<key>\", ... ] , (array, optional) Array of strings giving private keys whose corresponding public keys must occur in the output or redeemscript\n" " \"internal\": <true> , (boolean, optional, default: false) Stating whether matching outputs should be be treated as not incoming payments\n" " \"watchonly\": <true> , (boolean, optional, default: false) Stating whether matching outputs should be considered watched even when they're not spendable, only allowed if keys are empty\n" " \"label\": <label> , (string, optional, default: '') Label to assign to the address (aka account name, for now), only allowed with internal=false\n" - " \"timestamp\": 1454686740, (integer, optional, default now) Timestamp\n" " }\n" " ,...\n" " ]\n" @@ -1015,6 +1034,12 @@ UniValue importmulti(const JSONRPCRequest& mainRequest) LOCK2(cs_main, pwalletMain->cs_wallet); EnsureWalletIsUnlocked(); + // Verify all timestamps are present before importing any keys. + const int64_t now = chainActive.Tip() ? chainActive.Tip()->GetMedianTimePast() : 0; + for (const UniValue& data : requests.getValues()) { + GetImportTimestamp(data, now); + } + bool fRunScan = false; const int64_t minimumTimestamp = 1; int64_t nLowestTimestamp = 0; @@ -1028,7 +1053,8 @@ UniValue importmulti(const JSONRPCRequest& mainRequest) UniValue response(UniValue::VARR); BOOST_FOREACH (const UniValue& data, requests.getValues()) { - const UniValue result = processImport(data); + const int64_t timestamp = std::max(GetImportTimestamp(data, now), minimumTimestamp); + const UniValue result = ProcessImport(data, timestamp); response.push_back(result); if (!fRescan) { @@ -1041,20 +1067,40 @@ UniValue importmulti(const JSONRPCRequest& mainRequest) } // Get the lowest timestamp. - const int64_t& timestamp = data.exists("timestamp") && data["timestamp"].get_int64() > minimumTimestamp ? data["timestamp"].get_int64() : minimumTimestamp; - if (timestamp < nLowestTimestamp) { nLowestTimestamp = timestamp; } } - if (fRescan && fRunScan && requests.size() && nLowestTimestamp <= chainActive.Tip()->GetBlockTimeMax()) { - CBlockIndex* pindex = nLowestTimestamp > minimumTimestamp ? chainActive.FindEarliestAtLeast(nLowestTimestamp) : chainActive.Genesis(); - + if (fRescan && fRunScan && requests.size()) { + CBlockIndex* pindex = nLowestTimestamp > minimumTimestamp ? chainActive.FindEarliestAtLeast(std::max<int64_t>(nLowestTimestamp - 7200, 0)) : chainActive.Genesis(); + CBlockIndex* scannedRange = nullptr; if (pindex) { - pwalletMain->ScanForWalletTransactions(pindex, true); + scannedRange = pwalletMain->ScanForWalletTransactions(pindex, true); pwalletMain->ReacceptWalletTransactions(); } + + if (!scannedRange || scannedRange->nHeight > pindex->nHeight) { + std::vector<UniValue> results = response.getValues(); + response.clear(); + response.setArray(); + size_t i = 0; + for (const UniValue& request : requests.getValues()) { + // If key creation date is within the successfully scanned + // range, or if the import result already has an error set, let + // the result stand unmodified. Otherwise replace the result + // with an error message. + if (GetImportTimestamp(request, now) - 7200 >= scannedRange->GetBlockTimeMax() || results.at(i).exists("error")) { + response.push_back(results.at(i)); + } else { + UniValue result = UniValue(UniValue::VOBJ); + result.pushKV("success", UniValue(false)); + result.pushKV("error", JSONRPCError(RPC_MISC_ERROR, strprintf("Failed to rescan before time %d, transactions may be missing.", scannedRange->GetBlockTimeMax()))); + response.push_back(std::move(result)); + } + ++i; + } + } } return response; diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 6d08f60483..d785c95ae0 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -236,8 +236,8 @@ UniValue setaccount(const JSONRPCRequest& request) "1. \"address\" (string, required) The bitcoin address to be associated with an account.\n" "2. \"account\" (string, required) The account to assign the address to.\n" "\nExamples:\n" - + HelpExampleCli("setaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" \"tabby\"") - + HelpExampleRpc("setaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\", \"tabby\"") + + HelpExampleCli("setaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"tabby\"") + + HelpExampleRpc("setaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\", \"tabby\"") ); LOCK2(cs_main, pwalletMain->cs_wallet); @@ -283,8 +283,8 @@ UniValue getaccount(const JSONRPCRequest& request) "\nResult:\n" "\"accountname\" (string) the account address\n" "\nExamples:\n" - + HelpExampleCli("getaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\"") - + HelpExampleRpc("getaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\"") + + HelpExampleCli("getaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\"") + + HelpExampleRpc("getaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\"") ); LOCK2(cs_main, pwalletMain->cs_wallet); @@ -503,11 +503,11 @@ UniValue signmessage(const JSONRPCRequest& request) "\nUnlock the wallet for 30 seconds\n" + HelpExampleCli("walletpassphrase", "\"mypassphrase\" 30") + "\nCreate the signature\n" - + HelpExampleCli("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" \"my message\"") + + + HelpExampleCli("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"my message\"") + "\nVerify the signature\n" - + HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" \"signature\" \"my message\"") + + + HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"signature\" \"my message\"") + "\nAs json rpc\n" - + HelpExampleRpc("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\", \"my message\"") + + HelpExampleRpc("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\", \"my message\"") ); LOCK2(cs_main, pwalletMain->cs_wallet); @@ -556,13 +556,13 @@ UniValue getreceivedbyaddress(const JSONRPCRequest& request) "amount (numeric) The total amount in " + CURRENCY_UNIT + " received at this address.\n" "\nExamples:\n" "\nThe amount from transactions with at least 1 confirmation\n" - + HelpExampleCli("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\"") + + + HelpExampleCli("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\"") + "\nThe amount including unconfirmed transactions, zero confirmations\n" - + HelpExampleCli("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" 0") + + + HelpExampleCli("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" 0") + "\nThe amount with at least 6 confirmation, very safe\n" - + HelpExampleCli("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" 6") + + + HelpExampleCli("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" 6") + "\nAs a json rpc call\n" - + HelpExampleRpc("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\", 6") + + HelpExampleRpc("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\", 6") ); LOCK2(cs_main, pwalletMain->cs_wallet); @@ -668,8 +668,19 @@ UniValue getbalance(const JSONRPCRequest& request) "Note that the account \"\" is not the same as leaving the parameter out.\n" "The server total may be different to the balance in the default \"\" account.\n" "\nArguments:\n" - "1. \"account\" (string, optional) DEPRECATED. The selected account, or \"*\" for entire wallet. It may be the default account using \"\".\n" - "2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n" + "1. \"account\" (string, optional) DEPRECATED. The account string may be given as a\n" + " specific account name to find the balance associated with wallet keys in\n" + " a named account, or as the empty string (\"\") to find the balance\n" + " associated with wallet keys not in any named account, or as \"*\" to find\n" + " the balance associated with all wallet keys regardless of account.\n" + " When this option is specified, it calculates the balance in a different\n" + " way than when it is not specified, and which can count spends twice when\n" + " there are conflicting pending transactions (such as those created by\n" + " the bumpfee command), temporarily resulting in low or even negative\n" + " balances. In general, account balance calculation is not considered\n" + " reliable and has resulted in confusing outcomes, so it is recommended to\n" + " avoid passing this argument.\n" + "2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n" "3. include_watchonly (bool, optional, default=false) Also include balance in watch-only addresses (see 'importaddress')\n" "\nResult:\n" "amount (numeric) The total amount in " + CURRENCY_UNIT + " received for this account.\n" @@ -696,9 +707,12 @@ UniValue getbalance(const JSONRPCRequest& request) filter = filter | ISMINE_WATCH_ONLY; if (request.params[0].get_str() == "*") { - // Calculate total balance a different way from GetBalance() - // (GetBalance() sums up all unspent TxOuts) - // getbalance and "getbalance * 1 true" should return the same number + // Calculate total balance in a very different way from GetBalance(). + // The biggest difference is that GetBalance() sums up all unspent + // TxOuts paying to the wallet, while this sums up both spent and + // unspent TxOuts paying to the wallet, and then subtracts the values of + // TxIns spending from the wallet. This also has fewer restrictions on + // which unconfirmed transactions are considered trusted. CAmount nBalance = 0; for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) { @@ -805,6 +819,9 @@ UniValue sendfrom(const JSONRPCRequest& request) + HelpRequiringPassphrase() + "\n" "\nArguments:\n" "1. \"fromaccount\" (string, required) The name of the account to send funds from. May be the default account using \"\".\n" + " Specifying an account does not influence coin selection, but it does associate the newly created\n" + " transaction with the account, so the account's balance computation and transaction history can reflect\n" + " the spend.\n" "2. \"toaddress\" (string, required) The bitcoin address to send funds to.\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" @@ -889,13 +906,13 @@ UniValue sendmany(const JSONRPCRequest& request) " the number of addresses.\n" "\nExamples:\n" "\nSend two amounts to two different addresses:\n" - + HelpExampleCli("sendmany", "\"\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\"") + + + HelpExampleCli("sendmany", "\"\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\"") + "\nSend two amounts to two different addresses setting the confirmation and comment:\n" - + HelpExampleCli("sendmany", "\"\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\" 6 \"testing\"") + + + HelpExampleCli("sendmany", "\"\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\" 6 \"testing\"") + "\nSend two amounts to two different addresses, subtract fee from amount:\n" - + HelpExampleCli("sendmany", "\"\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\" 1 \"\" \"[\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\",\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\"]\"") + + + HelpExampleCli("sendmany", "\"\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\" 1 \"\" \"[\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\\\",\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\"]\"") + "\nAs a json rpc call\n" - + HelpExampleRpc("sendmany", "\"\", \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\", 6, \"testing\"") + + HelpExampleRpc("sendmany", "\"\", \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\", 6, \"testing\"") ); LOCK2(cs_main, pwalletMain->cs_wallet); @@ -2402,7 +2419,7 @@ UniValue listunspent(const JSONRPCRequest& request) " \"address\" : \"address\", (string) the bitcoin address\n" " \"account\" : \"account\", (string) DEPRECATED. The associated account, or \"\" for the default account\n" " \"scriptPubKey\" : \"key\", (string) the script key\n" - " \"amount\" : x.xxx, (numeric) the transaction amount in " + CURRENCY_UNIT + "\n" + " \"amount\" : x.xxx, (numeric) the transaction output amount in " + CURRENCY_UNIT + "\n" " \"confirmations\" : n, (numeric) The number of confirmations\n" " \"redeemScript\" : n (string) The redeemScript if scriptPubKey is P2SH\n" " \"spendable\" : xxx, (bool) Whether we have the private keys to spend this output\n" @@ -2650,6 +2667,33 @@ UniValue fundrawtransaction(const JSONRPCRequest& request) return result; } +// Calculate the size of the transaction assuming all signatures are max size +// Use DummySignatureCreator, which inserts 72 byte signatures everywhere. +// TODO: re-use this in CWallet::CreateTransaction (right now +// CreateTransaction uses the constructed dummy-signed tx to do a priority +// calculation, but we should be able to refactor after priority is removed). +// NOTE: this requires that all inputs must be in mapWallet (eg the tx should +// be IsAllFromMe). +int64_t CalculateMaximumSignedTxSize(const CTransaction &tx) +{ + CMutableTransaction txNew(tx); + std::vector<pair<CWalletTx *, unsigned int>> vCoins; + // Look up the inputs. We should have already checked that this transaction + // IsAllFromMe(ISMINE_SPENDABLE), so every input should already be in our + // wallet, with a valid index into the vout array. + for (auto& input : tx.vin) { + const auto mi = pwalletMain->mapWallet.find(input.prevout.hash); + assert(mi != pwalletMain->mapWallet.end() && input.prevout.n < mi->second.tx->vout.size()); + vCoins.emplace_back(make_pair(&(mi->second), input.prevout.n)); + } + if (!pwalletMain->DummySignTx(txNew, vCoins)) { + // This should never happen, because IsAllFromMe(ISMINE_SPENDABLE) + // implies that we can sign for every input. + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction contains inputs that cannot be signed"); + } + return GetVirtualTransactionSize(txNew); +} + UniValue bumpfee(const JSONRPCRequest& request) { if (!EnsureWalletIsAvailable(request.fHelp)) { @@ -2668,8 +2712,8 @@ UniValue bumpfee(const JSONRPCRequest& request) "By default, the new fee will be calculated automatically using estimatefee.\n" "The user can specify a confirmation target for estimatefee.\n" "Alternatively, the user can specify totalFee, or use RPC setpaytxfee to set a higher fee rate.\n" - "At a minimum, the new fee rate must be high enough to pay a new relay fee (relay fee amount returned\n" - "by getnetworkinfo RPC) and to enter the node's mempool.\n" + "At a minimum, the new fee rate must be high enough to pay an additional new relay fee (incrementalfee\n" + "returned by getnetworkinfo) to enter the node's mempool.\n" "\nArguments:\n" "1. txid (string, required) The txid to be bumped\n" "2. options (object, optional)\n" @@ -2684,14 +2728,15 @@ UniValue bumpfee(const JSONRPCRequest& request) " be left unchanged from the original. If false, any input sequence numbers in the\n" " original transaction that were less than 0xfffffffe will be increased to 0xfffffffe\n" " so the new transaction will not be explicitly bip-125 replaceable (though it may\n" - " still be replacable in practice, for example if it has unconfirmed ancestors which\n" + " still be replaceable in practice, for example if it has unconfirmed ancestors which\n" " are replaceable).\n" " }\n" "\nResult:\n" "{\n" " \"txid\": \"value\", (string) The id of the new transaction\n" - " \"oldfee\": n, (numeric) Fee of the replaced transaction\n" - " \"fee\": n, (numeric) Fee of the new transaction\n" + " \"origfee\": n, (numeric) Fee of the replaced transaction\n" + " \"fee\": n, (numeric) Fee of the new transaction\n" + " \"errors\": [ str... ] (json array of strings) Errors encountered during processing (may be empty)\n" "}\n" "\nExamples:\n" "\nBump the fee, get the new transaction\'s txid\n" + @@ -2755,6 +2800,10 @@ UniValue bumpfee(const JSONRPCRequest& request) throw JSONRPCError(RPC_MISC_ERROR, "Transaction does not have a change output"); } + // Calculate the expected size of the new transaction. + int64_t txSize = GetVirtualTransactionSize(*(wtx.tx)); + const int64_t maxNewTxSize = CalculateMaximumSignedTxSize(*wtx.tx); + // optional parameters bool specifiedConfirmTarget = false; int newConfirmTarget = nTxConfirmTarget; @@ -2780,10 +2829,11 @@ UniValue bumpfee(const JSONRPCRequest& request) } } else if (options.exists("totalFee")) { totalFee = options["totalFee"].get_int64(); - if (totalFee <= 0) { - throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid totalFee (cannot be <= 0)"); - } else if (totalFee > maxTxFee) { - throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid totalFee (cannot be higher than maxTxFee)"); + CAmount requiredFee = CWallet::GetRequiredFee(maxNewTxSize); + if (totalFee < requiredFee ) { + throw JSONRPCError(RPC_INVALID_PARAMETER, + strprintf("Insufficient totalFee (cannot be less than required fee %s)", + FormatMoney(requiredFee))); } } @@ -2792,42 +2842,57 @@ UniValue bumpfee(const JSONRPCRequest& request) } } - // signature sizes can vary by a byte, so add 1 for each input when calculating the new fee - int64_t txSize = GetVirtualTransactionSize(*(wtx.tx)); - const int64_t maxNewTxSize = txSize + wtx.tx->vin.size(); - // calculate the old fee and fee-rate CAmount nOldFee = wtx.GetDebit(ISMINE_SPENDABLE) - wtx.tx->GetValueOut(); CFeeRate nOldFeeRate(nOldFee, txSize); CAmount nNewFee; CFeeRate nNewFeeRate; + // The wallet uses a conservative WALLET_INCREMENTAL_RELAY_FEE value to + // future proof against changes to network wide policy for incremental relay + // fee that our node may not be aware of. + CFeeRate walletIncrementalRelayFee = CFeeRate(WALLET_INCREMENTAL_RELAY_FEE); + if (::incrementalRelayFee > walletIncrementalRelayFee) { + walletIncrementalRelayFee = ::incrementalRelayFee; + } if (totalFee > 0) { - CAmount minTotalFee = nOldFeeRate.GetFee(maxNewTxSize) + minRelayTxFee.GetFee(maxNewTxSize); + CAmount minTotalFee = nOldFeeRate.GetFee(maxNewTxSize) + ::incrementalRelayFee.GetFee(maxNewTxSize); if (totalFee < minTotalFee) { - throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid totalFee, must be at least %s (oldFee %s + relayFee %s)", FormatMoney(minTotalFee), nOldFeeRate.GetFee(maxNewTxSize), minRelayTxFee.GetFee(maxNewTxSize))); + throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Insufficient totalFee, must be at least %s (oldFee %s + incrementalFee %s)", + FormatMoney(minTotalFee), FormatMoney(nOldFeeRate.GetFee(maxNewTxSize)), FormatMoney(::incrementalRelayFee.GetFee(maxNewTxSize)))); } nNewFee = totalFee; nNewFeeRate = CFeeRate(totalFee, maxNewTxSize); } else { - // use the user-defined payTxFee if possible, otherwise use smartfee / fallbackfee - if (!specifiedConfirmTarget && payTxFee.GetFeePerK() != 0) { - nNewFeeRate = payTxFee; - } else { - nNewFeeRate = mempool.estimateSmartFee(newConfirmTarget); + // if user specified a confirm target then don't consider any global payTxFee + if (specifiedConfirmTarget) { + nNewFee = CWallet::GetMinimumFee(maxNewTxSize, newConfirmTarget, mempool, CAmount(0)); } - if (nNewFeeRate.GetFeePerK() == 0) { - nNewFeeRate = CWallet::fallbackFee; + // otherwise use the regular wallet logic to select payTxFee or default confirm target + else { + nNewFee = CWallet::GetMinimumFee(maxNewTxSize, newConfirmTarget, mempool); } - // new fee rate must be at least old rate + minimum relay rate - if (nNewFeeRate.GetFeePerK() < nOldFeeRate.GetFeePerK() + ::minRelayTxFee.GetFeePerK()) { - nNewFeeRate = CFeeRate(nOldFeeRate.GetFeePerK() + ::minRelayTxFee.GetFeePerK()); - } + nNewFeeRate = CFeeRate(nNewFee, maxNewTxSize); - nNewFee = nNewFeeRate.GetFee(maxNewTxSize); + // New fee rate must be at least old rate + minimum incremental relay rate + // walletIncrementalRelayFee.GetFeePerK() should be exact, because it's initialized + // in that unit (fee per kb). + // However, nOldFeeRate is a calculated value from the tx fee/size, so + // add 1 satoshi to the result, because it may have been rounded down. + if (nNewFeeRate.GetFeePerK() < nOldFeeRate.GetFeePerK() + 1 + walletIncrementalRelayFee.GetFeePerK()) { + nNewFeeRate = CFeeRate(nOldFeeRate.GetFeePerK() + 1 + walletIncrementalRelayFee.GetFeePerK()); + nNewFee = nNewFeeRate.GetFee(maxNewTxSize); + } } + // Check that in all cases the new fee doesn't violate maxTxFee + if (nNewFee > maxTxFee) { + throw JSONRPCError(RPC_MISC_ERROR, + strprintf("Specified or calculated fee %s is too high (cannot be higher than maxTxFee %s)", + FormatMoney(nNewFee), FormatMoney(maxTxFee))); + } + // check that fee rate is higher than mempool's minimum fee // (no point in bumping fee if we know that the new tx won't be accepted to the mempool) // This may occur if the user set TotalFee or paytxfee too low, if fallbackfee is too low, or, perhaps, @@ -2850,7 +2915,7 @@ UniValue bumpfee(const JSONRPCRequest& request) // If the output would become dust, discard it (converting the dust to fee) poutput->nValue -= nDelta; - if (poutput->nValue <= poutput->GetDustThreshold(::minRelayTxFee)) { + if (poutput->nValue <= poutput->GetDustThreshold(::dustRelayFee)) { LogPrint("rpc", "Bumping fee and discarding dust output\n"); nNewFee += poutput->nValue; tx.vout.erase(tx.vout.begin() + nOutput); @@ -2882,25 +2947,39 @@ UniValue bumpfee(const JSONRPCRequest& request) // commit/broadcast the tx CReserveKey reservekey(pwalletMain); CWalletTx wtxBumped(pwalletMain, MakeTransactionRef(std::move(tx))); + wtxBumped.mapValue = wtx.mapValue; wtxBumped.mapValue["replaces_txid"] = hash.ToString(); + wtxBumped.vOrderForm = wtx.vOrderForm; + wtxBumped.strFromAccount = wtx.strFromAccount; + wtxBumped.fTimeReceivedIsTxTime = true; + wtxBumped.fFromMe = true; CValidationState state; - if (!pwalletMain->CommitTransaction(wtxBumped, reservekey, g_connman.get(), state) || !state.IsValid()) { + if (!pwalletMain->CommitTransaction(wtxBumped, reservekey, g_connman.get(), state)) { + // NOTE: CommitTransaction never returns false, so this should never happen. throw JSONRPCError(RPC_WALLET_ERROR, strprintf("Error: The transaction was rejected! Reason given: %s", state.GetRejectReason())); } + UniValue vErrors(UniValue::VARR); + if (state.IsInvalid()) { + // This can happen if the mempool rejected the transaction. Report + // what happened in the "errors" response. + vErrors.push_back(strprintf("Error: The transaction was rejected: %s", FormatStateMessage(state))); + } + // mark the original tx as bumped if (!pwalletMain->MarkReplaced(wtx.GetHash(), wtxBumped.GetHash())) { // TODO: see if JSON-RPC has a standard way of returning a response // along with an exception. It would be good to return information about // wtxBumped to the caller even if marking the original transaction // replaced does not succeed for some reason. - throw JSONRPCError(RPC_WALLET_ERROR, "Error: Created new bumpfee transaction but could not mark the original transaction as replaced."); + vErrors.push_back("Error: Created new bumpfee transaction but could not mark the original transaction as replaced."); } UniValue result(UniValue::VOBJ); result.push_back(Pair("txid", wtxBumped.GetHash().GetHex())); - result.push_back(Pair("oldfee", ValueFromAmount(nOldFee))); + result.push_back(Pair("origfee", ValueFromAmount(nOldFee))); result.push_back(Pair("fee", ValueFromAmount(nNewFee))); + result.push_back(Pair("errors", vErrors)); return result; } diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp index ca086c86a8..7ac2112dd2 100644 --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -9,10 +9,16 @@ #include <utility> #include <vector> +#include "rpc/server.h" +#include "test/test_bitcoin.h" +#include "validation.h" #include "wallet/test/wallet_test_fixture.h" #include <boost/foreach.hpp> #include <boost/test/unit_test.hpp> +#include <univalue.h> + +extern UniValue importmulti(const JSONRPCRequest& request); // how many times to run all the tests to have a chance to catch errors that only show up with particular random shuffles #define RUN_TESTS 100 @@ -355,4 +361,71 @@ BOOST_AUTO_TEST_CASE(ApproximateBestSubset) empty_wallet(); } +BOOST_FIXTURE_TEST_CASE(rescan, TestChain100Setup) +{ + LOCK(cs_main); + + // Cap last block file size, and mine new block in a new block file. + CBlockIndex* oldTip = chainActive.Tip(); + GetBlockFileInfo(oldTip->GetBlockPos().nFile)->nSize = MAX_BLOCKFILE_SIZE; + CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey())); + CBlockIndex* newTip = chainActive.Tip(); + + // Verify ScanForWalletTransactions picks up transactions in both the old + // and new block files. + { + CWallet wallet; + LOCK(wallet.cs_wallet); + wallet.AddKeyPubKey(coinbaseKey, coinbaseKey.GetPubKey()); + BOOST_CHECK_EQUAL(oldTip, wallet.ScanForWalletTransactions(oldTip)); + BOOST_CHECK_EQUAL(wallet.GetImmatureBalance(), 100 * COIN); + } + + // Prune the older block file. + PruneOneBlockFile(oldTip->GetBlockPos().nFile); + UnlinkPrunedFiles({oldTip->GetBlockPos().nFile}); + + // Verify ScanForWalletTransactions only picks transactions in the new block + // file. + { + CWallet wallet; + LOCK(wallet.cs_wallet); + wallet.AddKeyPubKey(coinbaseKey, coinbaseKey.GetPubKey()); + BOOST_CHECK_EQUAL(newTip, wallet.ScanForWalletTransactions(oldTip)); + BOOST_CHECK_EQUAL(wallet.GetImmatureBalance(), 50 * COIN); + } + + // Verify importmulti RPC returns failure for a key whose creation time is + // before the missing block, and success for a key whose creation time is + // after. + { + CWallet wallet; + CWallet *backup = ::pwalletMain; + ::pwalletMain = &wallet; + UniValue keys; + keys.setArray(); + UniValue key; + key.setObject(); + key.pushKV("scriptPubKey", HexStr(GetScriptForRawPubKey(coinbaseKey.GetPubKey()))); + key.pushKV("timestamp", 0); + key.pushKV("internal", UniValue(true)); + keys.push_back(key); + key.clear(); + key.setObject(); + CKey futureKey; + futureKey.MakeNewKey(true); + key.pushKV("scriptPubKey", HexStr(GetScriptForRawPubKey(futureKey.GetPubKey()))); + key.pushKV("timestamp", newTip->GetBlockTimeMax() + 7200); + key.pushKV("internal", UniValue(true)); + keys.push_back(key); + JSONRPCRequest request; + request.params.setArray(); + request.params.push_back(keys); + + UniValue response = importmulti(request); + BOOST_CHECK_EQUAL(response.write(), strprintf("[{\"success\":false,\"error\":{\"code\":-1,\"message\":\"Failed to rescan before time %d, transactions may be missing.\"}},{\"success\":true}]", newTip->GetBlockTimeMax())); + ::pwalletMain = backup; + } +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 50e5e2a685..4231e02c4a 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -113,8 +113,7 @@ CPubKey CWallet::GenerateNewKey() assert(secret.VerifyPubKey(pubkey)); mapKeyMetadata[pubkey.GetID()] = metadata; - if (!nTimeFirstKey || nCreationTime < nTimeFirstKey) - nTimeFirstKey = nCreationTime; + UpdateTimeFirstKey(nCreationTime); if (!AddKeyPubKey(secret, pubkey)) throw std::runtime_error(std::string(__func__) + ": AddKey failed"); @@ -207,13 +206,11 @@ bool CWallet::AddCryptedKey(const CPubKey &vchPubKey, return false; } -bool CWallet::LoadKeyMetadata(const CPubKey &pubkey, const CKeyMetadata &meta) +bool CWallet::LoadKeyMetadata(const CTxDestination& keyID, const CKeyMetadata &meta) { AssertLockHeld(cs_wallet); // mapKeyMetadata - if (meta.nCreateTime && (!nTimeFirstKey || meta.nCreateTime < nTimeFirstKey)) - nTimeFirstKey = meta.nCreateTime; - - mapKeyMetadata[pubkey.GetID()] = meta; + UpdateTimeFirstKey(meta.nCreateTime); + mapKeyMetadata[keyID] = meta; return true; } @@ -222,6 +219,18 @@ bool CWallet::LoadCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigne return CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret); } +void CWallet::UpdateTimeFirstKey(int64_t nCreateTime) +{ + AssertLockHeld(cs_wallet); + if (nCreateTime <= 1) { + // Cannot determine birthday information, so set the wallet birthday to + // the beginning of time. + nTimeFirstKey = 1; + } else if (!nTimeFirstKey || nCreateTime < nTimeFirstKey) { + nTimeFirstKey = nCreateTime; + } +} + bool CWallet::AddCScript(const CScript& redeemScript) { if (!CCryptoKeyStore::AddCScript(redeemScript)) @@ -247,15 +256,22 @@ bool CWallet::LoadCScript(const CScript& redeemScript) return CCryptoKeyStore::AddCScript(redeemScript); } -bool CWallet::AddWatchOnly(const CScript &dest) +bool CWallet::AddWatchOnly(const CScript& dest) { if (!CCryptoKeyStore::AddWatchOnly(dest)) return false; - nTimeFirstKey = 1; // No birthday information for watch-only keys. + const CKeyMetadata& meta = mapKeyMetadata[CScriptID(dest)]; + UpdateTimeFirstKey(meta.nCreateTime); NotifyWatchonlyChanged(true); if (!fFileBacked) return true; - return CWalletDB(strWalletFile).WriteWatchOnly(dest); + return CWalletDB(strWalletFile).WriteWatchOnly(dest, meta); +} + +bool CWallet::AddWatchOnly(const CScript& dest, int64_t nCreateTime) +{ + mapKeyMetadata[CScriptID(dest)].nCreateTime = nCreateTime; + return AddWatchOnly(dest); } bool CWallet::RemoveWatchOnly(const CScript &dest) @@ -1003,9 +1019,17 @@ bool CWallet::LoadToWallet(const CWalletTx& wtxIn) } /** - * Add a transaction to the wallet, or update it. - * pblock is optional, but should be provided if the transaction is known to be in a block. + * Add a transaction to the wallet, or update it. pIndex and posInBlock should + * be set when the transaction was known to be included in a block. When + * posInBlock = SYNC_TRANSACTION_NOT_IN_BLOCK (-1) , then wallet state is not + * updated in AddToWallet, but notifications happen and cached balances are + * marked dirty. * If fUpdate is true, existing transactions will be updated. + * TODO: One exception to this is that the abandoned state is cleared under the + * assumption that any further notification of a transaction that was considered + * abandoned is an indication that it is not safe to be considered abandoned. + * Abandoned state should probably be more carefully tracked via different + * posInBlock signals or by checking mempool presence when necessary. */ bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlockIndex* pIndex, int posInBlock, bool fUpdate) { @@ -1521,10 +1545,14 @@ void CWalletTx::GetAccountAmounts(const string& strAccount, CAmount& nReceived, * Scan the block chain (starting in pindexStart) for transactions * from or to us. If fUpdate is true, found transactions that already * exist in the wallet will be updated. + * + * Returns pointer to the first block in the last contiguous range that was + * successfully scanned. + * */ -int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate) +CBlockIndex* CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate) { - int ret = 0; + CBlockIndex* ret = nullptr; int64_t nNow = GetTime(); const CChainParams& chainParams = Params(); @@ -1546,12 +1574,15 @@ int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate) ShowProgress(_("Rescanning..."), std::max(1, std::min(99, (int)((GuessVerificationProgress(chainParams.TxData(), pindex) - dProgressStart) / (dProgressTip - dProgressStart) * 100)))); CBlock block; - ReadBlockFromDisk(block, pindex, Params().GetConsensus()); - int posInBlock; - for (posInBlock = 0; posInBlock < (int)block.vtx.size(); posInBlock++) - { - if (AddToWalletIfInvolvingMe(*block.vtx[posInBlock], pindex, posInBlock, fUpdate)) - ret++; + if (ReadBlockFromDisk(block, pindex, Params().GetConsensus())) { + for (size_t posInBlock = 0; posInBlock < block.vtx.size(); ++posInBlock) { + AddToWalletIfInvolvingMe(*block.vtx[posInBlock], pindex, posInBlock, fUpdate); + } + if (!ret) { + ret = pindex; + } + } else { + ret = nullptr; } pindex = chainActive.Next(pindex); if (GetTime() >= nNow + 60) { @@ -2568,28 +2599,16 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wt // BIP125 defines opt-in RBF as any nSequence < maxint-1, so // we use the highest possible value in that range (maxint-2) // to avoid conflicting with other possible uses of nSequence, - // and in the spirit of "smallest posible change from prior + // and in the spirit of "smallest possible change from prior // behavior." for (const auto& coin : setCoins) txNew.vin.push_back(CTxIn(coin.first->GetHash(),coin.second,CScript(), std::numeric_limits<unsigned int>::max() - (fWalletRbf ? 2 : 1))); // Fill in dummy signatures for fee calculation. - int nIn = 0; - for (const auto& coin : setCoins) - { - const CScript& scriptPubKey = coin.first->tx->vout[coin.second].scriptPubKey; - SignatureData sigdata; - - if (!ProduceSignature(DummySignatureCreator(this), scriptPubKey, sigdata)) - { - strFailReason = _("Signing transaction failed"); - return false; - } else { - UpdateTransaction(txNew, nIn, sigdata); - } - - nIn++; + if (!DummySignTx(txNew, setCoins)) { + strFailReason = _("Signing transaction failed"); + return false; } unsigned int nBytes = GetVirtualTransactionSize(txNew); @@ -2794,8 +2813,13 @@ CAmount CWallet::GetRequiredFee(unsigned int nTxBytes) CAmount CWallet::GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarget, const CTxMemPool& pool) { - // payTxFee is user-set "I want to pay this much" - CAmount nFeeNeeded = payTxFee.GetFee(nTxBytes); + // payTxFee is the user-set global for desired feerate + return GetMinimumFee(nTxBytes, nConfirmTarget, pool, payTxFee.GetFee(nTxBytes)); +} + +CAmount CWallet::GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarget, const CTxMemPool& pool, CAmount targetFee) +{ + CAmount nFeeNeeded = targetFee; // User didn't set: use -txconfirmtarget to estimate... if (nFeeNeeded == 0) { int estimateFoundTarget = nConfirmTarget; @@ -3420,14 +3444,16 @@ public: void operator()(const CNoDestination &none) {} }; -void CWallet::GetKeyBirthTimes(std::map<CKeyID, int64_t> &mapKeyBirth) const { +void CWallet::GetKeyBirthTimes(std::map<CTxDestination, int64_t> &mapKeyBirth) const { AssertLockHeld(cs_wallet); // mapKeyMetadata mapKeyBirth.clear(); // get birth times for keys with metadata - for (std::map<CKeyID, CKeyMetadata>::const_iterator it = mapKeyMetadata.begin(); it != mapKeyMetadata.end(); it++) - if (it->second.nCreateTime) - mapKeyBirth[it->first] = it->second.nCreateTime; + for (const auto& entry : mapKeyMetadata) { + if (entry.second.nCreateTime) { + mapKeyBirth[entry.first] = entry.second.nCreateTime; + } + } // map in which we'll infer heights of other keys CBlockIndex *pindexMax = chainActive[std::max(0, chainActive.Height() - 144)]; // the tip can be reorganized; use a 144-block safety margin @@ -3695,7 +3721,7 @@ CWallet* CWallet::CreateWalletFromFile(const std::string walletFile) walletInstance->ScanForWalletTransactions(pindexRescan, true); LogPrintf(" rescan %15dms\n", GetTimeMillis() - nStart); walletInstance->SetBestChain(chainActive.GetLocator()); - nWalletDBUpdated++; + CWalletDB::IncrementUpdateCounter(); // Restore wallet transaction metadata after -zapwallettxes=1 if (GetBoolArg("-zapwallettxes", false) && GetArg("-zapwallettxes", "1") != "2") @@ -3878,11 +3904,7 @@ bool CWallet::BackupWallet(const std::string& strDest) pathDest /= strWalletFile; try { -#if BOOST_VERSION >= 104000 boost::filesystem::copy_file(pathSrc, pathDest, boost::filesystem::copy_option::overwrite_if_exists); -#else - boost::filesystem::copy_file(pathSrc, pathDest); -#endif LogPrintf("copied %s to %s\n", strWalletFile, pathDest.string()); return true; } catch (const boost::filesystem::filesystem_error& e) { diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index a7fc05b62d..98e4fb87b9 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -13,6 +13,7 @@ #include "utilstrencodings.h" #include "validationinterface.h" #include "script/ismine.h" +#include "script/sign.h" #include "wallet/crypter.h" #include "wallet/walletdb.h" #include "wallet/rpcwallet.h" @@ -48,6 +49,8 @@ static const CAmount DEFAULT_TRANSACTION_FEE = 0; static const CAmount DEFAULT_FALLBACK_FEE = 20000; //! -mintxfee default static const CAmount DEFAULT_TRANSACTION_MINFEE = 1000; +//! minimum recommended increment for BIP 125 replacement txs +static const CAmount WALLET_INCREMENTAL_RELAY_FEE = 5000; //! target minimum change amount static const CAmount MIN_CHANGE = CENT; //! final minimum change amount after paying for fees @@ -258,6 +261,11 @@ public: unsigned int fTimeReceivedIsTxTime; unsigned int nTimeReceived; //!< time received by this node unsigned int nTimeSmart; + /** + * From me flag is set to 1 for transactions that were created by the wallet + * on this bitcoin node, and set to 0 for transactions that were created + * externally and came in through the network or sendrawtransaction RPC. + */ char fFromMe; std::string strFromAccount; int64_t nOrderPos; //!< position in ordered transaction list @@ -603,6 +611,20 @@ private: bool fFileBacked; std::set<int64_t> setKeyPool; + + int64_t nTimeFirstKey; + + /** + * Private version of AddWatchOnly method which does not accept a + * timestamp, and which will reset the wallet's nTimeFirstKey value to 1 if + * the watch key did not previously have a timestamp associated with it. + * Because this is an inherited virtual method, it is accessible despite + * being marked private, but it is marked private anyway to encourage use + * of the other AddWatchOnly which accepts a timestamp and sets + * nTimeFirstKey more intelligently for more efficient rescans. + */ + bool AddWatchOnly(const CScript& dest) override; + public: /* * Main wallet lock. @@ -627,7 +649,9 @@ public: mapKeyMetadata[keyid] = CKeyMetadata(keypool.nTime); } - std::map<CKeyID, CKeyMetadata> mapKeyMetadata; + // Map from Key ID (for regular keys) or Script ID (for watch-only keys) to + // key metadata. + std::map<CTxDestination, CKeyMetadata> mapKeyMetadata; typedef std::map<unsigned int, CMasterKey> MasterKeyMap; MasterKeyMap mapMasterKeys; @@ -680,8 +704,6 @@ public: std::set<COutPoint> setLockedCoins; - int64_t nTimeFirstKey; - const CWalletTx* GetWalletTx(const uint256& hash) const; //! check whether we are allowed to upgrade (or already support) to the named feature @@ -715,19 +737,20 @@ public: CPubKey GenerateNewKey(); void DeriveNewChildKey(CKeyMetadata& metadata, CKey& secret); //! Adds a key to the store, and saves it to disk. - bool AddKeyPubKey(const CKey& key, const CPubKey &pubkey); + bool AddKeyPubKey(const CKey& key, const CPubKey &pubkey) override; //! Adds a key to the store, without saving it to disk (used by LoadWallet) bool LoadKey(const CKey& key, const CPubKey &pubkey) { return CCryptoKeyStore::AddKeyPubKey(key, pubkey); } //! Load metadata (used by LoadWallet) - bool LoadKeyMetadata(const CPubKey &pubkey, const CKeyMetadata &metadata); + bool LoadKeyMetadata(const CTxDestination& pubKey, const CKeyMetadata &metadata); bool LoadMinVersion(int nVersion) { AssertLockHeld(cs_wallet); nWalletVersion = nVersion; nWalletMaxVersion = std::max(nWalletMaxVersion, nVersion); return true; } + void UpdateTimeFirstKey(int64_t nCreateTime); //! Adds an encrypted key to the store, and saves it to disk. - bool AddCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret); + bool AddCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret) override; //! Adds an encrypted key to the store, without saving it to disk (used by LoadWallet) bool LoadCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret); - bool AddCScript(const CScript& redeemScript); + bool AddCScript(const CScript& redeemScript) override; bool LoadCScript(const CScript& redeemScript); //! Adds a destination data tuple to the store, and saves it to disk @@ -740,8 +763,8 @@ public: bool GetDestData(const CTxDestination &dest, const std::string &key, std::string *value) const; //! Adds a watch-only address to the store, and saves it to disk. - bool AddWatchOnly(const CScript &dest); - bool RemoveWatchOnly(const CScript &dest); + bool AddWatchOnly(const CScript& dest, int64_t nCreateTime); + bool RemoveWatchOnly(const CScript &dest) override; //! Adds a watch-only address to the store, without saving it to disk (used by LoadWallet) bool LoadWatchOnly(const CScript &dest); @@ -749,7 +772,7 @@ public: bool ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, const SecureString& strNewWalletPassphrase); bool EncryptWallet(const SecureString& strWalletPassphrase); - void GetKeyBirthTimes(std::map<CKeyID, int64_t> &mapKeyBirth) const; + void GetKeyBirthTimes(std::map<CTxDestination, int64_t> &mapKeyBirth) const; /** * Increment the next transaction order id @@ -763,11 +786,11 @@ public: void MarkDirty(); bool AddToWallet(const CWalletTx& wtxIn, bool fFlushOnClose=true); bool LoadToWallet(const CWalletTx& wtxIn); - void SyncTransaction(const CTransaction& tx, const CBlockIndex *pindex, int posInBlock); + void SyncTransaction(const CTransaction& tx, const CBlockIndex *pindex, int posInBlock) override; bool AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlockIndex* pIndex, int posInBlock, bool fUpdate); - int ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate = false); + CBlockIndex* ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate = false); void ReacceptWalletTransactions(); - void ResendWalletTransactions(int64_t nBestBlockTime, CConnman* connman); + void ResendWalletTransactions(int64_t nBestBlockTime, CConnman* connman) override; std::vector<uint256> ResendWalletTransactionsBefore(int64_t nTime, CConnman* connman); CAmount GetBalance() const; CAmount GetUnconfirmedBalance() const; @@ -794,6 +817,8 @@ public: void ListAccountCreditDebit(const std::string& strAccount, std::list<CAccountingEntry>& entries); bool AddAccountingEntry(const CAccountingEntry&); bool AddAccountingEntry(const CAccountingEntry&, CWalletDB *pwalletdb); + template <typename ContainerType> + bool DummySignTx(CMutableTransaction &txNew, const ContainerType &coins); static CFeeRate minTxFee; static CFeeRate fallbackFee; @@ -803,6 +828,11 @@ public: */ static CAmount GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarget, const CTxMemPool& pool); /** + * Estimate the minimum fee considering required fee and targetFee or if 0 + * then fee estimation for nConfirmTarget + */ + static CAmount GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarget, const CTxMemPool& pool, CAmount targetFee); + /** * Return the minimum required fee taking into account the * floating relay fee and user set minimum transaction fee */ @@ -842,7 +872,7 @@ public: bool IsAllFromMe(const CTransaction& tx, const isminefilter& filter) const; CAmount GetCredit(const CTransaction& tx, const isminefilter& filter) const; CAmount GetChange(const CTransaction& tx) const; - void SetBestChain(const CBlockLocator& loc); + void SetBestChain(const CBlockLocator& loc) override; DBErrors LoadWallet(bool& fFirstRunRet); DBErrors ZapWalletTx(std::vector<CWalletTx>& vWtx); @@ -852,9 +882,9 @@ public: bool DelAddressBook(const CTxDestination& address); - void UpdatedTransaction(const uint256 &hashTx); + void UpdatedTransaction(const uint256 &hashTx) override; - void Inventory(const uint256 &hash) + void Inventory(const uint256 &hash) override { { LOCK(cs_wallet); @@ -864,8 +894,8 @@ public: } } - void GetScriptForMining(boost::shared_ptr<CReserveScript> &script); - void ResetRequestCount(const uint256 &hash) + void GetScriptForMining(boost::shared_ptr<CReserveScript> &script) override; + void ResetRequestCount(const uint256 &hash) override { LOCK(cs_wallet); mapRequestCount[hash] = 0; @@ -1021,4 +1051,28 @@ public: } }; +// Helper for producing a bunch of max-sized low-S signatures (eg 72 bytes) +// ContainerType is meant to hold pair<CWalletTx *, int>, and be iterable +// so that each entry corresponds to each vIn, in order. +template <typename ContainerType> +bool CWallet::DummySignTx(CMutableTransaction &txNew, const ContainerType &coins) +{ + // Fill in dummy signatures for fee calculation. + int nIn = 0; + for (const auto& coin : coins) + { + const CScript& scriptPubKey = coin.first->tx->vout[coin.second].scriptPubKey; + SignatureData sigdata; + + if (!ProduceSignature(DummySignatureCreator(this), scriptPubKey, sigdata)) + { + return false; + } else { + UpdateTransaction(txNew, nIn, sigdata); + } + + nIn++; + } + return true; +} #endif // BITCOIN_WALLET_WALLET_H diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index e67b7f2c58..44a01d4a36 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -15,6 +15,8 @@ #include "utiltime.h" #include "wallet/wallet.h" +#include <atomic> + #include <boost/version.hpp> #include <boost/filesystem.hpp> #include <boost/foreach.hpp> @@ -24,13 +26,15 @@ using namespace std; static uint64_t nAccountingEntryNumber = 0; +static std::atomic<unsigned int> nWalletDBUpdateCounter; + // // CWalletDB // bool CWalletDB::WriteName(const string& strAddress, const string& strName) { - nWalletDBUpdated++; + nWalletDBUpdateCounter++; return Write(make_pair(string("name"), strAddress), strName); } @@ -38,37 +42,37 @@ bool CWalletDB::EraseName(const string& strAddress) { // This should only be used for sending addresses, never for receiving addresses, // receiving addresses must always have an address book entry if they're not change return. - nWalletDBUpdated++; + nWalletDBUpdateCounter++; return Erase(make_pair(string("name"), strAddress)); } bool CWalletDB::WritePurpose(const string& strAddress, const string& strPurpose) { - nWalletDBUpdated++; + nWalletDBUpdateCounter++; return Write(make_pair(string("purpose"), strAddress), strPurpose); } bool CWalletDB::ErasePurpose(const string& strPurpose) { - nWalletDBUpdated++; + nWalletDBUpdateCounter++; return Erase(make_pair(string("purpose"), strPurpose)); } bool CWalletDB::WriteTx(const CWalletTx& wtx) { - nWalletDBUpdated++; + nWalletDBUpdateCounter++; return Write(std::make_pair(std::string("tx"), wtx.GetHash()), wtx); } bool CWalletDB::EraseTx(uint256 hash) { - nWalletDBUpdated++; + nWalletDBUpdateCounter++; return Erase(std::make_pair(std::string("tx"), hash)); } bool CWalletDB::WriteKey(const CPubKey& vchPubKey, const CPrivKey& vchPrivKey, const CKeyMetadata& keyMeta) { - nWalletDBUpdated++; + nWalletDBUpdateCounter++; if (!Write(std::make_pair(std::string("keymeta"), vchPubKey), keyMeta, false)) @@ -88,7 +92,7 @@ bool CWalletDB::WriteCryptedKey(const CPubKey& vchPubKey, const CKeyMetadata &keyMeta) { const bool fEraseUnencryptedKey = true; - nWalletDBUpdated++; + nWalletDBUpdateCounter++; if (!Write(std::make_pair(std::string("keymeta"), vchPubKey), keyMeta)) @@ -106,31 +110,35 @@ bool CWalletDB::WriteCryptedKey(const CPubKey& vchPubKey, bool CWalletDB::WriteMasterKey(unsigned int nID, const CMasterKey& kMasterKey) { - nWalletDBUpdated++; + nWalletDBUpdateCounter++; return Write(std::make_pair(std::string("mkey"), nID), kMasterKey, true); } bool CWalletDB::WriteCScript(const uint160& hash, const CScript& redeemScript) { - nWalletDBUpdated++; + nWalletDBUpdateCounter++; return Write(std::make_pair(std::string("cscript"), hash), *(const CScriptBase*)(&redeemScript), false); } -bool CWalletDB::WriteWatchOnly(const CScript &dest) +bool CWalletDB::WriteWatchOnly(const CScript &dest, const CKeyMetadata& keyMeta) { - nWalletDBUpdated++; + nWalletDBUpdateCounter++; + if (!Write(std::make_pair(std::string("watchmeta"), *(const CScriptBase*)(&dest)), keyMeta)) + return false; return Write(std::make_pair(std::string("watchs"), *(const CScriptBase*)(&dest)), '1'); } bool CWalletDB::EraseWatchOnly(const CScript &dest) { - nWalletDBUpdated++; + nWalletDBUpdateCounter++; + if (!Erase(std::make_pair(std::string("watchmeta"), *(const CScriptBase*)(&dest)))) + return false; return Erase(std::make_pair(std::string("watchs"), *(const CScriptBase*)(&dest))); } bool CWalletDB::WriteBestBlock(const CBlockLocator& locator) { - nWalletDBUpdated++; + nWalletDBUpdateCounter++; Write(std::string("bestblock"), CBlockLocator()); // Write empty block locator so versions that require a merkle branch automatically rescan return Write(std::string("bestblock_nomerkle"), locator); } @@ -143,13 +151,13 @@ bool CWalletDB::ReadBestBlock(CBlockLocator& locator) bool CWalletDB::WriteOrderPosNext(int64_t nOrderPosNext) { - nWalletDBUpdated++; + nWalletDBUpdateCounter++; return Write(std::string("orderposnext"), nOrderPosNext); } bool CWalletDB::WriteDefaultKey(const CPubKey& vchPubKey) { - nWalletDBUpdated++; + nWalletDBUpdateCounter++; return Write(std::string("defaultkey"), vchPubKey); } @@ -160,13 +168,13 @@ bool CWalletDB::ReadPool(int64_t nPool, CKeyPool& keypool) bool CWalletDB::WritePool(int64_t nPool, const CKeyPool& keypool) { - nWalletDBUpdated++; + nWalletDBUpdateCounter++; return Write(std::make_pair(std::string("pool"), nPool), keypool); } bool CWalletDB::ErasePool(int64_t nPool) { - nWalletDBUpdated++; + nWalletDBUpdateCounter++; return Erase(std::make_pair(std::string("pool"), nPool)); } @@ -255,6 +263,7 @@ class CWalletScanState { public: unsigned int nKeys; unsigned int nCKeys; + unsigned int nWatchKeys; unsigned int nKeyMeta; bool fIsEncrypted; bool fAnyUnordered; @@ -262,7 +271,7 @@ public: vector<uint256> vWalletUpgrade; CWalletScanState() { - nKeys = nCKeys = nKeyMeta = 0; + nKeys = nCKeys = nWatchKeys = nKeyMeta = 0; fIsEncrypted = false; fAnyUnordered = false; nFileVersion = 0; @@ -344,16 +353,13 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, } else if (strType == "watchs") { + wss.nWatchKeys++; CScript script; ssKey >> *(CScriptBase*)(&script); char fYes; ssValue >> fYes; if (fYes == '1') pwallet->LoadWatchOnly(script); - - // Watch-only addresses have no birthday information for now, - // so set the wallet birthday to the beginning of time. - pwallet->nTimeFirstKey = 1; } else if (strType == "key" || strType == "wkey") { @@ -454,20 +460,27 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, } wss.fIsEncrypted = true; } - else if (strType == "keymeta") + else if (strType == "keymeta" || strType == "watchmeta") { - CPubKey vchPubKey; - ssKey >> vchPubKey; + CTxDestination keyID; + if (strType == "keymeta") + { + CPubKey vchPubKey; + ssKey >> vchPubKey; + keyID = vchPubKey.GetID(); + } + else if (strType == "watchmeta") + { + CScript script; + ssKey >> *(CScriptBase*)(&script); + keyID = CScriptID(script); + } + CKeyMetadata keyMeta; ssValue >> keyMeta; wss.nKeyMeta++; - pwallet->LoadKeyMetadata(vchPubKey, keyMeta); - - // find earliest key creation time, as wallet birthday - if (!pwallet->nTimeFirstKey || - (keyMeta.nCreateTime < pwallet->nTimeFirstKey)) - pwallet->nTimeFirstKey = keyMeta.nCreateTime; + pwallet->LoadKeyMetadata(keyID, keyMeta); } else if (strType == "defaultkey") { @@ -546,8 +559,8 @@ DBErrors CWalletDB::LoadWallet(CWallet* pwallet) bool fNoncriticalErrors = false; DBErrors result = DB_LOAD_OK; + LOCK(pwallet->cs_wallet); try { - LOCK(pwallet->cs_wallet); int nMinVersion = 0; if (Read((string)"minversion", nMinVersion)) { @@ -621,8 +634,8 @@ DBErrors CWalletDB::LoadWallet(CWallet* pwallet) wss.nKeys, wss.nCKeys, wss.nKeyMeta, wss.nKeys + wss.nCKeys); // nTimeFirstKey is only reliable if all keys have metadata - if ((wss.nKeys + wss.nCKeys) != wss.nKeyMeta) - pwallet->nTimeFirstKey = 1; // 0 would be considered 'no value' + if ((wss.nKeys + wss.nCKeys + wss.nWatchKeys) != wss.nKeyMeta) + pwallet->UpdateTimeFirstKey(1); BOOST_FOREACH(uint256 hash, wss.vWalletUpgrade) WriteTx(pwallet->mapWallet[hash]); @@ -776,20 +789,20 @@ void ThreadFlushWalletDB() if (!GetBoolArg("-flushwallet", DEFAULT_FLUSHWALLET)) return; - unsigned int nLastSeen = nWalletDBUpdated; - unsigned int nLastFlushed = nWalletDBUpdated; + unsigned int nLastSeen = CWalletDB::GetUpdateCounter(); + unsigned int nLastFlushed = CWalletDB::GetUpdateCounter(); int64_t nLastWalletUpdate = GetTime(); while (true) { MilliSleep(500); - if (nLastSeen != nWalletDBUpdated) + if (nLastSeen != CWalletDB::GetUpdateCounter()) { - nLastSeen = nWalletDBUpdated; + nLastSeen = CWalletDB::GetUpdateCounter(); nLastWalletUpdate = GetTime(); } - if (nLastFlushed != nWalletDBUpdated && GetTime() - nLastWalletUpdate >= 2) + if (nLastFlushed != CWalletDB::GetUpdateCounter() && GetTime() - nLastWalletUpdate >= 2) { TRY_LOCK(bitdb.cs_db,lockDb); if (lockDb) @@ -811,7 +824,7 @@ void ThreadFlushWalletDB() if (_mi != bitdb.mapFileUseCount.end()) { LogPrint("db", "Flushing %s\n", strFile); - nLastFlushed = nWalletDBUpdated; + nLastFlushed = CWalletDB::GetUpdateCounter(); int64_t nStart = GetTimeMillis(); // Flush wallet file so it's self contained @@ -918,19 +931,29 @@ bool CWalletDB::Recover(CDBEnv& dbenv, const std::string& filename) bool CWalletDB::WriteDestData(const std::string &address, const std::string &key, const std::string &value) { - nWalletDBUpdated++; + nWalletDBUpdateCounter++; return Write(std::make_pair(std::string("destdata"), std::make_pair(address, key)), value); } bool CWalletDB::EraseDestData(const std::string &address, const std::string &key) { - nWalletDBUpdated++; + nWalletDBUpdateCounter++; return Erase(std::make_pair(std::string("destdata"), std::make_pair(address, key))); } bool CWalletDB::WriteHDChain(const CHDChain& chain) { - nWalletDBUpdated++; + nWalletDBUpdateCounter++; return Write(std::string("hdchain"), chain); } + +void CWalletDB::IncrementUpdateCounter() +{ + nWalletDBUpdateCounter++; +} + +unsigned int CWalletDB::GetUpdateCounter() +{ + return nWalletDBUpdateCounter; +} diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h index 6040372d9b..4f1a64de42 100644 --- a/src/wallet/walletdb.h +++ b/src/wallet/walletdb.h @@ -135,7 +135,7 @@ public: bool WriteCScript(const uint160& hash, const CScript& redeemScript); - bool WriteWatchOnly(const CScript &script); + bool WriteWatchOnly(const CScript &script, const CKeyMetadata &keymeta); bool EraseWatchOnly(const CScript &script); bool WriteBestBlock(const CBlockLocator& locator); @@ -176,10 +176,11 @@ public: //! write the hdchain model (external chain child index counter) bool WriteHDChain(const CHDChain& chain); + static void IncrementUpdateCounter(); + static unsigned int GetUpdateCounter(); private: CWalletDB(const CWalletDB&); void operator=(const CWalletDB&); - }; void ThreadFlushWalletDB(); |