aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.cirrus.yml60
-rw-r--r--.gitignore2
-rw-r--r--Makefile.am2
-rw-r--r--build-aux/m4/bitcoin_qt.m465
-rw-r--r--ci/test/00_setup_env_arm.sh2
-rw-r--r--ci/test/00_setup_env_i686_centos.sh2
-rw-r--r--ci/test/00_setup_env_mac.sh2
-rw-r--r--ci/test/00_setup_env_mac_host.sh2
-rw-r--r--ci/test/00_setup_env_native_asan.sh2
-rw-r--r--ci/test/00_setup_env_native_fuzz.sh2
-rw-r--r--ci/test/00_setup_env_native_multiprocess.sh2
-rw-r--r--ci/test/00_setup_env_native_nowallet.sh2
-rw-r--r--ci/test/00_setup_env_native_qt5.sh2
-rw-r--r--ci/test/00_setup_env_native_tsan.sh4
-rw-r--r--ci/test/00_setup_env_s390x.sh2
-rw-r--r--ci/test/00_setup_env_win64.sh2
-rwxr-xr-xci/test/04_install.sh7
-rw-r--r--configure.ac13
-rw-r--r--contrib/bitcoin-qt.pro22
-rw-r--r--contrib/debian/copyright2
-rwxr-xr-xcontrib/gitian-descriptors/assign_DISTNAME2
-rw-r--r--contrib/guix/README.md116
-rwxr-xr-xcontrib/guix/guix-build (renamed from contrib/guix/guix-build.sh)207
-rwxr-xr-xcontrib/guix/guix-clean83
-rw-r--r--contrib/guix/libexec/build.sh82
-rw-r--r--contrib/guix/libexec/prelude.bash66
-rw-r--r--contrib/guix/manifest.scm6
-rwxr-xr-xcontrib/seeds/generate-seeds.py103
-rw-r--r--contrib/seeds/nodes_main.txt26
-rw-r--r--contrib/seeds/nodes_test.txt14
-rw-r--r--contrib/shell/git-utils.bash14
-rw-r--r--contrib/shell/realpath.bash71
-rw-r--r--depends/Makefile6
-rw-r--r--depends/README.md16
-rw-r--r--depends/funcs.mk8
-rw-r--r--depends/packages/native_libdmg-hfsplus.mk2
-rw-r--r--depends/packages/qt.mk3
-rw-r--r--depends/patches/qt/qtbase-moc-ignore-gcc-macro.patch17
-rw-r--r--doc/build-unix.md2
-rw-r--r--doc/developer-notes.md2
-rw-r--r--doc/external-signer.md4
-rw-r--r--doc/multiprocess.md2
-rw-r--r--doc/release-notes.md7
-rw-r--r--doc/translation_process.md2
-rw-r--r--src/Makefile.am11
-rw-r--r--src/bench/verify_script.cpp2
-rw-r--r--src/bitcoind.cpp2
-rw-r--r--src/chainparams.cpp55
-rw-r--r--src/chainparams.h9
-rw-r--r--src/chainparamsbase.cpp2
-rw-r--r--src/chainparamsseeds.h2373
-rw-r--r--src/consensus/params.h10
-rw-r--r--src/dummywallet.cpp1
-rw-r--r--src/external_signer.cpp (renamed from src/wallet/external_signer.cpp)39
-rw-r--r--src/external_signer.h (renamed from src/wallet/external_signer.h)33
-rw-r--r--src/httprpc.cpp5
-rw-r--r--src/i2p.cpp4
-rw-r--r--src/index/base.cpp3
-rw-r--r--src/index/base.h2
-rw-r--r--src/index/blockfilterindex.cpp2
-rw-r--r--src/init.cpp105
-rw-r--r--src/init.h2
-rw-r--r--src/net.cpp17
-rw-r--r--src/net_processing.cpp5
-rw-r--r--src/netbase.h3
-rw-r--r--src/node/README.md3
-rw-r--r--src/node/blockstorage.cpp244
-rw-r--r--src/node/blockstorage.h40
-rw-r--r--src/node/coinstats.cpp3
-rw-r--r--src/node/interfaces.cpp15
-rw-r--r--src/policy/feerate.h1
-rw-r--r--src/qt/bitcoin.cpp17
-rw-r--r--src/qt/bitcoin.h6
-rw-r--r--src/qt/bitcoingui.cpp2
-rw-r--r--src/qt/guiutil.cpp27
-rw-r--r--src/qt/guiutil.h57
-rw-r--r--src/qt/sendcoinsdialog.cpp4
-rw-r--r--src/qt/sendcoinsdialog.h2
-rw-r--r--src/qt/test/rpcnestedtests.cpp23
-rw-r--r--src/qt/test/wallettests.cpp2
-rw-r--r--src/qt/transactionview.cpp4
-rw-r--r--src/qt/transactionview.h2
-rw-r--r--src/qt/walletmodel.cpp5
-rw-r--r--src/qt/walletmodel.h2
-rw-r--r--src/rest.cpp6
-rw-r--r--src/rpc/blockchain.cpp9
-rw-r--r--src/rpc/external_signer.cpp76
-rw-r--r--src/rpc/misc.cpp2
-rw-r--r--src/rpc/net.cpp35
-rw-r--r--src/rpc/rawtransaction.cpp1
-rw-r--r--src/rpc/register.h5
-rw-r--r--src/rpc/request.h13
-rw-r--r--src/rpc/server.cpp5
-rw-r--r--src/rpc/util.cpp109
-rw-r--r--src/rpc/util.h9
-rw-r--r--src/script/bitcoinconsensus.cpp2
-rw-r--r--src/script/interpreter.cpp23
-rw-r--r--src/script/interpreter.h42
-rw-r--r--src/script/sigcache.h2
-rw-r--r--src/script/sign.cpp17
-rw-r--r--src/shutdown.cpp14
-rw-r--r--src/shutdown.h5
-rw-r--r--src/signet.cpp4
-rw-r--r--src/sync.h4
-rw-r--r--src/test/denialofservice_tests.cpp110
-rw-r--r--src/test/fuzz/psbt.cpp23
-rw-r--r--src/test/fuzz/script_assets_test_minimizer.cpp4
-rw-r--r--src/test/fuzz/script_flags.cpp2
-rw-r--r--src/test/fuzz/tx_pool.cpp2
-rw-r--r--src/test/fuzz/util.cpp189
-rw-r--r--src/test/fuzz/util.h176
-rw-r--r--src/test/fuzz/versionbits.cpp63
-rw-r--r--src/test/logging_tests.cpp3
-rw-r--r--src/test/mempool_tests.cpp2
-rw-r--r--src/test/multisig_tests.cpp16
-rw-r--r--src/test/net_tests.cpp3
-rw-r--r--src/test/rpc_tests.cpp58
-rw-r--r--src/test/script_p2sh_tests.cpp2
-rw-r--r--src/test/script_tests.cpp30
-rw-r--r--src/test/sigopcount_tests.cpp2
-rw-r--r--src/test/transaction_tests.cpp4
-rw-r--r--src/test/util/blockfilter.cpp1
-rw-r--r--src/test/util/net.h3
-rw-r--r--src/test/util/setup_common.cpp34
-rw-r--r--src/test/util/setup_common.h8
-rw-r--r--src/test/util_tests.cpp2
-rw-r--r--src/test/validation_chainstatemanager_tests.cpp7
-rw-r--r--src/test/validation_tests.cpp2
-rw-r--r--src/test/versionbits_tests.cpp305
-rw-r--r--src/txorphanage.h6
-rw-r--r--src/txrequest.cpp2
-rw-r--r--src/util/sock.h2
-rw-r--r--src/validation.cpp193
-rw-r--r--src/validation.h13
-rw-r--r--src/versionbits.cpp25
-rw-r--r--src/versionbits.h3
-rw-r--r--src/wallet/external_signer_scriptpubkeyman.cpp9
-rw-r--r--src/wallet/external_signer_scriptpubkeyman.h2
-rw-r--r--src/wallet/init.cpp6
-rw-r--r--src/wallet/interfaces.cpp14
-rw-r--r--src/wallet/rpcdump.cpp19
-rw-r--r--src/wallet/rpcsigner.cpp108
-rw-r--r--src/wallet/rpcsigner.h25
-rw-r--r--src/wallet/rpcwallet.cpp51
-rw-r--r--src/wallet/scriptpubkeyman.cpp4
-rw-r--r--src/wallet/sqlite.cpp90
-rw-r--r--src/wallet/test/wallet_tests.cpp16
-rw-r--r--src/wallet/wallet.cpp21
-rw-r--r--src/wallet/wallet.h7
-rw-r--r--src/zmq/zmqpublishnotifier.cpp3
-rwxr-xr-xtest/functional/rpc_blockchain.py4
-rwxr-xr-xtest/functional/rpc_net.py3
-rwxr-xr-xtest/functional/rpc_signer.py79
-rwxr-xr-xtest/functional/rpc_signrawtransaction.py83
-rw-r--r--test/functional/test_framework/util.py2
-rwxr-xr-xtest/functional/test_runner.py1
-rwxr-xr-xtest/functional/wallet_basic.py2
-rwxr-xr-xtest/functional/wallet_listdescriptors.py39
-rwxr-xr-xtest/functional/wallet_signer.py44
-rwxr-xr-xtest/lint/lint-circular-dependencies.sh4
-rw-r--r--test/sanitizer_suppressions/tsan26
-rw-r--r--test/sanitizer_suppressions/ubsan6
162 files changed, 3918 insertions, 2632 deletions
diff --git a/.cirrus.yml b/.cirrus.yml
index d7d5ab6c5c..6dc029ee51 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -3,10 +3,19 @@
env:
PACKAGE_MANAGER_INSTALL: "apt-get update && apt-get install -y"
MAKEJOBS: "-j4"
- DANGER_RUN_CI_ON_HOST: "1" # Containers will be discarded after the run, so there is no risk that the ci scripts modify the system
TEST_RUNNER_PORT_MIN: "14000" # Must be larger than 12321, which is used for the http cache. See https://cirrus-ci.org/guide/writing-tasks/#http-cache
CCACHE_SIZE: "200M"
CCACHE_DIR: "/tmp/ccache_dir"
+ CCACHE_NOHASHDIR: "1" # Debug info might contain a stale path if the build dir changes, but this is fine
+
+cirrus_ephemeral_worker_template_env: &CIRRUS_EPHEMERAL_WORKER_TEMPLATE_ENV
+ DANGER_RUN_CI_ON_HOST: "1" # Containers will be discarded after the run, so there is no risk that the ci scripts modify the system
+
+persistent_worker_template_env: &PERSISTENT_WORKER_TEMPLATE_ENV
+ RESTART_CI_DOCKER_BEFORE_RUN: "1"
+
+persistent_worker_template: &PERSISTENT_WORKER_TEMPLATE
+ persistent_worker: {} # https://cirrus-ci.org/guide/persistent-workers/
# https://cirrus-ci.org/guide/tips-and-tricks/#sharing-configuration-between-tasks
base_template: &BASE_TEMPLATE
@@ -28,16 +37,17 @@ global_task_template: &GLOBAL_TASK_TEMPLATE
# Each project has 16 CPU in total, assign 2 to each container, so that 8 tasks run in parallel
cpu: 2
memory: 8G # Set to 8GB to avoid OOM. https://cirrus-ci.org/guide/linux/#linux-containers
- kvm: true # Use kvm to avoid spurious CI failures in the default virtualization cluster, see https://github.com/bitcoin/bitcoin/issues/20093
ccache_cache:
folder: "/tmp/ccache_dir"
depends_built_cache:
- folder: "/tmp/cirrus-ci-build/depends/built"
- depends_sdk_cache:
- folder: "/tmp/cirrus-ci-build/depends/sdk-sources"
+ folder: "depends/built"
ci_script:
- ./ci/test_run_all.sh
+depends_sdk_cache_template: &DEPENDS_SDK_CACHE_TEMPLATE
+ depends_sdk_cache:
+ folder: "depends/sdk-sources"
+
compute_credits_template: &CREDITS_TEMPLATE
# https://cirrus-ci.org/pricing/#compute-credits
# Only use credits for pull requests to the main repo
@@ -70,6 +80,8 @@ task:
<< : *CREDITS_TEMPLATE
lint_script:
- ./ci/lint_run_all.sh
+ env:
+ << : *CIRRUS_EPHEMERAL_WORKER_TEMPLATE_ENV
task:
name: 'ARM [unit tests, no functional tests] [buster]'
@@ -77,6 +89,7 @@ task:
container:
image: debian:buster
env:
+ << : *CIRRUS_EPHEMERAL_WORKER_TEMPLATE_ENV
FILE_ENV: "./ci/test/00_setup_env_arm.sh"
task:
@@ -85,6 +98,7 @@ task:
container:
image: ubuntu:focal
env:
+ << : *CIRRUS_EPHEMERAL_WORKER_TEMPLATE_ENV
FILE_ENV: "./ci/test/00_setup_env_win64.sh"
task:
@@ -93,29 +107,29 @@ task:
container:
image: centos:8
env:
+ << : *CIRRUS_EPHEMERAL_WORKER_TEMPLATE_ENV
PACKAGE_MANAGER_INSTALL: "yum install -y"
FILE_ENV: "./ci/test/00_setup_env_i686_centos.sh"
task:
name: '[previous releases, uses qt5 dev package and some depends packages] [unsigned char] [bionic]'
- # For faster CI feedback, immediately schedule a task that compiles most modules
- << : *CREDITS_TEMPLATE
+ previous_releases_cache:
+ folder: "releases"
<< : *GLOBAL_TASK_TEMPLATE
- depends_releases_cache:
- folder: "/tmp/cirrus-ci-build/releases"
- container:
- image: ubuntu:bionic
+ << : *PERSISTENT_WORKER_TEMPLATE
env:
+ << : *PERSISTENT_WORKER_TEMPLATE_ENV
FILE_ENV: "./ci/test/00_setup_env_native_qt5.sh"
task:
- name: '[depends, sanitizers: thread (TSan), no gui] [focal]'
+ name: '[depends, sanitizers: thread (TSan), no gui] [hirsute]'
<< : *GLOBAL_TASK_TEMPLATE
container:
- image: ubuntu:focal
- cpu: 4 # Double CPU and increase Memory to avoid timeout
+ image: ubuntu:hirsute
+ cpu: 6 # Increase CPU and Memory to avoid timeout
memory: 24G
env:
+ << : *CIRRUS_EPHEMERAL_WORKER_TEMPLATE_ENV
MAKEJOBS: "-j8"
FILE_ENV: "./ci/test/00_setup_env_native_tsan.sh"
@@ -125,6 +139,7 @@ task:
container:
image: ubuntu:focal
env:
+ << : *CIRRUS_EPHEMERAL_WORKER_TEMPLATE_ENV
FILE_ENV: "./ci/test/00_setup_env_native_msan.sh"
task:
@@ -133,6 +148,7 @@ task:
container:
image: ubuntu:focal
env:
+ << : *CIRRUS_EPHEMERAL_WORKER_TEMPLATE_ENV
FILE_ENV: "./ci/test/00_setup_env_native_asan.sh"
task:
@@ -141,6 +157,7 @@ task:
container:
image: ubuntu:focal
env:
+ << : *CIRRUS_EPHEMERAL_WORKER_TEMPLATE_ENV
FILE_ENV: "./ci/test/00_setup_env_native_fuzz.sh"
task:
@@ -149,6 +166,7 @@ task:
container:
image: ubuntu:focal
env:
+ << : *CIRRUS_EPHEMERAL_WORKER_TEMPLATE_ENV
FILE_ENV: "./ci/test/00_setup_env_native_multiprocess.sh"
task:
@@ -157,36 +175,42 @@ task:
container:
image: ubuntu:bionic
env:
+ << : *CIRRUS_EPHEMERAL_WORKER_TEMPLATE_ENV
FILE_ENV: "./ci/test/00_setup_env_native_nowallet.sh"
task:
name: 'macOS 10.14 [gui, no tests] [focal]'
+ << : *DEPENDS_SDK_CACHE_TEMPLATE
<< : *GLOBAL_TASK_TEMPLATE
container:
image: ubuntu:focal
env:
+ << : *CIRRUS_EPHEMERAL_WORKER_TEMPLATE_ENV
FILE_ENV: "./ci/test/00_setup_env_mac.sh"
task:
name: 'macOS 11 native [gui] [no depends]'
- macos_brew_addon_script:
- - brew install boost libevent berkeley-db4 qt miniupnpc libnatpmp ccache zeromq qrencode sqlite libtool automake pkg-config gnu-getopt
+ brew_install_script:
+ - brew update
+ - brew install boost libevent berkeley-db4 qt@5 miniupnpc libnatpmp ccache zeromq qrencode sqlite libtool automake pkg-config gnu-getopt
<< : *GLOBAL_TASK_TEMPLATE
osx_instance:
# Use latest image, but hardcode version to avoid silent upgrades (and breaks)
image: big-sur-xcode-12.4 # https://cirrus-ci.org/guide/macOS
env:
- DANGER_RUN_CI_ON_HOST: "true"
+ << : *CIRRUS_EPHEMERAL_WORKER_TEMPLATE_ENV
CI_USE_APT_INSTALL: "no"
PACKAGE_MANAGER_INSTALL: "echo" # Nothing to do
FILE_ENV: "./ci/test/00_setup_env_mac_host.sh"
task:
name: 'ARM64 Android APK [focal]'
+ << : *DEPENDS_SDK_CACHE_TEMPLATE
depends_sources_cache:
- folder: "/tmp/cirrus-ci-build/depends/sources"
+ folder: "depends/sources"
<< : *GLOBAL_TASK_TEMPLATE
container:
image: ubuntu:focal
env:
+ << : *CIRRUS_EPHEMERAL_WORKER_TEMPLATE_ENV
FILE_ENV: "./ci/test/00_setup_env_android.sh"
diff --git a/.gitignore b/.gitignore
index c0b5661464..5d817c8bbd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -149,3 +149,5 @@ db4/
osx_volname
dist/
*.background.tiff
+
+/guix-build-*
diff --git a/Makefile.am b/Makefile.am
index be62c3e6a9..5e453b9ae1 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -4,7 +4,7 @@
# Pattern rule to print variables, e.g. make print-top_srcdir
print-%:
- @echo '$*' = '$($*)'
+ @echo '$*'='$($*)'
ACLOCAL_AMFLAGS = -I build-aux/m4
SUBDIRS = src
diff --git a/build-aux/m4/bitcoin_qt.m4 b/build-aux/m4/bitcoin_qt.m4
index cce06e2fff..57b4c10d77 100644
--- a/build-aux/m4/bitcoin_qt.m4
+++ b/build-aux/m4/bitcoin_qt.m4
@@ -108,11 +108,10 @@ AC_DEFUN([BITCOIN_QT_CONFIGURE],[
BITCOIN_QT_CHECK([_BITCOIN_QT_FIND_LIBS])
dnl This is ugly and complicated. Yuck. Works as follows:
- dnl For Qt5, we can check a header to find out whether Qt is build
- dnl statically. When Qt is built statically, some plugins must be linked into
- dnl the final binary as well.
- dnl _BITCOIN_QT_CHECK_STATIC_PLUGIN does a quick link-check and appends the
- dnl results to QT_LIBS.
+ dnl We check a header to find out whether Qt is built statically.
+ dnl When Qt is built statically, some plugins must be linked into
+ dnl the final binary as well. _BITCOIN_QT_CHECK_STATIC_PLUGIN does
+ dnl a quick link-check and appends the results to QT_LIBS.
BITCOIN_QT_CHECK([
TEMP_CPPFLAGS=$CPPFLAGS
TEMP_CXXFLAGS=$CXXFLAGS
@@ -162,7 +161,7 @@ AC_DEFUN([BITCOIN_QT_CONFIGURE],[
_BITCOIN_QT_CHECK_STATIC_PLUGIN([QMacStylePlugin], [-lqmacstyle])
AC_DEFINE(QT_QPA_PLATFORM_COCOA, 1, [Define this symbol if the qt platform is cocoa])
elif test "x$TARGET_OS" = xandroid; then
- QT_LIBS="-Wl,--export-dynamic,--undefined=JNI_OnLoad -lqtforandroid -ljnigraphics -landroid -lqtfreetype -lQt5EglSupport $QT_LIBS"
+ QT_LIBS="-Wl,--export-dynamic,--undefined=JNI_OnLoad -lqtforandroid -ljnigraphics -landroid -lqtfreetype $QT_LIBS"
AC_DEFINE(QT_QPA_PLATFORM_ANDROID, 1, [Define this symbol if the qt platform is android])
fi
fi
@@ -171,7 +170,7 @@ AC_DEFUN([BITCOIN_QT_CONFIGURE],[
])
if test "x$qt_bin_path" = x; then
- qt_bin_path="`$PKG_CONFIG --variable=host_bins Qt5Core 2>/dev/null`"
+ qt_bin_path="`$PKG_CONFIG --variable=host_bins ${qt_lib_prefix}Core 2>/dev/null`"
fi
if test "x$use_hardening" != xno; then
@@ -282,12 +281,13 @@ AC_DEFUN([BITCOIN_QT_CONFIGURE],[
AC_SUBST(MOC_DEFS)
])
-dnl All macros below are internal and should _not_ be used from the main
-dnl configure.ac.
-dnl ----
+dnl All macros below are internal and should _not_ be used from configure.ac.
-dnl Internal. Check if the linked version of Qt was built as static libs.
-dnl Requires: Qt5.
+dnl Internal. Check if the linked version of Qt was built statically.
+dnl
+dnl _BITCOIN_QT_IS_STATIC
+dnl ---------------------
+dnl
dnl Requires: INCLUDES and LIBS must be populated as necessary.
dnl Output: bitcoin_cv_static_qt=yes|no
AC_DEFUN([_BITCOIN_QT_IS_STATIC],[
@@ -335,47 +335,54 @@ dnl
dnl _BITCOIN_QT_CHECK_STATIC_LIBS
dnl -----------------------------
dnl
-dnl Inputs: no inputs.
dnl Outputs: QT_LIBS is prepended.
AC_DEFUN([_BITCOIN_QT_CHECK_STATIC_LIBS], [
- PKG_CHECK_MODULES([QTFONTDATABASE], [Qt5FontDatabaseSupport${qt_lib_suffix}], [QT_LIBS="-lQt5FontDatabaseSupport${qt_lib_suffix} $QT_LIBS"])
- PKG_CHECK_MODULES([QTEVENTDISPATCHER], [Qt5EventDispatcherSupport${qt_lib_suffix}], [QT_LIBS="-lQt5EventDispatcherSupport${qt_lib_suffix} $QT_LIBS"])
- PKG_CHECK_MODULES([QTTHEME], [Qt5ThemeSupport${qt_lib_suffix}], [QT_LIBS="-lQt5ThemeSupport${qt_lib_suffix} $QT_LIBS"])
- PKG_CHECK_MODULES([QTDEVICEDISCOVERY], [Qt5DeviceDiscoverySupport${qt_lib_suffix}], [QT_LIBS="-lQt5DeviceDiscoverySupport${qt_lib_suffix} $QT_LIBS"])
- PKG_CHECK_MODULES([QTACCESSIBILITY], [Qt5AccessibilitySupport${qt_lib_suffix}], [QT_LIBS="-lQt5AccessibilitySupport${qt_lib_suffix} $QT_LIBS"])
- PKG_CHECK_MODULES([QTFB], [Qt5FbSupport${qt_lib_suffix}], [QT_LIBS="-lQt5FbSupport${qt_lib_suffix} $QT_LIBS"])
+ PKG_CHECK_MODULES([QT_ACCESSIBILITY], [${qt_lib_prefix}AccessibilitySupport${qt_lib_suffix}], [QT_LIBS="$QT_ACCESSIBILITY_LIBS $QT_LIBS"])
+ PKG_CHECK_MODULES([QT_DEVICEDISCOVERY], [${qt_lib_prefix}DeviceDiscoverySupport${qt_lib_suffix}], [QT_LIBS="$QT_DEVICEDISCOVERY_LIBS $QT_LIBS"])
+ PKG_CHECK_MODULES([QT_EDID], [${qt_lib_prefix}EdidSupport${qt_lib_suffix}], [QT_LIBS="$QT_EDID_LIBS $QT_LIBS"])
+ PKG_CHECK_MODULES([QT_EVENTDISPATCHER], [${qt_lib_prefix}EventDispatcherSupport${qt_lib_suffix}], [QT_LIBS="$QT_EVENTDISPATCHER_LIBS $QT_LIBS"])
+ PKG_CHECK_MODULES([QT_FB], [${qt_lib_prefix}FbSupport${qt_lib_suffix}], [QT_LIBS="$QT_FB_LIBS $QT_LIBS"])
+ PKG_CHECK_MODULES([QT_FONTDATABASE], [${qt_lib_prefix}FontDatabaseSupport${qt_lib_suffix}], [QT_LIBS="$QT_FONTDATABASE_LIBS $QT_LIBS"])
+ PKG_CHECK_MODULES([QT_THEME], [${qt_lib_prefix}ThemeSupport${qt_lib_suffix}], [QT_LIBS="$QT_THEME_LIBS $QT_LIBS"])
if test "x$TARGET_OS" = xlinux; then
- PKG_CHECK_MODULES([QTXCBQPA], [Qt5XcbQpa], [QT_LIBS="$QTXCBQPA_LIBS $QT_LIBS"])
+ PKG_CHECK_MODULES([QT_INPUT], [${qt_lib_prefix}XcbQpa], [QT_LIBS="$QT_INPUT_LIBS $QT_LIBS"])
+ PKG_CHECK_MODULES([QT_SERVICE], [${qt_lib_prefix}ServiceSupport], [QT_LIBS="$QT_SERVICE_LIBS $QT_LIBS"])
+ PKG_CHECK_MODULES([QT_XCBQPA], [${qt_lib_prefix}XcbQpa], [QT_LIBS="$QT_XCBQPA_LIBS $QT_LIBS"])
elif test "x$TARGET_OS" = xdarwin; then
- PKG_CHECK_MODULES([QTCLIPBOARD], [Qt5ClipboardSupport${qt_lib_suffix}], [QT_LIBS="-lQt5ClipboardSupport${qt_lib_suffix} $QT_LIBS"])
- PKG_CHECK_MODULES([QTGRAPHICS], [Qt5GraphicsSupport${qt_lib_suffix}], [QT_LIBS="-lQt5GraphicsSupport${qt_lib_suffix} $QT_LIBS"])
+ PKG_CHECK_MODULES([QT_CLIPBOARD], [${qt_lib_prefix}ClipboardSupport${qt_lib_suffix}], [QT_LIBS="$QT_CLIPBOARD_LIBS $QT_LIBS"])
+ PKG_CHECK_MODULES([QT_GRAPHICS], [${qt_lib_prefix}GraphicsSupport${qt_lib_suffix}], [QT_LIBS="$QT_GRAPHICS_LIBS $QT_LIBS"])
+ PKG_CHECK_MODULES([QT_SERVICE], [${qt_lib_prefix}ServiceSupport${qt_lib_suffix}], [QT_LIBS="$QT_SERVICE_LIBS $QT_LIBS"])
elif test "x$TARGET_OS" = xwindows; then
- PKG_CHECK_MODULES([QTWINDOWSUIAUTOMATION], [Qt5WindowsUIAutomationSupport${qt_lib_suffix}], [QT_LIBS="-lQt5WindowsUIAutomationSupport${qt_lib_suffix} $QT_LIBS"])
+ PKG_CHECK_MODULES([QT_WINDOWSUIAUTOMATION], [${qt_lib_prefix}WindowsUIAutomationSupport${qt_lib_suffix}], [QT_LIBS="$QT_WINDOWSUIAUTOMATION_LIBS $QT_LIBS"])
+ elif test "x$TARGET_OS" = xandroid; then
+ PKG_CHECK_MODULES([QT_EGL], [${qt_lib_prefix}EglSupport], [QT_LIBS="$QT_EGL_LIBS $QT_LIBS"])
fi
])
dnl Internal. Find Qt libraries using pkg-config.
+dnl
+dnl _BITCOIN_QT_FIND_LIBS
+dnl ---------------------
+dnl
dnl Outputs: All necessary QT_* variables are set.
dnl Outputs: have_qt_test and have_qt_dbus are set (if applicable) to yes|no.
AC_DEFUN([_BITCOIN_QT_FIND_LIBS],[
BITCOIN_QT_CHECK([
- PKG_CHECK_MODULES([QT_CORE], [${qt_lib_prefix}Core${qt_lib_suffix} $qt_version], [],
+ PKG_CHECK_MODULES([QT_CORE], [${qt_lib_prefix}Core${qt_lib_suffix} $qt_version], [QT_INCLUDES="$QT_CORE_CFLAGS $QT_INCLUDES" QT_LIBS="$QT_CORE_LIBS $QT_LIBS"],
[BITCOIN_QT_FAIL([${qt_lib_prefix}Core${qt_lib_suffix} $qt_version not found])])
])
BITCOIN_QT_CHECK([
- PKG_CHECK_MODULES([QT_GUI], [${qt_lib_prefix}Gui${qt_lib_suffix} $qt_version], [],
+ PKG_CHECK_MODULES([QT_GUI], [${qt_lib_prefix}Gui${qt_lib_suffix} $qt_version], [QT_INCLUDES="$QT_GUI_CFLAGS $QT_INCLUDES" QT_LIBS="$QT_GUI_LIBS $QT_LIBS"],
[BITCOIN_QT_FAIL([${qt_lib_prefix}Gui${qt_lib_suffix} $qt_version not found])])
])
BITCOIN_QT_CHECK([
- PKG_CHECK_MODULES([QT_WIDGETS], [${qt_lib_prefix}Widgets${qt_lib_suffix} $qt_version], [],
+ PKG_CHECK_MODULES([QT_WIDGETS], [${qt_lib_prefix}Widgets${qt_lib_suffix} $qt_version], [QT_INCLUDES="$QT_WIDGETS_CFLAGS $QT_INCLUDES" QT_LIBS="$QT_WIDGETS_LIBS $QT_LIBS"],
[BITCOIN_QT_FAIL([${qt_lib_prefix}Widgets${qt_lib_suffix} $qt_version not found])])
])
BITCOIN_QT_CHECK([
- PKG_CHECK_MODULES([QT_NETWORK], [${qt_lib_prefix}Network${qt_lib_suffix} $qt_version], [],
+ PKG_CHECK_MODULES([QT_NETWORK], [${qt_lib_prefix}Network${qt_lib_suffix} $qt_version], [QT_INCLUDES="$QT_NETWORK_CFLAGS $QT_INCLUDES" QT_LIBS="$QT_NETWORK_LIBS $QT_LIBS"],
[BITCOIN_QT_FAIL([${qt_lib_prefix}Network${qt_lib_suffix} $qt_version not found])])
])
- QT_INCLUDES="$QT_CORE_CFLAGS $QT_GUI_CFLAGS $QT_WIDGETS_CFLAGS $QT_NETWORK_CFLAGS"
- QT_LIBS="$QT_CORE_LIBS $QT_GUI_LIBS $QT_WIDGETS_LIBS $QT_NETWORK_LIBS"
BITCOIN_QT_CHECK([
PKG_CHECK_MODULES([QT_TEST], [${qt_lib_prefix}Test${qt_lib_suffix} $qt_version], [QT_TEST_INCLUDES="$QT_TEST_CFLAGS"; have_qt_test=yes], [have_qt_test=no])
diff --git a/ci/test/00_setup_env_arm.sh b/ci/test/00_setup_env_arm.sh
index 42783197a9..07f099b85c 100644
--- a/ci/test/00_setup_env_arm.sh
+++ b/ci/test/00_setup_env_arm.sh
@@ -25,4 +25,4 @@ export RUN_FUNCTIONAL_TESTS=false
export GOAL="install"
# -Wno-psabi is to disable ABI warnings: "note: parameter passing for argument of type ... changed in GCC 7.1"
# This could be removed once the ABI change warning does not show up by default
-export BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports CXXFLAGS=-Wno-psabi --with-boost-process"
+export BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports CXXFLAGS=-Wno-psabi --enable-external-signer"
diff --git a/ci/test/00_setup_env_i686_centos.sh b/ci/test/00_setup_env_i686_centos.sh
index 07e7c2dc27..05c724fc0b 100644
--- a/ci/test/00_setup_env_i686_centos.sh
+++ b/ci/test/00_setup_env_i686_centos.sh
@@ -11,6 +11,6 @@ export CONTAINER_NAME=ci_i686_centos_8
export DOCKER_NAME_TAG=centos:8
export DOCKER_PACKAGES="gcc-c++ glibc-devel.x86_64 libstdc++-devel.x86_64 glibc-devel.i686 libstdc++-devel.i686 ccache libtool make git python3 python3-zmq which patch lbzip2 dash rsync coreutils bison"
export GOAL="install"
-export BITCOIN_CONFIG="--enable-zmq --with-gui=qt5 --enable-reduce-exports --with-boost-process"
+export BITCOIN_CONFIG="--enable-zmq --with-gui=qt5 --enable-reduce-exports --enable-external-signer"
export CONFIG_SHELL="/bin/dash"
export TEST_RUNNER_ENV="LC_ALL=en_US.UTF-8"
diff --git a/ci/test/00_setup_env_mac.sh b/ci/test/00_setup_env_mac.sh
index 6ce3812447..f051318a58 100644
--- a/ci/test/00_setup_env_mac.sh
+++ b/ci/test/00_setup_env_mac.sh
@@ -15,4 +15,4 @@ export XCODE_BUILD_ID=11C505
export RUN_UNIT_TESTS=false
export RUN_FUNCTIONAL_TESTS=false
export GOAL="deploy"
-export BITCOIN_CONFIG="--with-gui --enable-reduce-exports --with-boost-process"
+export BITCOIN_CONFIG="--with-gui --enable-reduce-exports --enable-external-signer"
diff --git a/ci/test/00_setup_env_mac_host.sh b/ci/test/00_setup_env_mac_host.sh
index 274a0d1b7c..e54e78add4 100644
--- a/ci/test/00_setup_env_mac_host.sh
+++ b/ci/test/00_setup_env_mac_host.sh
@@ -9,7 +9,7 @@ export LC_ALL=C.UTF-8
export HOST=x86_64-apple-darwin18
export PIP_PACKAGES="zmq"
export GOAL="install"
-export BITCOIN_CONFIG="--with-gui --enable-reduce-exports --with-boost-process"
+export BITCOIN_CONFIG="--with-gui --enable-reduce-exports --enable-external-signer"
export CI_OS_NAME="macos"
export NO_DEPENDS=1
export OSX_SDK=""
diff --git a/ci/test/00_setup_env_native_asan.sh b/ci/test/00_setup_env_native_asan.sh
index e47119e6fa..6039c51018 100644
--- a/ci/test/00_setup_env_native_asan.sh
+++ b/ci/test/00_setup_env_native_asan.sh
@@ -11,4 +11,4 @@ export PACKAGES="clang llvm python3-zmq qtbase5-dev qttools5-dev-tools libevent-
export DOCKER_NAME_TAG=ubuntu:20.04
export NO_DEPENDS=1
export GOAL="install"
-export BITCOIN_CONFIG="--enable-zmq --with-incompatible-bdb --with-gui=qt5 CPPFLAGS='-DARENA_DEBUG -DDEBUG_LOCKORDER' --with-sanitizers=address,integer,undefined CC=clang CXX=clang++ --with-boost-process"
+export BITCOIN_CONFIG="--enable-zmq --with-incompatible-bdb --with-gui=qt5 CPPFLAGS='-DARENA_DEBUG -DDEBUG_LOCKORDER' --with-sanitizers=address,integer,undefined CC=clang CXX=clang++ --enable-external-signer"
diff --git a/ci/test/00_setup_env_native_fuzz.sh b/ci/test/00_setup_env_native_fuzz.sh
index ebb5a1cabe..bedd0cf9aa 100644
--- a/ci/test/00_setup_env_native_fuzz.sh
+++ b/ci/test/00_setup_env_native_fuzz.sh
@@ -14,5 +14,5 @@ export RUN_UNIT_TESTS=false
export RUN_FUNCTIONAL_TESTS=false
export RUN_FUZZ_TESTS=true
export GOAL="install"
-export BITCOIN_CONFIG="--enable-fuzz --with-sanitizers=fuzzer,address,undefined,integer CC=clang CXX=clang++ --with-boost-process"
+export BITCOIN_CONFIG="--enable-fuzz --with-sanitizers=fuzzer,address,undefined,integer CC=clang CXX=clang++ --enable-external-signer"
export CCACHE_SIZE=200M
diff --git a/ci/test/00_setup_env_native_multiprocess.sh b/ci/test/00_setup_env_native_multiprocess.sh
index c5692d786a..26a3996ce2 100644
--- a/ci/test/00_setup_env_native_multiprocess.sh
+++ b/ci/test/00_setup_env_native_multiprocess.sh
@@ -11,6 +11,6 @@ export DOCKER_NAME_TAG=ubuntu:20.04
export PACKAGES="cmake python3"
export DEP_OPTS="MULTIPROCESS=1"
export GOAL="install"
-export BITCOIN_CONFIG="--with-boost-process"
+export BITCOIN_CONFIG="--enable-external-signer"
export TEST_RUNNER_ENV="BITCOIND=bitcoin-node"
export RUN_SECURITY_TESTS="true"
diff --git a/ci/test/00_setup_env_native_nowallet.sh b/ci/test/00_setup_env_native_nowallet.sh
index 7ff044c020..a496b5af6e 100644
--- a/ci/test/00_setup_env_native_nowallet.sh
+++ b/ci/test/00_setup_env_native_nowallet.sh
@@ -11,4 +11,4 @@ export DOCKER_NAME_TAG=ubuntu:18.04 # Use bionic to have one config run the tes
export PACKAGES="python3-zmq clang-5.0 llvm-5.0" # Use clang-5 to test C++17 compatibility, see doc/dependencies.md
export DEP_OPTS="NO_WALLET=1"
export GOAL="install"
-export BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports CC=clang-5.0 CXX=clang++-5.0 --with-boost-process"
+export BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports CC=clang-5.0 CXX=clang++-5.0 --enable-external-signer"
diff --git a/ci/test/00_setup_env_native_qt5.sh b/ci/test/00_setup_env_native_qt5.sh
index 4c42605e9a..61948ab221 100644
--- a/ci/test/00_setup_env_native_qt5.sh
+++ b/ci/test/00_setup_env_native_qt5.sh
@@ -16,4 +16,4 @@ export RUN_UNIT_TESTS="false"
export GOAL="install"
export PREVIOUS_RELEASES_TO_DOWNLOAD="v0.15.2 v0.16.3 v0.17.2 v0.18.1 v0.19.1"
export BITCOIN_CONFIG="--enable-zmq --with-libs=no --with-gui=qt5 --enable-glibc-back-compat --enable-reduce-exports
---enable-debug --disable-fuzz-binary CFLAGS=\"-g0 -O2 -funsigned-char\" CXXFLAGS=\"-g0 -O2 -funsigned-char\" --with-boost-process"
+--enable-debug --disable-fuzz-binary CFLAGS=\"-g0 -O2 -funsigned-char\" CXXFLAGS=\"-g0 -O2 -funsigned-char\" --enable-external-signer"
diff --git a/ci/test/00_setup_env_native_tsan.sh b/ci/test/00_setup_env_native_tsan.sh
index 182e42ee7d..33f63fa9ba 100644
--- a/ci/test/00_setup_env_native_tsan.sh
+++ b/ci/test/00_setup_env_native_tsan.sh
@@ -7,8 +7,8 @@
export LC_ALL=C.UTF-8
export CONTAINER_NAME=ci_native_tsan
-export DOCKER_NAME_TAG=ubuntu:20.04
+export DOCKER_NAME_TAG=ubuntu:hirsute
export PACKAGES="clang llvm libc++abi-dev libc++-dev python3-zmq"
export DEP_OPTS="CC=clang CXX='clang++ -stdlib=libc++'"
export GOAL="install"
-export BITCOIN_CONFIG="--enable-zmq --with-gui=no CPPFLAGS='-DARENA_DEBUG -DDEBUG_LOCKORDER' CXXFLAGS='-g' --with-sanitizers=thread CC=clang CXX='clang++ -stdlib=libc++' --with-boost-process"
+export BITCOIN_CONFIG="--enable-zmq --with-gui=no CPPFLAGS='-DARENA_DEBUG -DDEBUG_LOCKORDER' CXXFLAGS='-g' --with-sanitizers=thread CC=clang CXX='clang++ -stdlib=libc++' --enable-external-signer"
diff --git a/ci/test/00_setup_env_s390x.sh b/ci/test/00_setup_env_s390x.sh
index accbd07e22..88b431f3c7 100644
--- a/ci/test/00_setup_env_s390x.sh
+++ b/ci/test/00_setup_env_s390x.sh
@@ -23,4 +23,4 @@ export RUN_UNIT_TESTS=true
export TEST_RUNNER_ENV="LC_ALL=C"
export RUN_FUNCTIONAL_TESTS=true
export GOAL="install"
-export BITCOIN_CONFIG="--enable-reduce-exports --with-incompatible-bdb --with-boost-process"
+export BITCOIN_CONFIG="--enable-reduce-exports --with-incompatible-bdb --enable-external-signer"
diff --git a/ci/test/00_setup_env_win64.sh b/ci/test/00_setup_env_win64.sh
index 1e68d2a61a..4d5bde13fd 100644
--- a/ci/test/00_setup_env_win64.sh
+++ b/ci/test/00_setup_env_win64.sh
@@ -13,7 +13,7 @@ export DPKG_ADD_ARCH="i386"
export PACKAGES="python3 nsis g++-mingw-w64-x86-64 wine-binfmt wine64 wine32 file"
export RUN_FUNCTIONAL_TESTS=false
export GOAL="deploy"
-export BITCOIN_CONFIG="--enable-reduce-exports --disable-gui-tests --without-boost-process"
+export BITCOIN_CONFIG="--enable-reduce-exports --disable-gui-tests --disable-external-signer"
# Compiler for MinGW-w64 causes false -Wreturn-type warning.
# See https://sourceforge.net/p/mingw-w64/bugs/306/
diff --git a/ci/test/04_install.sh b/ci/test/04_install.sh
index f0ed314d19..608acfc2cf 100755
--- a/ci/test/04_install.sh
+++ b/ci/test/04_install.sh
@@ -33,7 +33,12 @@ if [ -z "$DANGER_RUN_CI_ON_HOST" ]; then
echo "Creating $DOCKER_NAME_TAG container to run in"
${CI_RETRY_EXE} docker pull "$DOCKER_NAME_TAG"
- DOCKER_ID=$(docker run $DOCKER_ADMIN -idt \
+ if [ -n "${RESTART_CI_DOCKER_BEFORE_RUN}" ] ; then
+ echo "Restart docker before run to stop and clear all containers started with --rm"
+ systemctl restart docker
+ fi
+
+ DOCKER_ID=$(docker run $DOCKER_ADMIN --rm --interactive --detach --tty \
--mount type=bind,src=$BASE_ROOT_DIR,dst=/ro_base,readonly \
--mount type=bind,src=$CCACHE_DIR,dst=$CCACHE_DIR \
--mount type=bind,src=$DEPENDS_DIR,dst=$DEPENDS_DIR \
diff --git a/configure.ac b/configure.ac
index c3eabad131..cce97e9259 100644
--- a/configure.ac
+++ b/configure.ac
@@ -439,6 +439,10 @@ if test "x$enable_werror" = "xyes"; then
[AC_LANG_SOURCE([[struct A { virtual void f(); }; struct B : A { void f() final; };]])])
AX_CHECK_COMPILE_FLAG([-Werror=unreachable-code-loop-increment],[ERROR_CXXFLAGS="$ERROR_CXXFLAGS -Werror=unreachable-code-loop-increment"],,[[$CXXFLAG_WERROR]])
AX_CHECK_COMPILE_FLAG([-Werror=mismatched-tags], [ERROR_CXXFLAGS="$ERROR_CXXFLAGS -Werror=mismatched-tags"], [], [$CXXFLAG_WERROR])
+
+ if test x$suppress_external_warnings != xno ; then
+ AX_CHECK_COMPILE_FLAG([-Werror=documentation],[ERROR_CXXFLAGS="$ERROR_CXXFLAGS -Werror=documentation"],,[[$CXXFLAG_WERROR]])
+ fi
fi
if test "x$CXXFLAGS_overridden" = "xno"; then
@@ -466,13 +470,16 @@ if test "x$CXXFLAGS_overridden" = "xno"; then
[AC_LANG_SOURCE([[struct A { virtual void f(); }; struct B : A { void f() final; };]])])
AX_CHECK_COMPILE_FLAG([-Wunreachable-code-loop-increment],[WARN_CXXFLAGS="$WARN_CXXFLAGS -Wunreachable-code-loop-increment"],,[[$CXXFLAG_WERROR]])
+ if test x$suppress_external_warnings != xno ; then
+ AX_CHECK_COMPILE_FLAG([-Wdocumentation],[WARN_CXXFLAGS="$WARN_CXXFLAGS -Wdocumentation"],,[[$CXXFLAG_WERROR]])
+ fi
+
dnl Some compilers (gcc) ignore unknown -Wno-* options, but warn about all
dnl unknown options if any other warning is produced. Test the -Wfoo case, and
dnl set the -Wno-foo case if it works.
AX_CHECK_COMPILE_FLAG([-Wunused-parameter],[NOWARN_CXXFLAGS="$NOWARN_CXXFLAGS -Wno-unused-parameter"],,[[$CXXFLAG_WERROR]])
AX_CHECK_COMPILE_FLAG([-Wself-assign],[NOWARN_CXXFLAGS="$NOWARN_CXXFLAGS -Wno-self-assign"],,[[$CXXFLAG_WERROR]])
AX_CHECK_COMPILE_FLAG([-Wunused-local-typedef],[NOWARN_CXXFLAGS="$NOWARN_CXXFLAGS -Wno-unused-local-typedef"],,[[$CXXFLAG_WERROR]])
- AX_CHECK_COMPILE_FLAG([-Wdeprecated-register],[NOWARN_CXXFLAGS="$NOWARN_CXXFLAGS -Wno-deprecated-register"],,[[$CXXFLAG_WERROR]])
AX_CHECK_COMPILE_FLAG([-Wimplicit-fallthrough],[NOWARN_CXXFLAGS="$NOWARN_CXXFLAGS -Wno-implicit-fallthrough"],,[[$CXXFLAG_WERROR]])
AX_CHECK_COMPILE_FLAG([-Wdeprecated-copy],[NOWARN_CXXFLAGS="$NOWARN_CXXFLAGS -Wno-deprecated-copy"],,[[$CXXFLAG_WERROR]])
fi
@@ -1486,6 +1493,10 @@ if test x$build_bitcoin_cli$build_bitcoind$bitcoin_enable_qt$use_tests$use_bench
if test x$TARGET_OS != xwindows; then
PKG_CHECK_MODULES([EVENT_PTHREADS], [libevent_pthreads >= 2.0.21],, [AC_MSG_ERROR([libevent_pthreads version 2.0.21 or greater not found.])])
fi
+
+ if test x$suppress_external_warnings != xno; then
+ EVENT_CFLAGS=SUPPRESS_WARNINGS($EVENT_CFLAGS)
+ fi
fi
dnl QR Code encoding library check
diff --git a/contrib/bitcoin-qt.pro b/contrib/bitcoin-qt.pro
deleted file mode 100644
index 0e4eeee0a7..0000000000
--- a/contrib/bitcoin-qt.pro
+++ /dev/null
@@ -1,22 +0,0 @@
-FORMS += \
- ../src/qt/forms/aboutdialog.ui \
- ../src/qt/forms/addressbookpage.ui \
- ../src/qt/forms/askpassphrasedialog.ui \
- ../src/qt/forms/coincontroldialog.ui \
- ../src/qt/forms/editaddressdialog.ui \
- ../src/qt/forms/helpmessagedialog.ui \
- ../src/qt/forms/intro.ui \
- ../src/qt/forms/openuridialog.ui \
- ../src/qt/forms/optionsdialog.ui \
- ../src/qt/forms/overviewpage.ui \
- ../src/qt/forms/receivecoinsdialog.ui \
- ../src/qt/forms/receiverequestdialog.ui \
- ../src/qt/forms/debugwindow.ui \
- ../src/qt/forms/sendcoinsdialog.ui \
- ../src/qt/forms/sendcoinsentry.ui \
- ../src/qt/forms/signverifymessagedialog.ui \
- ../src/qt/forms/transactiondescdialog.ui \
- ../src/qt/forms/createwalletdialog.ui
-
-RESOURCES += \
- ../src/qt/bitcoin.qrc
diff --git a/contrib/debian/copyright b/contrib/debian/copyright
index 7ee7f056d9..bc5535b4c7 100644
--- a/contrib/debian/copyright
+++ b/contrib/debian/copyright
@@ -87,7 +87,7 @@ Files: src/qt/res/icons/proxy.png
Copyright: Cristian Mircea Messel
License: public-domain
-Files: src/qt/fonts/RobotoMono-Bold.ttf
+Files: src/qt/res/fonts/RobotoMono-Bold.ttf
License: Apache-2.0
Comment: Site: https://fonts.google.com/specimen/Roboto+Mono
diff --git a/contrib/gitian-descriptors/assign_DISTNAME b/contrib/gitian-descriptors/assign_DISTNAME
index a2ca768aaa..330fbc041b 100755
--- a/contrib/gitian-descriptors/assign_DISTNAME
+++ b/contrib/gitian-descriptors/assign_DISTNAME
@@ -4,7 +4,7 @@
#
# A helper script to be sourced into the gitian descriptors
-if RECENT_TAG="$(git describe --exact-match HEAD)"; then
+if RECENT_TAG="$(git describe --exact-match HEAD 2> /dev/null)"; then
VERSION="${RECENT_TAG#v}"
else
VERSION="$(git rev-parse --short=12 HEAD)"
diff --git a/contrib/guix/README.md b/contrib/guix/README.md
index 1122ec9ba5..dad7de32c4 100644
--- a/contrib/guix/README.md
+++ b/contrib/guix/README.md
@@ -80,6 +80,50 @@ at the end of the `guix pull`)
export PATH="${HOME}/.config/guix/current/bin${PATH:+:}$PATH"
```
+### Controlling the number of threads used by `guix` build commands
+
+By default, the scripts under `./contrib/guix` will invoke all `guix` build
+commands with `--cores="$JOBS"`. Note that `$JOBS` defaults to `$(nproc)` if not
+specified. However, astute manual readers will also notice that there is a
+`--max-jobs=` flag (which defaults to 1 if unspecified).
+
+Here is the difference between `--cores=` and `--max-jobs=`:
+
+> Note: When I say "derivation," think "package"
+
+`--cores=`
+
+ - controls the number of CPU cores to build each derivation. This is the value
+ passed to `make`'s `--jobs=` flag.
+
+`--max-jobs=`
+
+ - controls how many derivations can be built in parallel
+ - defaults to 1
+
+Therefore, the default is for `guix` build commands to build one derivation at a
+time, utilizing `$JOBS` threads.
+
+Specifying the `$JOBS` environment variable will only modify `--cores=`, but you
+can also modify the value for `--max-jobs=` by specifying
+`$ADDITIONAL_GUIX_COMMON_FLAGS`. For example, if you have a LOT of memory, you
+may want to set:
+
+```sh
+export ADDITIONAL_GUIX_COMMON_FLAGS='--max-jobs=8'
+```
+
+Which allows for a maximum of 8 derivations to be built at the same time, each
+utilizing `$JOBS` threads.
+
+Or, if you'd like to avoid spurious build failures caused by issues with
+parallelism within a single package, but would still like to build multiple
+packages when the dependency graph allows for it, you may want to try:
+
+```sh
+export JOBS=1 ADDITIONAL_GUIX_COMMON_FLAGS='--max-jobs=8'
+```
+
## Usage
### As a Tool for Deterministic Builds
@@ -87,7 +131,7 @@ export PATH="${HOME}/.config/guix/current/bin${PATH:+:}$PATH"
From the top of a clean Bitcoin Core repository:
```sh
-./contrib/guix/guix-build.sh
+./contrib/guix/guix-build
```
After the build finishes successfully (check the status code please), compare
@@ -125,12 +169,16 @@ find output/ -type f -print0 | sort -z | xargs -r0 sha256sum
the actual SDK (e.g. SDK_PATH=$HOME/Downloads/macOS-SDKs instead of
$HOME/Downloads/macOS-SDKs/Xcode-11.3.1-11C505-extracted-SDK-with-libcxx-headers).
-* _**MAX_JOBS**_
+* _**JOBS**_
+
+ Override the number of jobs to run simultaneously, you might want to do so on
+ a memory-limited machine. This may be passed to:
+
+ - `guix` build commands as in `guix environment --cores="$JOBS"`
+ - `make` as in `make --jobs="$JOBS"`
+ - `xargs` as in `xargs -P"$JOBS"`
- Override the maximum number of jobs to run simultaneously, you might want to
- do so on a memory-limited machine. This may be passed to `make` as in `make
- --jobs="$MAX_JOBS"` or `xargs` as in `xargs -P"$MAX_JOBS"`. _(defaults to the
- value of `nproc` outside the container)_
+ _(defaults to the value of `nproc` outside the container)_
* _**SOURCE_DATE_EPOCH**_
@@ -157,10 +205,7 @@ find output/ -type f -print0 | sort -z | xargs -r0 sha256sum
* _**ADDITIONAL_GUIX_COMMON_FLAGS**_
- Additional flags to be passed to all `guix` commands. For a fully-bootstrapped
- build, set this to `--bootstrap --no-substitutes` (refer to the [security
- model section](#choosing-your-security-model) for more details). Note that a
- fully-bootstrapped build will take quite a long time on the first run.
+ Additional flags to be passed to all `guix` commands.
* _**ADDITIONAL_GUIX_TIMEMACHINE_FLAGS**_
@@ -217,6 +262,57 @@ To use dongcarl's substitute server for Bitcoin Core builds after having
export SUBSTITUTE_URLS='https://guix.carldong.io https://ci.guix.gnu.org'
```
+## Troubleshooting
+
+### Derivation failed to build
+
+When you see a build failure like below:
+
+```
+building /gnu/store/...-foo-3.6.12.drv...
+/ 'check' phasenote: keeping build directory `/tmp/guix-build-foo-3.6.12.drv-0'
+builder for `/gnu/store/...-foo-3.6.12.drv' failed with exit code 1
+build of /gnu/store/...-foo-3.6.12.drv failed
+View build log at '/var/log/guix/drvs/../...-foo-3.6.12.drv.bz2'.
+cannot build derivation `/gnu/store/...-qux-7.69.1.drv': 1 dependencies couldn't be built
+cannot build derivation `/gnu/store/...-bar-3.16.5.drv': 1 dependencies couldn't be built
+cannot build derivation `/gnu/store/...-baz-2.0.5.drv': 1 dependencies couldn't be built
+guix time-machine: error: build of `/gnu/store/...-baz-2.0.5.drv' failed
+```
+
+It means that `guix` failed to build a package named `foo`, which was a
+dependency of `qux`, `bar`, and `baz`. Importantly, note that the last "failed"
+line is not necessarily the root cause, the first "failed" line is.
+
+Most of the time, the build failure is due to a spurious test failure or the
+package's build system/test suite breaking when running multi-threaded. To
+rebuild _just_ this derivation in a single-threaded fashion:
+
+```sh
+$ guix build --cores=1 /gnu/store/...-foo-3.6.12.drv
+```
+
+If the single-threaded rebuild did not succeed, you may need to dig deeper.
+You may view `foo`'s build logs in `less` like so (please replace paths with the
+path you see in the build failure output):
+
+```sh
+$ bzcat /var/log/guix/drvs/../...-foo-3.6.12.drv.bz2 | less
+```
+
+`foo`'s build directory is also preserved and available at
+`/tmp/guix-build-foo-3.6.12.drv-0`. However, if you fail to build `foo` multiple
+times, it may be `/tmp/...drv-1` or `/tmp/...drv-2`. Always consult the build
+failure output for the most accurate, up-to-date information.
+
+#### python(-minimal): [Errno 84] Invalid or incomplete multibyte or wide character
+
+This error occurs when your `$TMPDIR` (default: /tmp) exists on a filesystem
+which rejects characters not present in the UTF-8 character code set. An example
+is ZFS with the utf8only=on option set.
+
+More information: https://bugs.python.org/issue37584
+
## FAQ
### How can I trust the binary installation?
diff --git a/contrib/guix/guix-build.sh b/contrib/guix/guix-build
index 7c32fb5726..5b3c20b234 100755
--- a/contrib/guix/guix-build.sh
+++ b/contrib/guix/guix-build
@@ -2,22 +2,26 @@
export LC_ALL=C
set -e -o pipefail
+# Source the common prelude, which:
+# 1. Checks if we're at the top directory of the Bitcoin Core repository
+# 2. Defines a few common functions and variables
+#
+# shellcheck source=libexec/prelude.bash
+source "$(dirname "${BASH_SOURCE[0]}")/libexec/prelude.bash"
+
+
###################
-## Sanity Checks ##
+## SANITY CHECKS ##
###################
################
-# Check 1: Make sure that we can invoke required tools
+# Required non-builtin commands should be invocable
################
-for cmd in git make guix cat mkdir curl; do
- if ! command -v "$cmd" > /dev/null 2>&1; then
- echo "ERR: This script requires that '$cmd' is installed and available in your \$PATH"
- exit 1
- fi
-done
+
+check_tools cat mkdir make git guix
################
-# Check 2: Make sure GUIX_BUILD_OPTIONS is empty
+# GUIX_BUILD_OPTIONS should be empty
################
#
# GUIX_BUILD_OPTIONS is an environment variable recognized by guix commands that
@@ -45,8 +49,9 @@ exit 1
fi
################
-# Check 3: Make sure that we're not in a dirty worktree
+# The git worktree should not be dirty
################
+
if ! git diff-index --quiet HEAD -- && [ -z "$FORCE_DIRTY_WORKTREE" ]; then
cat << EOF
ERR: The current git worktree is dirty, which may lead to broken builds.
@@ -60,12 +65,12 @@ Hint: To make your git worktree clean, You may want to:
using a dirty worktree
EOF
exit 1
-else
- GIT_COMMIT=$(git rev-parse --short=12 HEAD)
fi
+mkdir -p "$VERSION_BASE"
+
################
-# Check 4: Make sure that build directories do not exist
+# Build directories should not exist
################
# Default to building for all supported HOSTs (overridable by environment)
@@ -73,14 +78,12 @@ export HOSTS="${HOSTS:-x86_64-linux-gnu arm-linux-gnueabihf aarch64-linux-gnu ri
x86_64-w64-mingw32
x86_64-apple-darwin18}"
-DISTSRC_BASE="${DISTSRC_BASE:-${PWD}}"
-
# Usage: distsrc_for_host HOST
#
# HOST: The current platform triple we're building for
#
distsrc_for_host() {
- echo "${DISTSRC_BASE}/distsrc-${GIT_COMMIT}-${1}"
+ echo "${DISTSRC_BASE}/distsrc-${VERSION}-${1}"
}
# Accumulate a list of build directories that already exist...
@@ -100,24 +103,31 @@ ERR: Build directories for this commit already exist for the following platform
Aborting...
+Hint: To blow everything away, you may want to use:
+
+ $ ./contrib/guix/guix-clean
+
+Specifically, this will remove all files without an entry in the index,
+excluding the SDK directory, the depends download cache, the depends built
+packages cache, the garbage collector roots for Guix environments, and the
+output directory.
EOF
for host in $hosts_distsrc_exists; do
echo " ${host} '$(distsrc_for_host "$host")'"
done
exit 1
else
-
mkdir -p "$DISTSRC_BASE"
fi
################
-# Check 5: When building for darwin, make sure that the macOS SDK exists
+# When building for darwin, the macOS SDK should exists
################
for host in $HOSTS; do
case "$host" in
*darwin*)
- OSX_SDK="$(make -C "${PWD}/depends" --no-print-directory HOST="$host" print-OSX_SDK | sed 's@^[^=]\+=[[:space:]]\+@@g')"
+ OSX_SDK="$(make -C "${PWD}/depends" --no-print-directory HOST="$host" print-OSX_SDK | sed 's@^[^=]\+=@@g')"
if [ -e "$OSX_SDK" ]; then
echo "Found macOS SDK at '${OSX_SDK}', using..."
else
@@ -128,13 +138,40 @@ for host in $HOSTS; do
esac
done
+################
+# Check that we can connect to the guix-daemon
+################
+
+cat << EOF
+Checking that we can connect to the guix-daemon...
+
+Hint: If this hangs, you may want to try turning your guix-daemon off and on
+ again.
+
+EOF
+if ! guix gc --list-failures > /dev/null; then
+cat << EOF
+
+ERR: Failed to connect to the guix-daemon, please ensure that one is running and
+ reachable.
+EOF
+exit 1
+fi
+
+# Developer note: we could use `guix repl` for this check and run:
+#
+# (import (guix store)) (close-connection (open-connection))
+#
+# However, the internal API is likely to change more than the CLI invocation
+
+
#########
-# Setup #
+# SETUP #
#########
# Determine the maximum number of jobs to run simultaneously (overridable by
# environment)
-MAX_JOBS="${MAX_JOBS:-$(nproc)}"
+JOBS="${JOBS:-$(nproc)}"
# Usage: host_to_commonname HOST
#
@@ -149,12 +186,6 @@ host_to_commonname() {
esac
}
-# Download the depends sources now as we won't have internet access in the build
-# container
-for host in $HOSTS; do
- make -C "${PWD}/depends" -j"$MAX_JOBS" download-"$(host_to_commonname "$host")" ${V:+V=1} ${SOURCES_PATH:+SOURCES_PATH="$SOURCES_PATH"}
-done
-
# Determine the reference time used for determinism (overridable by environment)
SOURCE_DATE_EPOCH="${SOURCE_DATE_EPOCH:-$(git log --format=%at -1)}"
@@ -164,19 +195,97 @@ time-machine() {
# shellcheck disable=SC2086
guix time-machine --url=https://github.com/dongcarl/guix.git \
--commit=490e39ff303f4f6873a04bfb8253755bdae1b29c \
- --max-jobs="$MAX_JOBS" \
+ --cores="$JOBS" \
--keep-failed \
+ --fallback \
${SUBSTITUTE_URLS:+--substitute-urls="$SUBSTITUTE_URLS"} \
${ADDITIONAL_GUIX_COMMON_FLAGS} ${ADDITIONAL_GUIX_TIMEMACHINE_FLAGS} \
-- "$@"
}
+
+# Precious directories are those which should not be cleaned between successive
+# guix builds
+depends_precious_dir_names='SOURCES_PATH BASE_CACHE SDK_PATH'
+precious_dir_names="${depends_precious_dir_names} OUTDIR_BASE PROFILES_BASE"
+
+# Usage: contains IFS-SEPARATED-LIST ITEM
+contains() {
+ for i in ${1}; do
+ if [ "$i" = "${2}" ]; then
+ return 0 # Found!
+ fi
+ done
+ return 1
+}
+
+# If the user explicitly specified a precious directory, create it so we
+# can map it into the container
+for precious_dir_name in $precious_dir_names; do
+ precious_dir_path="${!precious_dir_name}"
+ if [ -n "$precious_dir_path" ]; then
+ if [ ! -e "$precious_dir_path" ]; then
+ mkdir -p "$precious_dir_path"
+ elif [ -L "$precious_dir_path" ]; then
+ echo "ERR: ${precious_dir_name} cannot be a symbolic link"
+ exit 1
+ elif [ ! -d "$precious_dir_path" ]; then
+ echo "ERR: ${precious_dir_name} must be a directory"
+ exit 1
+ fi
+ fi
+done
+
+mkdir -p "$VAR_BASE"
+
+# Record the _effective_ values of precious directories such that guix-clean can
+# avoid clobbering them if appropriate.
+#
+# shellcheck disable=SC2046,SC2086
+{
+ # Get depends precious dir definitions from depends
+ make -C "${PWD}/depends" \
+ --no-print-directory \
+ -- $(printf "print-%s\n" $depends_precious_dir_names)
+
+ # Get remaining precious dir definitions from the environment
+ for precious_dir_name in $precious_dir_names; do
+ precious_dir_path="${!precious_dir_name}"
+ if ! contains "$depends_precious_dir_names" "$precious_dir_name"; then
+ echo "${precious_dir_name}=${precious_dir_path}"
+ fi
+ done
+} > "${VAR_BASE}/precious_dirs"
+
# Make sure an output directory exists for our builds
-OUTDIR="${OUTDIR:-${PWD}/output}"
-[ -e "$OUTDIR" ] || mkdir -p "$OUTDIR"
+OUTDIR_BASE="${OUTDIR_BASE:-${VERSION_BASE}/output}"
+mkdir -p "$OUTDIR_BASE"
+
+# Download the depends sources now as we won't have internet access in the build
+# container
+for host in $HOSTS; do
+ make -C "${PWD}/depends" -j"$JOBS" download-"$(host_to_commonname "$host")" ${V:+V=1} ${SOURCES_PATH:+SOURCES_PATH="$SOURCES_PATH"}
+done
+
+# Usage: outdir_for_host HOST
+#
+# HOST: The current platform triple we're building for
+#
+outdir_for_host() {
+ echo "${OUTDIR_BASE}/${1}"
+}
+
+# Usage: profiledir_for_host HOST COMMAND
+#
+# HOST: The current platform triple we're building for
+#
+profiledir_for_host() {
+ echo "${PROFILES_BASE}/${2}-${1}"
+}
+
#########
-# Build #
+# BUILD #
#########
# Function to be called when building for host ${1} and the user interrupts the
@@ -184,24 +293,19 @@ OUTDIR="${OUTDIR:-${PWD}/output}"
int_trap() {
cat << EOF
** INT received while building ${1}, you may want to clean up the relevant
- output, deploy, and distsrc-* directories before rebuilding
+ work directories (e.g. distsrc-*) before rebuilding
Hint: To blow everything away, you may want to use:
- $ git clean -xdff --exclude='/depends/SDKs/*'
+ $ ./contrib/guix/guix-clean
Specifically, this will remove all files without an entry in the index,
-excluding the SDK directory. Practically speaking, this means that all ignored
-and untracked files and directories will be wiped, allowing you to start anew.
+excluding the SDK directory, the depends download cache, the depends built
+packages cache, the garbage collector roots for Guix environments, and the
+output directory.
EOF
}
-# Create SOURCES_PATH, BASE_CACHE, and SDK_PATH if they are non-empty so that we
-# can map them into the container
-[ -z "$SOURCES_PATH" ] || mkdir -p "$SOURCES_PATH"
-[ -z "$BASE_CACHE" ] || mkdir -p "$BASE_CACHE"
-[ -z "$SDK_PATH" ] || mkdir -p "$SDK_PATH"
-
# Deterministically build Bitcoin Core
# shellcheck disable=SC2153
for host in $HOSTS; do
@@ -216,15 +320,15 @@ for host in $HOSTS; do
# shellcheck disable=SC2030
cat << EOF
-INFO: Building commit ${GIT_COMMIT:?not set} for platform triple ${HOST:?not set}:
+INFO: Building ${VERSION:?not set} for platform triple ${HOST:?not set}:
...using reference timestamp: ${SOURCE_DATE_EPOCH:?not set}
- ...running at most ${MAX_JOBS:?not set} jobs
+ ...running at most ${JOBS:?not set} jobs
...from worktree directory: '${PWD}'
...bind-mounted in container to: '/bitcoin'
...in build directory: '$(distsrc_for_host "$HOST")'
...bind-mounted in container to: '$(DISTSRC_BASE=/distsrc-base && distsrc_for_host "$HOST")'
- ...outputting in: '${OUTDIR:?not set}'
- ...bind-mounted in container to: '/outdir'
+ ...outputting in: '$(outdir_for_host "$HOST")'
+ ...bind-mounted in container to: '$(OUTDIR_BASE=/outdir-base && outdir_for_host "$HOST")'
EOF
# Run the build script 'contrib/guix/libexec/build.sh' in the build
@@ -299,24 +403,29 @@ EOF
--no-cwd \
--share="$PWD"=/bitcoin \
--share="$DISTSRC_BASE"=/distsrc-base \
- --share="$OUTDIR"=/outdir \
+ --share="$OUTDIR_BASE"=/outdir-base \
--expose="$(git rev-parse --git-common-dir)" \
${SOURCES_PATH:+--share="$SOURCES_PATH"} \
${BASE_CACHE:+--share="$BASE_CACHE"} \
${SDK_PATH:+--share="$SDK_PATH"} \
- --max-jobs="$MAX_JOBS" \
+ --cores="$JOBS" \
--keep-failed \
+ --fallback \
+ --link-profile \
+ --root="$(profiledir_for_host "${HOST}" build)" \
${SUBSTITUTE_URLS:+--substitute-urls="$SUBSTITUTE_URLS"} \
${ADDITIONAL_GUIX_COMMON_FLAGS} ${ADDITIONAL_GUIX_ENVIRONMENT_FLAGS} \
-- env HOST="$host" \
- MAX_JOBS="$MAX_JOBS" \
+ DISTNAME="$DISTNAME" \
+ JOBS="$JOBS" \
SOURCE_DATE_EPOCH="${SOURCE_DATE_EPOCH:?unable to determine value}" \
${V:+V=1} \
${SOURCES_PATH:+SOURCES_PATH="$SOURCES_PATH"} \
${BASE_CACHE:+BASE_CACHE="$BASE_CACHE"} \
${SDK_PATH:+SDK_PATH="$SDK_PATH"} \
DISTSRC="$(DISTSRC_BASE=/distsrc-base && distsrc_for_host "$HOST")" \
- OUTDIR=/outdir \
+ OUTDIR="$(OUTDIR_BASE=/outdir-base && outdir_for_host "$HOST")" \
+ DIST_ARCHIVE_BASE=/outdir-base/dist-archive \
bash -c "cd /bitcoin && bash contrib/guix/libexec/build.sh"
)
diff --git a/contrib/guix/guix-clean b/contrib/guix/guix-clean
new file mode 100755
index 0000000000..9fa17191e8
--- /dev/null
+++ b/contrib/guix/guix-clean
@@ -0,0 +1,83 @@
+#!/usr/bin/env bash
+export LC_ALL=C
+set -e -o pipefail
+
+# Source the common prelude, which:
+# 1. Checks if we're at the top directory of the Bitcoin Core repository
+# 2. Defines a few common functions and variables
+#
+# shellcheck source=libexec/prelude.bash
+source "$(dirname "${BASH_SOURCE[0]}")/libexec/prelude.bash"
+
+
+###################
+## Sanity Checks ##
+###################
+
+################
+# Required non-builtin commands should be invokable
+################
+
+check_tools cat mkdir make git guix
+
+
+#############
+## Clean ##
+#############
+
+# Usage: under_dir MAYBE_PARENT MAYBE_CHILD
+#
+# If MAYBE_CHILD is a subdirectory of MAYBE_PARENT, print the relative path
+# from MAYBE_PARENT to MAYBE_CHILD. Otherwise, return 1 as the error code.
+#
+# NOTE: This does not perform any symlink-resolving or path canonicalization.
+#
+under_dir() {
+ local path_residue
+ path_residue="${2##${1}}"
+ if [ -z "$path_residue" ] || [ "$path_residue" = "$2" ]; then
+ return 1
+ else
+ echo "$path_residue"
+ fi
+}
+
+# Usage: dir_under_git_root MAYBE_CHILD
+#
+# If MAYBE_CHILD is under the current git repository and exists, print the
+# relative path from the git repository's top-level directory to MAYBE_CHILD,
+# otherwise, exit with an error code.
+#
+dir_under_git_root() {
+ local rv
+ rv="$(under_dir "$(git_root)" "$1")"
+ [ -n "$rv" ] && echo "$rv"
+}
+
+shopt -s nullglob
+found_precious_dirs_files=( "${version_base_prefix}"*/"${var_base_basename}/precious_dirs" ) # This expands to an array of directories...
+shopt -u nullglob
+
+exclude_flags=()
+
+for precious_dirs_file in "${found_precious_dirs_files[@]}"; do
+ # Make sure the precious directories (e.g. SOURCES_PATH, BASE_CACHE, SDK_PATH)
+ # are excluded from git-clean
+ echo "Found precious_dirs file: '${precious_dirs_file}'"
+
+ # Exclude the precious_dirs file itself
+ if dirs_file_exclude_fragment=$(dir_under_git_root "$(dirname "$precious_dirs_file")"); then
+ exclude_flags+=( --exclude="${dirs_file_exclude_fragment}/precious_dirs" )
+ fi
+
+ # Read each 'name=dir' pair from the precious_dirs file
+ while IFS='=' read -r name dir; do
+ # Add an exclusion flag if the precious directory is under the git root.
+ if under=$(dir_under_git_root "$dir"); then
+ echo "Avoiding ${name}: ${under}"
+ exclude_flags+=( --exclude="$under" )
+ fi
+ done < "$precious_dirs_file"
+done
+
+git clean -xdff "${exclude_flags[@]}"
diff --git a/contrib/guix/libexec/build.sh b/contrib/guix/libexec/build.sh
index 051066a6a0..4239c3d475 100644
--- a/contrib/guix/libexec/build.sh
+++ b/contrib/guix/libexec/build.sh
@@ -24,9 +24,11 @@ fi
# Check that required environment variables are set
cat << EOF
Required environment variables as seen inside the container:
+ DIST_ARCHIVE_BASE: ${DIST_ARCHIVE_BASE:?not set}
+ DISTNAME: ${DISTNAME:?not set}
HOST: ${HOST:?not set}
SOURCE_DATE_EPOCH: ${SOURCE_DATE_EPOCH:?not set}
- MAX_JOBS: ${MAX_JOBS:?not set}
+ JOBS: ${JOBS:?not set}
DISTSRC: ${DISTSRC:?not set}
OUTDIR: ${OUTDIR:?not set}
EOF
@@ -52,16 +54,36 @@ store_path() {
# Set environment variables to point the NATIVE toolchain to the right
# includes/libs
NATIVE_GCC="$(store_path gcc-toolchain)"
-export LIBRARY_PATH="${NATIVE_GCC}/lib:${NATIVE_GCC}/lib64"
-export CPATH="${NATIVE_GCC}/include"
+NATIVE_GCC_STATIC="$(store_path gcc-toolchain static)"
+
+unset LIBRARY_PATH
+unset CPATH
unset C_INCLUDE_PATH
unset CPLUS_INCLUDE_PATH
+unset OBJC_INCLUDE_PATH
+unset OBJCPLUS_INCLUDE_PATH
+
+export LIBRARY_PATH="${NATIVE_GCC}/lib:${NATIVE_GCC}/lib64:${NATIVE_GCC_STATIC}/lib:${NATIVE_GCC_STATIC}/lib64"
+export C_INCLUDE_PATH="${NATIVE_GCC}/include"
+export CPLUS_INCLUDE_PATH="${NATIVE_GCC}/include/c++:${NATIVE_GCC}/include"
+export OBJC_INCLUDE_PATH="${NATIVE_GCC}/include"
+export OBJCPLUS_INCLUDE_PATH="${NATIVE_GCC}/include/c++:${NATIVE_GCC}/include"
+
+prepend_to_search_env_var() {
+ export "${1}=${2}${!1:+:}${!1}"
+}
+
case "$HOST" in
*darwin*)
# When targeting darwin, zlib is required by native_libdmg-hfsplus.
zlib_store_path=$(store_path "zlib")
- export LIBRARY_PATH="${zlib_store_path}/lib:${LIBRARY_PATH}"
- export CPATH="${zlib_store_path}/include:${CPATH}"
+ zlib_static_store_path=$(store_path "zlib" static)
+
+ prepend_to_search_env_var LIBRARY_PATH "${zlib_static_store_path}/lib:${zlib_store_path}/lib"
+ prepend_to_search_env_var C_INCLUDE_PATH "${zlib_store_path}/include"
+ prepend_to_search_env_var CPLUS_INCLUDE_PATH "${zlib_store_path}/include"
+ prepend_to_search_env_var OBJC_INCLUDE_PATH "${zlib_store_path}/include"
+ prepend_to_search_env_var OBJCPLUS_INCLUDE_PATH "${zlib_store_path}/include"
esac
# Set environment variables to point the CROSS toolchain to the right
@@ -173,7 +195,7 @@ esac
####################
# Build the depends tree, overriding variables that assume multilib gcc
-make -C depends --jobs="$MAX_JOBS" HOST="$HOST" \
+make -C depends --jobs="$JOBS" HOST="$HOST" \
${V:+V=1} \
${SOURCES_PATH+SOURCES_PATH="$SOURCES_PATH"} \
${BASE_CACHE+BASE_CACHE="$BASE_CACHE"} \
@@ -198,11 +220,7 @@ make -C depends --jobs="$MAX_JOBS" HOST="$HOST" \
# Source Tarball Building #
###########################
-# Define DISTNAME variable.
-# shellcheck source=contrib/gitian-descriptors/assign_DISTNAME
-source contrib/gitian-descriptors/assign_DISTNAME
-
-GIT_ARCHIVE="${OUTDIR}/src/${DISTNAME}.tar.gz"
+GIT_ARCHIVE="${DIST_ARCHIVE_BASE}/${DISTNAME}.tar.gz"
# Create the source tarball if not already there
if [ ! -e "$GIT_ARCHIVE" ]; then
@@ -267,7 +285,7 @@ mkdir -p "$DISTSRC"
sed -i.old 's/-lstdc++ //g' config.status libtool src/univalue/config.status src/univalue/libtool
# Build Bitcoin Core
- make --jobs="$MAX_JOBS" ${V:+V=1}
+ make --jobs="$JOBS" ${V:+V=1}
# Perform basic ELF security checks on a series of executables.
make -C src --jobs=1 check-security ${V:+V=1}
@@ -275,6 +293,7 @@ mkdir -p "$DISTSRC"
# version symbols for Linux distro back-compatibility.
make -C src --jobs=1 check-symbols ${V:+V=1}
+ mkdir -p ${OUTDIR}
# Make the os-specific installers
case "$HOST" in
*mingw*)
@@ -306,9 +325,6 @@ mkdir -p "$DISTSRC"
osx_volname \
contrib/macdeploy/detached-sig-{apply,create}.sh \
"${BASEPREFIX}/${HOST}"/native/bin/dmg
- for util in codesign_allocate pagestuff; do
- cp --no-target-directory {"${BASEPREFIX}/${HOST}/native/bin/${HOST}-","unsigned-app-${HOST}/"}"$util"
- done
mv --target-directory="unsigned-app-${HOST}" dist
(
cd "unsigned-app-${HOST}"
@@ -344,7 +360,7 @@ mkdir -p "$DISTSRC"
{
find "${DISTNAME}/bin" -type f -executable -print0
find "${DISTNAME}/lib" -type f -print0
- } | xargs -0 -n1 -P"$MAX_JOBS" -I{} "${DISTSRC}/contrib/devtools/split-debug.sh" {} {} {}.dbg
+ } | xargs -0 -n1 -P"$JOBS" -I{} "${DISTSRC}/contrib/devtools/split-debug.sh" {} {} {}.dbg
;;
esac
@@ -394,21 +410,21 @@ mkdir -p "$DISTSRC"
|| ( rm -f "${OUTDIR}/${DISTNAME}-${HOST//x86_64-apple-darwin18/osx64}.tar.gz" && exit 1 )
;;
esac
- )
-)
+ ) # $DISTSRC/installed
-case "$HOST" in
- *mingw*)
- cp -rf --target-directory=. contrib/windeploy
- (
- cd ./windeploy
- mkdir unsigned
- cp --target-directory=unsigned/ "${OUTDIR}/${DISTNAME}-win64-setup-unsigned.exe"
- find . -print0 \
- | sort --zero-terminated \
- | tar --create --no-recursion --mode='u+rw,go+r-w,a+X' --null --files-from=- \
- | gzip -9n > "${OUTDIR}/${DISTNAME}-win-unsigned.tar.gz" \
- || ( rm -f "${OUTDIR}/${DISTNAME}-win-unsigned.tar.gz" && exit 1 )
- )
- ;;
-esac
+ case "$HOST" in
+ *mingw*)
+ cp -rf --target-directory=. contrib/windeploy
+ (
+ cd ./windeploy
+ mkdir -p unsigned
+ cp --target-directory=unsigned/ "${OUTDIR}/${DISTNAME}-win64-setup-unsigned.exe"
+ find . -print0 \
+ | sort --zero-terminated \
+ | tar --create --no-recursion --mode='u+rw,go+r-w,a+X' --null --files-from=- \
+ | gzip -9n > "${OUTDIR}/${DISTNAME}-win-unsigned.tar.gz" \
+ || ( rm -f "${OUTDIR}/${DISTNAME}-win-unsigned.tar.gz" && exit 1 )
+ )
+ ;;
+ esac
+) # $DISTSRC
diff --git a/contrib/guix/libexec/prelude.bash b/contrib/guix/libexec/prelude.bash
new file mode 100644
index 0000000000..9705607119
--- /dev/null
+++ b/contrib/guix/libexec/prelude.bash
@@ -0,0 +1,66 @@
+#!/usr/bin/env bash
+export LC_ALL=C
+set -e -o pipefail
+
+# shellcheck source=../../shell/realpath.bash
+source contrib/shell/realpath.bash
+
+# shellcheck source=../../shell/git-utils.bash
+source contrib/shell/git-utils.bash
+
+################
+# Required non-builtin commands should be invocable
+################
+
+check_tools() {
+ for cmd in "$@"; do
+ if ! command -v "$cmd" > /dev/null 2>&1; then
+ echo "ERR: This script requires that '$cmd' is installed and available in your \$PATH"
+ exit 1
+ fi
+ done
+}
+
+check_tools cat env readlink dirname basename git
+
+################
+# We should be at the top directory of the repository
+################
+
+same_dir() {
+ local resolved1 resolved2
+ resolved1="$(bash_realpath "${1}")"
+ resolved2="$(bash_realpath "${2}")"
+ [ "$resolved1" = "$resolved2" ]
+}
+
+if ! same_dir "${PWD}" "$(git_root)"; then
+cat << EOF
+ERR: This script must be invoked from the top level of the git repository
+
+Hint: This may look something like:
+ env FOO=BAR ./contrib/guix/guix-<blah>
+
+EOF
+exit 1
+fi
+
+################
+# Set common variables
+################
+
+VERSION="${VERSION:-$(git_head_version)}"
+DISTNAME="${DISTNAME:-bitcoin-${VERSION}}"
+
+version_base_prefix="${PWD}/guix-build-"
+VERSION_BASE="${version_base_prefix}${VERSION}" # TOP
+
+DISTSRC_BASE="${DISTSRC_BASE:-${VERSION_BASE}}"
+
+OUTDIR_BASE="${OUTDIR_BASE:-${VERSION_BASE}/output}"
+
+var_base_basename="var"
+VAR_BASE="${VAR_BASE:-${VERSION_BASE}/${var_base_basename}}"
+
+profiles_base_basename="profiles"
+PROFILES_BASE="${PROFILES_BASE:-${VAR_BASE}/${profiles_base_basename}}"
diff --git a/contrib/guix/manifest.scm b/contrib/guix/manifest.scm
index 4228532cb1..910a9dd6f6 100644
--- a/contrib/guix/manifest.scm
+++ b/contrib/guix/manifest.scm
@@ -214,6 +214,7 @@ chain for " target " development."))
gzip
xz
zlib
+ (list zlib "static")
;; Build tools
gnu-make
libtool
@@ -227,7 +228,8 @@ chain for " target " development."))
;; Git
git
;; Native gcc 7 toolchain
- gcc-toolchain-7)
+ gcc-toolchain-7
+ (list gcc-toolchain-7 "static"))
(let ((target (getenv "HOST")))
(cond ((string-suffix? "-mingw32" target)
;; Windows
@@ -237,5 +239,5 @@ chain for " target " development."))
((string-contains target "-linux-")
(list (make-bitcoin-cross-toolchain target)))
((string-contains target "darwin")
- (list clang-8 binutils imagemagick libtiff librsvg font-tuffy cmake xorriso))
+ (list clang-toolchain-8 binutils imagemagick libtiff librsvg font-tuffy cmake xorriso))
(else '())))))
diff --git a/contrib/seeds/generate-seeds.py b/contrib/seeds/generate-seeds.py
index 7630a7a4fa..d95069277d 100755
--- a/contrib/seeds/generate-seeds.py
+++ b/contrib/seeds/generate-seeds.py
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
-# Copyright (c) 2014-2017 Wladimir J. van der Laan
+# Copyright (c) 2014-2021 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
'''
@@ -13,19 +13,13 @@ argument:
These files must consist of lines in the format
- <ip>
<ip>:<port>
- [<ipv6>]
[<ipv6>]:<port>
- <onion>.onion
- 0xDDBBCCAA (IPv4 little-endian old pnSeeds format)
+ <onion>.onion:<port>
The output will be two data structures with the peers in binary format:
- static SeedSpec6 pnSeed6_main[]={
- ...
- }
- static SeedSpec6 pnSeed6_test[]={
+ static const uint8_t chainparams_seed_{main,test}[]={
...
}
@@ -33,24 +27,33 @@ These should be pasted into `src/chainparamsseeds.h`.
'''
from base64 import b32decode
-from binascii import a2b_hex
+from enum import Enum
+import struct
import sys
import os
import re
-# ipv4 in ipv6 prefix
-pchIPv4 = bytearray([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff])
-# tor-specific ipv6 prefix
-pchOnionCat = bytearray([0xFD,0x87,0xD8,0x7E,0xEB,0x43])
-
-def name_to_ipv6(addr):
- if len(addr)>6 and addr.endswith('.onion'):
+class BIP155Network(Enum):
+ IPV4 = 1
+ IPV6 = 2
+ TORV2 = 3
+ TORV3 = 4
+ I2P = 5
+ CJDNS = 6
+
+def name_to_bip155(addr):
+ '''Convert address string to BIP155 (networkID, addr) tuple.'''
+ if addr.endswith('.onion'):
vchAddr = b32decode(addr[0:-6], True)
- if len(vchAddr) != 16-len(pchOnionCat):
+ if len(vchAddr) == 10:
+ return (BIP155Network.TORV2, vchAddr)
+ elif len(vchAddr) == 35:
+ assert(vchAddr[34] == 3)
+ return (BIP155Network.TORV3, vchAddr[:32])
+ else:
raise ValueError('Invalid onion %s' % vchAddr)
- return pchOnionCat + vchAddr
elif '.' in addr: # IPv4
- return pchIPv4 + bytearray((int(x) for x in addr.split('.')))
+ return (BIP155Network.IPV4, bytes((int(x) for x in addr.split('.'))))
elif ':' in addr: # IPv6
sub = [[], []] # prefix, suffix
x = 0
@@ -67,13 +70,12 @@ def name_to_ipv6(addr):
sub[x].append(val & 0xff)
nullbytes = 16 - len(sub[0]) - len(sub[1])
assert((x == 0 and nullbytes == 0) or (x == 1 and nullbytes > 0))
- return bytearray(sub[0] + ([0] * nullbytes) + sub[1])
- elif addr.startswith('0x'): # IPv4-in-little-endian
- return pchIPv4 + bytearray(reversed(a2b_hex(addr[2:])))
+ return (BIP155Network.IPV6, bytes(sub[0] + ([0] * nullbytes) + sub[1]))
else:
raise ValueError('Could not parse address %s' % addr)
-def parse_spec(s, defaultport):
+def parse_spec(s):
+ '''Convert endpoint string to BIP155 (networkID, addr, port) tuple.'''
match = re.match(r'\[([0-9a-fA-F:]+)\](?::([0-9]+))?$', s)
if match: # ipv6
host = match.group(1)
@@ -85,17 +87,39 @@ def parse_spec(s, defaultport):
(host,_,port) = s.partition(':')
if not port:
- port = defaultport
+ port = 0
else:
port = int(port)
- host = name_to_ipv6(host)
+ host = name_to_bip155(host)
- return (host,port)
+ return host + (port, )
-def process_nodes(g, f, structname, defaultport):
- g.write('static SeedSpec6 %s[] = {\n' % structname)
- first = True
+def ser_compact_size(l):
+ r = b""
+ if l < 253:
+ r = struct.pack("B", l)
+ elif l < 0x10000:
+ r = struct.pack("<BH", 253, l)
+ elif l < 0x100000000:
+ r = struct.pack("<BI", 254, l)
+ else:
+ r = struct.pack("<BQ", 255, l)
+ return r
+
+def bip155_serialize(spec):
+ '''
+ Serialize (networkID, addr, port) tuple to BIP155 binary format.
+ '''
+ r = b""
+ r += struct.pack('B', spec[0].value)
+ r += ser_compact_size(len(spec[1]))
+ r += spec[1]
+ r += struct.pack('>H', spec[2])
+ return r
+
+def process_nodes(g, f, structname):
+ g.write('static const uint8_t %s[] = {\n' % structname)
for line in f:
comment = line.find('#')
if comment != -1:
@@ -103,14 +127,12 @@ def process_nodes(g, f, structname, defaultport):
line = line.strip()
if not line:
continue
- if not first:
- g.write(',\n')
- first = False
- (host,port) = parse_spec(line, defaultport)
- hoststr = ','.join(('0x%02x' % b) for b in host)
- g.write(' {{%s}, %i}' % (hoststr, port))
- g.write('\n};\n')
+ spec = parse_spec(line)
+ blob = bip155_serialize(spec)
+ hoststr = ','.join(('0x%02x' % b) for b in blob)
+ g.write(f' {hoststr},\n')
+ g.write('};\n')
def main():
if len(sys.argv)<2:
@@ -124,14 +146,13 @@ def main():
g.write(' * List of fixed seed nodes for the bitcoin network\n')
g.write(' * AUTOGENERATED by contrib/seeds/generate-seeds.py\n')
g.write(' *\n')
- g.write(' * Each line contains a 16-byte IPv6 address and a port.\n')
- g.write(' * IPv4 as well as onion addresses are wrapped inside an IPv6 address accordingly.\n')
+ g.write(' * Each line contains a BIP155 serialized (networkID, addr, port) tuple.\n')
g.write(' */\n')
with open(os.path.join(indir,'nodes_main.txt'), 'r', encoding="utf8") as f:
- process_nodes(g, f, 'pnSeed6_main', 8333)
+ process_nodes(g, f, 'chainparams_seed_main')
g.write('\n')
with open(os.path.join(indir,'nodes_test.txt'), 'r', encoding="utf8") as f:
- process_nodes(g, f, 'pnSeed6_test', 18333)
+ process_nodes(g, f, 'chainparams_seed_test')
g.write('#endif // BITCOIN_CHAINPARAMSSEEDS_H\n')
if __name__ == '__main__':
diff --git a/contrib/seeds/nodes_main.txt b/contrib/seeds/nodes_main.txt
index 7b97436013..c43caa73eb 100644
--- a/contrib/seeds/nodes_main.txt
+++ b/contrib/seeds/nodes_main.txt
@@ -1162,3 +1162,29 @@ zuytrfevzjcpizli.onion:8333
zvq6dpt3i2ofdp3g.onion:8333
zwwm6ga7u2hqe2sd.onion:8333
zyqb4lenfspntj5m.onion:8333
+
+# manually added 2021-03 for minimal torv3 bootstrap support
+2g5qfdkn2vvcbqhzcyvyiitg4ceukybxklraxjnu7atlhd22gdwywaid.onion:8333
+2jmtxvyup3ijr7u6uvu7ijtnojx4g5wodvaedivbv74w4vzntxbrhvad.onion:8333
+37m62wn7dz3uqpathpc4qfmgrbupachj52nt3jbtbjugpbu54kbud7yd.onion:8333
+5g72ppm3krkorsfopcm2bi7wlv4ohhs4u4mlseymasn7g7zhdcyjpfid.onion:8333
+7cgwjuwi5ehvcay4tazy7ya6463bndjk6xzrttw5t3xbpq4p22q6fyid.onion:8333
+7pyrpvqdhmayxggpcyqn5l3m5vqkw3qubnmgwlpya2mdo6x7pih7r7id.onion:8333
+b64xcbleqmwgq2u46bh4hegnlrzzvxntyzbmucn3zt7cssm7y4ubv3id.onion:8333
+ejxefzf5fpst4mg2rib7grksvscl7p6fvjp6agzgfc2yglxnjtxc3aid.onion:8333
+fjdyxicpm4o42xmedlwl3uvk5gmqdfs5j37wir52327vncjzvtpfv7yd.onion:8333
+fpz6r5ppsakkwypjcglz6gcnwt7ytfhxskkfhzu62tnylcknh3eq6pad.onion:8333
+fzhn4uoxfbfss7h7d6ffbn266ca432ekbbzvqtsdd55ylgxn4jucm5qd.onion:8333
+gxo5anvfnffnftfy5frkgvplq3rpga2ie3tcblo2vl754fvnhgorn5yd.onion:8333
+ifdu5qvbofrt4ekui2iyb3kbcyzcsglazhx2hn4wfskkrx2v24qxriid.onion:8333
+itz3oxsihs62muvknc237xabl5f6w6rfznfhbpayrslv2j2ubels47yd.onion:8333
+lrjh6fywjqttmlifuemq3puhvmshxzzyhoqx7uoufali57eypuenzzid.onion:8333
+m7cbpjolo662uel7rpaid46as2otcj44vvwg3gccodnvaeuwbm3anbyd.onion:8333
+opnyfyeiibe5qo5a3wbxzbb4xdiagc32bbce46owmertdknta5mi7uyd.onion:8333
+owjsdxmzla6d7lrwkbmetywqym5cyswpihciesfl5qdv2vrmwsgy4uqd.onion:8333
+q7kgmd7n7h27ds4fg7wocgniuqb3oe2zxp4nfe4skd5da6wyipibqzqd.onion:8333
+rp7k2go3s5lyj3fnj6zn62ktarlrsft2ohlsxkyd7v3e3idqyptvread.onion:8333
+sys54sv4xv3hn3sdiv3oadmzqpgyhd4u4xphv4xqk64ckvaxzm57a7yd.onion:8333
+tddeij4qigtjr6jfnrmq6btnirmq5msgwcsdpcdjr7atftm7cxlqztid.onion:8333
+vi5bnbxkleeqi6hfccjochnn65lcxlfqs4uwgmhudph554zibiusqnad.onion:8333
+xqt25cobm5zqucac3634zfght72he6u3eagfyej5ellbhcdgos7t2had.onion:8333
diff --git a/contrib/seeds/nodes_test.txt b/contrib/seeds/nodes_test.txt
index 98365ee505..0af88d1bde 100644
--- a/contrib/seeds/nodes_test.txt
+++ b/contrib/seeds/nodes_test.txt
@@ -1,11 +1,11 @@
# List of fixed seed nodes for testnet
# Onion nodes
-thfsmmn2jbitcoin.onion
-it2pj4f7657g3rhi.onion
-nkf5e6b7pl4jfd4a.onion
-4zhkir2ofl7orfom.onion
-t6xj6wilh4ytvcs7.onion
-i6y6ivorwakd7nw3.onion
-ubqj4rsu3nqtxmtp.onion
+thfsmmn2jbitcoin.onion:18333
+it2pj4f7657g3rhi.onion:18333
+nkf5e6b7pl4jfd4a.onion:18333
+4zhkir2ofl7orfom.onion:18333
+t6xj6wilh4ytvcs7.onion:18333
+i6y6ivorwakd7nw3.onion:18333
+ubqj4rsu3nqtxmtp.onion:18333
diff --git a/contrib/shell/git-utils.bash b/contrib/shell/git-utils.bash
new file mode 100644
index 0000000000..37bac1f38d
--- /dev/null
+++ b/contrib/shell/git-utils.bash
@@ -0,0 +1,14 @@
+#!/usr/bin/env bash
+
+git_root() {
+ git rev-parse --show-toplevel 2> /dev/null
+}
+
+git_head_version() {
+ local recent_tag
+ if recent_tag="$(git describe --exact-match HEAD 2> /dev/null)"; then
+ echo "${recent_tag#v}"
+ else
+ git rev-parse --short=12 HEAD
+ fi
+}
diff --git a/contrib/shell/realpath.bash b/contrib/shell/realpath.bash
new file mode 100644
index 0000000000..389b77b562
--- /dev/null
+++ b/contrib/shell/realpath.bash
@@ -0,0 +1,71 @@
+#!/usr/bin/env bash
+
+# Based on realpath.sh written by Michael Kropat
+# Found at: https://github.com/mkropat/sh-realpath/blob/65512368b8155b176b67122aa395ac580d9acc5b/realpath.sh
+
+bash_realpath() {
+ canonicalize_path "$(resolve_symlinks "$1")"
+}
+
+resolve_symlinks() {
+ _resolve_symlinks "$1"
+}
+
+_resolve_symlinks() {
+ _assert_no_path_cycles "$@" || return
+
+ local dir_context path
+ if path=$(readlink -- "$1"); then
+ dir_context=$(dirname -- "$1")
+ _resolve_symlinks "$(_prepend_dir_context_if_necessary "$dir_context" "$path")" "$@"
+ else
+ printf '%s\n' "$1"
+ fi
+}
+
+_prepend_dir_context_if_necessary() {
+ if [ "$1" = . ]; then
+ printf '%s\n' "$2"
+ else
+ _prepend_path_if_relative "$1" "$2"
+ fi
+}
+
+_prepend_path_if_relative() {
+ case "$2" in
+ /* ) printf '%s\n' "$2" ;;
+ * ) printf '%s\n' "$1/$2" ;;
+ esac
+}
+
+_assert_no_path_cycles() {
+ local target path
+
+ target=$1
+ shift
+
+ for path in "$@"; do
+ if [ "$path" = "$target" ]; then
+ return 1
+ fi
+ done
+}
+
+canonicalize_path() {
+ if [ -d "$1" ]; then
+ _canonicalize_dir_path "$1"
+ else
+ _canonicalize_file_path "$1"
+ fi
+}
+
+_canonicalize_dir_path() {
+ (cd "$1" 2>/dev/null && pwd -P)
+}
+
+_canonicalize_file_path() {
+ local dir file
+ dir=$(dirname -- "$1")
+ file=$(basename -- "$1")
+ (cd "$dir" 2>/dev/null && printf '%s/%s\n' "$(pwd -P)" "$file")
+}
diff --git a/depends/Makefile b/depends/Makefile
index 4cd4d72fc2..c5dfd1e8a7 100644
--- a/depends/Makefile
+++ b/depends/Makefile
@@ -2,7 +2,7 @@
# Pattern rule to print variables, e.g. make print-top_srcdir
print-%:
- @echo '$*' = '$($*)'
+ @echo '$*'='$($*)'
# When invoking a sub-make, keep only the command line variable definitions
# matching the pattern in the filter function.
@@ -141,8 +141,8 @@ build_id_string+=system_clang
$(host_arch)_$(host_os)_id_string+=system_clang
endif
-build_id_string+=GUIX_ENVIRONMENT=$(GUIX_ENVIRONMENT)
-$(host_arch)_$(host_os)_id_string+=GUIX_ENVIRONMENT=$(GUIX_ENVIRONMENT)
+build_id_string+=GUIX_ENVIRONMENT=$(realpath $(GUIX_ENVIRONMENT))
+$(host_arch)_$(host_os)_id_string+=GUIX_ENVIRONMENT=$(realpath $(GUIX_ENVIRONMENT))
qrencode_packages_$(NO_QR) = $(qrencode_packages)
diff --git a/depends/README.md b/depends/README.md
index a1d4a99084..6b20791281 100644
--- a/depends/README.md
+++ b/depends/README.md
@@ -12,15 +12,18 @@ For example:
make HOST=x86_64-w64-mingw32 -j4
-**Bitcoin Core's configure script by default will ignore the depends output.** In
+**Bitcoin Core's `configure` script by default will ignore the depends output.** In
order for it to pick up libraries, tools, and settings from the depends build,
-you must point it at the appropriate `--prefix` directory generated by the
-build. In the above example, a prefix dir named x86_64-w64-mingw32 will be
-created. To use it for Bitcoin:
+you must set the `CONFIG_SITE` environment variable to point to a `config.site` settings file.
+In the above example, a file named `depends/x86_64-w64-mingw32/share/config.site` will be
+created. To use it during compilation:
- ./configure --prefix=$PWD/depends/x86_64-w64-mingw32
+ CONFIG_SITE=$PWD/depends/x86_64-w64-mingw32/share/config.site ./configure
-Common `host-platform-triplets` for cross compilation are:
+The default install prefix when using `config.site` is `--prefix=depends/<host-platform-triplet>`,
+so depends build outputs will be installed in that location.
+
+Common `host-platform-triplet`s for cross compilation are:
- `i686-pc-linux-gnu` for Linux 32 bit
- `x86_64-pc-linux-gnu` for x86 Linux
@@ -133,4 +136,3 @@ This is an example command for a default build with no disabled dependencies:
- [description.md](description.md): General description of the depends system
- [packages.md](packages.md): Steps for adding packages
-
diff --git a/depends/funcs.mk b/depends/funcs.mk
index c0159f0e38..6e1a922f89 100644
--- a/depends/funcs.mk
+++ b/depends/funcs.mk
@@ -140,7 +140,13 @@ $(1)_config_env+=CMAKE_MODULE_PATH=$($($(1)_type)_prefix)/lib/cmake
$(1)_config_env+=PATH=$(build_prefix)/bin:$(PATH)
$(1)_build_env+=PATH=$(build_prefix)/bin:$(PATH)
$(1)_stage_env+=PATH=$(build_prefix)/bin:$(PATH)
-$(1)_autoconf=./configure --host=$($($(1)_type)_host) --prefix=$($($(1)_type)_prefix) $$($(1)_config_opts) CC="$$($(1)_cc)" CXX="$$($(1)_cxx)"
+
+# Setting a --build type that differs from --host will explicitly enable
+# cross-compilation mode. Note that --build defaults to the output of
+# config.guess, which is what we set it too here. This also quells autoconf
+# warnings, "If you wanted to set the --build type, don't use --host.",
+# when using versions older than 2.70.
+$(1)_autoconf=./configure --build=$(BUILD) --host=$($($(1)_type)_host) --prefix=$($($(1)_type)_prefix) $$($(1)_config_opts) CC="$$($(1)_cc)" CXX="$$($(1)_cxx)"
ifneq ($($(1)_nm),)
$(1)_autoconf += NM="$$($(1)_nm)"
endif
diff --git a/depends/packages/native_libdmg-hfsplus.mk b/depends/packages/native_libdmg-hfsplus.mk
index 035b767188..c7c8adef41 100644
--- a/depends/packages/native_libdmg-hfsplus.mk
+++ b/depends/packages/native_libdmg-hfsplus.mk
@@ -12,7 +12,7 @@ define $(package)_preprocess_cmds
endef
define $(package)_config_cmds
- $($(package)_cmake) -DCMAKE_C_FLAGS="$$($(1)_cflags) -Wl,--build-id=none" ..
+ $($(package)_cmake) -DCMAKE_C_FLAGS="$$($(1)_cflags) -Wl,--build-id=none" -DCMAKE_SKIP_RPATH="ON" -DCMAKE_EXE_LINKER_FLAGS="-static" -DCMAKE_FIND_LIBRARY_SUFFIXES=".a" ..
endef
define $(package)_build_cmds
diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk
index ee6796e2ad..ae83eae911 100644
--- a/depends/packages/qt.mk
+++ b/depends/packages/qt.mk
@@ -10,7 +10,7 @@ $(package)_patches=fix_qt_pkgconfig.patch mac-qmake.conf fix_no_printer.patch no
$(package)_patches+= fix_android_qmake_conf.patch fix_android_jni_static.patch dont_hardcode_pwd.patch
$(package)_patches+= drop_lrelease_dependency.patch no_sdk_version_check.patch
$(package)_patches+= fix_qpainter_non_determinism.patch fix_lib_paths.patch fix_android_pch.patch
-$(package)_patches+= fix_bigsur_drawing.patch
+$(package)_patches+= fix_bigsur_drawing.patch qtbase-moc-ignore-gcc-macro.patch
$(package)_qttranslations_file_name=qttranslations-$($(package)_suffix)
$(package)_qttranslations_sha256_hash=e1de58ed108b7e0a138815ea60fd46a2c4e1fc31396a707e5630e92de79c53de
@@ -232,6 +232,7 @@ define $(package)_preprocess_cmds
patch -p1 -i $($(package)_patch_dir)/no_sdk_version_check.patch && \
patch -p1 -i $($(package)_patch_dir)/fix_lib_paths.patch && \
patch -p1 -i $($(package)_patch_dir)/fix_bigsur_drawing.patch && \
+ patch -p1 -i $($(package)_patch_dir)/qtbase-moc-ignore-gcc-macro.patch && \
sed -i.old "s|updateqm.commands = \$$$$\$$$$LRELEASE|updateqm.commands = $($(package)_extract_dir)/qttools/bin/lrelease|" qttranslations/translations/translations.pro && \
mkdir -p qtbase/mkspecs/macx-clang-linux &&\
cp -f qtbase/mkspecs/macx-clang/qplatformdefs.h qtbase/mkspecs/macx-clang-linux/ &&\
diff --git a/depends/patches/qt/qtbase-moc-ignore-gcc-macro.patch b/depends/patches/qt/qtbase-moc-ignore-gcc-macro.patch
new file mode 100644
index 0000000000..0358bea6e9
--- /dev/null
+++ b/depends/patches/qt/qtbase-moc-ignore-gcc-macro.patch
@@ -0,0 +1,17 @@
+The moc executable loops through headers on CPLUS_INCLUDE_PATH and stumbles
+on the GCC internal _GLIBCXX_VISIBILITY macro. Tell it to ignore it as it is
+not supposed to be looking there to begin with.
+
+Upstream report: https://bugreports.qt.io/browse/QTBUG-83160
+
+diff --git a/qtbase/src/tools/moc/main.cpp b/qtbase/src/tools/moc/main.cpp
+--- a/qtbase/src/tools/moc/main.cpp
++++ b/qtbase/src/tools/moc/main.cpp
+@@ -188,6 +188,7 @@ int runMoc(int argc, char **argv)
+ dummyVariadicFunctionMacro.arguments += Symbol(0, PP_IDENTIFIER, "__VA_ARGS__");
+ pp.macros["__attribute__"] = dummyVariadicFunctionMacro;
+ pp.macros["__declspec"] = dummyVariadicFunctionMacro;
++ pp.macros["_GLIBCXX_VISIBILITY"] = dummyVariadicFunctionMacro;
+
+ QString filename;
+ QString output;
diff --git a/doc/build-unix.md b/doc/build-unix.md
index d7e0ff705d..0c438db29a 100644
--- a/doc/build-unix.md
+++ b/doc/build-unix.md
@@ -331,7 +331,7 @@ To build executables for ARM:
make HOST=arm-linux-gnueabihf NO_QT=1
cd ..
./autogen.sh
- ./configure --prefix=$PWD/depends/arm-linux-gnueabihf --enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++
+ CONFIG_SITE=$PWD/depends/arm-linux-gnueabihf/share/config.site ./configure --enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++
make
diff --git a/doc/developer-notes.md b/doc/developer-notes.md
index 0a78cdff20..2130332eec 100644
--- a/doc/developer-notes.md
+++ b/doc/developer-notes.md
@@ -812,7 +812,7 @@ class ChainstateManager
{
public:
...
- bool ProcessNewBlock(...) EXCLUSIVE_LOCKS_REQUIRED(!::cs_main);
+ bool ProcessNewBlock(...) LOCKS_EXCLUDED(::cs_main);
...
}
diff --git a/doc/external-signer.md b/doc/external-signer.md
index 2b3b378bee..de44cdd880 100644
--- a/doc/external-signer.md
+++ b/doc/external-signer.md
@@ -46,7 +46,7 @@ Display an address on the device:
```sh
$ bitcoin-cli -rpcwallet=<wallet> getnewaddress
-$ bitcoin-cli -rpcwallet=<wallet> signerdisplayaddress <address>
+$ bitcoin-cli -rpcwallet=<wallet> walletdisplayaddress <address>
```
Replace `<address>` with the result of `getnewaddress`.
@@ -166,6 +166,6 @@ The `createwallet` RPC calls:
It then imports descriptors for all support address types, in a BIP44/49/84 compatible manner.
-The `displayaddress` RPC reuses some code from `getaddressinfo` on the provided address and obtains the inferred descriptor. It then calls `<cmd> --fingerprint=00000000 displayaddress --desc=<descriptor>`.
+The `walletdisplayaddress` RPC reuses some code from `getaddressinfo` on the provided address and obtains the inferred descriptor. It then calls `<cmd> --fingerprint=00000000 displayaddress --desc=<descriptor>`.
`sendtoaddress` and `sendmany` check `inputs->bip32_derivs` to see if any inputs have the same `master_fingerprint` as the signer. If so, it calls `<cmd> --fingerprint=00000000 signtransaction <psbt>`. It waits for the device to return a (partially) signed psbt, tries to finalize it and broadcasts the transaction.
diff --git a/doc/multiprocess.md b/doc/multiprocess.md
index 471d8561f7..7a42fdd734 100644
--- a/doc/multiprocess.md
+++ b/doc/multiprocess.md
@@ -24,7 +24,7 @@ The multiprocess feature requires [Cap'n Proto](https://capnproto.org/) and [lib
```
cd <BITCOIN_SOURCE_DIRECTORY>
make -C depends NO_QT=1 MULTIPROCESS=1
-./configure --prefix=$PWD/depends/x86_64-pc-linux-gnu
+CONFIG_SITE=$PWD/depends/x86_64-pc-linux-gnu/share/config.site ./configure
make
src/bitcoin-node -regtest -printtoconsole -debug=ipc
BITCOIND=bitcoin-node test/functional/test_runner.py
diff --git a/doc/release-notes.md b/doc/release-notes.md
index 334dfa80a4..fced86254a 100644
--- a/doc/release-notes.md
+++ b/doc/release-notes.md
@@ -104,6 +104,10 @@ Updated RPCs
with the `-json` option set, the following fields: `addresses`, `reqSigs` are no longer
returned in the tx output of the response. (#20286)
+- The `listbanned` RPC now returns two new numeric fields: `ban_duration` and `time_remaining`.
+ Respectively, these new fields indicate the duration of a ban and the time remaining until a ban expires,
+ both in seconds. Additionally, the `ban_created` field is repositioned to come before `banned_until`. (#21602)
+
Changes to Wallet or GUI related RPCs can be found in the GUI or Wallet section below.
New RPCs
@@ -126,6 +130,9 @@ Changes to Wallet or GUI related settings can be found in the GUI or Wallet sect
- Passing an invalid `-rpcauth` argument now cause bitcoind to fail to start. (#20461)
+- The `getnodeaddresses` RPC now returns a "network" field indicating the
+ network type (ipv4, ipv6, onion, or i2p) for each address. (#21594)
+
Tools and Utilities
-------------------
diff --git a/doc/translation_process.md b/doc/translation_process.md
index 39f878cea3..785bb0047b 100644
--- a/doc/translation_process.md
+++ b/doc/translation_process.md
@@ -22,8 +22,6 @@ cd src/
make translate
```
-`contrib/bitcoin-qt.pro` takes care of generating `.qm` (binary compiled) files from `.ts` (source files) files. It’s mostly automated, and you shouldn’t need to worry about it.
-
**Example Qt translation**
```cpp
QToolBar *toolbar = addToolBar(tr("Tabs toolbar"));
diff --git a/src/Makefile.am b/src/Makefile.am
index 4e09c86ebd..ddeccd85ea 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -4,7 +4,7 @@
# Pattern rule to print variables, e.g. make print-top_srcdir
print-%:
- @echo '$*' = '$($*)'
+ @echo '$*'='$($*)'
DIST_SUBDIRS = secp256k1 univalue
@@ -144,6 +144,7 @@ BITCOIN_CORE_H = \
core_memusage.h \
cuckoocache.h \
dbwrapper.h \
+ external_signer.h \
flatfile.h \
fs.h \
httprpc.h \
@@ -174,6 +175,7 @@ BITCOIN_CORE_H = \
netaddress.h \
netbase.h \
netmessagemaker.h \
+ node/blockstorage.h \
node/coin.h \
node/coinstats.h \
node/context.h \
@@ -267,13 +269,11 @@ BITCOIN_CORE_H = \
wallet/crypter.h \
wallet/db.h \
wallet/dump.h \
- wallet/external_signer.h \
wallet/external_signer_scriptpubkeyman.h \
wallet/feebumper.h \
wallet/fees.h \
wallet/ismine.h \
wallet/load.h \
- wallet/rpcsigner.h \
wallet/rpcwallet.h \
wallet/salvage.h \
wallet/scriptpubkeyman.h \
@@ -324,6 +324,7 @@ libbitcoin_server_a_SOURCES = \
miner.cpp \
net.cpp \
net_processing.cpp \
+ node/blockstorage.cpp \
node/coin.cpp \
node/coinstats.cpp \
node/context.cpp \
@@ -387,13 +388,11 @@ libbitcoin_wallet_a_SOURCES = \
wallet/db.cpp \
wallet/dump.cpp \
wallet/external_signer_scriptpubkeyman.cpp \
- wallet/external_signer.cpp \
wallet/feebumper.cpp \
wallet/fees.cpp \
wallet/interfaces.cpp \
wallet/load.cpp \
wallet/rpcdump.cpp \
- wallet/rpcsigner.cpp \
wallet/rpcwallet.cpp \
wallet/scriptpubkeyman.cpp \
wallet/wallet.cpp \
@@ -520,6 +519,7 @@ libbitcoin_common_a_SOURCES = \
compressor.cpp \
core_read.cpp \
core_write.cpp \
+ external_signer.cpp \
key.cpp \
key_io.cpp \
merkleblock.cpp \
@@ -532,6 +532,7 @@ libbitcoin_common_a_SOURCES = \
protocol.cpp \
psbt.cpp \
rpc/rawtransaction_util.cpp \
+ rpc/external_signer.cpp \
rpc/util.cpp \
scheduler.cpp \
script/descriptor.cpp \
diff --git a/src/bench/verify_script.cpp b/src/bench/verify_script.cpp
index e3f6b35a7d..39e74b9b2b 100644
--- a/src/bench/verify_script.cpp
+++ b/src/bench/verify_script.cpp
@@ -56,7 +56,7 @@ static void VerifyScriptBench(benchmark::Bench& bench)
txCredit.vout[0].scriptPubKey,
&txSpend.vin[0].scriptWitness,
flags,
- MutableTransactionSignatureChecker(&txSpend, 0, txCredit.vout[0].nValue),
+ MutableTransactionSignatureChecker(&txSpend, 0, txCredit.vout[0].nValue, MissingDataBehavior::ASSERT_FAIL),
&err);
assert(err == SCRIPT_ERR_OK);
assert(success);
diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp
index 80ab69c131..225b8b1ec4 100644
--- a/src/bitcoind.cpp
+++ b/src/bitcoind.cpp
@@ -224,7 +224,7 @@ static bool AppInit(int argc, char* argv[])
// If locking the data directory failed, exit immediately
return false;
}
- fRet = AppInitInterfaces(node) && AppInitMain(context, node);
+ fRet = AppInitInterfaces(node) && AppInitMain(node);
}
catch (const std::exception& e) {
PrintExceptionContinue(&e, "AppInit()");
diff --git a/src/chainparams.cpp b/src/chainparams.cpp
index 28b64ee7ff..45d93ca014 100644
--- a/src/chainparams.cpp
+++ b/src/chainparams.cpp
@@ -78,16 +78,18 @@ public:
consensus.nPowTargetSpacing = 10 * 60;
consensus.fPowAllowMinDifficultyBlocks = false;
consensus.fPowNoRetargeting = false;
- consensus.nRuleChangeActivationThreshold = 1916; // 95% of 2016
+ consensus.nRuleChangeActivationThreshold = 1815; // 90% of 2016
consensus.nMinerConfirmationWindow = 2016; // nPowTargetTimespan / nPowTargetSpacing
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28;
- consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 1199145601; // January 1, 2008
- consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = 1230767999; // December 31, 2008
+ consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = Consensus::BIP9Deployment::NEVER_ACTIVE;
+ consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
+ consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].min_activation_height = 0; // No activation delay
// Deployment of Taproot (BIPs 340-342)
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].bit = 2;
- consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nStartTime = 1199145601; // January 1, 2008
- consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nTimeout = 1230767999; // December 31, 2008
+ consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nStartTime = 1619222400; // April 24th, 2021
+ consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nTimeout = 1628640000; // August 11th, 2021
+ consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].min_activation_height = 709632; // Approximately November 12th, 2021
consensus.nMinimumChainWork = uint256S("0x00000000000000000000000000000000000000001533efd8d716a517fe2c5008");
consensus.defaultAssumeValid = uint256S("0x0000000000000000000b9d2ec5a352ecba0592946514a92f14319dc2b367fc72"); // 654683
@@ -134,7 +136,7 @@ public:
bech32_hrp = "bc";
- vFixedSeeds = std::vector<SeedSpec6>(std::begin(pnSeed6_main), std::end(pnSeed6_main));
+ vFixedSeeds = std::vector<uint8_t>(std::begin(chainparams_seed_main), std::end(chainparams_seed_main));
fDefaultConsistencyChecks = false;
fRequireStandard = true;
@@ -198,13 +200,15 @@ public:
consensus.nRuleChangeActivationThreshold = 1512; // 75% for testchains
consensus.nMinerConfirmationWindow = 2016; // nPowTargetTimespan / nPowTargetSpacing
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28;
- consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 1199145601; // January 1, 2008
- consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = 1230767999; // December 31, 2008
+ consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = Consensus::BIP9Deployment::NEVER_ACTIVE;
+ consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
+ consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].min_activation_height = 0; // No activation delay
// Deployment of Taproot (BIPs 340-342)
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].bit = 2;
- consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nStartTime = 1199145601; // January 1, 2008
- consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nTimeout = 1230767999; // December 31, 2008
+ consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nStartTime = 1619222400; // April 24th, 2021
+ consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nTimeout = 1628640000; // August 11th, 2021
+ consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].min_activation_height = 0; // No activation delay
consensus.nMinimumChainWork = uint256S("0x0000000000000000000000000000000000000000000001db6ec4ac88cf2272c6");
consensus.defaultAssumeValid = uint256S("0x000000000000006433d1efec504c53ca332b64963c425395515b01977bd7b3b0"); // 1864000
@@ -239,7 +243,7 @@ public:
bech32_hrp = "tb";
- vFixedSeeds = std::vector<SeedSpec6>(std::begin(pnSeed6_test), std::end(pnSeed6_test));
+ vFixedSeeds = std::vector<uint8_t>(std::begin(chainparams_seed_test), std::end(chainparams_seed_test));
fDefaultConsistencyChecks = false;
fRequireStandard = false;
@@ -328,18 +332,20 @@ public:
consensus.nPowTargetSpacing = 10 * 60;
consensus.fPowAllowMinDifficultyBlocks = false;
consensus.fPowNoRetargeting = false;
- consensus.nRuleChangeActivationThreshold = 1916; // 95% of 2016
+ consensus.nRuleChangeActivationThreshold = 1815; // 90% of 2016
consensus.nMinerConfirmationWindow = 2016; // nPowTargetTimespan / nPowTargetSpacing
consensus.MinBIP9WarningHeight = 0;
consensus.powLimit = uint256S("00000377ae000000000000000000000000000000000000000000000000000000");
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28;
- consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 1199145601; // January 1, 2008
- consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = 1230767999; // December 31, 2008
+ consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = Consensus::BIP9Deployment::NEVER_ACTIVE;
+ consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
+ consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].min_activation_height = 0; // No activation delay
// Activation of Taproot (BIPs 340-342)
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].bit = 2;
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nStartTime = Consensus::BIP9Deployment::ALWAYS_ACTIVE;
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
+ consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].min_activation_height = 0; // No activation delay
// message start is defined as the first 4 bytes of the sha256d of the block script
CHashWriter h(SER_DISK, 0);
@@ -398,12 +404,16 @@ public:
consensus.fPowNoRetargeting = true;
consensus.nRuleChangeActivationThreshold = 108; // 75% for testchains
consensus.nMinerConfirmationWindow = 144; // Faster than normal for regtest (144 instead of 2016)
+
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28;
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 0;
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
+ consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].min_activation_height = 0; // No activation delay
+
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].bit = 2;
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nStartTime = Consensus::BIP9Deployment::ALWAYS_ACTIVE;
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
+ consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].min_activation_height = 0; // No activation delay
consensus.nMinimumChainWork = uint256{};
consensus.defaultAssumeValid = uint256{};
@@ -441,7 +451,7 @@ public:
m_assumeutxo_data = MapAssumeutxo{
{
110,
- {uint256S("0x76fd7334ac7c1baf57ddc0c626f073a655a35d98a4258cd1382c8cc2b8392e10"), 110},
+ {uint256S("0x1ebbf5850204c0bdb15bf030f47c7fe91d45c44c712697e4509ba67adb01c618"), 110},
},
{
210,
@@ -467,10 +477,11 @@ public:
/**
* Allows modifying the Version Bits regtest parameters.
*/
- void UpdateVersionBitsParameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout)
+ void UpdateVersionBitsParameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout, int min_activation_height)
{
consensus.vDeployments[d].nStartTime = nStartTime;
consensus.vDeployments[d].nTimeout = nTimeout;
+ consensus.vDeployments[d].min_activation_height = min_activation_height;
}
void UpdateActivationParametersFromArgs(const ArgsManager& args);
};
@@ -493,22 +504,26 @@ void CRegTestParams::UpdateActivationParametersFromArgs(const ArgsManager& args)
for (const std::string& strDeployment : args.GetArgs("-vbparams")) {
std::vector<std::string> vDeploymentParams;
boost::split(vDeploymentParams, strDeployment, boost::is_any_of(":"));
- if (vDeploymentParams.size() != 3) {
- throw std::runtime_error("Version bits parameters malformed, expecting deployment:start:end");
+ if (vDeploymentParams.size() < 3 || 4 < vDeploymentParams.size()) {
+ throw std::runtime_error("Version bits parameters malformed, expecting deployment:start:end[:min_activation_height]");
}
int64_t nStartTime, nTimeout;
+ int min_activation_height = 0;
if (!ParseInt64(vDeploymentParams[1], &nStartTime)) {
throw std::runtime_error(strprintf("Invalid nStartTime (%s)", vDeploymentParams[1]));
}
if (!ParseInt64(vDeploymentParams[2], &nTimeout)) {
throw std::runtime_error(strprintf("Invalid nTimeout (%s)", vDeploymentParams[2]));
}
+ if (vDeploymentParams.size() >= 4 && !ParseInt32(vDeploymentParams[3], &min_activation_height)) {
+ throw std::runtime_error(strprintf("Invalid min_activation_height (%s)", vDeploymentParams[3]));
+ }
bool found = false;
for (int j=0; j < (int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++j) {
if (vDeploymentParams[0] == VersionBitsDeploymentInfo[j].name) {
- UpdateVersionBitsParameters(Consensus::DeploymentPos(j), nStartTime, nTimeout);
+ UpdateVersionBitsParameters(Consensus::DeploymentPos(j), nStartTime, nTimeout, min_activation_height);
found = true;
- LogPrintf("Setting version bits activation parameters for %s to start=%ld, timeout=%ld\n", vDeploymentParams[0], nStartTime, nTimeout);
+ LogPrintf("Setting version bits activation parameters for %s to start=%ld, timeout=%ld, min_activation_height=%d\n", vDeploymentParams[0], nStartTime, nTimeout, min_activation_height);
break;
}
}
diff --git a/src/chainparams.h b/src/chainparams.h
index 6b43a44150..6f23199986 100644
--- a/src/chainparams.h
+++ b/src/chainparams.h
@@ -14,11 +14,6 @@
#include <memory>
#include <vector>
-struct SeedSpec6 {
- uint8_t addr[16];
- uint16_t port;
-};
-
typedef std::map<int, uint256> MapCheckpoints;
struct CCheckpointData {
@@ -105,7 +100,7 @@ public:
const std::vector<std::string>& DNSSeeds() const { return vSeeds; }
const std::vector<unsigned char>& Base58Prefix(Base58Type type) const { return base58Prefixes[type]; }
const std::string& Bech32HRP() const { return bech32_hrp; }
- const std::vector<SeedSpec6>& FixedSeeds() const { return vFixedSeeds; }
+ const std::vector<uint8_t>& FixedSeeds() const { return vFixedSeeds; }
const CCheckpointData& Checkpoints() const { return checkpointData; }
//! Get allowed assumeutxo configuration.
@@ -127,7 +122,7 @@ protected:
std::string bech32_hrp;
std::string strNetworkID;
CBlock genesis;
- std::vector<SeedSpec6> vFixedSeeds;
+ std::vector<uint8_t> vFixedSeeds;
bool fDefaultConsistencyChecks;
bool fRequireStandard;
bool m_is_test_chain;
diff --git a/src/chainparamsbase.cpp b/src/chainparamsbase.cpp
index 1631176477..e71b4bc859 100644
--- a/src/chainparamsbase.cpp
+++ b/src/chainparamsbase.cpp
@@ -22,7 +22,7 @@ void SetupChainParamsBaseOptions(ArgsManager& argsman)
"This is intended for regression testing tools and app development. Equivalent to -chain=regtest.", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS);
argsman.AddArg("-segwitheight=<n>", "Set the activation height of segwit. -1 to disable. (regtest-only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
argsman.AddArg("-testnet", "Use the test chain. Equivalent to -chain=test.", ArgsManager::ALLOW_ANY, OptionsCategory::CHAINPARAMS);
- argsman.AddArg("-vbparams=deployment:start:end", "Use given start/end times for specified version bits deployment (regtest-only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS);
+ argsman.AddArg("-vbparams=deployment:start:end[:min_activation_height]", "Use given start/end times and min_activation_height for specified version bits deployment (regtest-only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS);
argsman.AddArg("-signet", "Use the signet chain. Equivalent to -chain=signet. Note that the network is defined by the -signetchallenge parameter", ArgsManager::ALLOW_ANY, OptionsCategory::CHAINPARAMS);
argsman.AddArg("-signetchallenge", "Blocks must satisfy the given script to be considered valid (only for signet networks; defaults to the global default signet test network challenge)", ArgsManager::ALLOW_STRING, OptionsCategory::CHAINPARAMS);
argsman.AddArg("-signetseednode", "Specify a seed node for the signet network, in the hostname[:port] format, e.g. sig.net:1234 (may be used multiple times to specify multiple seed nodes; defaults to the global default signet test network seed node(s))", ArgsManager::ALLOW_STRING, OptionsCategory::CHAINPARAMS);
diff --git a/src/chainparamsseeds.h b/src/chainparamsseeds.h
index 3dfbae33bc..cd7b806621 100644
--- a/src/chainparamsseeds.h
+++ b/src/chainparamsseeds.h
@@ -4,1183 +4,1206 @@
* List of fixed seed nodes for the bitcoin network
* AUTOGENERATED by contrib/seeds/generate-seeds.py
*
- * Each line contains a 16-byte IPv6 address and a port.
- * IPv4 as well as onion addresses are wrapped inside an IPv6 address accordingly.
+ * Each line contains a BIP155 serialized (networkID, addr, port) tuple.
*/
-static SeedSpec6 pnSeed6_main[] = {
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x02,0x27,0xad,0x7e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x03,0x0e,0xa8,0xc9}, 48333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x04,0x24,0x70,0x2c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x08,0x12,0x1f}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x0e,0xc8,0xa7}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x38,0x14,0x02}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x66,0x92,0x63}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x67,0x89,0x92}, 9333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x80,0x57,0x7e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x85,0x41,0x52}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0xbb,0x37,0xf2}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0xbc,0x3e,0x18}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0xbc,0x3e,0x21}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0xc7,0x85,0xc1}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x08,0x26,0x59,0x98}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x0d,0xe7,0x14,0xf9}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x12,0x1b,0x4f,0x11}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x14,0xb8,0x0f,0x74}, 8433},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0x1c,0xcd,0x61}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0x6a,0xfc,0xe6}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0xaf,0x00,0xca}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0xaf,0x00,0xd4}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0xf1,0xfa,0xfc}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0xf5,0x18,0x9a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x56,0xb8,0x42}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x74,0xf6,0x09}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x8d,0x22,0xa6}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x9b,0xc4,0xf6}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x9d,0x82,0xde}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0xbc,0xb0,0xff}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0xed,0x46,0x35}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1b,0x7c,0x04,0x43}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0x11,0x46,0x50}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0x15,0x08,0x20}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0x2d,0x76,0x0a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0x84,0x11,0x38}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0x86,0x79,0xdf}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x20,0xd6,0xb7,0x72}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x23,0x89,0xec,0x20}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x23,0xb9,0x91,0x69}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x23,0xd1,0x33,0xd4}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x23,0xf5,0xaf,0x4c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0x74,0x5f,0x29}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0x8f,0x09,0x6b}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0x8f,0x74,0x2b}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xbf,0xf4,0x95}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xd3,0x4e,0xfd}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xdd,0xd1,0xde}, 24333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xe4,0x5c,0x6e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2b,0xe1,0x3e,0x6b}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2b,0xe1,0x9d,0x98}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x24,0xb8,0x06}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x30,0xa8,0x10}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x55,0x55,0x08}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x55,0x55,0x09}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x81,0xb4,0xd6}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x95,0x4e,0x80}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x97,0x7d,0xda}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x9a,0xff,0x2e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x9b,0x9d,0xef}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x1c,0x84,0x22}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x1c,0xcc,0x15}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x20,0x32,0x62}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x3b,0x0d,0x23}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x80,0x28,0xad}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x80,0x8c,0xc1}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x92,0xf8,0x59}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xa6,0xa2,0x2d}, 20001},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xbc,0x0f,0x06}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xe5,0xa5,0x8e}, 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,0xf9,0x53,0x52}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xfe,0xd9,0xa9}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2f,0x4a,0xbf,0x22}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2f,0x73,0x35,0xa3}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2f,0xbb,0x1a,0x87}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2f,0xde,0x67,0xea}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2f,0xfd,0x05,0x63}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x31,0xe8,0x52,0x4c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x31,0xf7,0xd7,0x2b}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x02,0x0d,0xa6}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x22,0x27,0x48}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x2d,0xe8,0xbd}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x44,0x68,0x5c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x33,0x44,0x24,0x39}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x33,0x9a,0x3c,0x22}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x34,0xa9,0xee,0x42}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xc5,0x1e,0xdf}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xe3,0x42,0x39}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3a,0x9e,0x00,0x56}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3a,0xab,0x87,0xf2}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3a,0xe5,0xd0,0x9e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3c,0xf4,0x6d,0x13}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0x26,0x4b,0xd0}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0x4a,0x8f,0x0b}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0x50,0xe3,0x31}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0x98,0x3a,0x10}, 9421},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0xd2,0xa7,0xc7}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0xea,0xbc,0xa0}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0xfb,0x36,0xa3}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3f,0xe3,0x74,0xa2}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x41,0x13,0x9b,0x52}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x41,0x5f,0x31,0x66}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0x12,0xac,0x15}, 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,0xd2,0xe4,0xcb}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x1e,0xd7,0x2a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x3b,0x12,0xce}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x40,0x21,0x47}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x77,0xc1,0x09}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0xd1,0x17,0x48}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x46,0x7b,0x7d,0xed}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x46,0xb9,0x38,0x88}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0x26,0x5a,0xeb}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0x0c,0x49,0x46}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0x35,0x86,0xb6}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0xe1,0x07,0x50}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0xea,0xb6,0x27}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0xfa,0xb8,0x39}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x49,0x53,0x67,0x4f}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0x76,0x89,0x77}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0x85,0x64,0x4a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0xd7,0xdb,0xd6}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0xdc,0xff,0xbe}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4b,0x9e,0x27,0xe7}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0x35,0x35,0xc4}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0x46,0x10,0xf5}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0x69,0x57,0x61}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0x78,0x71,0x45}, 8433},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0x78,0x7a,0x16}, 8433},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0xa6,0x53,0xa7}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0xf7,0xb2,0x82}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x1b,0x8b,0x0d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x3f,0x1c,0x92}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x53,0x67,0x04}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x8d,0x7b,0x63}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4f,0x4d,0x21,0x83}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4f,0x4d,0x85,0x1e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4f,0x65,0x01,0x19}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4f,0x75,0xc0,0xe5}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4f,0x85,0xe4,0x37}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4f,0x92,0x15,0xa3}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0x59,0xcb,0xac}, 8001},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0x5d,0xd5,0xf6}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0xc0,0x62,0x6e}, 8334},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0xe5,0x1c,0x3c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0xe8,0xf7,0xd2}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0xf2,0x27,0x4c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0xfd,0x5e,0xfc}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0x00,0xc6,0x19}, 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,0x75,0xe1,0xf5}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0x87,0x89,0xe1}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0xab,0x16,0x8f}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0xbf,0xe9,0x86}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0xe8,0x4e,0x4b}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0xf2,0x5b,0x17}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0x1d,0x3a,0x6d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0x88,0x63,0x16}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0x95,0x61,0x19}, 17567},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xa5,0x13,0x30}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xc2,0x99,0xe9}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xc5,0xd7,0x7d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xc7,0x66,0x0a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xc8,0xcd,0x1e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xca,0x44,0xe7}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xdd,0x80,0x1f}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xe4,0x06,0x83}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0x55,0x8b,0x5e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0x63,0xf5,0x14}, 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,0xae,0xd1,0x57}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xd9,0x08,0x1f}, 44420},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0x26,0x03,0xf9}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0x26,0xb9,0x7a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0x5c,0x5c,0xf7}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0xc0,0x10,0xea}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0xc2,0x9e,0x7c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0xd4,0x91,0x18}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0xd4,0xf4,0x5f}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0xd8,0x33,0x24}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0xff,0xf9,0xa3}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0x19,0xff,0x93}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0x46,0x9c,0xd1}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0x91,0x8e,0x2e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0xaa,0xe9,0x5f}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0xb8,0x8a,0x6c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0xbe,0x00,0x05}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0xbf,0xc8,0x33}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0xc0,0xbf,0x06}, 18500},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0xc2,0xee,0x83}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0xc3,0x36,0x6e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0xd6,0xa1,0xfc}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0xd6,0xb9,0x33}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0xf1,0x6a,0xcb}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0xf6,0xa8,0xfc}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x56,0x38,0xee,0xf7}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0x3d,0x5a,0xe6}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0x4f,0x44,0x56}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0x4f,0x5e,0xdd}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0x78,0x08,0x05}, 20008},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0xf6,0x2e,0x84}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0xf7,0x6f,0xde}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0x54,0xde,0xfc}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0x56,0xf3,0xf1}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0x57,0x5d,0x34}, 1691},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0x77,0xc5,0xc8}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0x81,0xfd,0x5e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0x93,0xf4,0xfa}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xd0,0x03,0xc3}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xd4,0x2c,0x21}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xd6,0x39,0x5f}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0x6a,0xc7,0x26}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0x6c,0x7e,0xe4}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0x73,0x78,0x2b}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0x85,0x44,0x41}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0xbe,0x13,0xa2}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0xf8,0xac,0x0a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5a,0x92,0x99,0x15}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5a,0xb6,0xa5,0x12}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x6a,0xbc,0xe5}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xc1,0xed,0x74}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xcc,0x63,0xb2}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xcc,0x95,0x05}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xd6,0x46,0x3f}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xe4,0x98,0xec}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5c,0x0c,0x9a,0x73}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5c,0xf9,0x8f,0x2c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5d,0x0c,0x42,0x62}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5d,0x2e,0x36,0x04}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5d,0x73,0x14,0x82}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5d,0x7b,0xb4,0xa4}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5d,0xbd,0x91,0xa9}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5d,0xf1,0xe4,0x66}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x13,0x07,0x37}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x13,0x80,0xcc}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x34,0x70,0xe3}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x9a,0x60,0x82}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x9c,0xae,0xc9}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x9e,0xf6,0xb7}, 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,0xc7,0xb2,0xe9}, 8100},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xed,0x7d,0x1e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xf7,0x86,0x4d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0x30,0xe4,0x2d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0x45,0xf9,0x3f}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0x52,0x92,0x46}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0x53,0x49,0x1f}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0x54,0xa4,0x2b}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0x57,0xe2,0x38}, 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,0xa3,0x47,0x7e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0xa4,0x41,0xc2}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0xae,0x42,0xd3}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0xd3,0xae,0x89}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0xd8,0x0b,0x9c}, 8433},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x60,0x2f,0x72,0x6c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x61,0x54,0xe8,0x69}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x61,0x63,0xcd,0xf1}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0x19,0xc1,0x72}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x63,0x73,0x19,0x0d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x65,0x20,0x13,0xb8}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x65,0x64,0xae,0xf0}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x66,0x84,0xf5,0x10}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x67,0x0e,0xf4,0xbe}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x67,0x4c,0x30,0x05}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x67,0x54,0x54,0xfa}, 8335},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x67,0x63,0xa8,0x96}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x67,0x6d,0x65,0xd8}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x67,0x7a,0xf7,0x66}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x67,0x81,0x0d,0x2d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x67,0xc6,0xc0,0x0e}, 20008},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x67,0xe0,0x77,0x63}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x67,0xe7,0xbf,0x07}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x67,0xeb,0xe6,0xc4}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0xab,0xf2,0x9b}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0xee,0xdc,0xc7}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6a,0xa3,0x9e,0x7f}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6b,0x96,0x29,0xb3}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6b,0x9f,0x5d,0x67}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0xb7,0x4d,0x0c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0x09,0xaf,0x41}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0x63,0x3f,0x9f}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0x6e,0x51,0x5a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0x7b,0xd5,0x82}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0x86,0xe8,0x51}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xa9,0x14,0xa8}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xc7,0xf1,0x94}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xe5,0xd2,0x06}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xec,0x69,0x28}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xf8,0xce,0x0d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6f,0x2a,0x4a,0x41}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6f,0x5a,0x8c,0xb3}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x70,0xd7,0xcd,0xec}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x71,0x34,0x87,0x7d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x72,0x17,0xf6,0x89}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x73,0x2f,0x8d,0xfa}, 8885},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x73,0x46,0x6e,0x04}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x74,0x22,0xbd,0x37}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x76,0x67,0x7e,0x8c}, 28333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x76,0xbd,0xbb,0xdb}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x77,0x03,0xd0,0xec}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x77,0x08,0x2f,0xe1}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x77,0x11,0x97,0x3d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x78,0x19,0x18,0x1e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x78,0xf1,0x22,0x0a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x79,0x62,0xcd,0x64}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x7a,0x70,0x94,0x99}, 8339},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x7a,0x74,0x2a,0x8c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x7c,0xd9,0xeb,0xb4}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x7d,0xec,0xd7,0x85}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x81,0x0d,0xbd,0xd4}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x82,0xb9,0x4d,0x69}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x83,0xbc,0x28,0xbf}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x83,0xc1,0xdc,0x0f}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x87,0x17,0x7c,0xef}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x88,0x21,0xb9,0x20}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x88,0x38,0xaa,0x60}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x89,0xe2,0x22,0x2e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8a,0xe5,0x1a,0x2a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8b,0x09,0xf9,0xea}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8d,0x65,0x08,0x24}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8f,0xb0,0xe0,0x68}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x90,0x02,0x45,0xe0}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x90,0x22,0xa1,0x41}, 18333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x90,0x5b,0x74,0x2c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x90,0x89,0x1d,0xb5}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x94,0x42,0x32,0x32}, 8335},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x94,0x48,0x96,0xe7}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x94,0xaa,0xd4,0x2c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x95,0xa7,0x63,0xbe}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x9a,0x5c,0x10,0xbf}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x9a,0xdd,0x1b,0x15}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x9c,0x13,0x13,0x5a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x9c,0xf1,0x05,0xbe}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x9d,0x0d,0x3d,0x4c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x9d,0x0d,0x3d,0x50}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x9d,0xe6,0xa6,0x62}, 14391},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x9e,0x4b,0xcb,0x02}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x9e,0xb5,0x7d,0x96}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x9e,0xb5,0xe2,0x21}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x9f,0x64,0xf2,0xfe}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x9f,0x64,0xf8,0xea}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x9f,0x8a,0x57,0x12}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa0,0x10,0x00,0x1e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0x00,0xe3,0x36}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0x00,0xe3,0x38}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0x3e,0x12,0xe2}, 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,0xf3,0xaf,0x56}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xf4,0x50,0xd0}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xfa,0xbc,0x57}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xfa,0xbd,0x35}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa3,0x9e,0xca,0x70}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa3,0x9e,0xf3,0xe6}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa5,0x49,0x3e,0x1f}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa6,0x3e,0x52,0x67}, 32771},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa6,0x46,0x5e,0x6a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa7,0x56,0x5a,0xef}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa9,0x2c,0x22,0xcb}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xac,0x5d,0x65,0x49}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xac,0x69,0x07,0x2f}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0x17,0x67,0x1e}, 8000},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0x35,0x4f,0x06}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0x46,0x0c,0x56}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0x59,0x1c,0x89}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xb0,0xb8,0x36}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xd0,0x80,0x0a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xfe,0xcc,0x45}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xff,0xcc,0x7c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x5e,0x9b,0xe0}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x72,0x66,0x29}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x72,0x7c,0x0c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x0a,0xe3,0x3b}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x1f,0xe0,0xd6}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x4a,0x88,0xed}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x63,0x02,0xcf}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x6a,0xbf,0x02}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0xa0,0xe4,0x09}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0xbf,0xb6,0x03}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0xd4,0xb9,0x99}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0xf1,0x89,0xb7}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb1,0x26,0xd7,0x49}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x10,0xde,0x92}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x84,0x02,0xf6}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x8f,0xbf,0xab}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x94,0xac,0xd1}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x94,0xe2,0xb4}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x96,0x60,0x2e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xb6,0xe3,0x32}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xec,0x89,0x3f}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xff,0x2a,0x7e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb4,0x96,0x34,0x25}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb5,0x27,0x20,0x63}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb5,0x30,0x4d,0x1a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb5,0x34,0xdf,0x34}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb5,0xee,0x33,0x98}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb7,0x58,0xdf,0xd0}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb7,0x6e,0xdc,0xd2}, 30301},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb8,0x5f,0x3a,0xa6}, 8336},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb8,0xa4,0x93,0x52}, 41333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb8,0xab,0xd0,0x6d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x19,0x30,0x27}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x19,0x30,0xb8}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x40,0x74,0x0f}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x50,0xdb,0x84}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x55,0x03,0x8c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x5f,0xdb,0x35}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x6c,0xf4,0x29}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x86,0xe9,0x79}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x91,0x80,0x15}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x94,0x03,0xe3}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x99,0xc4,0xf0}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x9e,0x72,0xb8}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0xa5,0xa8,0xc4}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0xb5,0xe6,0x4a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0xb9,0x1a,0x8d}, 8111},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0xba,0xd0,0xa2}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0xbd,0x84,0xb2}, 57780},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0xd3,0x3b,0x32}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0xe9,0x94,0x92}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0xee,0x81,0x71}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0xf9,0xc7,0x6a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0xfb,0xa1,0x36}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbb,0xbd,0x99,0x88}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x25,0x18,0xbe}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x2a,0x28,0xea}, 18333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x3d,0x2e,0x24}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x44,0x2d,0x8f}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x7f,0xe5,0x69}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x86,0x06,0x54}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x86,0x08,0x24}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0xd6,0x81,0x41}, 20012},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0xe6,0xa8,0x72}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbd,0x22,0x0e,0x5d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbd,0xcf,0x2e,0x20}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbe,0xd3,0xcc,0x44}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbf,0xd1,0x15,0xbc}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x03,0x0b,0x14}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x03,0xb9,0xd2}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x41,0xaa,0x0f}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x41,0xaa,0x32}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x92,0x89,0x12}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x9d,0xca,0xb2}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0xe3,0x50,0x53}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0x0a,0xcb,0x17}, 8334},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0x19,0x06,0xce}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0x2a,0x6e,0x1e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0x3a,0xc4,0xd4}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0x6a,0x1c,0x08}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0xbd,0xbe,0x7b}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0xc2,0xa3,0x23}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0xc2,0xa3,0x35}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc2,0x0e,0xf6,0xcd}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc2,0x24,0x5b,0xfd}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc2,0x7e,0x71,0x87}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc2,0x87,0x87,0x45}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0x38,0x3f,0x04}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0x38,0x3f,0x05}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0x43,0x8b,0x36}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0x87,0xc2,0x08}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0xca,0xa9,0x95}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0xce,0x69,0x2a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0xd1,0xf9,0xa4}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x01,0xe7,0x06}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0xc8,0x2b,0xd7}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc7,0xb6,0xb8,0xcc}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc7,0xf7,0x07,0xd0}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc7,0xf7,0xf9,0xbc}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc8,0x07,0xfc,0x76}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc8,0x14,0xba,0xfe}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc8,0x53,0xa6,0x88}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xca,0x37,0x57,0x2d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xca,0x4f,0xa7,0x41}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xca,0x6c,0xd3,0x87}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xca,0xa9,0x66,0x49}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcb,0x82,0x30,0x75}, 8885},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcb,0x84,0x5f,0x0a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcb,0x97,0xa6,0x7b}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcc,0x5d,0x71,0x6c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcc,0x6f,0xf1,0xc3}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xce,0x7c,0x95,0x42}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcf,0x73,0x66,0x62}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcf,0xe5,0x2e,0x96}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd0,0x4c,0xfc,0xc6}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd0,0x64,0x0d,0x38}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd0,0x64,0xb2,0xaf}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd0,0x6e,0x63,0x69}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0x06,0xd2,0xb3}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0x85,0xdc,0x4a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0x8d,0x39,0x39}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd3,0x1b,0x93,0x43}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0x22,0xe1,0x76}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0x59,0xad,0xd8}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0x63,0xe2,0x24}, 9020},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0xed,0x60,0x62}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0x59,0x83,0x35}, 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,0x86,0xa5,0x37}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0x92,0xfb,0x08}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0xbd,0xbe,0x5f}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0xe2,0x80,0xbd}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0xec,0xa4,0x52}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x13,0xd8,0xd2}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x1a,0x20,0x0a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x40,0x2f,0x8a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x40,0x85,0xdc}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x5c,0x37,0xf6}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xda,0x1f,0x71,0xf5}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xda,0xff,0xf2,0x72}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xdc,0x85,0x27,0x3d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xdf,0x10,0x1e,0xaf}, 8333},
- {{0x20,0x01,0x19,0xf0,0x60,0x01,0x30,0x6f,0x0e,0xc4,0x7a,0xff,0xfe,0x8f,0x66,0xec}, 8333},
- {{0x20,0x01,0x1b,0xc0,0x00,0xcc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x01}, 8333},
- {{0x20,0x01,0x1c,0x02,0x2f,0x18,0x0d,0x00,0xb6,0x2e,0x99,0xff,0xfe,0x49,0xd4,0x92}, 8333},
- {{0x20,0x01,0x41,0x00,0x00,0x00,0x00,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x93}, 8333},
- {{0x20,0x01,0x41,0x00,0x00,0x00,0x00,0x64,0xdc,0xaf,0xaf,0xff,0xfe,0x00,0x67,0x07}, 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,0x4b,0xa0,0xff,0xfa,0x00,0x5d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x93}, 8333},
- {{0x20,0x01,0x06,0x10,0x19,0x08,0xff,0x01,0xf8,0x16,0x3e,0xff,0xfe,0x33,0x2e,0x32}, 8333},
- {{0x20,0x01,0x06,0x38,0xa0,0x00,0x41,0x40,0x00,0x00,0x00,0x00,0xff,0xff,0x01,0x91}, 8333},
- {{0x20,0x01,0x06,0x48,0x28,0x00,0x01,0x31,0x4b,0x1f,0xf6,0xfc,0x20,0xf7,0xf9,0x9f}, 8333},
- {{0x20,0x01,0x06,0x78,0x07,0xdc,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
- {{0x20,0x01,0x06,0x78,0x0c,0xc8,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x10,0x00,0x88}, 20008},
- {{0x20,0x01,0x06,0x7c,0x12,0x20,0x08,0x0c,0x00,0x00,0x00,0x00,0x93,0xe5,0x0d,0xd2}, 8333},
- {{0x20,0x01,0x06,0x7c,0x12,0x20,0x08,0x0c,0xe5,0xdc,0xad,0x0c,0x92,0x89,0xc2,0x8f}, 8333},
- {{0x20,0x01,0x06,0x7c,0x16,0xdc,0x12,0x01,0x50,0x54,0x00,0xff,0xfe,0x17,0x4d,0xac}, 8333},
- {{0x20,0x01,0x06,0x7c,0x23,0x54,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x22}, 8333},
- {{0x20,0x01,0x06,0x7c,0x26,0xb4,0x00,0x12,0x7a,0xe3,0xb5,0xff,0xfe,0x04,0x6f,0x9c}, 8333},
- {{0x20,0x01,0x06,0x7c,0x02,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0xfa}, 8333},
- {{0x20,0x01,0x07,0x18,0x08,0x01,0x03,0x11,0x50,0x54,0x00,0xff,0xfe,0x19,0xc4,0x83}, 8333},
- {{0x20,0x01,0x08,0xd8,0x08,0x7c,0x7c,0x00,0x00,0x00,0x00,0x00,0x00,0x99,0x03,0xc1}, 8333},
- {{0x20,0x01,0x08,0xf1,0x14,0x04,0x37,0x00,0x8e,0x49,0x71,0x5a,0x2e,0x09,0xb6,0x34}, 9444},
- {{0x20,0x01,0x0b,0x07,0x5d,0x29,0x99,0xa5,0x19,0x4b,0x38,0x74,0xd6,0x5e,0xa9,0x0d}, 8333},
- {{0x20,0x01,0x0b,0xa8,0x01,0xf1,0xf0,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
- {{0x20,0x01,0x0b,0xc8,0x12,0x00,0x00,0x00,0xda,0xc4,0x97,0xff,0xfe,0x2a,0x35,0x54}, 20008},
- {{0x20,0x01,0x0d,0xa8,0x10,0x0d,0x00,0x22,0x10,0xfa,0xd8,0x5f,0x10,0xf2,0x21,0xfd}, 8333},
- {{0x20,0x01,0x0d,0xa8,0x80,0x01,0x7a,0x39,0xf0,0x35,0x00,0x7d,0xb9,0x9f,0xeb,0x79}, 8333},
- {{0x20,0x01,0x0e,0x42,0x01,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30}, 8333},
- {{0x24,0x00,0x24,0x12,0x01,0x03,0xc9,0x00,0x08,0x25,0x8f,0x20,0xea,0xff,0x65,0xc2}, 8333},
- {{0x24,0x00,0x40,0x52,0x0e,0x20,0x4f,0x00,0x69,0xfe,0xbb,0x33,0x7b,0x1c,0xa1,0xca}, 8333},
- {{0x24,0x01,0x18,0x00,0x78,0x00,0x01,0x05,0xbe,0x76,0x4e,0xff,0xfe,0x1c,0x0b,0x35}, 8333},
- {{0x24,0x01,0x39,0x00,0x00,0x02,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
- {{0x24,0x01,0xb1,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x01,0x50}, 8333},
- {{0x24,0x01,0xd0,0x02,0x44,0x02,0x00,0x00,0x8f,0x28,0x59,0x1a,0x6e,0xa0,0xc6,0x83}, 8333},
- {{0x24,0x03,0x62,0x00,0x88,0x21,0x3d,0x68,0x19,0x5b,0x87,0xe9,0x68,0x19,0xd5,0xc8}, 8333},
- {{0x24,0x05,0x65,0x80,0x21,0x40,0x3a,0x00,0xc2,0x8c,0x09,0x83,0x36,0x4b,0x5d,0x70}, 8333},
- {{0x24,0x05,0x98,0x00,0xb9,0x11,0xa1,0x8a,0x58,0xeb,0xcd,0x3c,0x9d,0x82,0xea,0x4a}, 8333},
- {{0x24,0x05,0xaa,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40}, 8333},
- {{0x24,0x09,0x00,0x10,0xca,0x20,0x1d,0xf0,0x02,0x24,0xe8,0xff,0xfe,0x1f,0x60,0xd9}, 8333},
- {{0x24,0x09,0x8a,0x1e,0xa9,0xaf,0x36,0x60,0x1c,0x5a,0x5b,0x6b,0x8a,0x2d,0x98,0x48}, 8333},
- {{0x24,0x09,0x8a,0x1e,0xa9,0xaf,0x36,0x60,0x04,0x04,0x39,0xba,0x88,0xf2,0xe8,0xdf}, 8333},
- {{0x24,0x0b,0x00,0x10,0x91,0x41,0x04,0x00,0x49,0xb4,0x3a,0x2e,0x01,0xe5,0x08,0x4c}, 8333},
- {{0x24,0x0d,0x00,0x1a,0x07,0x59,0x60,0x00,0xa7,0xb1,0x45,0x1a,0x88,0x74,0xe1,0xac}, 8333},
- {{0x24,0x0d,0x00,0x1a,0x07,0x59,0x60,0x00,0xdd,0xab,0x31,0x41,0x4d,0xa0,0x88,0x78}, 8333},
- {{0x26,0x00,0x88,0x05,0x24,0x00,0x01,0x4e,0x12,0xdd,0xb1,0xff,0xfe,0xf2,0x30,0x13}, 8333},
- {{0x26,0x01,0x06,0x02,0x8d,0x80,0x0b,0x63,0xdc,0x3e,0x24,0xff,0xfe,0x92,0x05,0xeb}, 8333},
- {{0x26,0x02,0xff,0xb6,0x00,0x04,0x27,0x98,0xf8,0x16,0x3e,0xff,0xfe,0x2f,0x54,0x41}, 8333},
- {{0x26,0x02,0xff,0xb6,0x00,0x04,0x73,0x9e,0xf8,0x16,0x3e,0xff,0xfe,0x00,0xc2,0xb3}, 8333},
- {{0x26,0x02,0xff,0xb8,0x00,0x00,0x00,0x00,0x02,0x08,0x00,0x72,0x00,0x57,0x02,0x00}, 8333},
- {{0x26,0x04,0x13,0x80,0x41,0x11,0x93,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333},
- {{0x26,0x04,0x43,0x00,0x00,0x0a,0x00,0x2e,0x02,0x1b,0x21,0xff,0xfe,0x11,0x03,0x92}, 8333},
- {{0x26,0x04,0x45,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2e,0x06}, 8112},
- {{0x26,0x04,0x55,0x00,0x70,0x6a,0x40,0x00,0xfc,0x79,0xb9,0xbb,0x01,0xd7,0xc3,0x25}, 8333},
- {{0x26,0x04,0x55,0x00,0xc1,0x34,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xfc}, 32797},
- {{0x26,0x04,0x68,0x00,0x5e,0x11,0x01,0x62,0x5c,0x8f,0xd2,0xff,0xfe,0x26,0x14,0x6f}, 8333},
- {{0x26,0x05,0x4d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x50}, 8333},
- {{0x26,0x05,0x64,0x00,0x00,0x20,0x13,0xbf,0xdf,0x1d,0x18,0x1c,0x83,0xbb,0x22,0xe8}, 8333},
- {{0x26,0x05,0xae,0x00,0x02,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x03}, 8333},
- {{0x26,0x05,0xc0,0x00,0x2a,0x0a,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02}, 8333},
- {{0x26,0x07,0xf2,0xc0,0xf0,0x0e,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x54}, 8333},
- {{0x26,0x07,0xf2,0xf8,0xad,0x40,0x0b,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333},
- {{0x26,0x07,0xf4,0x70,0x00,0x08,0x10,0x48,0xae,0x1f,0x6b,0xff,0xfe,0x70,0x72,0x40}, 8333},
- {{0x26,0x07,0xff,0x28,0x80,0x0f,0x00,0x97,0x02,0x25,0x90,0xff,0xfe,0x75,0x11,0x10}, 8333},
- {{0x26,0x20,0x01,0x1c,0x50,0x01,0x11,0x18,0xd2,0x67,0xe5,0xff,0xfe,0xe9,0xe6,0x73}, 8333},
- {{0x26,0x20,0x00,0x6e,0xa0,0x00,0x20,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06}, 8333},
- {{0x28,0x04,0x01,0x4d,0x4c,0x93,0x98,0x09,0x97,0x69,0xda,0x80,0x18,0x32,0x34,0x80}, 8333},
- {{0x2a,0x00,0x13,0x28,0xe1,0x01,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x63}, 8333},
- {{0x2a,0x00,0x13,0x98,0x00,0x04,0x2a,0x03,0x02,0x15,0x5d,0xff,0xfe,0xd6,0x10,0x33}, 8333},
- {{0x2a,0x00,0x13,0xa0,0x30,0x15,0x00,0x01,0x00,0x85,0x00,0x14,0x00,0x79,0x00,0x26}, 8333},
- {{0x2a,0x00,0x16,0x30,0x00,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01}, 8333},
- {{0x2a,0x00,0x17,0x68,0x20,0x01,0x00,0x27,0x00,0x00,0x00,0x00,0x00,0x00,0xef,0x6a}, 8333},
- {{0x2a,0x00,0x18,0x28,0xa0,0x04,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x66}, 8333},
- {{0x2a,0x00,0x18,0x38,0x00,0x36,0x00,0x17,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0xcb}, 8333},
- {{0x2a,0x00,0x18,0x38,0x00,0x36,0x00,0x7d,0x00,0x00,0x00,0x00,0x00,0x00,0xd3,0xc6}, 8333},
- {{0x2a,0x00,0x1c,0x10,0x00,0x02,0x07,0x09,0x58,0xf7,0xe0,0xff,0xfe,0x24,0xa0,0xba}, 22220},
- {{0x2a,0x00,0x1c,0x10,0x00,0x02,0x07,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x17}, 22220},
- {{0x2a,0x00,0x1f,0x40,0x50,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x31}, 8333},
- {{0x2a,0x00,0x60,0x20,0x13,0x95,0x14,0x00,0xba,0xf7,0x2d,0x43,0x60,0xb3,0x19,0x8b}, 8333},
- {{0x2a,0x00,0x7c,0x80,0x00,0x00,0x01,0x0b,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xaf}, 8333},
- {{0x2a,0x00,0x8a,0x60,0xe0,0x12,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x21}, 8333},
- {{0x2a,0x00,0xab,0x00,0x06,0x03,0x00,0x84,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03}, 8333},
- {{0x2a,0x00,0xbb,0xe0,0x00,0xcc,0x00,0x00,0x62,0xa4,0x4c,0xff,0xfe,0x23,0x75,0x10}, 8333},
- {{0x2a,0x00,0x0c,0xa8,0x0a,0x1f,0x30,0x25,0xf9,0x49,0xe4,0x42,0xc9,0x40,0x13,0xe8}, 8333},
- {{0x2a,0x00,0xd2,0xa0,0x00,0x0a,0x3d,0x00,0x1c,0xdf,0x38,0xbb,0xa7,0xd6,0xc2,0x51}, 8333},
- {{0x2a,0x00,0xd8,0x80,0x00,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x0e}, 8333},
- {{0x2a,0x00,0x0e,0xc0,0x72,0x07,0x91,0x00,0x5f,0x8f,0x25,0xdd,0x25,0x74,0x39,0x82}, 8333},
- {{0x2a,0x00,0xf8,0x20,0x04,0x33,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x36}, 8333},
- {{0x2a,0x01,0x01,0x38,0xa0,0x17,0xb0,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x42}, 8333},
- {{0x2a,0x01,0x04,0x30,0x00,0x17,0x00,0x01,0x00,0x00,0x00,0x00,0xff,0xff,0x11,0x53}, 8333},
- {{0x2a,0x01,0x04,0x90,0x00,0x16,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
- {{0x2a,0x01,0x4b,0x00,0x80,0x7c,0x1b,0x00,0xcd,0xa1,0x0c,0x6a,0x2b,0xad,0x24,0x18}, 8333},
- {{0x2a,0x01,0x4b,0x00,0x80,0xe7,0x54,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333},
- {{0x2a,0x01,0x04,0xf8,0x01,0x92,0x42,0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8433},
- {{0x2a,0x01,0x07,0xa0,0x00,0x02,0x13,0x7c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03}, 8333},
- {{0x2a,0x01,0x07,0xa7,0x00,0x02,0x14,0x67,0x0e,0xc4,0x7a,0xff,0xfe,0xe2,0x56,0x90}, 8333},
- {{0x2a,0x01,0x07,0xc8,0xd0,0x02,0x01,0x0f,0x50,0x54,0x00,0xff,0xfe,0x5c,0xda,0xc7}, 8333},
- {{0x2a,0x01,0x07,0xc8,0xd0,0x02,0x03,0x18,0x50,0x54,0x00,0xff,0xfe,0xbe,0xcb,0xb1}, 8333},
- {{0x2a,0x01,0x87,0x40,0x00,0x01,0xff,0xc5,0x00,0x00,0x00,0x00,0x00,0x00,0x8c,0x6a}, 8333},
- {{0x2a,0x01,0xcb,0x00,0x0f,0x98,0xca,0x00,0x50,0x54,0x00,0xff,0xfe,0xd4,0x76,0x3d}, 8333},
- {{0x2a,0x01,0xcb,0x14,0x0c,0xf6,0xbc,0x00,0x21,0xe5,0xf1,0x2e,0x32,0xc8,0x01,0x45}, 8333},
- {{0x2a,0x01,0x00,0xd0,0x00,0x00,0x00,0x1c,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x45}, 8333},
- {{0x2a,0x01,0x00,0xd0,0xbe,0xf2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x12}, 8333},
- {{0x2a,0x01,0x0e,0x35,0x2e,0x40,0x68,0x30,0x02,0x11,0x32,0xff,0xfe,0xa6,0xde,0x3d}, 8333},
- {{0x2a,0x02,0x12,0x05,0xc6,0xaa,0x60,0xc0,0x70,0xd8,0xaa,0xee,0xa8,0x2d,0x99,0x3c}, 8333},
- {{0x2a,0x02,0x01,0x69,0x05,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x14}, 8333},
- {{0x2a,0x02,0x01,0x80,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x5b,0x8f,0x53,0x8c}, 8333},
- {{0x2a,0x02,0x03,0x48,0x00,0x62,0x5e,0xf7,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333},
- {{0x2a,0x02,0x03,0x90,0x90,0x00,0x00,0x00,0x02,0x18,0x7d,0xff,0xfe,0x10,0xbe,0x33}, 8333},
- {{0x2a,0x02,0x7a,0xa0,0x16,0x19,0x00,0x00,0x00,0x00,0x00,0x00,0x0a,0xdc,0x8d,0xe0}, 8333},
- {{0x2a,0x02,0x7b,0x40,0xb0,0xdf,0x89,0x25,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333},
- {{0x2a,0x02,0x7b,0x40,0xb9,0x05,0x37,0xdb,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333},
- {{0x2a,0x02,0x81,0x0d,0x8c,0xbf,0xf3,0xa8,0x96,0xc6,0x91,0xff,0xfe,0x17,0xae,0x1d}, 8333},
- {{0x2a,0x02,0x83,0x89,0x01,0xc0,0x96,0x80,0x02,0x01,0x2e,0xff,0xfe,0x82,0xb3,0xcc}, 8333},
- {{0x2a,0x02,0xa4,0x54,0xa5,0x16,0x00,0x01,0x05,0x17,0x09,0x28,0x7e,0x0d,0x95,0x7c}, 8333},
- {{0x2a,0x02,0x0a,0xf8,0xfa,0xb0,0x08,0x04,0x01,0x51,0x02,0x36,0x00,0x34,0x01,0x61}, 8333},
- {{0x2a,0x02,0x0a,0xf8,0xfa,0xb0,0x08,0x08,0x00,0x85,0x02,0x34,0x01,0x45,0x01,0x32}, 8333},
- {{0x2a,0x02,0x0e,0x00,0xff,0xf0,0x01,0xe2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0a}, 8333},
- {{0x2a,0x03,0x22,0x60,0x30,0x06,0x00,0x0d,0xd3,0x07,0x5d,0x1d,0x32,0xca,0x1f,0xe8}, 8333},
- {{0x2a,0x03,0x60,0x00,0x08,0x70,0x00,0x00,0x00,0x46,0x00,0x23,0x00,0x87,0x02,0x18}, 8333},
- {{0x2a,0x03,0x9d,0xa0,0x00,0xf6,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
- {{0x2a,0x03,0xc9,0x80,0x00,0xdb,0x00,0x47,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333},
- {{0x2a,0x03,0xe2,0xc0,0x01,0xce,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
- {{0x2a,0x04,0x35,0x44,0x10,0x00,0x15,0x10,0x70,0x6c,0xab,0xff,0xfe,0x6c,0x50,0x1c}, 8333},
- {{0x2a,0x04,0x52,0xc0,0x01,0x01,0x03,0x83,0x00,0x00,0x00,0x00,0x00,0x00,0x2a,0x87}, 8333},
- {{0x2a,0x04,0x52,0xc0,0x01,0x01,0x03,0xfb,0x00,0x00,0x00,0x00,0x00,0x00,0x4c,0x27}, 8333},
- {{0x2a,0x04,0xee,0x41,0x00,0x83,0x50,0xdf,0xd9,0x08,0xf7,0x1d,0x2a,0x86,0xb3,0x37}, 8333},
- {{0x2a,0x05,0x6d,0x40,0xb9,0x4e,0xd1,0x00,0x02,0x25,0x90,0xff,0xfe,0x0d,0xcf,0xc2}, 8333},
- {{0x2a,0x05,0xe5,0xc0,0x00,0x00,0x01,0x00,0x02,0x50,0x56,0xff,0xfe,0xb9,0xd6,0xcb}, 8333},
- {{0x2a,0x05,0xfc,0x87,0x00,0x01,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
- {{0x2a,0x05,0xfc,0x87,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08}, 8333},
- {{0x2a,0x07,0x57,0x41,0x00,0x00,0x11,0x5d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333},
- {{0x2a,0x07,0xa8,0x80,0x46,0x01,0x10,0x62,0xb4,0xb4,0xbd,0x2a,0x39,0xd4,0x7a,0xcf}, 51401},
- {{0x2a,0x07,0xab,0xc4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x09,0x46}, 8333},
- {{0x2a,0x07,0xb4,0x00,0x00,0x01,0x03,0x4c,0x00,0x00,0x00,0x00,0x00,0x02,0x10,0x02}, 8333},
- {{0x2a,0x0a,0x8c,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb4}, 8333},
- {{0x2a,0x0a,0xc8,0x01,0x00,0x01,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x83}, 8333},
- {{0x2a,0x0b,0xae,0x40,0x00,0x03,0x4a,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x15}, 8333},
- {{0x2a,0x0f,0xdf,0x00,0x00,0x00,0x02,0x54,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x46}, 8333},
- {{0x2c,0x0f,0xf5,0x98,0x00,0x05,0x00,0x01,0x10,0x01,0x00,0x00,0x00,0x00,0x00,0x01}, 8333},
- {{0x2c,0x0f,0xfc,0xe8,0x00,0x00,0x04,0x00,0x0b,0x7c,0x00,0x00,0x00,0x00,0x00,0x01}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xd6,0xbc,0x4a,0x3c,0x6d,0x03,0xa9,0x4e,0x1f,0x55}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xd6,0x8f,0xf0,0xf8,0xbb,0x10,0x00,0x18,0x42,0x54}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xd6,0xec,0x32,0xc1,0x59,0x9c,0xd8,0x46,0xd5,0x48}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xd6,0xf0,0x8d,0x96,0x37,0xc3,0x27,0x61,0x9a,0x24}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xd0,0x12,0xe6,0xed,0x8e,0xc1,0x78,0x8d,0x1c,0x21}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xd0,0x4a,0xc5,0xbd,0x5d,0xe9,0xca,0x57,0xaf,0xc4}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xd0,0x94,0xc0,0x97,0xd2,0x32,0xed,0x81,0x92,0x67}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xd1,0xd5,0x49,0x23,0xa6,0x10,0x01,0x49,0xda,0x05}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xd2,0x2a,0x76,0x2c,0x37,0x09,0x9a,0xa1,0x61,0x4b}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xd3,0x19,0x77,0x50,0xf5,0xf3,0x48,0x17,0x59,0x50}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xd4,0x24,0xda,0xf8,0x97,0x6d,0x28,0x80,0x47,0xf9}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xd4,0x28,0x30,0x9d,0x6d,0xac,0x1e,0xb4,0x6e,0x59}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xd5,0x13,0x71,0x95,0xd5,0x2e,0x12,0xf6,0x0e,0x6e}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xd5,0xc6,0x62,0x50,0xb1,0x22,0xb6,0x4a,0x31,0x56}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xd5,0xc7,0x99,0x46,0x87,0x91,0x13,0xc9,0xc9,0x16}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xdf,0x22,0x06,0xea,0xce,0x87,0x08,0x09,0x32,0x52}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xdf,0xa1,0xf5,0x1c,0xe4,0x4e,0x97,0x71,0xee,0xc5}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xdf,0xf7,0x64,0x8e,0x4f,0xa3,0xbb,0xaa,0x4f,0x30}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xdf,0xfc,0xa5,0x92,0x7d,0xbc,0x03,0x13,0x69,0x35}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xdf,0xd5,0x61,0xfc,0xb7,0x73,0xff,0xef,0x2f,0xaa}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xd9,0x3b,0x3f,0x9e,0x1c,0x02,0xe7,0xd9,0xba,0xb7}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xd9,0x83,0x73,0x90,0x25,0x3b,0xa9,0x4b,0x18,0x5b}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xd9,0xcc,0x14,0xe4,0x9a,0x68,0x6d,0x8a,0x12,0xc5}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xda,0x29,0x4a,0xc4,0x7a,0xb0,0x0e,0x0d,0x0a,0xee}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xda,0x67,0x7a,0x24,0x60,0x45,0x8f,0xe4,0x2e,0x74}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xda,0xfa,0x48,0x68,0x74,0xfb,0x2b,0x21,0x27,0x80}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xdb,0x5c,0x56,0x99,0xb0,0x5c,0x08,0x43,0xb7,0xee}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xdc,0x79,0xc1,0x8f,0x29,0x44,0xf2,0xdc,0x00,0xf6}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xdd,0x66,0x1a,0x59,0x93,0x73,0x7f,0x58,0x76,0x19}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xe7,0x9c,0x7c,0xce,0x79,0xe3,0xc8,0xa4,0x73,0x66}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xe7,0xca,0xbd,0xa2,0xab,0xe5,0x7b,0xe4,0xca,0x71}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xe7,0xd1,0xe8,0x45,0x7a,0x42,0x60,0x2b,0x2c,0xde}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xe7,0xe9,0x47,0x9b,0x22,0x6c,0x6c,0x03,0xba,0x6e}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xe0,0xba,0x25,0x23,0x7f,0x25,0x5c,0x51,0xcb,0xc3}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xe1,0x21,0xbf,0x26,0x37,0xfd,0xe9,0x89,0x95,0xe2}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xe1,0x2c,0xa1,0xde,0xa2,0x37,0x7e,0x01,0xc5,0xa8}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xe1,0x57,0x53,0x20,0x2d,0x66,0x9a,0xb1,0xed,0xa0}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xe2,0x00,0xe6,0xcf,0x0c,0xe7,0xd0,0xc0,0x58,0x9c}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xe2,0x6f,0x9d,0xfd,0xce,0xa7,0x40,0x6f,0xfb,0x62}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xe3,0x1a,0xaa,0xa7,0xc7,0x07,0xf6,0x48,0x34,0x2a}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xe3,0x5b,0x4c,0x5d,0x9d,0x57,0x66,0xbc,0x26,0x1b}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xe3,0x73,0xac,0x1b,0x82,0x6b,0xa6,0x4d,0x91,0x3f}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xe3,0xdd,0x9b,0x1f,0xdd,0xf7,0x30,0x6c,0x8c,0x6a}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xe4,0x0c,0x50,0xf7,0xd1,0xab,0xc2,0xc2,0x4a,0xff}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xe4,0x64,0x0b,0xeb,0x73,0x04,0x33,0x66,0x21,0x89}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xe5,0x3a,0x9e,0x83,0x1e,0x88,0x24,0xeb,0x4f,0x8c}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xe5,0x5d,0x1a,0xcd,0xd8,0x21,0x8f,0xcc,0x86,0xb1}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xee,0xa5,0xc4,0xf5,0xeb,0x1d,0x96,0xfc,0x9e,0x76}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xe8,0x02,0xf4,0x22,0x05,0xa9,0x14,0xe2,0x26,0x2e}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xe8,0x30,0x3c,0xde,0xfe,0x4e,0x1d,0x9d,0xb4,0x99}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xe8,0xaf,0x91,0xca,0x33,0x72,0xba,0x33,0x3b,0x80}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xe9,0x07,0x44,0x29,0xf4,0x1a,0x09,0xb4,0xe2,0x25}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xe9,0x1e,0x40,0x15,0x4c,0xc0,0x38,0x5a,0xf4,0x7d}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xe9,0x71,0x75,0xe6,0x68,0x16,0xe7,0xe6,0xba,0x79}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xe9,0xc7,0xe2,0x60,0x96,0xee,0x02,0xd8,0x78,0xc1}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xea,0x70,0x5c,0x9e,0xca,0x90,0x7d,0x48,0xc5,0xfa}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xeb,0x5c,0xe8,0x18,0x53,0xef,0xbe,0x83,0x77,0xf5}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xeb,0x64,0x56,0x71,0xb0,0x86,0x72,0xf8,0xa6,0x2f}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xeb,0xa1,0x29,0xde,0x4f,0xc9,0xd6,0x64,0x90,0xbe}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xeb,0xf3,0x96,0x0f,0x93,0x2b,0x9b,0x18,0x64,0x3a}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xec,0x84,0xa6,0x5f,0x98,0xa0,0x82,0xd7,0xf1,0x0e}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xed,0x09,0xfb,0x3a,0x39,0x0b,0x7c,0x77,0x37,0x64}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xed,0xae,0x7b,0xea,0x6e,0xcb,0xdd,0x52,0xfb,0x3b}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xed,0xd5,0xbc,0x51,0xbb,0xf1,0x37,0xa2,0x6f,0x88}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xee,0x4c,0x79,0xe8,0xdf,0xa8,0xa4,0x07,0xa3,0xdd}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xf6,0x86,0x21,0xbe,0xa3,0x72,0xcb,0x95,0x0f,0x2b}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xf6,0xc2,0xa7,0x69,0x87,0x45,0xda,0xdd,0x07,0xe3}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xf7,0xce,0x9a,0x96,0xbe,0xb2,0x05,0x30,0x2d,0x9d}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xf1,0xbc,0xa7,0x71,0x4b,0x51,0x7a,0x09,0xac,0x68}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xf2,0xbb,0x98,0x90,0x97,0xb7,0x04,0x01,0xdd,0x1d}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xf2,0x8b,0xd0,0x60,0xeb,0x79,0x1b,0x8b,0x18,0x12}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xf3,0x00,0x83,0x5d,0x35,0x11,0x27,0xc7,0xa2,0x64}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xf4,0x49,0x29,0x57,0x83,0xab,0xd6,0x1e,0xa0,0xe7}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xf4,0x52,0x4b,0xf8,0xd8,0xa0,0x28,0x8d,0x8b,0xa4}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xf4,0x94,0x66,0x97,0x9b,0x7b,0xce,0x3a,0xa6,0x80}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xf4,0xa7,0x70,0x38,0x74,0xb2,0x24,0x6e,0xca,0x07}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xf5,0xe1,0x8e,0x4e,0x5e,0x0b,0xbd,0x4e,0x8c,0xcc}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xf8,0x2a,0xd5,0xec,0x70,0x79,0xa9,0xad,0xa6,0xa0}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xf9,0x4b,0xcb,0x2b,0x5e,0xf3,0x5d,0xad,0xce,0xed}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xf9,0xd0,0xf0,0xd3,0x25,0x18,0xb1,0x98,0x29,0x46}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xfc,0x92,0xc5,0xe6,0x33,0x3a,0x56,0xf2,0xe0,0x6a}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xfc,0xe9,0x3d,0xe6,0x7a,0x02,0xad,0x16,0x5b,0xd7}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xfd,0x0f,0x24,0xe5,0x3e,0x6d,0xf6,0x32,0xb6,0xf3}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xfd,0x99,0xcb,0x49,0xdb,0xb5,0x41,0x3b,0xb4,0x33}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xfe,0x14,0xcc,0xd3,0x01,0xb0,0xf4,0xf9,0xe4,0xdc}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x06,0xbe,0x1a,0x9d,0x0d,0x07,0x31,0xad,0xa6,0xee}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x07,0x77,0x59,0x8d,0x9f,0xa2,0x09,0x3e,0xd4,0x6b}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x07,0x7d,0xdf,0xea,0xe9,0xa3,0x8a,0xd9,0xe8,0x6f}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x00,0x5f,0xae,0xa9,0xa8,0x28,0xe4,0xd1,0x6a,0x35}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x01,0x0b,0x7f,0xd0,0x39,0x78,0x17,0xf1,0x2c,0x0a}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x02,0x3b,0x1d,0x0d,0x0e,0xcb,0x89,0xf8,0xc4,0x79}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x02,0x1f,0x47,0xbc,0xe8,0x9e,0xc8,0xd3,0x19,0xe9}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x02,0xcc,0xf4,0xa7,0x06,0x1e,0xcd,0x36,0xb1,0xef}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x02,0xd0,0x7a,0x03,0xf1,0x3e,0x05,0xce,0xe8,0xf1}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x03,0x36,0x6c,0x60,0xb8,0x6d,0xf3,0x6c,0x5c,0xf7}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x03,0x54,0xec,0xe4,0xa7,0x5e,0xa3,0xba,0x0b,0xd4}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x04,0xf7,0x3b,0x25,0x61,0x98,0xb4,0xb8,0x36,0x1d}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x05,0x60,0xe0,0xaf,0xfa,0x7b,0x05,0xee,0x0f,0x08}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x05,0x98,0x3c,0xe8,0xb2,0xd8,0x7a,0x7e,0xd2,0x7d}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x06,0x31,0x67,0xa3,0x1f,0xf8,0x69,0x31,0xa6,0x29}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x0e,0x91,0xb7,0xa7,0xe2,0xd7,0x05,0x57,0xc6,0x5f}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x0f,0x10,0xb2,0x07,0x17,0x15,0x3c,0xd9,0xcd,0x0e}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x0f,0x2b,0x55,0x06,0x08,0x78,0x98,0xab,0x3f,0x95}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x08,0xc6,0x58,0x5d,0xf2,0xea,0x02,0x3d,0x96,0x76}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x09,0x3a,0x13,0x09,0xee,0xe3,0x9d,0x4b,0xf6,0x18}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x09,0x96,0x0e,0x33,0xd9,0x24,0xeb,0x3a,0xfd,0x72}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x09,0xf7,0xa3,0x66,0xdb,0x6e,0x04,0xac,0xc2,0x93}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x09,0xdd,0xc5,0x38,0x6f,0x21,0xdb,0xfb,0xc7,0x77}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x0a,0x26,0x27,0x21,0xbc,0x8a,0xca,0x0e,0x5a,0x17}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x0a,0x2d,0xf9,0x79,0x25,0xf4,0x74,0xc2,0xec,0x54}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x0a,0xbf,0x87,0xf8,0x8f,0x6b,0x04,0xb5,0xc3,0xfa}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x0a,0xc4,0xa9,0xc4,0xd5,0x27,0x6a,0x49,0xa6,0x4a}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x0a,0xec,0x17,0xfc,0xc5,0x19,0x4a,0x39,0x5f,0x86}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x0b,0x6e,0xdf,0x42,0x02,0xef,0x4d,0x56,0xf5,0xcf}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x0b,0xfe,0xed,0x69,0x75,0x12,0x41,0x62,0x2e,0xb5}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x0c,0x21,0x88,0x50,0x46,0x4f,0x26,0x23,0xb7,0xdc}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x0d,0x47,0x96,0x52,0x62,0x81,0x7e,0x6c,0xe5,0xbd}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x16,0xfd,0x96,0x10,0xc9,0x52,0x1a,0x59,0xb2,0x65}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x17,0x0a,0xdf,0x68,0xcd,0x5c,0xd6,0x68,0xbe,0x75}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x10,0x00,0x45,0xf7,0x04,0x1d,0x50,0xe7,0x43,0x2a}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x10,0x21,0xde,0x00,0x2b,0x28,0x62,0xda,0x30,0x63}, 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,0xe2,0x8f,0x22,0x66,0x48,0x00,0x67,0x17,0x93}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x13,0x45,0x64,0x2b,0x73,0x68,0xf4,0x44,0xb3,0xb9}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x15,0x30,0x98,0x3b,0x28,0x23,0x04,0xcb,0x02,0xeb}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x15,0xff,0x00,0x68,0xcf,0x86,0x1f,0xf7,0xac,0x7d}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x16,0x5f,0xfb,0x18,0x14,0x97,0x0d,0x54,0x3b,0xfa}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x1e,0x8a,0xde,0xf2,0x25,0xc2,0x46,0x06,0x99,0x1c}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x1e,0xa4,0xae,0x76,0x9e,0x10,0x3d,0xcc,0x12,0x07}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x1e,0xc0,0xeb,0x31,0xa6,0xaa,0xa7,0x2c,0xa0,0x04}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x1f,0x51,0x4e,0x01,0x19,0xde,0x34,0xa3,0x08,0xc9}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x1f,0xb2,0x1b,0x6a,0x57,0x6d,0xcc,0x9e,0xca,0xbb}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x18,0x7b,0x11,0xf4,0x9c,0xf4,0xfe,0xc3,0x21,0xa8}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x18,0x91,0xa3,0x51,0x6e,0x8a,0xf9,0xcc,0x27,0xbd}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x18,0xdf,0x33,0xe9,0x96,0x9e,0xe3,0x2a,0xb9,0xc6}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x19,0x63,0x6c,0x83,0xe5,0x11,0x04,0xa6,0xb5,0x92}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x1a,0x6c,0x74,0x95,0x3c,0x89,0xf6,0xec,0xef,0x09}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x1a,0x95,0xd6,0x31,0xe4,0xea,0x66,0x97,0x0d,0x5d}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x1b,0x93,0xbc,0x99,0x92,0x0e,0x69,0x16,0x40,0xcf}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x1b,0xc4,0x4e,0x17,0x71,0x14,0x06,0x3c,0x86,0xfd}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x1c,0x6c,0xed,0xd5,0xb7,0x11,0xfa,0xec,0x94,0x2e}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x1d,0x10,0xa5,0x20,0x77,0x43,0xf6,0xbc,0x12,0xed}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x1d,0x20,0x35,0xa1,0xf3,0x16,0xb4,0x8f,0x1c,0xbd}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x1d,0x30,0xfe,0x09,0xc7,0xe8,0xfe,0xd3,0xee,0x83}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x1d,0x33,0xd9,0xd9,0xdb,0xcf,0xc5,0xde,0xae,0xe9}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x1d,0x69,0xe1,0xac,0x11,0xf1,0x32,0x2f,0x5c,0x8d}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x1e,0x3d,0x98,0x4b,0x9e,0xc0,0x96,0x40,0x63,0x0f}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x1e,0x75,0x81,0xb1,0x3b,0xc4,0x22,0x26,0x72,0x3f}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x26,0x83,0xa0,0x76,0x54,0xa8,0xc1,0x6c,0xde,0x83}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x26,0xf6,0x7e,0xfd,0x3a,0x25,0x94,0xa8,0x49,0xbd}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x27,0x54,0x94,0x03,0x1f,0x7e,0x53,0xd8,0x3f,0x35}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x27,0xd0,0xa7,0x73,0x43,0xd5,0xb2,0x26,0x57,0x1c}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x20,0x3c,0x17,0x1f,0x8a,0x74,0xe1,0xdf,0x5a,0x5d}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x21,0x47,0x7f,0x18,0x5c,0x97,0x49,0x9c,0x40,0x86}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x21,0x62,0xfa,0x51,0x02,0xf5,0x14,0x4c,0x40,0x52}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x21,0xa3,0x41,0x6c,0x28,0xda,0x27,0x1a,0x78,0xd0}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x24,0x45,0xe9,0xa6,0x5a,0xa0,0xb0,0x01,0xaf,0x5b}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x25,0x09,0xa6,0xf6,0x4a,0xec,0xd5,0x33,0x74,0x35}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x26,0x55,0x1f,0xca,0x70,0xe5,0xbe,0xe3,0xa6,0x33}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x2e,0xdb,0x8c,0x24,0x20,0xf2,0x9f,0x7c,0xb4,0xea}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x28,0x21,0xfd,0xd5,0x3c,0x78,0xa5,0xfd,0xcc,0xf4}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x28,0xeb,0x35,0xa7,0x6f,0x90,0x83,0x7a,0x1f,0xfd}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x29,0x86,0xfb,0xba,0xbc,0x6e,0x6f,0x53,0x89,0xf5}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x2a,0x25,0x08,0x7a,0xb9,0x56,0xd9,0xe9,0xeb,0x5d}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x2a,0x8c,0xfd,0xc2,0xc4,0x30,0x05,0x11,0xe8,0x29}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x2b,0xb7,0x31,0x96,0xd7,0xd7,0xe6,0x05,0x42,0x1d}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x2c,0x15,0x79,0x88,0xf6,0xc3,0xd1,0x27,0xa9,0xf5}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x2c,0x28,0xda,0x1d,0x76,0xa8,0xff,0x18,0x78,0x7d}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x2c,0x6d,0x3e,0xb2,0x42,0x7e,0x0e,0x8a,0x59,0xe4}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x2c,0xc1,0xc3,0x15,0x28,0xa5,0x7c,0x5d,0x2c,0x9a}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x2d,0x1d,0x8d,0x21,0xf4,0x84,0x61,0x62,0x74,0x45}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x2e,0x7c,0xd9,0x21,0x3e,0x4a,0x31,0x4b,0x2e,0x42}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x36,0xea,0xb6,0x80,0x00,0x71,0xbb,0x23,0x51,0x1d}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x37,0x38,0x8f,0x26,0xd2,0xa4,0xd5,0x66,0x49,0xf9}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x37,0x7b,0x3f,0x74,0x7d,0x12,0x92,0x8b,0x89,0xb6}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x30,0x12,0x3f,0x13,0x11,0x5e,0xa1,0x65,0x15,0x86}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x30,0x57,0x42,0x6c,0xf1,0xee,0xdf,0xc3,0x46,0xff}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x30,0x5f,0x17,0x76,0x79,0x1d,0x11,0x42,0x97,0x95}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x30,0xb8,0xbd,0xce,0x0b,0xde,0xa0,0x72,0x99,0x88}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x30,0x9a,0xb7,0x46,0xb3,0x7e,0x05,0x40,0x24,0x5e}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x30,0xe4,0x80,0xe9,0xaa,0xd1,0x08,0xe4,0x0c,0xc2}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x31,0x3a,0x66,0x7c,0x5e,0xb7,0xf0,0x03,0xbf,0x3f}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x31,0x0c,0x29,0x90,0x84,0x7f,0x05,0x62,0xcd,0x7d}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x31,0x5d,0x88,0x82,0x83,0x35,0x7b,0x04,0x8d,0x54}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x31,0x9e,0x1a,0x61,0xec,0xb9,0x91,0xaf,0x2c,0x5e}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x31,0xe0,0x8a,0xe0,0x9f,0x11,0x44,0xa4,0x49,0xb3}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x32,0x22,0x05,0x5d,0xcc,0x69,0x3a,0x50,0xe3,0xdc}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x32,0xf3,0xd3,0x15,0x5b,0xdc,0xe9,0x43,0x75,0xa4}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x33,0xd6,0x09,0xdd,0xd8,0x37,0x5b,0x75,0xf6,0x29}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x34,0x50,0xf5,0xf6,0xe9,0xb6,0x34,0x31,0x47,0xc2}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x34,0xce,0x7c,0xad,0x90,0x12,0x35,0xa6,0xde,0x34}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x34,0xdd,0xa1,0xfb,0x92,0xb3,0xa4,0x56,0x2b,0xc2}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x35,0x00,0x24,0x34,0x98,0xee,0x98,0x61,0x05,0xfa}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x35,0x95,0x33,0x45,0x93,0xb2,0xbc,0xda,0xf6,0x42}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x35,0x9d,0x76,0xb9,0x43,0x15,0x85,0xf3,0xe3,0x8f}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x3e,0xf7,0xb2,0xf2,0x0d,0xb1,0x3e,0xc8,0xe1,0x8d}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x3f,0x81,0xbd,0x37,0x81,0x58,0x6d,0x6c,0x37,0x83}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x38,0x0b,0x69,0xc4,0x2e,0x74,0xb2,0xe2,0x30,0x2c}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x38,0x6c,0x73,0x48,0x3b,0x21,0x10,0xd6,0xc7,0xd3}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x38,0xab,0xe2,0xba,0xe7,0xeb,0x15,0xf2,0x9c,0x3d}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x38,0xfc,0x75,0x4c,0x4b,0xf5,0x80,0xcc,0xaf,0x2c}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x38,0xc1,0xe6,0x48,0x1c,0xaf,0x23,0x3f,0xfc,0xd7}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x38,0xcc,0xdb,0xaa,0x90,0x90,0xfd,0x64,0xda,0xd7}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x39,0x8f,0xb0,0x65,0xbb,0x21,0x24,0x31,0xd4,0x46}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x39,0xf1,0x7a,0x78,0x36,0x52,0x48,0x52,0x25,0xd9}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x3a,0x32,0xdf,0x45,0x8e,0x2c,0x8d,0xba,0x3d,0x8d}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x3a,0x61,0x7b,0xcb,0x1a,0x74,0x88,0xc2,0xd4,0x95}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x3a,0x82,0xff,0xb0,0x26,0xb7,0x94,0xb5,0xcb,0x92}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x3a,0xdc,0x9a,0x59,0x16,0x0a,0x9c,0x9e,0x28,0x79}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x3a,0xf3,0x79,0x26,0x3f,0x70,0x77,0x0c,0xe6,0x10}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x3b,0x51,0x4c,0xbd,0x64,0xc9,0x03,0x83,0xd7,0xe0}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x3b,0x9a,0x32,0x59,0x49,0xe4,0xb9,0x11,0x8a,0xc5}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x3c,0x17,0xd6,0xd7,0xd5,0x38,0x88,0x81,0xec,0x2d}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x3c,0x9e,0x97,0x7d,0x90,0x8c,0x49,0xd3,0x62,0xf1}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x3d,0x3d,0xc9,0x69,0x83,0x8e,0xef,0xfc,0x5d,0x40}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x3d,0x6d,0x58,0x6a,0x56,0x54,0x2d,0xb8,0x57,0x0e}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x3d,0x9d,0xa0,0xa3,0x0d,0x1c,0x63,0x57,0xaf,0xc5}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x3e,0x6e,0x9d,0x8e,0x67,0xde,0x35,0x79,0xf3,0xae}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x46,0xe8,0x5b,0xd2,0xdb,0x9f,0xc5,0x72,0x8d,0xf0}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x40,0x36,0xdd,0xc3,0xb4,0xe7,0x4d,0x57,0xdf,0xe0}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x40,0x8a,0x69,0x6c,0xa2,0x98,0x94,0x3e,0x60,0x8e}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x40,0x9f,0x9f,0x4c,0xf0,0xa8,0xd2,0x2b,0x2e,0xa1}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x41,0x77,0xac,0xbb,0xb4,0xe3,0x0e,0x3a,0x34,0xa3}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x41,0xb8,0xb3,0x52,0x0b,0xf5,0x6e,0xa0,0xb1,0x91}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x41,0xce,0x28,0xfc,0xa7,0x16,0x60,0x30,0x0b,0x98}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x42,0x59,0xa9,0xe2,0xee,0x0f,0xea,0xaa,0x83,0x39}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x43,0xf6,0xfa,0x52,0x06,0x3d,0x18,0x5c,0xf6,0xd6}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x44,0x36,0xa2,0x4f,0xfa,0x2e,0xf1,0xa2,0xc5,0xe6}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x44,0x00,0x69,0xf4,0x4e,0xe0,0xe7,0xf3,0xf8,0xe5}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x45,0x0d,0x6e,0x69,0x07,0xf1,0xdf,0x18,0x47,0x5e}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x45,0x4b,0xff,0xf2,0xbc,0x9f,0xd5,0xed,0xa3,0xc3}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x45,0x4a,0x01,0x0c,0xbf,0x12,0x0d,0xac,0xeb,0x1a}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x45,0x65,0x71,0xd9,0x54,0xeb,0x8d,0xac,0xa7,0x8b}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x45,0xec,0x68,0x9c,0x0a,0x5d,0x69,0xc3,0x79,0xdf}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x46,0x7b,0xe6,0x39,0xde,0x62,0x9f,0xb3,0x7e,0xee}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x4e,0x84,0xfe,0xb2,0x96,0xea,0x76,0xba,0x30,0x57}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x4e,0x97,0x15,0x46,0xd4,0x32,0xc7,0x62,0x5a,0xd2}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x4e,0xa1,0x36,0x28,0x7a,0x18,0x02,0xb9,0x4b,0x3c}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x4f,0x49,0xac,0x50,0x0d,0xef,0xeb,0xa3,0xf4,0x8b}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x4f,0x52,0x58,0x8e,0x67,0x84,0xfa,0x6d,0x76,0xf9}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x4f,0x56,0xad,0x52,0xba,0x0c,0x9e,0x58,0x5c,0xaa}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x48,0x1b,0x5a,0xe6,0x4c,0xc8,0xa4,0x9d,0x95,0x0b}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x49,0x1a,0xdd,0x4d,0x98,0x5e,0xef,0x70,0x45,0x90}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x49,0x5c,0x4e,0x97,0x52,0x16,0x5c,0x92,0xbf,0x7a}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x49,0x84,0x64,0x79,0x5a,0x7d,0xdc,0xe4,0x76,0x1b}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x49,0xc0,0xd0,0x6b,0x92,0xd8,0xf2,0xa4,0x4f,0x2f}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x4a,0x26,0x6a,0x2c,0x3a,0xe3,0x2a,0x58,0x44,0x66}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x4a,0x69,0x5b,0x05,0x25,0xca,0xd2,0xc6,0xfe,0x7b}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x4a,0xc4,0x57,0x30,0xd1,0xed,0xca,0x4b,0x81,0x05}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x4a,0xc8,0x79,0x7b,0x01,0x0e,0xbd,0x05,0xb5,0xa0}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x4a,0xd3,0x9c,0xf2,0x6c,0x0c,0x23,0x78,0x6e,0x1d}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x4b,0x85,0xc7,0x40,0x44,0x20,0xd4,0x6f,0xfe,0xa5}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x4c,0x7b,0x8f,0x35,0x34,0x08,0x83,0x5f,0x1b,0x7f}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x4c,0x5c,0x07,0x4b,0xcb,0x07,0x2a,0x82,0x1d,0xdc}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x4c,0x98,0xf3,0x99,0x40,0xc7,0xd0,0x83,0x85,0x51}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x4c,0xd5,0x26,0xb9,0x54,0x90,0x72,0xc9,0x7e,0xcb}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x4d,0x3a,0x3a,0x3b,0x71,0xf3,0xfc,0x34,0x65,0xa2}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x4d,0xbd,0x9c,0x32,0xe2,0x69,0x02,0x03,0xd2,0x89}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x4d,0xc0,0xba,0x9c,0xbf,0xb7,0xec,0x4a,0xc3,0x36}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x4e,0x32,0x72,0x6d,0x06,0xe7,0x10,0x25,0x62,0x41}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x4e,0x49,0xea,0x29,0xbc,0x40,0xe2,0x7e,0x70,0x8e}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x57,0x0c,0xb7,0x4d,0x77,0x6b,0x27,0x30,0xf8,0x53}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x57,0xe9,0x8d,0xa2,0xcc,0xa9,0xa9,0x9c,0x18,0x7a}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x52,0xf5,0xb7,0x14,0x06,0xdd,0x14,0x1f,0x1e,0xeb}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x53,0x95,0x3d,0x42,0x3e,0x1f,0x1e,0xcc,0x07,0x43}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x53,0xc0,0xba,0x6c,0xfd,0xc0,0xd4,0xe0,0x22,0xb2}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x54,0x46,0xf0,0x8e,0xb3,0x85,0xba,0x2e,0xac,0x84}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x54,0x51,0x6f,0x2b,0x29,0xc8,0x23,0x93,0x07,0x66}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x54,0x5f,0xa9,0x9c,0x4c,0xb4,0x5f,0x27,0x50,0x9e}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x55,0x71,0x51,0xd9,0x36,0x98,0x09,0xd6,0x3b,0xff}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x56,0x23,0x78,0xa3,0xb1,0x0c,0x7c,0x87,0xd2,0x32}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x56,0x76,0xeb,0x9b,0xff,0xe7,0x47,0x79,0xfb,0x50}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x5e,0xed,0xd2,0x89,0x48,0xd5,0x83,0x17,0x6a,0x01}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x5f,0x38,0x14,0x4a,0x97,0x39,0xff,0x12,0x07,0xb0}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x5f,0x7d,0xd3,0x77,0x5b,0x23,0x12,0x40,0xd2,0x49}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x5f,0xad,0xd5,0x0c,0x88,0x35,0xa4,0x66,0x97,0xb3}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x5f,0xc1,0xc2,0x32,0x38,0x2d,0xd4,0x93,0x31,0x81}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x5f,0xe4,0xb7,0x48,0x49,0x84,0x02,0x82,0x8a,0x56}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x58,0x00,0x54,0xc2,0xb3,0x71,0xbe,0x34,0x95,0x7a}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x58,0x0f,0xef,0xf9,0x57,0x09,0x82,0x6b,0x6e,0x9a}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x58,0x61,0xa0,0x7d,0xed,0x7b,0x2a,0x8b,0x6a,0x0e}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x58,0xb9,0x66,0xbe,0x0b,0xd7,0xeb,0x86,0x23,0x7d}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x58,0xdc,0x52,0x84,0xaf,0x56,0xd3,0xe1,0x7f,0x1f}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x59,0x0e,0xf6,0x19,0x6a,0x45,0x5c,0x18,0x6a,0x0e}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x59,0x89,0x67,0xa7,0x3f,0x41,0x3e,0x30,0x42,0x11}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x59,0x95,0x50,0xd6,0x2e,0xf7,0xd2,0xe6,0x3a,0x56}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x5a,0x2d,0xdc,0xf1,0xa6,0x40,0xbc,0x1f,0xd5,0xb5}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x5a,0x65,0xf3,0x5a,0x2c,0x66,0x41,0xe8,0x78,0xc0}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x5b,0x2a,0x0b,0xec,0x9e,0x05,0x81,0x7a,0x9e,0x08}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x5c,0x73,0xff,0x8e,0xc5,0xfe,0x21,0xc1,0x19,0xb3}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x5d,0x41,0xde,0x3d,0xa1,0x86,0x9b,0x26,0x27,0x11}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x5d,0xc5,0xaa,0x3c,0xf7,0xc6,0x2e,0x55,0x9d,0xa5}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x5e,0x13,0x80,0x8e,0x3c,0x3b,0x13,0xb0,0xc0,0x01}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x5e,0x75,0x95,0xb5,0x98,0xc3,0x6d,0x33,0x58,0xba}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x67,0x8e,0x26,0xbd,0x0a,0x43,0x30,0x7d,0xff,0x0f}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x60,0xfd,0xbe,0xb9,0x89,0x6c,0x4c,0x72,0x10,0x7b}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x60,0xc3,0xb7,0x51,0xf6,0x2f,0x0b,0xa8,0x61,0x21}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x61,0x3c,0x3e,0x12,0x57,0xfb,0x8e,0x36,0xdd,0xa4}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x61,0x04,0x55,0x21,0x5d,0x12,0x39,0xfb,0x09,0x49}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x61,0x63,0x52,0x55,0xbf,0xb7,0xa3,0x69,0x3f,0x91}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x62,0x19,0x4a,0x4d,0x64,0xb7,0x65,0x19,0x8e,0x8a}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x63,0x71,0x25,0x6d,0x19,0xbd,0x62,0x0d,0x9e,0x95}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x64,0x29,0xe3,0x42,0x71,0x3b,0x3d,0x7c,0xda,0xc7}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x65,0xa8,0x2f,0x55,0xcc,0xe3,0x4c,0x84,0xcc,0x3b}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x65,0xc7,0x38,0xa4,0xe4,0xd6,0x0b,0x2b,0xed,0xe6}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x6f,0x10,0x12,0x4f,0x8f,0x44,0x85,0x5d,0x69,0xa9}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x6f,0x87,0xcf,0x54,0x39,0xbf,0x36,0x12,0x55,0x61}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x6f,0xa7,0xe5,0x14,0xd9,0x5d,0x5d,0x9b,0x9c,0xac}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x6f,0xe3,0x17,0x08,0xf6,0x24,0x4b,0xa8,0x5f,0x24}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x68,0xa4,0x34,0x41,0x8d,0xb9,0xda,0xd4,0x86,0x59}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x6a,0x27,0x7b,0x6d,0x0b,0x29,0x5a,0x67,0xd1,0x95}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x6a,0x57,0x2a,0xd0,0x28,0x58,0xc8,0x75,0xd2,0xd1}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x6a,0x64,0xb2,0xc9,0x15,0xc6,0x0e,0x8b,0x86,0x4f}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x6a,0x8b,0xd2,0x78,0x3f,0x7a,0xf8,0x92,0x8f,0x80}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x6a,0x9e,0xf9,0x07,0x73,0xd8,0xe8,0x24,0x93,0xcc}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x6a,0xcb,0x6c,0x41,0x52,0x61,0x20,0x4e,0x77,0x39}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x6a,0xf0,0x96,0x3c,0x4c,0x78,0x33,0xd0,0xf0,0x00}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x6b,0x59,0x5f,0xe7,0xdd,0x57,0xba,0xc1,0x12,0x51}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x6c,0x62,0x5b,0x0d,0x91,0x66,0xd0,0xca,0x10,0x2d}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x6c,0x62,0xc5,0x19,0x94,0x5b,0xcd,0x20,0xd9,0x73}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x6d,0xb8,0x7f,0xac,0x82,0x55,0x27,0xf2,0x01,0xf5}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x6d,0x95,0x8d,0xd8,0x7b,0x41,0xdc,0x81,0xd4,0x3d}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x6e,0x38,0xa5,0x11,0x8c,0x64,0x2b,0xc5,0xbe,0x6c}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x76,0xbb,0x65,0x0a,0xdf,0x23,0xa2,0x6d,0x4d,0xc8}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x76,0x8d,0x46,0x54,0x2a,0xb7,0x9e,0xce,0x74,0x45}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x77,0x30,0x99,0x1c,0x76,0x58,0x64,0x7c,0x2e,0x16}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x71,0x6f,0xc8,0x1a,0xde,0x5b,0xde,0xda,0xcc,0xd5}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x72,0x89,0x34,0x3d,0x7c,0x33,0x47,0x01,0x02,0x92}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x74,0x3b,0x0e,0x42,0x30,0x42,0x63,0xa5,0x3e,0x8d}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x74,0x2d,0xb6,0x15,0xc8,0x70,0x60,0x25,0x2e,0xe7}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x74,0x65,0x8d,0x57,0xdb,0x20,0xa2,0xc1,0xa7,0xbd}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x74,0xf9,0x3c,0xb3,0x2d,0xc2,0x18,0xc5,0xcb,0x2a}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x75,0x95,0xe1,0x69,0x25,0x99,0xec,0xac,0x00,0xe4}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x76,0x3f,0x29,0x6c,0xec,0xd3,0x95,0x7e,0x4e,0x8d}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x7e,0x9e,0x2f,0x58,0x20,0x23,0xea,0x34,0x78,0x44}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x7e,0xaf,0xae,0x18,0x67,0x04,0x98,0x61,0x2f,0xa9}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x7f,0x84,0xea,0x51,0x31,0xd3,0x46,0x75,0xae,0xbb}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x78,0x3e,0x3b,0x74,0x2b,0x6f,0x57,0x06,0x53,0xbb}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x78,0x24,0xc1,0x1e,0x6e,0x73,0x93,0xa5,0x08,0xe3}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x78,0xc0,0xf5,0x28,0xea,0xf3,0xc2,0x2c,0x6a,0x69}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x79,0x0f,0xd0,0x25,0xd4,0xa5,0xbc,0xcb,0x72,0x51}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x7a,0xa9,0x41,0x75,0xf6,0x5f,0x6f,0x83,0x58,0xf1}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x7c,0x39,0x64,0xaf,0xf5,0x37,0xe7,0x22,0xe0,0x42}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x7c,0xc3,0x68,0x1e,0x92,0x7c,0xbb,0x04,0x12,0x0b}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x7c,0xec,0xf0,0xdb,0x09,0xea,0xdb,0x82,0x5b,0x45}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x7d,0x3f,0x6d,0xa4,0xb8,0x8e,0x5f,0xf9,0x5e,0x48}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x7d,0xb0,0xb0,0xe2,0xa5,0xa0,0xbd,0xa3,0x9e,0xb7}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x86,0x8a,0x76,0xb7,0x13,0xe8,0x74,0x0c,0x54,0x44}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x86,0xd1,0xb0,0x3e,0x88,0x73,0x42,0x0c,0xb0,0xa4}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x80,0xfc,0x51,0x3e,0x9b,0x7d,0x42,0x5d,0x63,0x77}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x81,0x49,0x6a,0xef,0x1f,0x06,0xdf,0xc4,0x6c,0x23}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x81,0xf1,0x31,0xce,0x65,0x59,0xc2,0x2e,0x46,0x47}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x82,0x9b,0xbe,0xc4,0x3b,0xbe,0x8d,0x70,0xda,0x1c}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x82,0xea,0xb2,0x5e,0x5f,0x7d,0x80,0x2d,0x17,0x81}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x83,0x8c,0x28,0x22,0x33,0xa4,0xc1,0xe8,0xae,0xe6}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x84,0x73,0x02,0xdd,0x47,0x8b,0x29,0xda,0xf6,0x2e}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x84,0xb0,0x90,0x4a,0x1c,0xf0,0x75,0x2c,0x23,0x12}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x85,0x29,0xc0,0xeb,0x29,0x0b,0x63,0xaa,0x13,0x98}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x85,0x30,0x22,0xa7,0x56,0x23,0x73,0xe0,0x97,0x03}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x85,0x47,0x8d,0x89,0x8e,0x13,0x57,0x5e,0xd7,0xe2}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x85,0x6c,0x77,0xc3,0x06,0x03,0x75,0x75,0x63,0xa7}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x86,0x29,0x3b,0x0b,0x5e,0xa2,0xd7,0x44,0x80,0xa1}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x8f,0x3b,0x03,0x68,0x7e,0x45,0x8a,0x33,0xc2,0xcb}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x8f,0x2f,0x41,0xc7,0xd4,0xe4,0x7a,0xdc,0x18,0x1c}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x8f,0x80,0xf0,0x76,0x52,0xa2,0x6e,0x1b,0x0f,0x7c}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x8f,0xb3,0xa3,0x0a,0x54,0xdf,0xd5,0xb3,0x00,0x07}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x88,0x62,0x93,0x14,0x42,0x07,0xab,0xd0,0xff,0x0e}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x88,0x90,0x5b,0xa0,0x20,0xb4,0x27,0xe8,0xdf,0x39}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x88,0xdd,0xbb,0x8a,0x6a,0xde,0x55,0x94,0xd5,0x6d}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x88,0xea,0xb2,0x3f,0x1e,0x31,0xcc,0xf0,0x3f,0x2e}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x89,0x05,0x2d,0x83,0x5f,0x11,0xeb,0xa5,0x9b,0xdd}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x89,0x58,0x14,0x63,0xb5,0xcc,0xea,0xdf,0x1f,0x0d}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x8a,0xd1,0xd5,0x85,0x24,0xe2,0xbf,0xf4,0x37,0x36}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x8b,0xa1,0x66,0xb0,0x8f,0x12,0x79,0xdd,0xd4,0xa7}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x8b,0xc2,0xdb,0xf7,0x90,0x6a,0x11,0x58,0xb0,0xfb}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x8c,0xab,0x57,0x1a,0x03,0x5a,0x12,0xff,0xfc,0xf5}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x8d,0x99,0xd1,0xf0,0xe6,0xd9,0xc5,0xff,0xa8,0x73}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x96,0xf0,0x45,0xaa,0xa2,0xe9,0x7b,0x72,0x62,0x56}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x97,0xa3,0x7e,0xe8,0xe8,0x9b,0x1e,0xfe,0x2c,0xc4}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x90,0x3c,0xcd,0xc6,0xb8,0x12,0x1e,0x62,0x31,0x58}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x90,0x2a,0x40,0x90,0x92,0x62,0x91,0x56,0x14,0x2e}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x90,0x70,0x98,0xf5,0xaf,0x56,0x98,0xb6,0x16,0xdf}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x91,0x23,0x64,0xf3,0x49,0x61,0x3b,0x73,0x9d,0x96}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x91,0xb9,0x56,0x50,0x35,0xd8,0xd3,0x1c,0xd6,0x87}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x91,0xe4,0x65,0x49,0x74,0xcf,0x92,0xa3,0x3f,0xc6}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x92,0x71,0x96,0x5a,0xd4,0xf0,0xd0,0x84,0x4f,0x71}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x92,0xb6,0x46,0xee,0x24,0xa0,0xcd,0xb9,0x0c,0xdd}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x92,0x9c,0x82,0xbf,0x8e,0x4f,0xd7,0xc7,0x4a,0x9d}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x92,0xc9,0xa1,0x01,0xeb,0x52,0xdb,0xbd,0x93,0xf8}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x93,0x06,0x3f,0xc3,0xe6,0x73,0x40,0x91,0xb1,0x30}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x93,0xd8,0x7a,0x5d,0x21,0xd0,0x87,0xf5,0x92,0x8d}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x94,0x54,0x6c,0x57,0xa4,0x1b,0x74,0xf0,0x7d,0x0b}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x94,0x96,0xd4,0xa4,0xed,0x65,0x96,0xbc,0x4a,0xbc}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x95,0x3d,0xec,0x1a,0x20,0x97,0xa2,0xa1,0xcd,0xab}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x95,0x1a,0x3a,0xb0,0x29,0x8c,0xcc,0x32,0x80,0xf7}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x95,0x47,0xee,0xab,0xa9,0x78,0x17,0xa7,0xed,0x73}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x95,0x68,0x0e,0x9d,0x10,0x5d,0x2d,0xf7,0x6a,0x56}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x95,0xe0,0x9a,0x05,0x94,0x67,0x22,0xc2,0x99,0xf4}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x9e,0xb9,0xda,0xa3,0xfc,0xd4,0xd1,0xb9,0xb5,0x40}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x9f,0x0a,0x17,0x56,0xa6,0xcb,0xda,0x86,0x0f,0x4f}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x9f,0x17,0xcb,0x57,0x64,0x8a,0x8e,0xf1,0x93,0x4f}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x9f,0x60,0x23,0xd8,0x31,0xf5,0x3b,0x5d,0x00,0xca}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x9f,0xd2,0xb0,0x27,0xc6,0x36,0x2f,0xf9,0x76,0xb8}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x98,0x3d,0x24,0x92,0x18,0x0e,0xbe,0x5e,0x37,0x80}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x98,0x2b,0xfa,0x4d,0xf6,0xe3,0xcb,0x8f,0xa7,0xca}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x98,0x2e,0x6e,0xe7,0x52,0xb9,0x59,0xd1,0x70,0x7e}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x99,0x15,0x6a,0xb4,0x2e,0x18,0x73,0x15,0xd0,0xb2}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x99,0xb9,0x4b,0x45,0x2c,0x9c,0x74,0x95,0x85,0x38}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x99,0xf8,0x24,0xd4,0xa5,0x4c,0xed,0xea,0xb9,0x94}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x99,0xfc,0x5b,0xe1,0x93,0xb3,0x4a,0x82,0xc0,0x94}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x99,0xe6,0x23,0x9d,0x7a,0xed,0x35,0xe6,0x99,0x70}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x9a,0x10,0x03,0xfc,0x52,0xa3,0x94,0xb1,0x55,0x1e}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x9a,0xbd,0xbb,0xf4,0xaa,0xde,0xf7,0xfc,0xee,0x83}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x9a,0x8c,0xe7,0x4c,0x13,0xf0,0xa0,0xdf,0xd7,0x18}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x9b,0x53,0xdf,0x76,0xd6,0x86,0x7b,0x67,0xa6,0xb2}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x9c,0xbd,0x0b,0xef,0xec,0x63,0xe9,0xe6,0xa7,0xb8}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x9c,0xd2,0x89,0x56,0xf8,0x19,0x83,0x37,0xf7,0xc5}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x9d,0x9b,0xde,0x57,0xf1,0x06,0xae,0x93,0x0f,0xbd}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x9d,0xc8,0xce,0xb0,0x94,0x36,0xb8,0x6d,0x13,0x23}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x9e,0x11,0x46,0xb7,0x7e,0x5b,0x0a,0x28,0x75,0x71}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x9e,0x2b,0xdf,0x5e,0x5e,0x37,0x9a,0x3c,0xc2,0x97}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xa7,0x3e,0x5d,0x9e,0xf6,0x87,0xbb,0x23,0x4b,0x8e}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xa7,0x23,0xf2,0xb4,0xee,0x5c,0x47,0x6b,0x2d,0xa8}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xa7,0x7b,0xe7,0x14,0x3b,0x66,0x01,0x10,0x16,0xcd}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xa7,0x61,0xb3,0x07,0x3c,0x83,0xf3,0xcb,0x55,0x71}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xa0,0x14,0xbc,0x6f,0x03,0x89,0x2b,0x57,0xde,0xc8}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xa1,0xbc,0x70,0x3d,0x1c,0x84,0xc8,0xac,0x8b,0xf5}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xa2,0x3b,0xdd,0xc1,0xd3,0x1f,0xa2,0xe6,0xee,0x25}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xa2,0x23,0xf2,0xee,0xcb,0x9b,0x94,0x0f,0x04,0x21}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xa2,0xa2,0x94,0x9e,0xce,0x1a,0xf9,0xcb,0x31,0xc5}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xa2,0xfa,0x66,0x69,0x17,0xc7,0xd5,0x01,0x96,0xc6}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xa3,0x46,0x3f,0xc6,0x49,0xe3,0xc8,0xdd,0xd9,0xdc}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xa3,0xa3,0x67,0xe4,0xa4,0x3c,0xf0,0xa8,0x9b,0x9b}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xa3,0xab,0x27,0xeb,0x0b,0x9b,0x40,0xe4,0xc3,0xcb}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xa4,0x81,0x96,0x0c,0x52,0xde,0x9b,0x8d,0x70,0x78}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xa4,0x81,0x99,0x7c,0xcb,0x67,0xcc,0x4c,0x5d,0x4b}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xa4,0xa5,0xa5,0x10,0x66,0xfc,0x15,0x63,0x0e,0x3d}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xa4,0xcd,0x88,0xd6,0xdf,0xed,0xab,0xa6,0xe1,0x88}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xa6,0x6c,0x01,0x32,0x5f,0x56,0x32,0x72,0x1c,0x2b}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xae,0x94,0x31,0x12,0x75,0x92,0xd8,0x32,0x8a,0xd1}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xaf,0x56,0x76,0xe7,0x35,0xf3,0x5a,0x62,0x9b,0xa3}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xa8,0xb9,0xc3,0x07,0x95,0x23,0xde,0xe0,0xc6,0x7b}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xa9,0x6d,0x83,0xa6,0x9c,0xdd,0xae,0x7c,0xd6,0x97}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xa9,0xa8,0x9a,0x15,0x5d,0xda,0xe1,0x87,0x2d,0x0e}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xa9,0xc8,0x44,0xc2,0x1a,0xaf,0x46,0xa0,0xf2,0xf1}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xaa,0x7d,0xc2,0x0c,0x95,0xe2,0x5b,0x02,0x8e,0x41}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xab,0x00,0x8e,0xd1,0x06,0x26,0x63,0xa5,0x1d,0x49}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xab,0x29,0x85,0x0f,0xf2,0xb8,0x58,0x8f,0xdb,0xbf}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xab,0x98,0x40,0x0a,0x73,0x43,0x6f,0xb6,0x3d,0x8b}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xab,0xdd,0x6d,0x5d,0xc5,0x36,0xcb,0x6c,0xc8,0x70}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xac,0x81,0x65,0xa3,0x8b,0xea,0x0b,0x71,0xe4,0x16}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xad,0x1b,0x40,0xc1,0x45,0x64,0xbf,0x24,0x15,0xca}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xad,0x1c,0xc0,0xb4,0x95,0xb5,0x17,0xc0,0xc2,0x41}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xad,0xc4,0xfa,0x8d,0xa6,0xf7,0x40,0x42,0xe7,0xd3}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xae,0x2e,0xe4,0x64,0x79,0x05,0x5f,0xb7,0x04,0x14}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xb0,0x48,0xe6,0xe8,0x48,0xfa,0xca,0x87,0x78,0x18}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xb0,0x6c,0x4a,0x92,0xde,0xd3,0x0d,0x28,0xc4,0x79}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xb1,0x41,0x81,0xac,0xde,0xce,0x0b,0x94,0x8a,0x9d}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xb1,0x73,0xdf,0x4b,0xab,0xc3,0x7a,0x3c,0x48,0x99}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xb1,0xb6,0xc8,0x72,0x86,0xc6,0x34,0x6b,0xef,0x41}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xb1,0xd5,0x8e,0xf0,0x22,0x9a,0x8b,0xa6,0xf1,0xfb}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xb1,0xd8,0x90,0x36,0x0e,0xc6,0x51,0x9c,0x8b,0x93}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xb2,0xce,0xea,0x6a,0xd7,0x34,0x30,0x8d,0xdf,0x65}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xb2,0xea,0xa2,0xc5,0xeb,0x2a,0x10,0xec,0xeb,0x4e}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xbe,0xda,0x60,0xee,0xa0,0xf8,0xdd,0x5a,0x11,0xb6}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xbf,0x7f,0x7f,0x68,0x2c,0x63,0x70,0xba,0xbb,0xf1}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xb9,0xaa,0xce,0xfd,0x87,0x35,0x7b,0xee,0x0d,0x40}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xb9,0xe5,0xb3,0x2c,0xb6,0x6d,0x91,0x46,0x22,0xad}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xba,0x49,0xd2,0xda,0xb8,0x28,0xe8,0x4d,0x53,0xca}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xba,0xcd,0x40,0x9b,0x0b,0xc6,0x82,0xba,0xc8,0xdd}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xbb,0x57,0x4d,0xce,0xa0,0x53,0x4d,0x8f,0xcd,0x4f}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xbb,0xba,0xc0,0x45,0x0b,0x3d,0x30,0xef,0x86,0x93}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xbc,0x80,0x0b,0xa0,0xe3,0xc1,0x9b,0x6b,0xc5,0x17}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xbd,0x3a,0xc5,0xd0,0xc3,0x93,0x32,0x55,0x57,0x27}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xbd,0x63,0x78,0x09,0xf3,0x85,0x50,0x42,0x0c,0x3a}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xbd,0xb2,0x78,0xc7,0x06,0x2c,0xe1,0xb8,0x72,0xdc}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xc7,0x25,0x66,0x48,0x17,0x18,0x9d,0x2d,0x05,0xb4}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xc7,0x66,0xbe,0x2e,0x08,0xdf,0xba,0xf7,0xae,0x83}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xc7,0x6d,0x92,0x43,0x00,0x24,0xe5,0xd6,0x83,0xd3}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xc7,0xf7,0x05,0x69,0x99,0x52,0x54,0x77,0x2b,0x1f}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xc7,0xdd,0x9d,0xe0,0x6d,0xaa,0x03,0xcb,0x9c,0x21}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xc0,0x0f,0xf8,0x18,0xb0,0x84,0x66,0x47,0x08,0xe4}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xc0,0x41,0xc0,0xc5,0x9d,0xef,0x46,0x46,0xae,0x7f}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xc1,0x89,0x05,0x1b,0x88,0x6b,0xd7,0x20,0x08,0x9b}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xc2,0x4e,0xd2,0xd3,0xfd,0x58,0x32,0x14,0x6f,0x87}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xc2,0x6d,0xf5,0x40,0x0f,0xbd,0xfb,0x53,0x19,0xc9}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xc3,0x3e,0x86,0xb1,0xd5,0x0c,0x5a,0x0e,0x18,0x4e}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xc4,0x3a,0x2a,0x49,0xb4,0x72,0xa4,0x2c,0x7b,0x99}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xc4,0x44,0x04,0x3a,0x11,0x84,0x47,0x67,0x2a,0x13}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xc4,0x45,0x1f,0xbc,0xc9,0xa0,0x32,0x01,0xeb,0xbc}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xc4,0x55,0x2a,0xb9,0xbb,0x9b,0x2a,0xe7,0x1c,0x75}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xc4,0xdf,0x49,0x72,0xb7,0xed,0xbe,0x9f,0x59,0xfa}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xc4,0xe0,0x24,0x19,0x5a,0x39,0xc6,0xbe,0x74,0xee}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xc5,0xdc,0x95,0xee,0xec,0x4d,0x25,0xb1,0xa1,0x5a}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xc6,0x47,0x01,0xca,0x17,0xe1,0x47,0x46,0x9b,0xd6}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xce,0xf6,0xda,0x2a,0x7f,0x69,0x90,0xad,0x89,0xe4}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xce,0xf1,0x60,0x80,0x76,0xe7,0x9a,0x36,0xdc,0xc7}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xcf,0x98,0x18,0x43,0xeb,0x5d,0xd7,0x16,0xf1,0x50}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xc8,0x76,0xb8,0x89,0x52,0x6f,0x23,0x93,0xe5,0x24}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xc9,0x3e,0xe1,0xbf,0xef,0xc8,0x22,0x97,0xae,0x51}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xc9,0x82,0xc3,0xcc,0x29,0x07,0x0b,0x8d,0x6f,0xfb}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xc9,0xfe,0x7a,0x81,0x62,0x35,0x52,0xf7,0x02,0x0c}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xca,0x33,0x3a,0xdc,0x87,0x62,0x7a,0xc2,0x1d,0xe6}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xca,0x50,0x8d,0xe0,0x82,0x1c,0x59,0x0f,0xef,0x1b}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xca,0xa3,0x66,0x19,0x34,0xac,0xb2,0x0f,0x60,0x9a}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xcb,0xb3,0xa0,0x39,0xf6,0x46,0xec,0x5a,0x42,0xc6}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xcc,0xc6,0x22,0xb4,0xfc,0xf7,0xff,0xb0,0xa2,0xb4}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xcd,0x2e,0x71,0x78,0x7b,0x6d,0x9e,0x61,0x70,0x05}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xcd,0x31,0x38,0x94,0x95,0xca,0x44,0xf4,0x65,0x68}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xcd,0x61,0xe1,0xbe,0x7b,0x46,0x9c,0x51,0xbf,0x66}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xcd,0xac,0xcf,0x18,0x1f,0xa6,0x8f,0x02,0x6a,0x43}, 8333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xce,0x20,0x1e,0x2c,0x8d,0x2c,0x9e,0xd9,0xa7,0xac}, 8333}
+static const uint8_t chainparams_seed_main[] = {
+ 0x01,0x04,0x02,0x27,0xad,0x7e,0x20,0x8d,
+ 0x01,0x04,0x03,0x0e,0xa8,0xc9,0xbc,0xcd,
+ 0x01,0x04,0x04,0x24,0x70,0x2c,0x20,0x8d,
+ 0x01,0x04,0x05,0x08,0x12,0x1f,0x20,0x8d,
+ 0x01,0x04,0x05,0x0e,0xc8,0xa7,0x20,0x8d,
+ 0x01,0x04,0x05,0x38,0x14,0x02,0x20,0x8d,
+ 0x01,0x04,0x05,0x66,0x92,0x63,0x20,0x8d,
+ 0x01,0x04,0x05,0x67,0x89,0x92,0x24,0x75,
+ 0x01,0x04,0x05,0x80,0x57,0x7e,0x20,0x8d,
+ 0x01,0x04,0x05,0x85,0x41,0x52,0x20,0x8d,
+ 0x01,0x04,0x05,0xbb,0x37,0xf2,0x20,0x8d,
+ 0x01,0x04,0x05,0xbc,0x3e,0x18,0x20,0x8d,
+ 0x01,0x04,0x05,0xbc,0x3e,0x21,0x20,0x8d,
+ 0x01,0x04,0x05,0xc7,0x85,0xc1,0x20,0x8d,
+ 0x01,0x04,0x08,0x26,0x59,0x98,0x20,0x8d,
+ 0x01,0x04,0x0d,0xe7,0x14,0xf9,0x20,0x8d,
+ 0x01,0x04,0x12,0x1b,0x4f,0x11,0x20,0x8d,
+ 0x01,0x04,0x14,0xb8,0x0f,0x74,0x20,0xf1,
+ 0x01,0x04,0x17,0x1c,0xcd,0x61,0x20,0x8d,
+ 0x01,0x04,0x17,0x6a,0xfc,0xe6,0x20,0x8d,
+ 0x01,0x04,0x17,0xaf,0x00,0xca,0x20,0x8d,
+ 0x01,0x04,0x17,0xaf,0x00,0xd4,0x20,0x8d,
+ 0x01,0x04,0x17,0xf1,0xfa,0xfc,0x20,0x8d,
+ 0x01,0x04,0x17,0xf5,0x18,0x9a,0x20,0x8d,
+ 0x01,0x04,0x18,0x56,0xb8,0x42,0x20,0x8d,
+ 0x01,0x04,0x18,0x74,0xf6,0x09,0x20,0x8d,
+ 0x01,0x04,0x18,0x8d,0x22,0xa6,0x20,0x8d,
+ 0x01,0x04,0x18,0x9b,0xc4,0xf6,0x20,0x8d,
+ 0x01,0x04,0x18,0x9d,0x82,0xde,0x20,0x8d,
+ 0x01,0x04,0x18,0xbc,0xb0,0xff,0x20,0x8d,
+ 0x01,0x04,0x18,0xed,0x46,0x35,0x20,0x8d,
+ 0x01,0x04,0x1b,0x7c,0x04,0x43,0x20,0x8d,
+ 0x01,0x04,0x1f,0x11,0x46,0x50,0x20,0x8d,
+ 0x01,0x04,0x1f,0x15,0x08,0x20,0x20,0x8d,
+ 0x01,0x04,0x1f,0x2d,0x76,0x0a,0x20,0x8d,
+ 0x01,0x04,0x1f,0x84,0x11,0x38,0x20,0x8d,
+ 0x01,0x04,0x1f,0x86,0x79,0xdf,0x20,0x8d,
+ 0x01,0x04,0x20,0xd6,0xb7,0x72,0x20,0x8d,
+ 0x01,0x04,0x23,0x89,0xec,0x20,0x20,0x8d,
+ 0x01,0x04,0x23,0xb9,0x91,0x69,0x20,0x8d,
+ 0x01,0x04,0x23,0xd1,0x33,0xd4,0x20,0x8d,
+ 0x01,0x04,0x23,0xf5,0xaf,0x4c,0x20,0x8d,
+ 0x01,0x04,0x25,0x74,0x5f,0x29,0x20,0x8d,
+ 0x01,0x04,0x25,0x8f,0x09,0x6b,0x20,0x8d,
+ 0x01,0x04,0x25,0x8f,0x74,0x2b,0x20,0x8d,
+ 0x01,0x04,0x25,0xbf,0xf4,0x95,0x20,0x8d,
+ 0x01,0x04,0x25,0xd3,0x4e,0xfd,0x20,0x8d,
+ 0x01,0x04,0x25,0xdd,0xd1,0xde,0x5f,0x0d,
+ 0x01,0x04,0x25,0xe4,0x5c,0x6e,0x20,0x8d,
+ 0x01,0x04,0x2b,0xe1,0x3e,0x6b,0x20,0x8d,
+ 0x01,0x04,0x2b,0xe1,0x9d,0x98,0x20,0x8d,
+ 0x01,0x04,0x2d,0x24,0xb8,0x06,0x20,0x8d,
+ 0x01,0x04,0x2d,0x30,0xa8,0x10,0x20,0x8d,
+ 0x01,0x04,0x2d,0x55,0x55,0x08,0x20,0x8d,
+ 0x01,0x04,0x2d,0x55,0x55,0x09,0x20,0x8d,
+ 0x01,0x04,0x2d,0x81,0xb4,0xd6,0x20,0x8d,
+ 0x01,0x04,0x2d,0x95,0x4e,0x80,0x20,0x8d,
+ 0x01,0x04,0x2d,0x97,0x7d,0xda,0x20,0x8d,
+ 0x01,0x04,0x2d,0x9a,0xff,0x2e,0x20,0x8d,
+ 0x01,0x04,0x2d,0x9b,0x9d,0xef,0x20,0x8d,
+ 0x01,0x04,0x2e,0x1c,0x84,0x22,0x20,0x8d,
+ 0x01,0x04,0x2e,0x1c,0xcc,0x15,0x20,0x8d,
+ 0x01,0x04,0x2e,0x20,0x32,0x62,0x20,0x8d,
+ 0x01,0x04,0x2e,0x3b,0x0d,0x23,0x20,0x8d,
+ 0x01,0x04,0x2e,0x80,0x28,0xad,0x20,0x8d,
+ 0x01,0x04,0x2e,0x80,0x8c,0xc1,0x20,0x8d,
+ 0x01,0x04,0x2e,0x92,0xf8,0x59,0x20,0x8d,
+ 0x01,0x04,0x2e,0xa6,0xa2,0x2d,0x4e,0x21,
+ 0x01,0x04,0x2e,0xbc,0x0f,0x06,0x20,0x8d,
+ 0x01,0x04,0x2e,0xe5,0xa5,0x8e,0x20,0x8d,
+ 0x01,0x04,0x2e,0xe5,0xee,0xbb,0x20,0x8d,
+ 0x01,0x04,0x2e,0xf9,0x53,0x52,0x20,0x8d,
+ 0x01,0x04,0x2e,0xfe,0xd9,0xa9,0x20,0x8d,
+ 0x01,0x04,0x2f,0x4a,0xbf,0x22,0x20,0x8d,
+ 0x01,0x04,0x2f,0x73,0x35,0xa3,0x20,0x8d,
+ 0x01,0x04,0x2f,0xbb,0x1a,0x87,0x20,0x8d,
+ 0x01,0x04,0x2f,0xde,0x67,0xea,0x20,0x8d,
+ 0x01,0x04,0x2f,0xfd,0x05,0x63,0x20,0x8d,
+ 0x01,0x04,0x31,0xe8,0x52,0x4c,0x20,0x8d,
+ 0x01,0x04,0x31,0xf7,0xd7,0x2b,0x20,0x8d,
+ 0x01,0x04,0x32,0x02,0x0d,0xa6,0x20,0x8d,
+ 0x01,0x04,0x32,0x22,0x27,0x48,0x20,0x8d,
+ 0x01,0x04,0x32,0x2d,0xe8,0xbd,0x20,0x8d,
+ 0x01,0x04,0x32,0x44,0x68,0x5c,0x20,0x8d,
+ 0x01,0x04,0x33,0x44,0x24,0x39,0x20,0x8d,
+ 0x01,0x04,0x33,0x9a,0x3c,0x22,0x20,0x8d,
+ 0x01,0x04,0x34,0xa9,0xee,0x42,0x20,0x8d,
+ 0x01,0x04,0x36,0xc5,0x1e,0xdf,0x20,0x8d,
+ 0x01,0x04,0x36,0xe3,0x42,0x39,0x20,0x8d,
+ 0x01,0x04,0x3a,0x9e,0x00,0x56,0x20,0x8d,
+ 0x01,0x04,0x3a,0xab,0x87,0xf2,0x20,0x8d,
+ 0x01,0x04,0x3a,0xe5,0xd0,0x9e,0x20,0x8d,
+ 0x01,0x04,0x3c,0xf4,0x6d,0x13,0x20,0x8d,
+ 0x01,0x04,0x3e,0x26,0x4b,0xd0,0x20,0x8d,
+ 0x01,0x04,0x3e,0x4a,0x8f,0x0b,0x20,0x8d,
+ 0x01,0x04,0x3e,0x50,0xe3,0x31,0x20,0x8d,
+ 0x01,0x04,0x3e,0x98,0x3a,0x10,0x24,0xcd,
+ 0x01,0x04,0x3e,0xd2,0xa7,0xc7,0x20,0x8d,
+ 0x01,0x04,0x3e,0xea,0xbc,0xa0,0x20,0x8d,
+ 0x01,0x04,0x3e,0xfb,0x36,0xa3,0x20,0x8d,
+ 0x01,0x04,0x3f,0xe3,0x74,0xa2,0x20,0x8d,
+ 0x01,0x04,0x41,0x13,0x9b,0x52,0x20,0x8d,
+ 0x01,0x04,0x41,0x5f,0x31,0x66,0x20,0x8d,
+ 0x01,0x04,0x42,0x12,0xac,0x15,0x20,0x8d,
+ 0x01,0x04,0x42,0xf0,0xed,0x9b,0x20,0x8d,
+ 0x01,0x04,0x43,0xd2,0xe4,0xcb,0x20,0x8d,
+ 0x01,0x04,0x45,0x1e,0xd7,0x2a,0x20,0x8d,
+ 0x01,0x04,0x45,0x3b,0x12,0xce,0x20,0x8d,
+ 0x01,0x04,0x45,0x40,0x21,0x47,0x20,0x8d,
+ 0x01,0x04,0x45,0x77,0xc1,0x09,0x20,0x8d,
+ 0x01,0x04,0x45,0xd1,0x17,0x48,0x20,0x8d,
+ 0x01,0x04,0x46,0x7b,0x7d,0xed,0x20,0x8d,
+ 0x01,0x04,0x46,0xb9,0x38,0x88,0x20,0x8d,
+ 0x01,0x04,0x47,0x26,0x5a,0xeb,0x20,0x8d,
+ 0x01,0x04,0x48,0x0c,0x49,0x46,0x20,0x8d,
+ 0x01,0x04,0x48,0x35,0x86,0xb6,0x20,0x8d,
+ 0x01,0x04,0x48,0xe1,0x07,0x50,0x20,0x8d,
+ 0x01,0x04,0x48,0xea,0xb6,0x27,0x20,0x8d,
+ 0x01,0x04,0x48,0xfa,0xb8,0x39,0x20,0x8d,
+ 0x01,0x04,0x49,0x53,0x67,0x4f,0x20,0x8d,
+ 0x01,0x04,0x4a,0x76,0x89,0x77,0x20,0x8d,
+ 0x01,0x04,0x4a,0x85,0x64,0x4a,0x20,0x8d,
+ 0x01,0x04,0x4a,0xd7,0xdb,0xd6,0x20,0x8d,
+ 0x01,0x04,0x4a,0xdc,0xff,0xbe,0x20,0x8d,
+ 0x01,0x04,0x4b,0x9e,0x27,0xe7,0x20,0x8d,
+ 0x01,0x04,0x4d,0x35,0x35,0xc4,0x20,0x8d,
+ 0x01,0x04,0x4d,0x46,0x10,0xf5,0x20,0x8d,
+ 0x01,0x04,0x4d,0x69,0x57,0x61,0x20,0x8d,
+ 0x01,0x04,0x4d,0x78,0x71,0x45,0x20,0xf1,
+ 0x01,0x04,0x4d,0x78,0x7a,0x16,0x20,0xf1,
+ 0x01,0x04,0x4d,0xa6,0x53,0xa7,0x20,0x8d,
+ 0x01,0x04,0x4d,0xf7,0xb2,0x82,0x20,0x8d,
+ 0x01,0x04,0x4e,0x1b,0x8b,0x0d,0x20,0x8d,
+ 0x01,0x04,0x4e,0x3f,0x1c,0x92,0x20,0x8d,
+ 0x01,0x04,0x4e,0x53,0x67,0x04,0x20,0x8d,
+ 0x01,0x04,0x4e,0x8d,0x7b,0x63,0x20,0x8d,
+ 0x01,0x04,0x4f,0x4d,0x21,0x83,0x20,0x8d,
+ 0x01,0x04,0x4f,0x4d,0x85,0x1e,0x20,0x8d,
+ 0x01,0x04,0x4f,0x65,0x01,0x19,0x20,0x8d,
+ 0x01,0x04,0x4f,0x75,0xc0,0xe5,0x20,0x8d,
+ 0x01,0x04,0x4f,0x85,0xe4,0x37,0x20,0x8d,
+ 0x01,0x04,0x4f,0x92,0x15,0xa3,0x20,0x8d,
+ 0x01,0x04,0x50,0x59,0xcb,0xac,0x1f,0x41,
+ 0x01,0x04,0x50,0x5d,0xd5,0xf6,0x20,0x8d,
+ 0x01,0x04,0x50,0xc0,0x62,0x6e,0x20,0x8e,
+ 0x01,0x04,0x50,0xe5,0x1c,0x3c,0x20,0x8d,
+ 0x01,0x04,0x50,0xe8,0xf7,0xd2,0x20,0x8d,
+ 0x01,0x04,0x50,0xf2,0x27,0x4c,0x20,0x8d,
+ 0x01,0x04,0x50,0xfd,0x5e,0xfc,0x20,0x8d,
+ 0x01,0x04,0x51,0x00,0xc6,0x19,0x20,0x8d,
+ 0x01,0x04,0x51,0x07,0x0d,0x54,0x20,0x8d,
+ 0x01,0x04,0x51,0x75,0xe1,0xf5,0x20,0x8d,
+ 0x01,0x04,0x51,0x87,0x89,0xe1,0x20,0x8d,
+ 0x01,0x04,0x51,0xab,0x16,0x8f,0x20,0x8d,
+ 0x01,0x04,0x51,0xbf,0xe9,0x86,0x20,0x8d,
+ 0x01,0x04,0x51,0xe8,0x4e,0x4b,0x20,0x8d,
+ 0x01,0x04,0x51,0xf2,0x5b,0x17,0x20,0x8d,
+ 0x01,0x04,0x52,0x1d,0x3a,0x6d,0x20,0x8d,
+ 0x01,0x04,0x52,0x88,0x63,0x16,0x20,0x8d,
+ 0x01,0x04,0x52,0x95,0x61,0x19,0x44,0x9f,
+ 0x01,0x04,0x52,0xa5,0x13,0x30,0x20,0x8d,
+ 0x01,0x04,0x52,0xc2,0x99,0xe9,0x20,0x8d,
+ 0x01,0x04,0x52,0xc5,0xd7,0x7d,0x20,0x8d,
+ 0x01,0x04,0x52,0xc7,0x66,0x0a,0x20,0x8d,
+ 0x01,0x04,0x52,0xc8,0xcd,0x1e,0x20,0x8d,
+ 0x01,0x04,0x52,0xca,0x44,0xe7,0x20,0x8d,
+ 0x01,0x04,0x52,0xdd,0x80,0x1f,0x20,0x8d,
+ 0x01,0x04,0x52,0xe4,0x06,0x83,0x20,0x8d,
+ 0x01,0x04,0x53,0x55,0x8b,0x5e,0x20,0x8d,
+ 0x01,0x04,0x53,0x63,0xf5,0x14,0x20,0x8d,
+ 0x01,0x04,0x53,0x89,0x29,0x0a,0x20,0x8d,
+ 0x01,0x04,0x53,0xae,0xd1,0x57,0x20,0x8d,
+ 0x01,0x04,0x53,0xd9,0x08,0x1f,0xad,0x84,
+ 0x01,0x04,0x54,0x26,0x03,0xf9,0x20,0x8d,
+ 0x01,0x04,0x54,0x26,0xb9,0x7a,0x20,0x8d,
+ 0x01,0x04,0x54,0x5c,0x5c,0xf7,0x20,0x8d,
+ 0x01,0x04,0x54,0xc0,0x10,0xea,0x20,0x8d,
+ 0x01,0x04,0x54,0xc2,0x9e,0x7c,0x20,0x8d,
+ 0x01,0x04,0x54,0xd4,0x91,0x18,0x20,0x8d,
+ 0x01,0x04,0x54,0xd4,0xf4,0x5f,0x20,0x8d,
+ 0x01,0x04,0x54,0xd8,0x33,0x24,0x20,0x8d,
+ 0x01,0x04,0x54,0xff,0xf9,0xa3,0x20,0x8d,
+ 0x01,0x04,0x55,0x19,0xff,0x93,0x20,0x8d,
+ 0x01,0x04,0x55,0x46,0x9c,0xd1,0x20,0x8d,
+ 0x01,0x04,0x55,0x91,0x8e,0x2e,0x20,0x8d,
+ 0x01,0x04,0x55,0xaa,0xe9,0x5f,0x20,0x8d,
+ 0x01,0x04,0x55,0xb8,0x8a,0x6c,0x20,0x8d,
+ 0x01,0x04,0x55,0xbe,0x00,0x05,0x20,0x8d,
+ 0x01,0x04,0x55,0xbf,0xc8,0x33,0x20,0x8d,
+ 0x01,0x04,0x55,0xc0,0xbf,0x06,0x48,0x44,
+ 0x01,0x04,0x55,0xc2,0xee,0x83,0x20,0x8d,
+ 0x01,0x04,0x55,0xc3,0x36,0x6e,0x20,0x8d,
+ 0x01,0x04,0x55,0xd6,0xa1,0xfc,0x20,0x8d,
+ 0x01,0x04,0x55,0xd6,0xb9,0x33,0x20,0x8d,
+ 0x01,0x04,0x55,0xf1,0x6a,0xcb,0x20,0x8d,
+ 0x01,0x04,0x55,0xf6,0xa8,0xfc,0x20,0x8d,
+ 0x01,0x04,0x56,0x38,0xee,0xf7,0x20,0x8d,
+ 0x01,0x04,0x57,0x3d,0x5a,0xe6,0x20,0x8d,
+ 0x01,0x04,0x57,0x4f,0x44,0x56,0x20,0x8d,
+ 0x01,0x04,0x57,0x4f,0x5e,0xdd,0x20,0x8d,
+ 0x01,0x04,0x57,0x78,0x08,0x05,0x4e,0x28,
+ 0x01,0x04,0x57,0xf6,0x2e,0x84,0x20,0x8d,
+ 0x01,0x04,0x57,0xf7,0x6f,0xde,0x20,0x8d,
+ 0x01,0x04,0x58,0x54,0xde,0xfc,0x20,0x8d,
+ 0x01,0x04,0x58,0x56,0xf3,0xf1,0x20,0x8d,
+ 0x01,0x04,0x58,0x57,0x5d,0x34,0x06,0x9b,
+ 0x01,0x04,0x58,0x77,0xc5,0xc8,0x20,0x8d,
+ 0x01,0x04,0x58,0x81,0xfd,0x5e,0x20,0x8d,
+ 0x01,0x04,0x58,0x93,0xf4,0xfa,0x20,0x8d,
+ 0x01,0x04,0x58,0xd0,0x03,0xc3,0x20,0x8d,
+ 0x01,0x04,0x58,0xd4,0x2c,0x21,0x20,0x8d,
+ 0x01,0x04,0x58,0xd6,0x39,0x5f,0x20,0x8d,
+ 0x01,0x04,0x59,0x6a,0xc7,0x26,0x20,0x8d,
+ 0x01,0x04,0x59,0x6c,0x7e,0xe4,0x20,0x8d,
+ 0x01,0x04,0x59,0x73,0x78,0x2b,0x20,0x8d,
+ 0x01,0x04,0x59,0x85,0x44,0x41,0x20,0x8d,
+ 0x01,0x04,0x59,0xbe,0x13,0xa2,0x20,0x8d,
+ 0x01,0x04,0x59,0xf8,0xac,0x0a,0x20,0x8d,
+ 0x01,0x04,0x5a,0x92,0x99,0x15,0x20,0x8d,
+ 0x01,0x04,0x5a,0xb6,0xa5,0x12,0x20,0x8d,
+ 0x01,0x04,0x5b,0x6a,0xbc,0xe5,0x20,0x8d,
+ 0x01,0x04,0x5b,0xc1,0xed,0x74,0x20,0x8d,
+ 0x01,0x04,0x5b,0xcc,0x63,0xb2,0x20,0x8d,
+ 0x01,0x04,0x5b,0xcc,0x95,0x05,0x20,0x8d,
+ 0x01,0x04,0x5b,0xd6,0x46,0x3f,0x20,0x8d,
+ 0x01,0x04,0x5b,0xe4,0x98,0xec,0x20,0x8d,
+ 0x01,0x04,0x5c,0x0c,0x9a,0x73,0x20,0x8d,
+ 0x01,0x04,0x5c,0xf9,0x8f,0x2c,0x20,0x8d,
+ 0x01,0x04,0x5d,0x0c,0x42,0x62,0x20,0x8d,
+ 0x01,0x04,0x5d,0x2e,0x36,0x04,0x20,0x8d,
+ 0x01,0x04,0x5d,0x73,0x14,0x82,0x20,0x8d,
+ 0x01,0x04,0x5d,0x7b,0xb4,0xa4,0x20,0x8d,
+ 0x01,0x04,0x5d,0xbd,0x91,0xa9,0x20,0x8d,
+ 0x01,0x04,0x5d,0xf1,0xe4,0x66,0x20,0x8d,
+ 0x01,0x04,0x5e,0x13,0x07,0x37,0x20,0x8d,
+ 0x01,0x04,0x5e,0x13,0x80,0xcc,0x20,0x8d,
+ 0x01,0x04,0x5e,0x34,0x70,0xe3,0x20,0x8d,
+ 0x01,0x04,0x5e,0x9a,0x60,0x82,0x20,0x8d,
+ 0x01,0x04,0x5e,0x9c,0xae,0xc9,0x20,0x8d,
+ 0x01,0x04,0x5e,0x9e,0xf6,0xb7,0x20,0x8d,
+ 0x01,0x04,0x5e,0xb1,0xab,0x49,0x20,0x8d,
+ 0x01,0x04,0x5e,0xc7,0xb2,0xe9,0x1f,0xa4,
+ 0x01,0x04,0x5e,0xed,0x7d,0x1e,0x20,0x8d,
+ 0x01,0x04,0x5e,0xf7,0x86,0x4d,0x20,0x8d,
+ 0x01,0x04,0x5f,0x30,0xe4,0x2d,0x20,0x8d,
+ 0x01,0x04,0x5f,0x45,0xf9,0x3f,0x20,0x8d,
+ 0x01,0x04,0x5f,0x52,0x92,0x46,0x20,0x8d,
+ 0x01,0x04,0x5f,0x53,0x49,0x1f,0x20,0x8d,
+ 0x01,0x04,0x5f,0x54,0xa4,0x2b,0x20,0x8d,
+ 0x01,0x04,0x5f,0x57,0xe2,0x38,0x20,0x8d,
+ 0x01,0x04,0x5f,0x6e,0xea,0x5d,0x20,0x8d,
+ 0x01,0x04,0x5f,0xa3,0x47,0x7e,0x20,0x8d,
+ 0x01,0x04,0x5f,0xa4,0x41,0xc2,0x20,0x8d,
+ 0x01,0x04,0x5f,0xae,0x42,0xd3,0x20,0x8d,
+ 0x01,0x04,0x5f,0xd3,0xae,0x89,0x20,0x8d,
+ 0x01,0x04,0x5f,0xd8,0x0b,0x9c,0x20,0xf1,
+ 0x01,0x04,0x60,0x2f,0x72,0x6c,0x20,0x8d,
+ 0x01,0x04,0x61,0x54,0xe8,0x69,0x20,0x8d,
+ 0x01,0x04,0x61,0x63,0xcd,0xf1,0x20,0x8d,
+ 0x01,0x04,0x62,0x19,0xc1,0x72,0x20,0x8d,
+ 0x01,0x04,0x63,0x73,0x19,0x0d,0x20,0x8d,
+ 0x01,0x04,0x65,0x20,0x13,0xb8,0x20,0x8d,
+ 0x01,0x04,0x65,0x64,0xae,0xf0,0x20,0x8d,
+ 0x01,0x04,0x66,0x84,0xf5,0x10,0x20,0x8d,
+ 0x01,0x04,0x67,0x0e,0xf4,0xbe,0x20,0x8d,
+ 0x01,0x04,0x67,0x4c,0x30,0x05,0x20,0x8d,
+ 0x01,0x04,0x67,0x54,0x54,0xfa,0x20,0x8f,
+ 0x01,0x04,0x67,0x63,0xa8,0x96,0x20,0x8d,
+ 0x01,0x04,0x67,0x6d,0x65,0xd8,0x20,0x8d,
+ 0x01,0x04,0x67,0x7a,0xf7,0x66,0x20,0x8d,
+ 0x01,0x04,0x67,0x81,0x0d,0x2d,0x20,0x8d,
+ 0x01,0x04,0x67,0xc6,0xc0,0x0e,0x4e,0x28,
+ 0x01,0x04,0x67,0xe0,0x77,0x63,0x20,0x8d,
+ 0x01,0x04,0x67,0xe7,0xbf,0x07,0x20,0x8d,
+ 0x01,0x04,0x67,0xeb,0xe6,0xc4,0x20,0x8d,
+ 0x01,0x04,0x68,0xab,0xf2,0x9b,0x20,0x8d,
+ 0x01,0x04,0x68,0xee,0xdc,0xc7,0x20,0x8d,
+ 0x01,0x04,0x6a,0xa3,0x9e,0x7f,0x20,0x8d,
+ 0x01,0x04,0x6b,0x96,0x29,0xb3,0x20,0x8d,
+ 0x01,0x04,0x6b,0x9f,0x5d,0x67,0x20,0x8d,
+ 0x01,0x04,0x6c,0xb7,0x4d,0x0c,0x20,0x8d,
+ 0x01,0x04,0x6d,0x09,0xaf,0x41,0x20,0x8d,
+ 0x01,0x04,0x6d,0x63,0x3f,0x9f,0x20,0x8d,
+ 0x01,0x04,0x6d,0x6e,0x51,0x5a,0x20,0x8d,
+ 0x01,0x04,0x6d,0x7b,0xd5,0x82,0x20,0x8d,
+ 0x01,0x04,0x6d,0x86,0xe8,0x51,0x20,0x8d,
+ 0x01,0x04,0x6d,0xa9,0x14,0xa8,0x20,0x8d,
+ 0x01,0x04,0x6d,0xc7,0xf1,0x94,0x20,0x8d,
+ 0x01,0x04,0x6d,0xe5,0xd2,0x06,0x20,0x8d,
+ 0x01,0x04,0x6d,0xec,0x69,0x28,0x20,0x8d,
+ 0x01,0x04,0x6d,0xf8,0xce,0x0d,0x20,0x8d,
+ 0x01,0x04,0x6f,0x2a,0x4a,0x41,0x20,0x8d,
+ 0x01,0x04,0x6f,0x5a,0x8c,0xb3,0x20,0x8d,
+ 0x01,0x04,0x70,0xd7,0xcd,0xec,0x20,0x8d,
+ 0x01,0x04,0x71,0x34,0x87,0x7d,0x20,0x8d,
+ 0x01,0x04,0x72,0x17,0xf6,0x89,0x20,0x8d,
+ 0x01,0x04,0x73,0x2f,0x8d,0xfa,0x22,0xb5,
+ 0x01,0x04,0x73,0x46,0x6e,0x04,0x20,0x8d,
+ 0x01,0x04,0x74,0x22,0xbd,0x37,0x20,0x8d,
+ 0x01,0x04,0x76,0x67,0x7e,0x8c,0x6e,0xad,
+ 0x01,0x04,0x76,0xbd,0xbb,0xdb,0x20,0x8d,
+ 0x01,0x04,0x77,0x03,0xd0,0xec,0x20,0x8d,
+ 0x01,0x04,0x77,0x08,0x2f,0xe1,0x20,0x8d,
+ 0x01,0x04,0x77,0x11,0x97,0x3d,0x20,0x8d,
+ 0x01,0x04,0x78,0x19,0x18,0x1e,0x20,0x8d,
+ 0x01,0x04,0x78,0xf1,0x22,0x0a,0x20,0x8d,
+ 0x01,0x04,0x79,0x62,0xcd,0x64,0x20,0x8d,
+ 0x01,0x04,0x7a,0x70,0x94,0x99,0x20,0x93,
+ 0x01,0x04,0x7a,0x74,0x2a,0x8c,0x20,0x8d,
+ 0x01,0x04,0x7c,0xd9,0xeb,0xb4,0x20,0x8d,
+ 0x01,0x04,0x7d,0xec,0xd7,0x85,0x20,0x8d,
+ 0x01,0x04,0x81,0x0d,0xbd,0xd4,0x20,0x8d,
+ 0x01,0x04,0x82,0xb9,0x4d,0x69,0x20,0x8d,
+ 0x01,0x04,0x83,0xbc,0x28,0xbf,0x20,0x8d,
+ 0x01,0x04,0x83,0xc1,0xdc,0x0f,0x20,0x8d,
+ 0x01,0x04,0x87,0x17,0x7c,0xef,0x20,0x8d,
+ 0x01,0x04,0x88,0x21,0xb9,0x20,0x20,0x8d,
+ 0x01,0x04,0x88,0x38,0xaa,0x60,0x20,0x8d,
+ 0x01,0x04,0x89,0xe2,0x22,0x2e,0x20,0x8d,
+ 0x01,0x04,0x8a,0xe5,0x1a,0x2a,0x20,0x8d,
+ 0x01,0x04,0x8b,0x09,0xf9,0xea,0x20,0x8d,
+ 0x01,0x04,0x8d,0x65,0x08,0x24,0x20,0x8d,
+ 0x01,0x04,0x8f,0xb0,0xe0,0x68,0x20,0x8d,
+ 0x01,0x04,0x90,0x02,0x45,0xe0,0x20,0x8d,
+ 0x01,0x04,0x90,0x22,0xa1,0x41,0x47,0x9d,
+ 0x01,0x04,0x90,0x5b,0x74,0x2c,0x20,0x8d,
+ 0x01,0x04,0x90,0x89,0x1d,0xb5,0x20,0x8d,
+ 0x01,0x04,0x94,0x42,0x32,0x32,0x20,0x8f,
+ 0x01,0x04,0x94,0x48,0x96,0xe7,0x20,0x8d,
+ 0x01,0x04,0x94,0xaa,0xd4,0x2c,0x20,0x8d,
+ 0x01,0x04,0x95,0xa7,0x63,0xbe,0x20,0x8d,
+ 0x01,0x04,0x9a,0x5c,0x10,0xbf,0x20,0x8d,
+ 0x01,0x04,0x9a,0xdd,0x1b,0x15,0x20,0x8d,
+ 0x01,0x04,0x9c,0x13,0x13,0x5a,0x20,0x8d,
+ 0x01,0x04,0x9c,0xf1,0x05,0xbe,0x20,0x8d,
+ 0x01,0x04,0x9d,0x0d,0x3d,0x4c,0x20,0x8d,
+ 0x01,0x04,0x9d,0x0d,0x3d,0x50,0x20,0x8d,
+ 0x01,0x04,0x9d,0xe6,0xa6,0x62,0x38,0x37,
+ 0x01,0x04,0x9e,0x4b,0xcb,0x02,0x20,0x8d,
+ 0x01,0x04,0x9e,0xb5,0x7d,0x96,0x20,0x8d,
+ 0x01,0x04,0x9e,0xb5,0xe2,0x21,0x20,0x8d,
+ 0x01,0x04,0x9f,0x64,0xf2,0xfe,0x20,0x8d,
+ 0x01,0x04,0x9f,0x64,0xf8,0xea,0x20,0x8d,
+ 0x01,0x04,0x9f,0x8a,0x57,0x12,0x20,0x8d,
+ 0x01,0x04,0xa0,0x10,0x00,0x1e,0x20,0x8d,
+ 0x01,0x04,0xa2,0x00,0xe3,0x36,0x20,0x8d,
+ 0x01,0x04,0xa2,0x00,0xe3,0x38,0x20,0x8d,
+ 0x01,0x04,0xa2,0x3e,0x12,0xe2,0x20,0x8d,
+ 0x01,0x04,0xa2,0xd1,0x01,0xe9,0x20,0x8d,
+ 0x01,0x04,0xa2,0xf3,0xaf,0x56,0x20,0x8d,
+ 0x01,0x04,0xa2,0xf4,0x50,0xd0,0x20,0x8d,
+ 0x01,0x04,0xa2,0xfa,0xbc,0x57,0x20,0x8d,
+ 0x01,0x04,0xa2,0xfa,0xbd,0x35,0x20,0x8d,
+ 0x01,0x04,0xa3,0x9e,0xca,0x70,0x20,0x8d,
+ 0x01,0x04,0xa3,0x9e,0xf3,0xe6,0x20,0x8d,
+ 0x01,0x04,0xa5,0x49,0x3e,0x1f,0x20,0x8d,
+ 0x01,0x04,0xa6,0x3e,0x52,0x67,0x80,0x03,
+ 0x01,0x04,0xa6,0x46,0x5e,0x6a,0x20,0x8d,
+ 0x01,0x04,0xa7,0x56,0x5a,0xef,0x20,0x8d,
+ 0x01,0x04,0xa9,0x2c,0x22,0xcb,0x20,0x8d,
+ 0x01,0x04,0xac,0x5d,0x65,0x49,0x20,0x8d,
+ 0x01,0x04,0xac,0x69,0x07,0x2f,0x20,0x8d,
+ 0x01,0x04,0xad,0x17,0x67,0x1e,0x1f,0x40,
+ 0x01,0x04,0xad,0x35,0x4f,0x06,0x20,0x8d,
+ 0x01,0x04,0xad,0x46,0x0c,0x56,0x20,0x8d,
+ 0x01,0x04,0xad,0x59,0x1c,0x89,0x20,0x8d,
+ 0x01,0x04,0xad,0xb0,0xb8,0x36,0x20,0x8d,
+ 0x01,0x04,0xad,0xd0,0x80,0x0a,0x20,0x8d,
+ 0x01,0x04,0xad,0xfe,0xcc,0x45,0x20,0x8d,
+ 0x01,0x04,0xad,0xff,0xcc,0x7c,0x20,0x8d,
+ 0x01,0x04,0xae,0x5e,0x9b,0xe0,0x20,0x8d,
+ 0x01,0x04,0xae,0x72,0x66,0x29,0x20,0x8d,
+ 0x01,0x04,0xae,0x72,0x7c,0x0c,0x20,0x8d,
+ 0x01,0x04,0xb0,0x0a,0xe3,0x3b,0x20,0x8d,
+ 0x01,0x04,0xb0,0x1f,0xe0,0xd6,0x20,0x8d,
+ 0x01,0x04,0xb0,0x4a,0x88,0xed,0x20,0x8d,
+ 0x01,0x04,0xb0,0x63,0x02,0xcf,0x20,0x8d,
+ 0x01,0x04,0xb0,0x6a,0xbf,0x02,0x20,0x8d,
+ 0x01,0x04,0xb0,0xa0,0xe4,0x09,0x20,0x8d,
+ 0x01,0x04,0xb0,0xbf,0xb6,0x03,0x20,0x8d,
+ 0x01,0x04,0xb0,0xd4,0xb9,0x99,0x20,0x8d,
+ 0x01,0x04,0xb0,0xf1,0x89,0xb7,0x20,0x8d,
+ 0x01,0x04,0xb1,0x26,0xd7,0x49,0x20,0x8d,
+ 0x01,0x04,0xb2,0x10,0xde,0x92,0x20,0x8d,
+ 0x01,0x04,0xb2,0x84,0x02,0xf6,0x20,0x8d,
+ 0x01,0x04,0xb2,0x8f,0xbf,0xab,0x20,0x8d,
+ 0x01,0x04,0xb2,0x94,0xac,0xd1,0x20,0x8d,
+ 0x01,0x04,0xb2,0x94,0xe2,0xb4,0x20,0x8d,
+ 0x01,0x04,0xb2,0x96,0x60,0x2e,0x20,0x8d,
+ 0x01,0x04,0xb2,0xb6,0xe3,0x32,0x20,0x8d,
+ 0x01,0x04,0xb2,0xec,0x89,0x3f,0x20,0x8d,
+ 0x01,0x04,0xb2,0xff,0x2a,0x7e,0x20,0x8d,
+ 0x01,0x04,0xb4,0x96,0x34,0x25,0x20,0x8d,
+ 0x01,0x04,0xb5,0x27,0x20,0x63,0x20,0x8d,
+ 0x01,0x04,0xb5,0x30,0x4d,0x1a,0x20,0x8d,
+ 0x01,0x04,0xb5,0x34,0xdf,0x34,0x20,0x8d,
+ 0x01,0x04,0xb5,0xee,0x33,0x98,0x20,0x8d,
+ 0x01,0x04,0xb7,0x58,0xdf,0xd0,0x20,0x8d,
+ 0x01,0x04,0xb7,0x6e,0xdc,0xd2,0x76,0x5d,
+ 0x01,0x04,0xb8,0x5f,0x3a,0xa6,0x20,0x90,
+ 0x01,0x04,0xb8,0xa4,0x93,0x52,0xa1,0x75,
+ 0x01,0x04,0xb8,0xab,0xd0,0x6d,0x20,0x8d,
+ 0x01,0x04,0xb9,0x19,0x30,0x27,0x20,0x8d,
+ 0x01,0x04,0xb9,0x19,0x30,0xb8,0x20,0x8d,
+ 0x01,0x04,0xb9,0x40,0x74,0x0f,0x20,0x8d,
+ 0x01,0x04,0xb9,0x50,0xdb,0x84,0x20,0x8d,
+ 0x01,0x04,0xb9,0x55,0x03,0x8c,0x20,0x8d,
+ 0x01,0x04,0xb9,0x5f,0xdb,0x35,0x20,0x8d,
+ 0x01,0x04,0xb9,0x6c,0xf4,0x29,0x20,0x8d,
+ 0x01,0x04,0xb9,0x86,0xe9,0x79,0x20,0x8d,
+ 0x01,0x04,0xb9,0x91,0x80,0x15,0x20,0x8d,
+ 0x01,0x04,0xb9,0x94,0x03,0xe3,0x20,0x8d,
+ 0x01,0x04,0xb9,0x99,0xc4,0xf0,0x20,0x8d,
+ 0x01,0x04,0xb9,0x9e,0x72,0xb8,0x20,0x8d,
+ 0x01,0x04,0xb9,0xa5,0xa8,0xc4,0x20,0x8d,
+ 0x01,0x04,0xb9,0xb5,0xe6,0x4a,0x20,0x8d,
+ 0x01,0x04,0xb9,0xb9,0x1a,0x8d,0x1f,0xaf,
+ 0x01,0x04,0xb9,0xba,0xd0,0xa2,0x20,0x8d,
+ 0x01,0x04,0xb9,0xbd,0x84,0xb2,0xe1,0xb4,
+ 0x01,0x04,0xb9,0xd3,0x3b,0x32,0x20,0x8d,
+ 0x01,0x04,0xb9,0xe9,0x94,0x92,0x20,0x8d,
+ 0x01,0x04,0xb9,0xee,0x81,0x71,0x20,0x8d,
+ 0x01,0x04,0xb9,0xf9,0xc7,0x6a,0x20,0x8d,
+ 0x01,0x04,0xb9,0xfb,0xa1,0x36,0x20,0x8d,
+ 0x01,0x04,0xbb,0xbd,0x99,0x88,0x20,0x8d,
+ 0x01,0x04,0xbc,0x25,0x18,0xbe,0x20,0x8d,
+ 0x01,0x04,0xbc,0x2a,0x28,0xea,0x47,0x9d,
+ 0x01,0x04,0xbc,0x3d,0x2e,0x24,0x20,0x8d,
+ 0x01,0x04,0xbc,0x44,0x2d,0x8f,0x20,0x8d,
+ 0x01,0x04,0xbc,0x7f,0xe5,0x69,0x20,0x8d,
+ 0x01,0x04,0xbc,0x86,0x06,0x54,0x20,0x8d,
+ 0x01,0x04,0xbc,0x86,0x08,0x24,0x20,0x8d,
+ 0x01,0x04,0xbc,0xd6,0x81,0x41,0x4e,0x2c,
+ 0x01,0x04,0xbc,0xe6,0xa8,0x72,0x20,0x8d,
+ 0x01,0x04,0xbd,0x22,0x0e,0x5d,0x20,0x8d,
+ 0x01,0x04,0xbd,0xcf,0x2e,0x20,0x20,0x8d,
+ 0x01,0x04,0xbe,0xd3,0xcc,0x44,0x20,0x8d,
+ 0x01,0x04,0xbf,0xd1,0x15,0xbc,0x20,0x8d,
+ 0x01,0x04,0xc0,0x03,0x0b,0x14,0x20,0x8d,
+ 0x01,0x04,0xc0,0x03,0xb9,0xd2,0x20,0x8d,
+ 0x01,0x04,0xc0,0x41,0xaa,0x0f,0x20,0x8d,
+ 0x01,0x04,0xc0,0x41,0xaa,0x32,0x20,0x8d,
+ 0x01,0x04,0xc0,0x92,0x89,0x12,0x20,0x8d,
+ 0x01,0x04,0xc0,0x9d,0xca,0xb2,0x20,0x8d,
+ 0x01,0x04,0xc0,0xe3,0x50,0x53,0x20,0x8d,
+ 0x01,0x04,0xc1,0x0a,0xcb,0x17,0x20,0x8e,
+ 0x01,0x04,0xc1,0x19,0x06,0xce,0x20,0x8d,
+ 0x01,0x04,0xc1,0x2a,0x6e,0x1e,0x20,0x8d,
+ 0x01,0x04,0xc1,0x3a,0xc4,0xd4,0x20,0x8d,
+ 0x01,0x04,0xc1,0x6a,0x1c,0x08,0x20,0x8d,
+ 0x01,0x04,0xc1,0xbd,0xbe,0x7b,0x20,0x8d,
+ 0x01,0x04,0xc1,0xc2,0xa3,0x23,0x20,0x8d,
+ 0x01,0x04,0xc1,0xc2,0xa3,0x35,0x20,0x8d,
+ 0x01,0x04,0xc2,0x0e,0xf6,0xcd,0x20,0x8d,
+ 0x01,0x04,0xc2,0x24,0x5b,0xfd,0x20,0x8d,
+ 0x01,0x04,0xc2,0x7e,0x71,0x87,0x20,0x8d,
+ 0x01,0x04,0xc2,0x87,0x87,0x45,0x20,0x8d,
+ 0x01,0x04,0xc3,0x38,0x3f,0x04,0x20,0x8d,
+ 0x01,0x04,0xc3,0x38,0x3f,0x05,0x20,0x8d,
+ 0x01,0x04,0xc3,0x43,0x8b,0x36,0x20,0x8d,
+ 0x01,0x04,0xc3,0x87,0xc2,0x08,0x20,0x8d,
+ 0x01,0x04,0xc3,0xca,0xa9,0x95,0x20,0x8d,
+ 0x01,0x04,0xc3,0xce,0x69,0x2a,0x20,0x8d,
+ 0x01,0x04,0xc3,0xd1,0xf9,0xa4,0x20,0x8d,
+ 0x01,0x04,0xc6,0x01,0xe7,0x06,0x20,0x8d,
+ 0x01,0x04,0xc6,0xc8,0x2b,0xd7,0x20,0x8d,
+ 0x01,0x04,0xc7,0xb6,0xb8,0xcc,0x20,0x8d,
+ 0x01,0x04,0xc7,0xf7,0x07,0xd0,0x20,0x8d,
+ 0x01,0x04,0xc7,0xf7,0xf9,0xbc,0x20,0x8d,
+ 0x01,0x04,0xc8,0x07,0xfc,0x76,0x20,0x8d,
+ 0x01,0x04,0xc8,0x14,0xba,0xfe,0x20,0x8d,
+ 0x01,0x04,0xc8,0x53,0xa6,0x88,0x20,0x8d,
+ 0x01,0x04,0xca,0x37,0x57,0x2d,0x20,0x8d,
+ 0x01,0x04,0xca,0x4f,0xa7,0x41,0x20,0x8d,
+ 0x01,0x04,0xca,0x6c,0xd3,0x87,0x20,0x8d,
+ 0x01,0x04,0xca,0xa9,0x66,0x49,0x20,0x8d,
+ 0x01,0x04,0xcb,0x82,0x30,0x75,0x22,0xb5,
+ 0x01,0x04,0xcb,0x84,0x5f,0x0a,0x20,0x8d,
+ 0x01,0x04,0xcb,0x97,0xa6,0x7b,0x20,0x8d,
+ 0x01,0x04,0xcc,0x5d,0x71,0x6c,0x20,0x8d,
+ 0x01,0x04,0xcc,0x6f,0xf1,0xc3,0x20,0x8d,
+ 0x01,0x04,0xce,0x7c,0x95,0x42,0x20,0x8d,
+ 0x01,0x04,0xcf,0x73,0x66,0x62,0x20,0x8d,
+ 0x01,0x04,0xcf,0xe5,0x2e,0x96,0x20,0x8d,
+ 0x01,0x04,0xd0,0x4c,0xfc,0xc6,0x20,0x8d,
+ 0x01,0x04,0xd0,0x64,0x0d,0x38,0x20,0x8d,
+ 0x01,0x04,0xd0,0x64,0xb2,0xaf,0x20,0x8d,
+ 0x01,0x04,0xd0,0x6e,0x63,0x69,0x20,0x8d,
+ 0x01,0x04,0xd1,0x06,0xd2,0xb3,0x20,0x8d,
+ 0x01,0x04,0xd1,0x85,0xdc,0x4a,0x20,0x8d,
+ 0x01,0x04,0xd1,0x8d,0x39,0x39,0x20,0x8d,
+ 0x01,0x04,0xd3,0x1b,0x93,0x43,0x20,0x8d,
+ 0x01,0x04,0xd4,0x22,0xe1,0x76,0x20,0x8d,
+ 0x01,0x04,0xd4,0x59,0xad,0xd8,0x20,0x8d,
+ 0x01,0x04,0xd4,0x63,0xe2,0x24,0x23,0x3c,
+ 0x01,0x04,0xd4,0xed,0x60,0x62,0x20,0x8d,
+ 0x01,0x04,0xd5,0x59,0x83,0x35,0x20,0x8d,
+ 0x01,0x04,0xd8,0x26,0x81,0xa4,0x20,0x8d,
+ 0x01,0x04,0xd8,0x86,0xa5,0x37,0x20,0x8d,
+ 0x01,0x04,0xd8,0x92,0xfb,0x08,0x20,0x8d,
+ 0x01,0x04,0xd8,0xbd,0xbe,0x5f,0x20,0x8d,
+ 0x01,0x04,0xd8,0xe2,0x80,0xbd,0x20,0x8d,
+ 0x01,0x04,0xd8,0xec,0xa4,0x52,0x20,0x8d,
+ 0x01,0x04,0xd9,0x13,0xd8,0xd2,0x20,0x8d,
+ 0x01,0x04,0xd9,0x1a,0x20,0x0a,0x20,0x8d,
+ 0x01,0x04,0xd9,0x40,0x2f,0x8a,0x20,0x8d,
+ 0x01,0x04,0xd9,0x40,0x85,0xdc,0x20,0x8d,
+ 0x01,0x04,0xd9,0x5c,0x37,0xf6,0x20,0x8d,
+ 0x01,0x04,0xda,0x1f,0x71,0xf5,0x20,0x8d,
+ 0x01,0x04,0xda,0xff,0xf2,0x72,0x20,0x8d,
+ 0x01,0x04,0xdc,0x85,0x27,0x3d,0x20,0x8d,
+ 0x01,0x04,0xdf,0x10,0x1e,0xaf,0x20,0x8d,
+ 0x02,0x10,0x20,0x01,0x19,0xf0,0x60,0x01,0x30,0x6f,0x0e,0xc4,0x7a,0xff,0xfe,0x8f,0x66,0xec,0x20,0x8d,
+ 0x02,0x10,0x20,0x01,0x1b,0xc0,0x00,0xcc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x01,0x20,0x8d,
+ 0x02,0x10,0x20,0x01,0x1c,0x02,0x2f,0x18,0x0d,0x00,0xb6,0x2e,0x99,0xff,0xfe,0x49,0xd4,0x92,0x20,0x8d,
+ 0x02,0x10,0x20,0x01,0x41,0x00,0x00,0x00,0x00,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x93,0x20,0x8d,
+ 0x02,0x10,0x20,0x01,0x41,0x00,0x00,0x00,0x00,0x64,0xdc,0xaf,0xaf,0xff,0xfe,0x00,0x67,0x07,0x20,0x8d,
+ 0x02,0x10,0x20,0x01,0x04,0x70,0x00,0x0a,0x0c,0x13,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x20,0x8d,
+ 0x02,0x10,0x20,0x01,0x48,0x01,0x78,0x19,0x00,0x74,0xb7,0x45,0xb9,0xd5,0xff,0x10,0xa6,0x1a,0x20,0x8d,
+ 0x02,0x10,0x20,0x01,0x4b,0xa0,0xff,0xfa,0x00,0x5d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x93,0x20,0x8d,
+ 0x02,0x10,0x20,0x01,0x06,0x10,0x19,0x08,0xff,0x01,0xf8,0x16,0x3e,0xff,0xfe,0x33,0x2e,0x32,0x20,0x8d,
+ 0x02,0x10,0x20,0x01,0x06,0x38,0xa0,0x00,0x41,0x40,0x00,0x00,0x00,0x00,0xff,0xff,0x01,0x91,0x20,0x8d,
+ 0x02,0x10,0x20,0x01,0x06,0x48,0x28,0x00,0x01,0x31,0x4b,0x1f,0xf6,0xfc,0x20,0xf7,0xf9,0x9f,0x20,0x8d,
+ 0x02,0x10,0x20,0x01,0x06,0x78,0x07,0xdc,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x20,0x8d,
+ 0x02,0x10,0x20,0x01,0x06,0x78,0x0c,0xc8,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x10,0x00,0x88,0x4e,0x28,
+ 0x02,0x10,0x20,0x01,0x06,0x7c,0x12,0x20,0x08,0x0c,0x00,0x00,0x00,0x00,0x93,0xe5,0x0d,0xd2,0x20,0x8d,
+ 0x02,0x10,0x20,0x01,0x06,0x7c,0x12,0x20,0x08,0x0c,0xe5,0xdc,0xad,0x0c,0x92,0x89,0xc2,0x8f,0x20,0x8d,
+ 0x02,0x10,0x20,0x01,0x06,0x7c,0x16,0xdc,0x12,0x01,0x50,0x54,0x00,0xff,0xfe,0x17,0x4d,0xac,0x20,0x8d,
+ 0x02,0x10,0x20,0x01,0x06,0x7c,0x23,0x54,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x22,0x20,0x8d,
+ 0x02,0x10,0x20,0x01,0x06,0x7c,0x26,0xb4,0x00,0x12,0x7a,0xe3,0xb5,0xff,0xfe,0x04,0x6f,0x9c,0x20,0x8d,
+ 0x02,0x10,0x20,0x01,0x06,0x7c,0x02,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0xfa,0x20,0x8d,
+ 0x02,0x10,0x20,0x01,0x07,0x18,0x08,0x01,0x03,0x11,0x50,0x54,0x00,0xff,0xfe,0x19,0xc4,0x83,0x20,0x8d,
+ 0x02,0x10,0x20,0x01,0x08,0xd8,0x08,0x7c,0x7c,0x00,0x00,0x00,0x00,0x00,0x00,0x99,0x03,0xc1,0x20,0x8d,
+ 0x02,0x10,0x20,0x01,0x08,0xf1,0x14,0x04,0x37,0x00,0x8e,0x49,0x71,0x5a,0x2e,0x09,0xb6,0x34,0x24,0xe4,
+ 0x02,0x10,0x20,0x01,0x0b,0x07,0x5d,0x29,0x99,0xa5,0x19,0x4b,0x38,0x74,0xd6,0x5e,0xa9,0x0d,0x20,0x8d,
+ 0x02,0x10,0x20,0x01,0x0b,0xa8,0x01,0xf1,0xf0,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x20,0x8d,
+ 0x02,0x10,0x20,0x01,0x0b,0xc8,0x12,0x00,0x00,0x00,0xda,0xc4,0x97,0xff,0xfe,0x2a,0x35,0x54,0x4e,0x28,
+ 0x02,0x10,0x20,0x01,0x0d,0xa8,0x10,0x0d,0x00,0x22,0x10,0xfa,0xd8,0x5f,0x10,0xf2,0x21,0xfd,0x20,0x8d,
+ 0x02,0x10,0x20,0x01,0x0d,0xa8,0x80,0x01,0x7a,0x39,0xf0,0x35,0x00,0x7d,0xb9,0x9f,0xeb,0x79,0x20,0x8d,
+ 0x02,0x10,0x20,0x01,0x0e,0x42,0x01,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x20,0x8d,
+ 0x02,0x10,0x24,0x00,0x24,0x12,0x01,0x03,0xc9,0x00,0x08,0x25,0x8f,0x20,0xea,0xff,0x65,0xc2,0x20,0x8d,
+ 0x02,0x10,0x24,0x00,0x40,0x52,0x0e,0x20,0x4f,0x00,0x69,0xfe,0xbb,0x33,0x7b,0x1c,0xa1,0xca,0x20,0x8d,
+ 0x02,0x10,0x24,0x01,0x18,0x00,0x78,0x00,0x01,0x05,0xbe,0x76,0x4e,0xff,0xfe,0x1c,0x0b,0x35,0x20,0x8d,
+ 0x02,0x10,0x24,0x01,0x39,0x00,0x00,0x02,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x20,0x8d,
+ 0x02,0x10,0x24,0x01,0xb1,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x01,0x50,0x20,0x8d,
+ 0x02,0x10,0x24,0x01,0xd0,0x02,0x44,0x02,0x00,0x00,0x8f,0x28,0x59,0x1a,0x6e,0xa0,0xc6,0x83,0x20,0x8d,
+ 0x02,0x10,0x24,0x03,0x62,0x00,0x88,0x21,0x3d,0x68,0x19,0x5b,0x87,0xe9,0x68,0x19,0xd5,0xc8,0x20,0x8d,
+ 0x02,0x10,0x24,0x05,0x65,0x80,0x21,0x40,0x3a,0x00,0xc2,0x8c,0x09,0x83,0x36,0x4b,0x5d,0x70,0x20,0x8d,
+ 0x02,0x10,0x24,0x05,0x98,0x00,0xb9,0x11,0xa1,0x8a,0x58,0xeb,0xcd,0x3c,0x9d,0x82,0xea,0x4a,0x20,0x8d,
+ 0x02,0x10,0x24,0x05,0xaa,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x20,0x8d,
+ 0x02,0x10,0x24,0x09,0x00,0x10,0xca,0x20,0x1d,0xf0,0x02,0x24,0xe8,0xff,0xfe,0x1f,0x60,0xd9,0x20,0x8d,
+ 0x02,0x10,0x24,0x09,0x8a,0x1e,0xa9,0xaf,0x36,0x60,0x1c,0x5a,0x5b,0x6b,0x8a,0x2d,0x98,0x48,0x20,0x8d,
+ 0x02,0x10,0x24,0x09,0x8a,0x1e,0xa9,0xaf,0x36,0x60,0x04,0x04,0x39,0xba,0x88,0xf2,0xe8,0xdf,0x20,0x8d,
+ 0x02,0x10,0x24,0x0b,0x00,0x10,0x91,0x41,0x04,0x00,0x49,0xb4,0x3a,0x2e,0x01,0xe5,0x08,0x4c,0x20,0x8d,
+ 0x02,0x10,0x24,0x0d,0x00,0x1a,0x07,0x59,0x60,0x00,0xa7,0xb1,0x45,0x1a,0x88,0x74,0xe1,0xac,0x20,0x8d,
+ 0x02,0x10,0x24,0x0d,0x00,0x1a,0x07,0x59,0x60,0x00,0xdd,0xab,0x31,0x41,0x4d,0xa0,0x88,0x78,0x20,0x8d,
+ 0x02,0x10,0x26,0x00,0x88,0x05,0x24,0x00,0x01,0x4e,0x12,0xdd,0xb1,0xff,0xfe,0xf2,0x30,0x13,0x20,0x8d,
+ 0x02,0x10,0x26,0x01,0x06,0x02,0x8d,0x80,0x0b,0x63,0xdc,0x3e,0x24,0xff,0xfe,0x92,0x05,0xeb,0x20,0x8d,
+ 0x02,0x10,0x26,0x02,0xff,0xb6,0x00,0x04,0x27,0x98,0xf8,0x16,0x3e,0xff,0xfe,0x2f,0x54,0x41,0x20,0x8d,
+ 0x02,0x10,0x26,0x02,0xff,0xb6,0x00,0x04,0x73,0x9e,0xf8,0x16,0x3e,0xff,0xfe,0x00,0xc2,0xb3,0x20,0x8d,
+ 0x02,0x10,0x26,0x02,0xff,0xb8,0x00,0x00,0x00,0x00,0x02,0x08,0x00,0x72,0x00,0x57,0x02,0x00,0x20,0x8d,
+ 0x02,0x10,0x26,0x04,0x13,0x80,0x41,0x11,0x93,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x8d,
+ 0x02,0x10,0x26,0x04,0x43,0x00,0x00,0x0a,0x00,0x2e,0x02,0x1b,0x21,0xff,0xfe,0x11,0x03,0x92,0x20,0x8d,
+ 0x02,0x10,0x26,0x04,0x45,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2e,0x06,0x1f,0xb0,
+ 0x02,0x10,0x26,0x04,0x55,0x00,0x70,0x6a,0x40,0x00,0xfc,0x79,0xb9,0xbb,0x01,0xd7,0xc3,0x25,0x20,0x8d,
+ 0x02,0x10,0x26,0x04,0x55,0x00,0xc1,0x34,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xfc,0x80,0x1d,
+ 0x02,0x10,0x26,0x04,0x68,0x00,0x5e,0x11,0x01,0x62,0x5c,0x8f,0xd2,0xff,0xfe,0x26,0x14,0x6f,0x20,0x8d,
+ 0x02,0x10,0x26,0x05,0x4d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x20,0x8d,
+ 0x02,0x10,0x26,0x05,0x64,0x00,0x00,0x20,0x13,0xbf,0xdf,0x1d,0x18,0x1c,0x83,0xbb,0x22,0xe8,0x20,0x8d,
+ 0x02,0x10,0x26,0x05,0xae,0x00,0x02,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x03,0x20,0x8d,
+ 0x02,0x10,0x26,0x05,0xc0,0x00,0x2a,0x0a,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x20,0x8d,
+ 0x02,0x10,0x26,0x07,0xf2,0xc0,0xf0,0x0e,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x54,0x20,0x8d,
+ 0x02,0x10,0x26,0x07,0xf2,0xf8,0xad,0x40,0x0b,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x8d,
+ 0x02,0x10,0x26,0x07,0xf4,0x70,0x00,0x08,0x10,0x48,0xae,0x1f,0x6b,0xff,0xfe,0x70,0x72,0x40,0x20,0x8d,
+ 0x02,0x10,0x26,0x07,0xff,0x28,0x80,0x0f,0x00,0x97,0x02,0x25,0x90,0xff,0xfe,0x75,0x11,0x10,0x20,0x8d,
+ 0x02,0x10,0x26,0x20,0x01,0x1c,0x50,0x01,0x11,0x18,0xd2,0x67,0xe5,0xff,0xfe,0xe9,0xe6,0x73,0x20,0x8d,
+ 0x02,0x10,0x26,0x20,0x00,0x6e,0xa0,0x00,0x20,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x20,0x8d,
+ 0x02,0x10,0x28,0x04,0x01,0x4d,0x4c,0x93,0x98,0x09,0x97,0x69,0xda,0x80,0x18,0x32,0x34,0x80,0x20,0x8d,
+ 0x02,0x10,0x2a,0x00,0x13,0x28,0xe1,0x01,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x63,0x20,0x8d,
+ 0x02,0x10,0x2a,0x00,0x13,0x98,0x00,0x04,0x2a,0x03,0x02,0x15,0x5d,0xff,0xfe,0xd6,0x10,0x33,0x20,0x8d,
+ 0x02,0x10,0x2a,0x00,0x13,0xa0,0x30,0x15,0x00,0x01,0x00,0x85,0x00,0x14,0x00,0x79,0x00,0x26,0x20,0x8d,
+ 0x02,0x10,0x2a,0x00,0x16,0x30,0x00,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x20,0x8d,
+ 0x02,0x10,0x2a,0x00,0x17,0x68,0x20,0x01,0x00,0x27,0x00,0x00,0x00,0x00,0x00,0x00,0xef,0x6a,0x20,0x8d,
+ 0x02,0x10,0x2a,0x00,0x18,0x28,0xa0,0x04,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x66,0x20,0x8d,
+ 0x02,0x10,0x2a,0x00,0x18,0x38,0x00,0x36,0x00,0x17,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0xcb,0x20,0x8d,
+ 0x02,0x10,0x2a,0x00,0x18,0x38,0x00,0x36,0x00,0x7d,0x00,0x00,0x00,0x00,0x00,0x00,0xd3,0xc6,0x20,0x8d,
+ 0x02,0x10,0x2a,0x00,0x1c,0x10,0x00,0x02,0x07,0x09,0x58,0xf7,0xe0,0xff,0xfe,0x24,0xa0,0xba,0x56,0xcc,
+ 0x02,0x10,0x2a,0x00,0x1c,0x10,0x00,0x02,0x07,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x17,0x56,0xcc,
+ 0x02,0x10,0x2a,0x00,0x1f,0x40,0x50,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x31,0x20,0x8d,
+ 0x02,0x10,0x2a,0x00,0x60,0x20,0x13,0x95,0x14,0x00,0xba,0xf7,0x2d,0x43,0x60,0xb3,0x19,0x8b,0x20,0x8d,
+ 0x02,0x10,0x2a,0x00,0x7c,0x80,0x00,0x00,0x01,0x0b,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xaf,0x20,0x8d,
+ 0x02,0x10,0x2a,0x00,0x8a,0x60,0xe0,0x12,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x21,0x20,0x8d,
+ 0x02,0x10,0x2a,0x00,0xab,0x00,0x06,0x03,0x00,0x84,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x20,0x8d,
+ 0x02,0x10,0x2a,0x00,0xbb,0xe0,0x00,0xcc,0x00,0x00,0x62,0xa4,0x4c,0xff,0xfe,0x23,0x75,0x10,0x20,0x8d,
+ 0x02,0x10,0x2a,0x00,0x0c,0xa8,0x0a,0x1f,0x30,0x25,0xf9,0x49,0xe4,0x42,0xc9,0x40,0x13,0xe8,0x20,0x8d,
+ 0x02,0x10,0x2a,0x00,0xd2,0xa0,0x00,0x0a,0x3d,0x00,0x1c,0xdf,0x38,0xbb,0xa7,0xd6,0xc2,0x51,0x20,0x8d,
+ 0x02,0x10,0x2a,0x00,0xd8,0x80,0x00,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x0e,0x20,0x8d,
+ 0x02,0x10,0x2a,0x00,0x0e,0xc0,0x72,0x07,0x91,0x00,0x5f,0x8f,0x25,0xdd,0x25,0x74,0x39,0x82,0x20,0x8d,
+ 0x02,0x10,0x2a,0x00,0xf8,0x20,0x04,0x33,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x36,0x20,0x8d,
+ 0x02,0x10,0x2a,0x01,0x01,0x38,0xa0,0x17,0xb0,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x42,0x20,0x8d,
+ 0x02,0x10,0x2a,0x01,0x04,0x30,0x00,0x17,0x00,0x01,0x00,0x00,0x00,0x00,0xff,0xff,0x11,0x53,0x20,0x8d,
+ 0x02,0x10,0x2a,0x01,0x04,0x90,0x00,0x16,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x20,0x8d,
+ 0x02,0x10,0x2a,0x01,0x4b,0x00,0x80,0x7c,0x1b,0x00,0xcd,0xa1,0x0c,0x6a,0x2b,0xad,0x24,0x18,0x20,0x8d,
+ 0x02,0x10,0x2a,0x01,0x4b,0x00,0x80,0xe7,0x54,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x8d,
+ 0x02,0x10,0x2a,0x01,0x04,0xf8,0x01,0x92,0x42,0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x20,0xf1,
+ 0x02,0x10,0x2a,0x01,0x07,0xa0,0x00,0x02,0x13,0x7c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x20,0x8d,
+ 0x02,0x10,0x2a,0x01,0x07,0xa7,0x00,0x02,0x14,0x67,0x0e,0xc4,0x7a,0xff,0xfe,0xe2,0x56,0x90,0x20,0x8d,
+ 0x02,0x10,0x2a,0x01,0x07,0xc8,0xd0,0x02,0x01,0x0f,0x50,0x54,0x00,0xff,0xfe,0x5c,0xda,0xc7,0x20,0x8d,
+ 0x02,0x10,0x2a,0x01,0x07,0xc8,0xd0,0x02,0x03,0x18,0x50,0x54,0x00,0xff,0xfe,0xbe,0xcb,0xb1,0x20,0x8d,
+ 0x02,0x10,0x2a,0x01,0x87,0x40,0x00,0x01,0xff,0xc5,0x00,0x00,0x00,0x00,0x00,0x00,0x8c,0x6a,0x20,0x8d,
+ 0x02,0x10,0x2a,0x01,0xcb,0x00,0x0f,0x98,0xca,0x00,0x50,0x54,0x00,0xff,0xfe,0xd4,0x76,0x3d,0x20,0x8d,
+ 0x02,0x10,0x2a,0x01,0xcb,0x14,0x0c,0xf6,0xbc,0x00,0x21,0xe5,0xf1,0x2e,0x32,0xc8,0x01,0x45,0x20,0x8d,
+ 0x02,0x10,0x2a,0x01,0x00,0xd0,0x00,0x00,0x00,0x1c,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x45,0x20,0x8d,
+ 0x02,0x10,0x2a,0x01,0x00,0xd0,0xbe,0xf2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x12,0x20,0x8d,
+ 0x02,0x10,0x2a,0x01,0x0e,0x35,0x2e,0x40,0x68,0x30,0x02,0x11,0x32,0xff,0xfe,0xa6,0xde,0x3d,0x20,0x8d,
+ 0x02,0x10,0x2a,0x02,0x12,0x05,0xc6,0xaa,0x60,0xc0,0x70,0xd8,0xaa,0xee,0xa8,0x2d,0x99,0x3c,0x20,0x8d,
+ 0x02,0x10,0x2a,0x02,0x01,0x69,0x05,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x14,0x20,0x8d,
+ 0x02,0x10,0x2a,0x02,0x01,0x80,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x5b,0x8f,0x53,0x8c,0x20,0x8d,
+ 0x02,0x10,0x2a,0x02,0x03,0x48,0x00,0x62,0x5e,0xf7,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x8d,
+ 0x02,0x10,0x2a,0x02,0x03,0x90,0x90,0x00,0x00,0x00,0x02,0x18,0x7d,0xff,0xfe,0x10,0xbe,0x33,0x20,0x8d,
+ 0x02,0x10,0x2a,0x02,0x7a,0xa0,0x16,0x19,0x00,0x00,0x00,0x00,0x00,0x00,0x0a,0xdc,0x8d,0xe0,0x20,0x8d,
+ 0x02,0x10,0x2a,0x02,0x7b,0x40,0xb0,0xdf,0x89,0x25,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x8d,
+ 0x02,0x10,0x2a,0x02,0x7b,0x40,0xb9,0x05,0x37,0xdb,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x8d,
+ 0x02,0x10,0x2a,0x02,0x81,0x0d,0x8c,0xbf,0xf3,0xa8,0x96,0xc6,0x91,0xff,0xfe,0x17,0xae,0x1d,0x20,0x8d,
+ 0x02,0x10,0x2a,0x02,0x83,0x89,0x01,0xc0,0x96,0x80,0x02,0x01,0x2e,0xff,0xfe,0x82,0xb3,0xcc,0x20,0x8d,
+ 0x02,0x10,0x2a,0x02,0xa4,0x54,0xa5,0x16,0x00,0x01,0x05,0x17,0x09,0x28,0x7e,0x0d,0x95,0x7c,0x20,0x8d,
+ 0x02,0x10,0x2a,0x02,0x0a,0xf8,0xfa,0xb0,0x08,0x04,0x01,0x51,0x02,0x36,0x00,0x34,0x01,0x61,0x20,0x8d,
+ 0x02,0x10,0x2a,0x02,0x0a,0xf8,0xfa,0xb0,0x08,0x08,0x00,0x85,0x02,0x34,0x01,0x45,0x01,0x32,0x20,0x8d,
+ 0x02,0x10,0x2a,0x02,0x0e,0x00,0xff,0xf0,0x01,0xe2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0a,0x20,0x8d,
+ 0x02,0x10,0x2a,0x03,0x22,0x60,0x30,0x06,0x00,0x0d,0xd3,0x07,0x5d,0x1d,0x32,0xca,0x1f,0xe8,0x20,0x8d,
+ 0x02,0x10,0x2a,0x03,0x60,0x00,0x08,0x70,0x00,0x00,0x00,0x46,0x00,0x23,0x00,0x87,0x02,0x18,0x20,0x8d,
+ 0x02,0x10,0x2a,0x03,0x9d,0xa0,0x00,0xf6,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x20,0x8d,
+ 0x02,0x10,0x2a,0x03,0xc9,0x80,0x00,0xdb,0x00,0x47,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x8d,
+ 0x02,0x10,0x2a,0x03,0xe2,0xc0,0x01,0xce,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x20,0x8d,
+ 0x02,0x10,0x2a,0x04,0x35,0x44,0x10,0x00,0x15,0x10,0x70,0x6c,0xab,0xff,0xfe,0x6c,0x50,0x1c,0x20,0x8d,
+ 0x02,0x10,0x2a,0x04,0x52,0xc0,0x01,0x01,0x03,0x83,0x00,0x00,0x00,0x00,0x00,0x00,0x2a,0x87,0x20,0x8d,
+ 0x02,0x10,0x2a,0x04,0x52,0xc0,0x01,0x01,0x03,0xfb,0x00,0x00,0x00,0x00,0x00,0x00,0x4c,0x27,0x20,0x8d,
+ 0x02,0x10,0x2a,0x04,0xee,0x41,0x00,0x83,0x50,0xdf,0xd9,0x08,0xf7,0x1d,0x2a,0x86,0xb3,0x37,0x20,0x8d,
+ 0x02,0x10,0x2a,0x05,0x6d,0x40,0xb9,0x4e,0xd1,0x00,0x02,0x25,0x90,0xff,0xfe,0x0d,0xcf,0xc2,0x20,0x8d,
+ 0x02,0x10,0x2a,0x05,0xe5,0xc0,0x00,0x00,0x01,0x00,0x02,0x50,0x56,0xff,0xfe,0xb9,0xd6,0xcb,0x20,0x8d,
+ 0x02,0x10,0x2a,0x05,0xfc,0x87,0x00,0x01,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x20,0x8d,
+ 0x02,0x10,0x2a,0x05,0xfc,0x87,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x20,0x8d,
+ 0x02,0x10,0x2a,0x07,0x57,0x41,0x00,0x00,0x11,0x5d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x8d,
+ 0x02,0x10,0x2a,0x07,0xa8,0x80,0x46,0x01,0x10,0x62,0xb4,0xb4,0xbd,0x2a,0x39,0xd4,0x7a,0xcf,0xc8,0xc9,
+ 0x02,0x10,0x2a,0x07,0xab,0xc4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x09,0x46,0x20,0x8d,
+ 0x02,0x10,0x2a,0x07,0xb4,0x00,0x00,0x01,0x03,0x4c,0x00,0x00,0x00,0x00,0x00,0x02,0x10,0x02,0x20,0x8d,
+ 0x02,0x10,0x2a,0x0a,0x8c,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb4,0x20,0x8d,
+ 0x02,0x10,0x2a,0x0a,0xc8,0x01,0x00,0x01,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x83,0x20,0x8d,
+ 0x02,0x10,0x2a,0x0b,0xae,0x40,0x00,0x03,0x4a,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x15,0x20,0x8d,
+ 0x02,0x10,0x2a,0x0f,0xdf,0x00,0x00,0x00,0x02,0x54,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x46,0x20,0x8d,
+ 0x02,0x10,0x2c,0x0f,0xf5,0x98,0x00,0x05,0x00,0x01,0x10,0x01,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x8d,
+ 0x02,0x10,0x2c,0x0f,0xfc,0xe8,0x00,0x00,0x04,0x00,0x0b,0x7c,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x8d,
+ 0x03,0x0a,0xd6,0xbc,0x4a,0x3c,0x6d,0x03,0xa9,0x4e,0x1f,0x55,0x20,0x8d,
+ 0x03,0x0a,0xd6,0x8f,0xf0,0xf8,0xbb,0x10,0x00,0x18,0x42,0x54,0x20,0x8d,
+ 0x03,0x0a,0xd6,0xec,0x32,0xc1,0x59,0x9c,0xd8,0x46,0xd5,0x48,0x20,0x8d,
+ 0x03,0x0a,0xd6,0xf0,0x8d,0x96,0x37,0xc3,0x27,0x61,0x9a,0x24,0x20,0x8d,
+ 0x03,0x0a,0xd0,0x12,0xe6,0xed,0x8e,0xc1,0x78,0x8d,0x1c,0x21,0x20,0x8d,
+ 0x03,0x0a,0xd0,0x4a,0xc5,0xbd,0x5d,0xe9,0xca,0x57,0xaf,0xc4,0x20,0x8d,
+ 0x03,0x0a,0xd0,0x94,0xc0,0x97,0xd2,0x32,0xed,0x81,0x92,0x67,0x20,0x8d,
+ 0x03,0x0a,0xd1,0xd5,0x49,0x23,0xa6,0x10,0x01,0x49,0xda,0x05,0x20,0x8d,
+ 0x03,0x0a,0xd2,0x2a,0x76,0x2c,0x37,0x09,0x9a,0xa1,0x61,0x4b,0x20,0x8d,
+ 0x03,0x0a,0xd3,0x19,0x77,0x50,0xf5,0xf3,0x48,0x17,0x59,0x50,0x20,0x8d,
+ 0x03,0x0a,0xd4,0x24,0xda,0xf8,0x97,0x6d,0x28,0x80,0x47,0xf9,0x20,0x8d,
+ 0x03,0x0a,0xd4,0x28,0x30,0x9d,0x6d,0xac,0x1e,0xb4,0x6e,0x59,0x20,0x8d,
+ 0x03,0x0a,0xd5,0x13,0x71,0x95,0xd5,0x2e,0x12,0xf6,0x0e,0x6e,0x20,0x8d,
+ 0x03,0x0a,0xd5,0xc6,0x62,0x50,0xb1,0x22,0xb6,0x4a,0x31,0x56,0x20,0x8d,
+ 0x03,0x0a,0xd5,0xc7,0x99,0x46,0x87,0x91,0x13,0xc9,0xc9,0x16,0x20,0x8d,
+ 0x03,0x0a,0xdf,0x22,0x06,0xea,0xce,0x87,0x08,0x09,0x32,0x52,0x20,0x8d,
+ 0x03,0x0a,0xdf,0xa1,0xf5,0x1c,0xe4,0x4e,0x97,0x71,0xee,0xc5,0x20,0x8d,
+ 0x03,0x0a,0xdf,0xf7,0x64,0x8e,0x4f,0xa3,0xbb,0xaa,0x4f,0x30,0x20,0x8d,
+ 0x03,0x0a,0xdf,0xfc,0xa5,0x92,0x7d,0xbc,0x03,0x13,0x69,0x35,0x20,0x8d,
+ 0x03,0x0a,0xdf,0xd5,0x61,0xfc,0xb7,0x73,0xff,0xef,0x2f,0xaa,0x20,0x8d,
+ 0x03,0x0a,0xd9,0x3b,0x3f,0x9e,0x1c,0x02,0xe7,0xd9,0xba,0xb7,0x20,0x8d,
+ 0x03,0x0a,0xd9,0x83,0x73,0x90,0x25,0x3b,0xa9,0x4b,0x18,0x5b,0x20,0x8d,
+ 0x03,0x0a,0xd9,0xcc,0x14,0xe4,0x9a,0x68,0x6d,0x8a,0x12,0xc5,0x20,0x8d,
+ 0x03,0x0a,0xda,0x29,0x4a,0xc4,0x7a,0xb0,0x0e,0x0d,0x0a,0xee,0x20,0x8d,
+ 0x03,0x0a,0xda,0x67,0x7a,0x24,0x60,0x45,0x8f,0xe4,0x2e,0x74,0x20,0x8d,
+ 0x03,0x0a,0xda,0xfa,0x48,0x68,0x74,0xfb,0x2b,0x21,0x27,0x80,0x20,0x8d,
+ 0x03,0x0a,0xdb,0x5c,0x56,0x99,0xb0,0x5c,0x08,0x43,0xb7,0xee,0x20,0x8d,
+ 0x03,0x0a,0xdc,0x79,0xc1,0x8f,0x29,0x44,0xf2,0xdc,0x00,0xf6,0x20,0x8d,
+ 0x03,0x0a,0xdd,0x66,0x1a,0x59,0x93,0x73,0x7f,0x58,0x76,0x19,0x20,0x8d,
+ 0x03,0x0a,0xe7,0x9c,0x7c,0xce,0x79,0xe3,0xc8,0xa4,0x73,0x66,0x20,0x8d,
+ 0x03,0x0a,0xe7,0xca,0xbd,0xa2,0xab,0xe5,0x7b,0xe4,0xca,0x71,0x20,0x8d,
+ 0x03,0x0a,0xe7,0xd1,0xe8,0x45,0x7a,0x42,0x60,0x2b,0x2c,0xde,0x20,0x8d,
+ 0x03,0x0a,0xe7,0xe9,0x47,0x9b,0x22,0x6c,0x6c,0x03,0xba,0x6e,0x20,0x8d,
+ 0x03,0x0a,0xe0,0xba,0x25,0x23,0x7f,0x25,0x5c,0x51,0xcb,0xc3,0x20,0x8d,
+ 0x03,0x0a,0xe1,0x21,0xbf,0x26,0x37,0xfd,0xe9,0x89,0x95,0xe2,0x20,0x8d,
+ 0x03,0x0a,0xe1,0x2c,0xa1,0xde,0xa2,0x37,0x7e,0x01,0xc5,0xa8,0x20,0x8d,
+ 0x03,0x0a,0xe1,0x57,0x53,0x20,0x2d,0x66,0x9a,0xb1,0xed,0xa0,0x20,0x8d,
+ 0x03,0x0a,0xe2,0x00,0xe6,0xcf,0x0c,0xe7,0xd0,0xc0,0x58,0x9c,0x20,0x8d,
+ 0x03,0x0a,0xe2,0x6f,0x9d,0xfd,0xce,0xa7,0x40,0x6f,0xfb,0x62,0x20,0x8d,
+ 0x03,0x0a,0xe3,0x1a,0xaa,0xa7,0xc7,0x07,0xf6,0x48,0x34,0x2a,0x20,0x8d,
+ 0x03,0x0a,0xe3,0x5b,0x4c,0x5d,0x9d,0x57,0x66,0xbc,0x26,0x1b,0x20,0x8d,
+ 0x03,0x0a,0xe3,0x73,0xac,0x1b,0x82,0x6b,0xa6,0x4d,0x91,0x3f,0x20,0x8d,
+ 0x03,0x0a,0xe3,0xdd,0x9b,0x1f,0xdd,0xf7,0x30,0x6c,0x8c,0x6a,0x20,0x8d,
+ 0x03,0x0a,0xe4,0x0c,0x50,0xf7,0xd1,0xab,0xc2,0xc2,0x4a,0xff,0x20,0x8d,
+ 0x03,0x0a,0xe4,0x64,0x0b,0xeb,0x73,0x04,0x33,0x66,0x21,0x89,0x20,0x8d,
+ 0x03,0x0a,0xe5,0x3a,0x9e,0x83,0x1e,0x88,0x24,0xeb,0x4f,0x8c,0x20,0x8d,
+ 0x03,0x0a,0xe5,0x5d,0x1a,0xcd,0xd8,0x21,0x8f,0xcc,0x86,0xb1,0x20,0x8d,
+ 0x03,0x0a,0xee,0xa5,0xc4,0xf5,0xeb,0x1d,0x96,0xfc,0x9e,0x76,0x20,0x8d,
+ 0x03,0x0a,0xe8,0x02,0xf4,0x22,0x05,0xa9,0x14,0xe2,0x26,0x2e,0x20,0x8d,
+ 0x03,0x0a,0xe8,0x30,0x3c,0xde,0xfe,0x4e,0x1d,0x9d,0xb4,0x99,0x20,0x8d,
+ 0x03,0x0a,0xe8,0xaf,0x91,0xca,0x33,0x72,0xba,0x33,0x3b,0x80,0x20,0x8d,
+ 0x03,0x0a,0xe9,0x07,0x44,0x29,0xf4,0x1a,0x09,0xb4,0xe2,0x25,0x20,0x8d,
+ 0x03,0x0a,0xe9,0x1e,0x40,0x15,0x4c,0xc0,0x38,0x5a,0xf4,0x7d,0x20,0x8d,
+ 0x03,0x0a,0xe9,0x71,0x75,0xe6,0x68,0x16,0xe7,0xe6,0xba,0x79,0x20,0x8d,
+ 0x03,0x0a,0xe9,0xc7,0xe2,0x60,0x96,0xee,0x02,0xd8,0x78,0xc1,0x20,0x8d,
+ 0x03,0x0a,0xea,0x70,0x5c,0x9e,0xca,0x90,0x7d,0x48,0xc5,0xfa,0x20,0x8d,
+ 0x03,0x0a,0xeb,0x5c,0xe8,0x18,0x53,0xef,0xbe,0x83,0x77,0xf5,0x20,0x8d,
+ 0x03,0x0a,0xeb,0x64,0x56,0x71,0xb0,0x86,0x72,0xf8,0xa6,0x2f,0x20,0x8d,
+ 0x03,0x0a,0xeb,0xa1,0x29,0xde,0x4f,0xc9,0xd6,0x64,0x90,0xbe,0x20,0x8d,
+ 0x03,0x0a,0xeb,0xf3,0x96,0x0f,0x93,0x2b,0x9b,0x18,0x64,0x3a,0x20,0x8d,
+ 0x03,0x0a,0xec,0x84,0xa6,0x5f,0x98,0xa0,0x82,0xd7,0xf1,0x0e,0x20,0x8d,
+ 0x03,0x0a,0xed,0x09,0xfb,0x3a,0x39,0x0b,0x7c,0x77,0x37,0x64,0x20,0x8d,
+ 0x03,0x0a,0xed,0xae,0x7b,0xea,0x6e,0xcb,0xdd,0x52,0xfb,0x3b,0x20,0x8d,
+ 0x03,0x0a,0xed,0xd5,0xbc,0x51,0xbb,0xf1,0x37,0xa2,0x6f,0x88,0x20,0x8d,
+ 0x03,0x0a,0xee,0x4c,0x79,0xe8,0xdf,0xa8,0xa4,0x07,0xa3,0xdd,0x20,0x8d,
+ 0x03,0x0a,0xf6,0x86,0x21,0xbe,0xa3,0x72,0xcb,0x95,0x0f,0x2b,0x20,0x8d,
+ 0x03,0x0a,0xf6,0xc2,0xa7,0x69,0x87,0x45,0xda,0xdd,0x07,0xe3,0x20,0x8d,
+ 0x03,0x0a,0xf7,0xce,0x9a,0x96,0xbe,0xb2,0x05,0x30,0x2d,0x9d,0x20,0x8d,
+ 0x03,0x0a,0xf1,0xbc,0xa7,0x71,0x4b,0x51,0x7a,0x09,0xac,0x68,0x20,0x8d,
+ 0x03,0x0a,0xf2,0xbb,0x98,0x90,0x97,0xb7,0x04,0x01,0xdd,0x1d,0x20,0x8d,
+ 0x03,0x0a,0xf2,0x8b,0xd0,0x60,0xeb,0x79,0x1b,0x8b,0x18,0x12,0x20,0x8d,
+ 0x03,0x0a,0xf3,0x00,0x83,0x5d,0x35,0x11,0x27,0xc7,0xa2,0x64,0x20,0x8d,
+ 0x03,0x0a,0xf4,0x49,0x29,0x57,0x83,0xab,0xd6,0x1e,0xa0,0xe7,0x20,0x8d,
+ 0x03,0x0a,0xf4,0x52,0x4b,0xf8,0xd8,0xa0,0x28,0x8d,0x8b,0xa4,0x20,0x8d,
+ 0x03,0x0a,0xf4,0x94,0x66,0x97,0x9b,0x7b,0xce,0x3a,0xa6,0x80,0x20,0x8d,
+ 0x03,0x0a,0xf4,0xa7,0x70,0x38,0x74,0xb2,0x24,0x6e,0xca,0x07,0x20,0x8d,
+ 0x03,0x0a,0xf5,0xe1,0x8e,0x4e,0x5e,0x0b,0xbd,0x4e,0x8c,0xcc,0x20,0x8d,
+ 0x03,0x0a,0xf8,0x2a,0xd5,0xec,0x70,0x79,0xa9,0xad,0xa6,0xa0,0x20,0x8d,
+ 0x03,0x0a,0xf9,0x4b,0xcb,0x2b,0x5e,0xf3,0x5d,0xad,0xce,0xed,0x20,0x8d,
+ 0x03,0x0a,0xf9,0xd0,0xf0,0xd3,0x25,0x18,0xb1,0x98,0x29,0x46,0x20,0x8d,
+ 0x03,0x0a,0xfc,0x92,0xc5,0xe6,0x33,0x3a,0x56,0xf2,0xe0,0x6a,0x20,0x8d,
+ 0x03,0x0a,0xfc,0xe9,0x3d,0xe6,0x7a,0x02,0xad,0x16,0x5b,0xd7,0x20,0x8d,
+ 0x03,0x0a,0xfd,0x0f,0x24,0xe5,0x3e,0x6d,0xf6,0x32,0xb6,0xf3,0x20,0x8d,
+ 0x03,0x0a,0xfd,0x99,0xcb,0x49,0xdb,0xb5,0x41,0x3b,0xb4,0x33,0x20,0x8d,
+ 0x03,0x0a,0xfe,0x14,0xcc,0xd3,0x01,0xb0,0xf4,0xf9,0xe4,0xdc,0x20,0x8d,
+ 0x03,0x0a,0x06,0xbe,0x1a,0x9d,0x0d,0x07,0x31,0xad,0xa6,0xee,0x20,0x8d,
+ 0x03,0x0a,0x07,0x77,0x59,0x8d,0x9f,0xa2,0x09,0x3e,0xd4,0x6b,0x20,0x8d,
+ 0x03,0x0a,0x07,0x7d,0xdf,0xea,0xe9,0xa3,0x8a,0xd9,0xe8,0x6f,0x20,0x8d,
+ 0x03,0x0a,0x00,0x5f,0xae,0xa9,0xa8,0x28,0xe4,0xd1,0x6a,0x35,0x20,0x8d,
+ 0x03,0x0a,0x01,0x0b,0x7f,0xd0,0x39,0x78,0x17,0xf1,0x2c,0x0a,0x20,0x8d,
+ 0x03,0x0a,0x02,0x3b,0x1d,0x0d,0x0e,0xcb,0x89,0xf8,0xc4,0x79,0x20,0x8d,
+ 0x03,0x0a,0x02,0x1f,0x47,0xbc,0xe8,0x9e,0xc8,0xd3,0x19,0xe9,0x20,0x8d,
+ 0x03,0x0a,0x02,0xcc,0xf4,0xa7,0x06,0x1e,0xcd,0x36,0xb1,0xef,0x20,0x8d,
+ 0x03,0x0a,0x02,0xd0,0x7a,0x03,0xf1,0x3e,0x05,0xce,0xe8,0xf1,0x20,0x8d,
+ 0x03,0x0a,0x03,0x36,0x6c,0x60,0xb8,0x6d,0xf3,0x6c,0x5c,0xf7,0x20,0x8d,
+ 0x03,0x0a,0x03,0x54,0xec,0xe4,0xa7,0x5e,0xa3,0xba,0x0b,0xd4,0x20,0x8d,
+ 0x03,0x0a,0x04,0xf7,0x3b,0x25,0x61,0x98,0xb4,0xb8,0x36,0x1d,0x20,0x8d,
+ 0x03,0x0a,0x05,0x60,0xe0,0xaf,0xfa,0x7b,0x05,0xee,0x0f,0x08,0x20,0x8d,
+ 0x03,0x0a,0x05,0x98,0x3c,0xe8,0xb2,0xd8,0x7a,0x7e,0xd2,0x7d,0x20,0x8d,
+ 0x03,0x0a,0x06,0x31,0x67,0xa3,0x1f,0xf8,0x69,0x31,0xa6,0x29,0x20,0x8d,
+ 0x03,0x0a,0x0e,0x91,0xb7,0xa7,0xe2,0xd7,0x05,0x57,0xc6,0x5f,0x20,0x8d,
+ 0x03,0x0a,0x0f,0x10,0xb2,0x07,0x17,0x15,0x3c,0xd9,0xcd,0x0e,0x20,0x8d,
+ 0x03,0x0a,0x0f,0x2b,0x55,0x06,0x08,0x78,0x98,0xab,0x3f,0x95,0x20,0x8d,
+ 0x03,0x0a,0x08,0xc6,0x58,0x5d,0xf2,0xea,0x02,0x3d,0x96,0x76,0x20,0x8d,
+ 0x03,0x0a,0x09,0x3a,0x13,0x09,0xee,0xe3,0x9d,0x4b,0xf6,0x18,0x20,0x8d,
+ 0x03,0x0a,0x09,0x96,0x0e,0x33,0xd9,0x24,0xeb,0x3a,0xfd,0x72,0x20,0x8d,
+ 0x03,0x0a,0x09,0xf7,0xa3,0x66,0xdb,0x6e,0x04,0xac,0xc2,0x93,0x20,0x8d,
+ 0x03,0x0a,0x09,0xdd,0xc5,0x38,0x6f,0x21,0xdb,0xfb,0xc7,0x77,0x20,0x8d,
+ 0x03,0x0a,0x0a,0x26,0x27,0x21,0xbc,0x8a,0xca,0x0e,0x5a,0x17,0x20,0x8d,
+ 0x03,0x0a,0x0a,0x2d,0xf9,0x79,0x25,0xf4,0x74,0xc2,0xec,0x54,0x20,0x8d,
+ 0x03,0x0a,0x0a,0xbf,0x87,0xf8,0x8f,0x6b,0x04,0xb5,0xc3,0xfa,0x20,0x8d,
+ 0x03,0x0a,0x0a,0xc4,0xa9,0xc4,0xd5,0x27,0x6a,0x49,0xa6,0x4a,0x20,0x8d,
+ 0x03,0x0a,0x0a,0xec,0x17,0xfc,0xc5,0x19,0x4a,0x39,0x5f,0x86,0x20,0x8d,
+ 0x03,0x0a,0x0b,0x6e,0xdf,0x42,0x02,0xef,0x4d,0x56,0xf5,0xcf,0x20,0x8d,
+ 0x03,0x0a,0x0b,0xfe,0xed,0x69,0x75,0x12,0x41,0x62,0x2e,0xb5,0x20,0x8d,
+ 0x03,0x0a,0x0c,0x21,0x88,0x50,0x46,0x4f,0x26,0x23,0xb7,0xdc,0x20,0x8d,
+ 0x03,0x0a,0x0d,0x47,0x96,0x52,0x62,0x81,0x7e,0x6c,0xe5,0xbd,0x20,0x8d,
+ 0x03,0x0a,0x16,0xfd,0x96,0x10,0xc9,0x52,0x1a,0x59,0xb2,0x65,0x20,0x8d,
+ 0x03,0x0a,0x17,0x0a,0xdf,0x68,0xcd,0x5c,0xd6,0x68,0xbe,0x75,0x20,0x8d,
+ 0x03,0x0a,0x10,0x00,0x45,0xf7,0x04,0x1d,0x50,0xe7,0x43,0x2a,0x20,0x8d,
+ 0x03,0x0a,0x10,0x21,0xde,0x00,0x2b,0x28,0x62,0xda,0x30,0x63,0x20,0x8d,
+ 0x03,0x0a,0x11,0x22,0xd8,0xb2,0x2a,0xee,0x5c,0xcc,0xbb,0x2d,0x20,0x8d,
+ 0x03,0x0a,0x11,0xe2,0x8f,0x22,0x66,0x48,0x00,0x67,0x17,0x93,0x20,0x8d,
+ 0x03,0x0a,0x13,0x45,0x64,0x2b,0x73,0x68,0xf4,0x44,0xb3,0xb9,0x20,0x8d,
+ 0x03,0x0a,0x15,0x30,0x98,0x3b,0x28,0x23,0x04,0xcb,0x02,0xeb,0x20,0x8d,
+ 0x03,0x0a,0x15,0xff,0x00,0x68,0xcf,0x86,0x1f,0xf7,0xac,0x7d,0x20,0x8d,
+ 0x03,0x0a,0x16,0x5f,0xfb,0x18,0x14,0x97,0x0d,0x54,0x3b,0xfa,0x20,0x8d,
+ 0x03,0x0a,0x1e,0x8a,0xde,0xf2,0x25,0xc2,0x46,0x06,0x99,0x1c,0x20,0x8d,
+ 0x03,0x0a,0x1e,0xa4,0xae,0x76,0x9e,0x10,0x3d,0xcc,0x12,0x07,0x20,0x8d,
+ 0x03,0x0a,0x1e,0xc0,0xeb,0x31,0xa6,0xaa,0xa7,0x2c,0xa0,0x04,0x20,0x8d,
+ 0x03,0x0a,0x1f,0x51,0x4e,0x01,0x19,0xde,0x34,0xa3,0x08,0xc9,0x20,0x8d,
+ 0x03,0x0a,0x1f,0xb2,0x1b,0x6a,0x57,0x6d,0xcc,0x9e,0xca,0xbb,0x20,0x8d,
+ 0x03,0x0a,0x18,0x7b,0x11,0xf4,0x9c,0xf4,0xfe,0xc3,0x21,0xa8,0x20,0x8d,
+ 0x03,0x0a,0x18,0x91,0xa3,0x51,0x6e,0x8a,0xf9,0xcc,0x27,0xbd,0x20,0x8d,
+ 0x03,0x0a,0x18,0xdf,0x33,0xe9,0x96,0x9e,0xe3,0x2a,0xb9,0xc6,0x20,0x8d,
+ 0x03,0x0a,0x19,0x63,0x6c,0x83,0xe5,0x11,0x04,0xa6,0xb5,0x92,0x20,0x8d,
+ 0x03,0x0a,0x1a,0x6c,0x74,0x95,0x3c,0x89,0xf6,0xec,0xef,0x09,0x20,0x8d,
+ 0x03,0x0a,0x1a,0x95,0xd6,0x31,0xe4,0xea,0x66,0x97,0x0d,0x5d,0x20,0x8d,
+ 0x03,0x0a,0x1b,0x93,0xbc,0x99,0x92,0x0e,0x69,0x16,0x40,0xcf,0x20,0x8d,
+ 0x03,0x0a,0x1b,0xc4,0x4e,0x17,0x71,0x14,0x06,0x3c,0x86,0xfd,0x20,0x8d,
+ 0x03,0x0a,0x1c,0x6c,0xed,0xd5,0xb7,0x11,0xfa,0xec,0x94,0x2e,0x20,0x8d,
+ 0x03,0x0a,0x1d,0x10,0xa5,0x20,0x77,0x43,0xf6,0xbc,0x12,0xed,0x20,0x8d,
+ 0x03,0x0a,0x1d,0x20,0x35,0xa1,0xf3,0x16,0xb4,0x8f,0x1c,0xbd,0x20,0x8d,
+ 0x03,0x0a,0x1d,0x30,0xfe,0x09,0xc7,0xe8,0xfe,0xd3,0xee,0x83,0x20,0x8d,
+ 0x03,0x0a,0x1d,0x33,0xd9,0xd9,0xdb,0xcf,0xc5,0xde,0xae,0xe9,0x20,0x8d,
+ 0x03,0x0a,0x1d,0x69,0xe1,0xac,0x11,0xf1,0x32,0x2f,0x5c,0x8d,0x20,0x8d,
+ 0x03,0x0a,0x1e,0x3d,0x98,0x4b,0x9e,0xc0,0x96,0x40,0x63,0x0f,0x20,0x8d,
+ 0x03,0x0a,0x1e,0x75,0x81,0xb1,0x3b,0xc4,0x22,0x26,0x72,0x3f,0x20,0x8d,
+ 0x03,0x0a,0x26,0x83,0xa0,0x76,0x54,0xa8,0xc1,0x6c,0xde,0x83,0x20,0x8d,
+ 0x03,0x0a,0x26,0xf6,0x7e,0xfd,0x3a,0x25,0x94,0xa8,0x49,0xbd,0x20,0x8d,
+ 0x03,0x0a,0x27,0x54,0x94,0x03,0x1f,0x7e,0x53,0xd8,0x3f,0x35,0x20,0x8d,
+ 0x03,0x0a,0x27,0xd0,0xa7,0x73,0x43,0xd5,0xb2,0x26,0x57,0x1c,0x20,0x8d,
+ 0x03,0x0a,0x20,0x3c,0x17,0x1f,0x8a,0x74,0xe1,0xdf,0x5a,0x5d,0x20,0x8d,
+ 0x03,0x0a,0x21,0x47,0x7f,0x18,0x5c,0x97,0x49,0x9c,0x40,0x86,0x20,0x8d,
+ 0x03,0x0a,0x21,0x62,0xfa,0x51,0x02,0xf5,0x14,0x4c,0x40,0x52,0x20,0x8d,
+ 0x03,0x0a,0x21,0xa3,0x41,0x6c,0x28,0xda,0x27,0x1a,0x78,0xd0,0x20,0x8d,
+ 0x03,0x0a,0x24,0x45,0xe9,0xa6,0x5a,0xa0,0xb0,0x01,0xaf,0x5b,0x20,0x8d,
+ 0x03,0x0a,0x25,0x09,0xa6,0xf6,0x4a,0xec,0xd5,0x33,0x74,0x35,0x20,0x8d,
+ 0x03,0x0a,0x26,0x55,0x1f,0xca,0x70,0xe5,0xbe,0xe3,0xa6,0x33,0x20,0x8d,
+ 0x03,0x0a,0x2e,0xdb,0x8c,0x24,0x20,0xf2,0x9f,0x7c,0xb4,0xea,0x20,0x8d,
+ 0x03,0x0a,0x28,0x21,0xfd,0xd5,0x3c,0x78,0xa5,0xfd,0xcc,0xf4,0x20,0x8d,
+ 0x03,0x0a,0x28,0xeb,0x35,0xa7,0x6f,0x90,0x83,0x7a,0x1f,0xfd,0x20,0x8d,
+ 0x03,0x0a,0x29,0x86,0xfb,0xba,0xbc,0x6e,0x6f,0x53,0x89,0xf5,0x20,0x8d,
+ 0x03,0x0a,0x2a,0x25,0x08,0x7a,0xb9,0x56,0xd9,0xe9,0xeb,0x5d,0x20,0x8d,
+ 0x03,0x0a,0x2a,0x8c,0xfd,0xc2,0xc4,0x30,0x05,0x11,0xe8,0x29,0x20,0x8d,
+ 0x03,0x0a,0x2b,0xb7,0x31,0x96,0xd7,0xd7,0xe6,0x05,0x42,0x1d,0x20,0x8d,
+ 0x03,0x0a,0x2c,0x15,0x79,0x88,0xf6,0xc3,0xd1,0x27,0xa9,0xf5,0x20,0x8d,
+ 0x03,0x0a,0x2c,0x28,0xda,0x1d,0x76,0xa8,0xff,0x18,0x78,0x7d,0x20,0x8d,
+ 0x03,0x0a,0x2c,0x6d,0x3e,0xb2,0x42,0x7e,0x0e,0x8a,0x59,0xe4,0x20,0x8d,
+ 0x03,0x0a,0x2c,0xc1,0xc3,0x15,0x28,0xa5,0x7c,0x5d,0x2c,0x9a,0x20,0x8d,
+ 0x03,0x0a,0x2d,0x1d,0x8d,0x21,0xf4,0x84,0x61,0x62,0x74,0x45,0x20,0x8d,
+ 0x03,0x0a,0x2e,0x7c,0xd9,0x21,0x3e,0x4a,0x31,0x4b,0x2e,0x42,0x20,0x8d,
+ 0x03,0x0a,0x36,0xea,0xb6,0x80,0x00,0x71,0xbb,0x23,0x51,0x1d,0x20,0x8d,
+ 0x03,0x0a,0x37,0x38,0x8f,0x26,0xd2,0xa4,0xd5,0x66,0x49,0xf9,0x20,0x8d,
+ 0x03,0x0a,0x37,0x7b,0x3f,0x74,0x7d,0x12,0x92,0x8b,0x89,0xb6,0x20,0x8d,
+ 0x03,0x0a,0x30,0x12,0x3f,0x13,0x11,0x5e,0xa1,0x65,0x15,0x86,0x20,0x8d,
+ 0x03,0x0a,0x30,0x57,0x42,0x6c,0xf1,0xee,0xdf,0xc3,0x46,0xff,0x20,0x8d,
+ 0x03,0x0a,0x30,0x5f,0x17,0x76,0x79,0x1d,0x11,0x42,0x97,0x95,0x20,0x8d,
+ 0x03,0x0a,0x30,0xb8,0xbd,0xce,0x0b,0xde,0xa0,0x72,0x99,0x88,0x20,0x8d,
+ 0x03,0x0a,0x30,0x9a,0xb7,0x46,0xb3,0x7e,0x05,0x40,0x24,0x5e,0x20,0x8d,
+ 0x03,0x0a,0x30,0xe4,0x80,0xe9,0xaa,0xd1,0x08,0xe4,0x0c,0xc2,0x20,0x8d,
+ 0x03,0x0a,0x31,0x3a,0x66,0x7c,0x5e,0xb7,0xf0,0x03,0xbf,0x3f,0x20,0x8d,
+ 0x03,0x0a,0x31,0x0c,0x29,0x90,0x84,0x7f,0x05,0x62,0xcd,0x7d,0x20,0x8d,
+ 0x03,0x0a,0x31,0x5d,0x88,0x82,0x83,0x35,0x7b,0x04,0x8d,0x54,0x20,0x8d,
+ 0x03,0x0a,0x31,0x9e,0x1a,0x61,0xec,0xb9,0x91,0xaf,0x2c,0x5e,0x20,0x8d,
+ 0x03,0x0a,0x31,0xe0,0x8a,0xe0,0x9f,0x11,0x44,0xa4,0x49,0xb3,0x20,0x8d,
+ 0x03,0x0a,0x32,0x22,0x05,0x5d,0xcc,0x69,0x3a,0x50,0xe3,0xdc,0x20,0x8d,
+ 0x03,0x0a,0x32,0xf3,0xd3,0x15,0x5b,0xdc,0xe9,0x43,0x75,0xa4,0x20,0x8d,
+ 0x03,0x0a,0x33,0xd6,0x09,0xdd,0xd8,0x37,0x5b,0x75,0xf6,0x29,0x20,0x8d,
+ 0x03,0x0a,0x34,0x50,0xf5,0xf6,0xe9,0xb6,0x34,0x31,0x47,0xc2,0x20,0x8d,
+ 0x03,0x0a,0x34,0xce,0x7c,0xad,0x90,0x12,0x35,0xa6,0xde,0x34,0x20,0x8d,
+ 0x03,0x0a,0x34,0xdd,0xa1,0xfb,0x92,0xb3,0xa4,0x56,0x2b,0xc2,0x20,0x8d,
+ 0x03,0x0a,0x35,0x00,0x24,0x34,0x98,0xee,0x98,0x61,0x05,0xfa,0x20,0x8d,
+ 0x03,0x0a,0x35,0x95,0x33,0x45,0x93,0xb2,0xbc,0xda,0xf6,0x42,0x20,0x8d,
+ 0x03,0x0a,0x35,0x9d,0x76,0xb9,0x43,0x15,0x85,0xf3,0xe3,0x8f,0x20,0x8d,
+ 0x03,0x0a,0x3e,0xf7,0xb2,0xf2,0x0d,0xb1,0x3e,0xc8,0xe1,0x8d,0x20,0x8d,
+ 0x03,0x0a,0x3f,0x81,0xbd,0x37,0x81,0x58,0x6d,0x6c,0x37,0x83,0x20,0x8d,
+ 0x03,0x0a,0x38,0x0b,0x69,0xc4,0x2e,0x74,0xb2,0xe2,0x30,0x2c,0x20,0x8d,
+ 0x03,0x0a,0x38,0x6c,0x73,0x48,0x3b,0x21,0x10,0xd6,0xc7,0xd3,0x20,0x8d,
+ 0x03,0x0a,0x38,0xab,0xe2,0xba,0xe7,0xeb,0x15,0xf2,0x9c,0x3d,0x20,0x8d,
+ 0x03,0x0a,0x38,0xfc,0x75,0x4c,0x4b,0xf5,0x80,0xcc,0xaf,0x2c,0x20,0x8d,
+ 0x03,0x0a,0x38,0xc1,0xe6,0x48,0x1c,0xaf,0x23,0x3f,0xfc,0xd7,0x20,0x8d,
+ 0x03,0x0a,0x38,0xcc,0xdb,0xaa,0x90,0x90,0xfd,0x64,0xda,0xd7,0x20,0x8d,
+ 0x03,0x0a,0x39,0x8f,0xb0,0x65,0xbb,0x21,0x24,0x31,0xd4,0x46,0x20,0x8d,
+ 0x03,0x0a,0x39,0xf1,0x7a,0x78,0x36,0x52,0x48,0x52,0x25,0xd9,0x20,0x8d,
+ 0x03,0x0a,0x3a,0x32,0xdf,0x45,0x8e,0x2c,0x8d,0xba,0x3d,0x8d,0x20,0x8d,
+ 0x03,0x0a,0x3a,0x61,0x7b,0xcb,0x1a,0x74,0x88,0xc2,0xd4,0x95,0x20,0x8d,
+ 0x03,0x0a,0x3a,0x82,0xff,0xb0,0x26,0xb7,0x94,0xb5,0xcb,0x92,0x20,0x8d,
+ 0x03,0x0a,0x3a,0xdc,0x9a,0x59,0x16,0x0a,0x9c,0x9e,0x28,0x79,0x20,0x8d,
+ 0x03,0x0a,0x3a,0xf3,0x79,0x26,0x3f,0x70,0x77,0x0c,0xe6,0x10,0x20,0x8d,
+ 0x03,0x0a,0x3b,0x51,0x4c,0xbd,0x64,0xc9,0x03,0x83,0xd7,0xe0,0x20,0x8d,
+ 0x03,0x0a,0x3b,0x9a,0x32,0x59,0x49,0xe4,0xb9,0x11,0x8a,0xc5,0x20,0x8d,
+ 0x03,0x0a,0x3c,0x17,0xd6,0xd7,0xd5,0x38,0x88,0x81,0xec,0x2d,0x20,0x8d,
+ 0x03,0x0a,0x3c,0x9e,0x97,0x7d,0x90,0x8c,0x49,0xd3,0x62,0xf1,0x20,0x8d,
+ 0x03,0x0a,0x3d,0x3d,0xc9,0x69,0x83,0x8e,0xef,0xfc,0x5d,0x40,0x20,0x8d,
+ 0x03,0x0a,0x3d,0x6d,0x58,0x6a,0x56,0x54,0x2d,0xb8,0x57,0x0e,0x20,0x8d,
+ 0x03,0x0a,0x3d,0x9d,0xa0,0xa3,0x0d,0x1c,0x63,0x57,0xaf,0xc5,0x20,0x8d,
+ 0x03,0x0a,0x3e,0x6e,0x9d,0x8e,0x67,0xde,0x35,0x79,0xf3,0xae,0x20,0x8d,
+ 0x03,0x0a,0x46,0xe8,0x5b,0xd2,0xdb,0x9f,0xc5,0x72,0x8d,0xf0,0x20,0x8d,
+ 0x03,0x0a,0x40,0x36,0xdd,0xc3,0xb4,0xe7,0x4d,0x57,0xdf,0xe0,0x20,0x8d,
+ 0x03,0x0a,0x40,0x8a,0x69,0x6c,0xa2,0x98,0x94,0x3e,0x60,0x8e,0x20,0x8d,
+ 0x03,0x0a,0x40,0x9f,0x9f,0x4c,0xf0,0xa8,0xd2,0x2b,0x2e,0xa1,0x20,0x8d,
+ 0x03,0x0a,0x41,0x77,0xac,0xbb,0xb4,0xe3,0x0e,0x3a,0x34,0xa3,0x20,0x8d,
+ 0x03,0x0a,0x41,0xb8,0xb3,0x52,0x0b,0xf5,0x6e,0xa0,0xb1,0x91,0x20,0x8d,
+ 0x03,0x0a,0x41,0xce,0x28,0xfc,0xa7,0x16,0x60,0x30,0x0b,0x98,0x20,0x8d,
+ 0x03,0x0a,0x42,0x59,0xa9,0xe2,0xee,0x0f,0xea,0xaa,0x83,0x39,0x20,0x8d,
+ 0x03,0x0a,0x43,0xf6,0xfa,0x52,0x06,0x3d,0x18,0x5c,0xf6,0xd6,0x20,0x8d,
+ 0x03,0x0a,0x44,0x36,0xa2,0x4f,0xfa,0x2e,0xf1,0xa2,0xc5,0xe6,0x20,0x8d,
+ 0x03,0x0a,0x44,0x00,0x69,0xf4,0x4e,0xe0,0xe7,0xf3,0xf8,0xe5,0x20,0x8d,
+ 0x03,0x0a,0x45,0x0d,0x6e,0x69,0x07,0xf1,0xdf,0x18,0x47,0x5e,0x20,0x8d,
+ 0x03,0x0a,0x45,0x4b,0xff,0xf2,0xbc,0x9f,0xd5,0xed,0xa3,0xc3,0x20,0x8d,
+ 0x03,0x0a,0x45,0x4a,0x01,0x0c,0xbf,0x12,0x0d,0xac,0xeb,0x1a,0x20,0x8d,
+ 0x03,0x0a,0x45,0x65,0x71,0xd9,0x54,0xeb,0x8d,0xac,0xa7,0x8b,0x20,0x8d,
+ 0x03,0x0a,0x45,0xec,0x68,0x9c,0x0a,0x5d,0x69,0xc3,0x79,0xdf,0x20,0x8d,
+ 0x03,0x0a,0x46,0x7b,0xe6,0x39,0xde,0x62,0x9f,0xb3,0x7e,0xee,0x20,0x8d,
+ 0x03,0x0a,0x4e,0x84,0xfe,0xb2,0x96,0xea,0x76,0xba,0x30,0x57,0x20,0x8d,
+ 0x03,0x0a,0x4e,0x97,0x15,0x46,0xd4,0x32,0xc7,0x62,0x5a,0xd2,0x20,0x8d,
+ 0x03,0x0a,0x4e,0xa1,0x36,0x28,0x7a,0x18,0x02,0xb9,0x4b,0x3c,0x20,0x8d,
+ 0x03,0x0a,0x4f,0x49,0xac,0x50,0x0d,0xef,0xeb,0xa3,0xf4,0x8b,0x20,0x8d,
+ 0x03,0x0a,0x4f,0x52,0x58,0x8e,0x67,0x84,0xfa,0x6d,0x76,0xf9,0x20,0x8d,
+ 0x03,0x0a,0x4f,0x56,0xad,0x52,0xba,0x0c,0x9e,0x58,0x5c,0xaa,0x20,0x8d,
+ 0x03,0x0a,0x48,0x1b,0x5a,0xe6,0x4c,0xc8,0xa4,0x9d,0x95,0x0b,0x20,0x8d,
+ 0x03,0x0a,0x49,0x1a,0xdd,0x4d,0x98,0x5e,0xef,0x70,0x45,0x90,0x20,0x8d,
+ 0x03,0x0a,0x49,0x5c,0x4e,0x97,0x52,0x16,0x5c,0x92,0xbf,0x7a,0x20,0x8d,
+ 0x03,0x0a,0x49,0x84,0x64,0x79,0x5a,0x7d,0xdc,0xe4,0x76,0x1b,0x20,0x8d,
+ 0x03,0x0a,0x49,0xc0,0xd0,0x6b,0x92,0xd8,0xf2,0xa4,0x4f,0x2f,0x20,0x8d,
+ 0x03,0x0a,0x4a,0x26,0x6a,0x2c,0x3a,0xe3,0x2a,0x58,0x44,0x66,0x20,0x8d,
+ 0x03,0x0a,0x4a,0x69,0x5b,0x05,0x25,0xca,0xd2,0xc6,0xfe,0x7b,0x20,0x8d,
+ 0x03,0x0a,0x4a,0xc4,0x57,0x30,0xd1,0xed,0xca,0x4b,0x81,0x05,0x20,0x8d,
+ 0x03,0x0a,0x4a,0xc8,0x79,0x7b,0x01,0x0e,0xbd,0x05,0xb5,0xa0,0x20,0x8d,
+ 0x03,0x0a,0x4a,0xd3,0x9c,0xf2,0x6c,0x0c,0x23,0x78,0x6e,0x1d,0x20,0x8d,
+ 0x03,0x0a,0x4b,0x85,0xc7,0x40,0x44,0x20,0xd4,0x6f,0xfe,0xa5,0x20,0x8d,
+ 0x03,0x0a,0x4c,0x7b,0x8f,0x35,0x34,0x08,0x83,0x5f,0x1b,0x7f,0x20,0x8d,
+ 0x03,0x0a,0x4c,0x5c,0x07,0x4b,0xcb,0x07,0x2a,0x82,0x1d,0xdc,0x20,0x8d,
+ 0x03,0x0a,0x4c,0x98,0xf3,0x99,0x40,0xc7,0xd0,0x83,0x85,0x51,0x20,0x8d,
+ 0x03,0x0a,0x4c,0xd5,0x26,0xb9,0x54,0x90,0x72,0xc9,0x7e,0xcb,0x20,0x8d,
+ 0x03,0x0a,0x4d,0x3a,0x3a,0x3b,0x71,0xf3,0xfc,0x34,0x65,0xa2,0x20,0x8d,
+ 0x03,0x0a,0x4d,0xbd,0x9c,0x32,0xe2,0x69,0x02,0x03,0xd2,0x89,0x20,0x8d,
+ 0x03,0x0a,0x4d,0xc0,0xba,0x9c,0xbf,0xb7,0xec,0x4a,0xc3,0x36,0x20,0x8d,
+ 0x03,0x0a,0x4e,0x32,0x72,0x6d,0x06,0xe7,0x10,0x25,0x62,0x41,0x20,0x8d,
+ 0x03,0x0a,0x4e,0x49,0xea,0x29,0xbc,0x40,0xe2,0x7e,0x70,0x8e,0x20,0x8d,
+ 0x03,0x0a,0x57,0x0c,0xb7,0x4d,0x77,0x6b,0x27,0x30,0xf8,0x53,0x20,0x8d,
+ 0x03,0x0a,0x57,0xe9,0x8d,0xa2,0xcc,0xa9,0xa9,0x9c,0x18,0x7a,0x20,0x8d,
+ 0x03,0x0a,0x52,0xf5,0xb7,0x14,0x06,0xdd,0x14,0x1f,0x1e,0xeb,0x20,0x8d,
+ 0x03,0x0a,0x53,0x95,0x3d,0x42,0x3e,0x1f,0x1e,0xcc,0x07,0x43,0x20,0x8d,
+ 0x03,0x0a,0x53,0xc0,0xba,0x6c,0xfd,0xc0,0xd4,0xe0,0x22,0xb2,0x20,0x8d,
+ 0x03,0x0a,0x54,0x46,0xf0,0x8e,0xb3,0x85,0xba,0x2e,0xac,0x84,0x20,0x8d,
+ 0x03,0x0a,0x54,0x51,0x6f,0x2b,0x29,0xc8,0x23,0x93,0x07,0x66,0x20,0x8d,
+ 0x03,0x0a,0x54,0x5f,0xa9,0x9c,0x4c,0xb4,0x5f,0x27,0x50,0x9e,0x20,0x8d,
+ 0x03,0x0a,0x55,0x71,0x51,0xd9,0x36,0x98,0x09,0xd6,0x3b,0xff,0x20,0x8d,
+ 0x03,0x0a,0x56,0x23,0x78,0xa3,0xb1,0x0c,0x7c,0x87,0xd2,0x32,0x20,0x8d,
+ 0x03,0x0a,0x56,0x76,0xeb,0x9b,0xff,0xe7,0x47,0x79,0xfb,0x50,0x20,0x8d,
+ 0x03,0x0a,0x5e,0xed,0xd2,0x89,0x48,0xd5,0x83,0x17,0x6a,0x01,0x20,0x8d,
+ 0x03,0x0a,0x5f,0x38,0x14,0x4a,0x97,0x39,0xff,0x12,0x07,0xb0,0x20,0x8d,
+ 0x03,0x0a,0x5f,0x7d,0xd3,0x77,0x5b,0x23,0x12,0x40,0xd2,0x49,0x20,0x8d,
+ 0x03,0x0a,0x5f,0xad,0xd5,0x0c,0x88,0x35,0xa4,0x66,0x97,0xb3,0x20,0x8d,
+ 0x03,0x0a,0x5f,0xc1,0xc2,0x32,0x38,0x2d,0xd4,0x93,0x31,0x81,0x20,0x8d,
+ 0x03,0x0a,0x5f,0xe4,0xb7,0x48,0x49,0x84,0x02,0x82,0x8a,0x56,0x20,0x8d,
+ 0x03,0x0a,0x58,0x00,0x54,0xc2,0xb3,0x71,0xbe,0x34,0x95,0x7a,0x20,0x8d,
+ 0x03,0x0a,0x58,0x0f,0xef,0xf9,0x57,0x09,0x82,0x6b,0x6e,0x9a,0x20,0x8d,
+ 0x03,0x0a,0x58,0x61,0xa0,0x7d,0xed,0x7b,0x2a,0x8b,0x6a,0x0e,0x20,0x8d,
+ 0x03,0x0a,0x58,0xb9,0x66,0xbe,0x0b,0xd7,0xeb,0x86,0x23,0x7d,0x20,0x8d,
+ 0x03,0x0a,0x58,0xdc,0x52,0x84,0xaf,0x56,0xd3,0xe1,0x7f,0x1f,0x20,0x8d,
+ 0x03,0x0a,0x59,0x0e,0xf6,0x19,0x6a,0x45,0x5c,0x18,0x6a,0x0e,0x20,0x8d,
+ 0x03,0x0a,0x59,0x89,0x67,0xa7,0x3f,0x41,0x3e,0x30,0x42,0x11,0x20,0x8d,
+ 0x03,0x0a,0x59,0x95,0x50,0xd6,0x2e,0xf7,0xd2,0xe6,0x3a,0x56,0x20,0x8d,
+ 0x03,0x0a,0x5a,0x2d,0xdc,0xf1,0xa6,0x40,0xbc,0x1f,0xd5,0xb5,0x20,0x8d,
+ 0x03,0x0a,0x5a,0x65,0xf3,0x5a,0x2c,0x66,0x41,0xe8,0x78,0xc0,0x20,0x8d,
+ 0x03,0x0a,0x5b,0x2a,0x0b,0xec,0x9e,0x05,0x81,0x7a,0x9e,0x08,0x20,0x8d,
+ 0x03,0x0a,0x5c,0x73,0xff,0x8e,0xc5,0xfe,0x21,0xc1,0x19,0xb3,0x20,0x8d,
+ 0x03,0x0a,0x5d,0x41,0xde,0x3d,0xa1,0x86,0x9b,0x26,0x27,0x11,0x20,0x8d,
+ 0x03,0x0a,0x5d,0xc5,0xaa,0x3c,0xf7,0xc6,0x2e,0x55,0x9d,0xa5,0x20,0x8d,
+ 0x03,0x0a,0x5e,0x13,0x80,0x8e,0x3c,0x3b,0x13,0xb0,0xc0,0x01,0x20,0x8d,
+ 0x03,0x0a,0x5e,0x75,0x95,0xb5,0x98,0xc3,0x6d,0x33,0x58,0xba,0x20,0x8d,
+ 0x03,0x0a,0x67,0x8e,0x26,0xbd,0x0a,0x43,0x30,0x7d,0xff,0x0f,0x20,0x8d,
+ 0x03,0x0a,0x60,0xfd,0xbe,0xb9,0x89,0x6c,0x4c,0x72,0x10,0x7b,0x20,0x8d,
+ 0x03,0x0a,0x60,0xc3,0xb7,0x51,0xf6,0x2f,0x0b,0xa8,0x61,0x21,0x20,0x8d,
+ 0x03,0x0a,0x61,0x3c,0x3e,0x12,0x57,0xfb,0x8e,0x36,0xdd,0xa4,0x20,0x8d,
+ 0x03,0x0a,0x61,0x04,0x55,0x21,0x5d,0x12,0x39,0xfb,0x09,0x49,0x20,0x8d,
+ 0x03,0x0a,0x61,0x63,0x52,0x55,0xbf,0xb7,0xa3,0x69,0x3f,0x91,0x20,0x8d,
+ 0x03,0x0a,0x62,0x19,0x4a,0x4d,0x64,0xb7,0x65,0x19,0x8e,0x8a,0x20,0x8d,
+ 0x03,0x0a,0x63,0x71,0x25,0x6d,0x19,0xbd,0x62,0x0d,0x9e,0x95,0x20,0x8d,
+ 0x03,0x0a,0x64,0x29,0xe3,0x42,0x71,0x3b,0x3d,0x7c,0xda,0xc7,0x20,0x8d,
+ 0x03,0x0a,0x65,0xa8,0x2f,0x55,0xcc,0xe3,0x4c,0x84,0xcc,0x3b,0x20,0x8d,
+ 0x03,0x0a,0x65,0xc7,0x38,0xa4,0xe4,0xd6,0x0b,0x2b,0xed,0xe6,0x20,0x8d,
+ 0x03,0x0a,0x6f,0x10,0x12,0x4f,0x8f,0x44,0x85,0x5d,0x69,0xa9,0x20,0x8d,
+ 0x03,0x0a,0x6f,0x87,0xcf,0x54,0x39,0xbf,0x36,0x12,0x55,0x61,0x20,0x8d,
+ 0x03,0x0a,0x6f,0xa7,0xe5,0x14,0xd9,0x5d,0x5d,0x9b,0x9c,0xac,0x20,0x8d,
+ 0x03,0x0a,0x6f,0xe3,0x17,0x08,0xf6,0x24,0x4b,0xa8,0x5f,0x24,0x20,0x8d,
+ 0x03,0x0a,0x68,0xa4,0x34,0x41,0x8d,0xb9,0xda,0xd4,0x86,0x59,0x20,0x8d,
+ 0x03,0x0a,0x6a,0x27,0x7b,0x6d,0x0b,0x29,0x5a,0x67,0xd1,0x95,0x20,0x8d,
+ 0x03,0x0a,0x6a,0x57,0x2a,0xd0,0x28,0x58,0xc8,0x75,0xd2,0xd1,0x20,0x8d,
+ 0x03,0x0a,0x6a,0x64,0xb2,0xc9,0x15,0xc6,0x0e,0x8b,0x86,0x4f,0x20,0x8d,
+ 0x03,0x0a,0x6a,0x8b,0xd2,0x78,0x3f,0x7a,0xf8,0x92,0x8f,0x80,0x20,0x8d,
+ 0x03,0x0a,0x6a,0x9e,0xf9,0x07,0x73,0xd8,0xe8,0x24,0x93,0xcc,0x20,0x8d,
+ 0x03,0x0a,0x6a,0xcb,0x6c,0x41,0x52,0x61,0x20,0x4e,0x77,0x39,0x20,0x8d,
+ 0x03,0x0a,0x6a,0xf0,0x96,0x3c,0x4c,0x78,0x33,0xd0,0xf0,0x00,0x20,0x8d,
+ 0x03,0x0a,0x6b,0x59,0x5f,0xe7,0xdd,0x57,0xba,0xc1,0x12,0x51,0x20,0x8d,
+ 0x03,0x0a,0x6c,0x62,0x5b,0x0d,0x91,0x66,0xd0,0xca,0x10,0x2d,0x20,0x8d,
+ 0x03,0x0a,0x6c,0x62,0xc5,0x19,0x94,0x5b,0xcd,0x20,0xd9,0x73,0x20,0x8d,
+ 0x03,0x0a,0x6d,0xb8,0x7f,0xac,0x82,0x55,0x27,0xf2,0x01,0xf5,0x20,0x8d,
+ 0x03,0x0a,0x6d,0x95,0x8d,0xd8,0x7b,0x41,0xdc,0x81,0xd4,0x3d,0x20,0x8d,
+ 0x03,0x0a,0x6e,0x38,0xa5,0x11,0x8c,0x64,0x2b,0xc5,0xbe,0x6c,0x20,0x8d,
+ 0x03,0x0a,0x76,0xbb,0x65,0x0a,0xdf,0x23,0xa2,0x6d,0x4d,0xc8,0x20,0x8d,
+ 0x03,0x0a,0x76,0x8d,0x46,0x54,0x2a,0xb7,0x9e,0xce,0x74,0x45,0x20,0x8d,
+ 0x03,0x0a,0x77,0x30,0x99,0x1c,0x76,0x58,0x64,0x7c,0x2e,0x16,0x20,0x8d,
+ 0x03,0x0a,0x71,0x6f,0xc8,0x1a,0xde,0x5b,0xde,0xda,0xcc,0xd5,0x20,0x8d,
+ 0x03,0x0a,0x72,0x89,0x34,0x3d,0x7c,0x33,0x47,0x01,0x02,0x92,0x20,0x8d,
+ 0x03,0x0a,0x74,0x3b,0x0e,0x42,0x30,0x42,0x63,0xa5,0x3e,0x8d,0x20,0x8d,
+ 0x03,0x0a,0x74,0x2d,0xb6,0x15,0xc8,0x70,0x60,0x25,0x2e,0xe7,0x20,0x8d,
+ 0x03,0x0a,0x74,0x65,0x8d,0x57,0xdb,0x20,0xa2,0xc1,0xa7,0xbd,0x20,0x8d,
+ 0x03,0x0a,0x74,0xf9,0x3c,0xb3,0x2d,0xc2,0x18,0xc5,0xcb,0x2a,0x20,0x8d,
+ 0x03,0x0a,0x75,0x95,0xe1,0x69,0x25,0x99,0xec,0xac,0x00,0xe4,0x20,0x8d,
+ 0x03,0x0a,0x76,0x3f,0x29,0x6c,0xec,0xd3,0x95,0x7e,0x4e,0x8d,0x20,0x8d,
+ 0x03,0x0a,0x7e,0x9e,0x2f,0x58,0x20,0x23,0xea,0x34,0x78,0x44,0x20,0x8d,
+ 0x03,0x0a,0x7e,0xaf,0xae,0x18,0x67,0x04,0x98,0x61,0x2f,0xa9,0x20,0x8d,
+ 0x03,0x0a,0x7f,0x84,0xea,0x51,0x31,0xd3,0x46,0x75,0xae,0xbb,0x20,0x8d,
+ 0x03,0x0a,0x78,0x3e,0x3b,0x74,0x2b,0x6f,0x57,0x06,0x53,0xbb,0x20,0x8d,
+ 0x03,0x0a,0x78,0x24,0xc1,0x1e,0x6e,0x73,0x93,0xa5,0x08,0xe3,0x20,0x8d,
+ 0x03,0x0a,0x78,0xc0,0xf5,0x28,0xea,0xf3,0xc2,0x2c,0x6a,0x69,0x20,0x8d,
+ 0x03,0x0a,0x79,0x0f,0xd0,0x25,0xd4,0xa5,0xbc,0xcb,0x72,0x51,0x20,0x8d,
+ 0x03,0x0a,0x7a,0xa9,0x41,0x75,0xf6,0x5f,0x6f,0x83,0x58,0xf1,0x20,0x8d,
+ 0x03,0x0a,0x7c,0x39,0x64,0xaf,0xf5,0x37,0xe7,0x22,0xe0,0x42,0x20,0x8d,
+ 0x03,0x0a,0x7c,0xc3,0x68,0x1e,0x92,0x7c,0xbb,0x04,0x12,0x0b,0x20,0x8d,
+ 0x03,0x0a,0x7c,0xec,0xf0,0xdb,0x09,0xea,0xdb,0x82,0x5b,0x45,0x20,0x8d,
+ 0x03,0x0a,0x7d,0x3f,0x6d,0xa4,0xb8,0x8e,0x5f,0xf9,0x5e,0x48,0x20,0x8d,
+ 0x03,0x0a,0x7d,0xb0,0xb0,0xe2,0xa5,0xa0,0xbd,0xa3,0x9e,0xb7,0x20,0x8d,
+ 0x03,0x0a,0x86,0x8a,0x76,0xb7,0x13,0xe8,0x74,0x0c,0x54,0x44,0x20,0x8d,
+ 0x03,0x0a,0x86,0xd1,0xb0,0x3e,0x88,0x73,0x42,0x0c,0xb0,0xa4,0x20,0x8d,
+ 0x03,0x0a,0x80,0xfc,0x51,0x3e,0x9b,0x7d,0x42,0x5d,0x63,0x77,0x20,0x8d,
+ 0x03,0x0a,0x81,0x49,0x6a,0xef,0x1f,0x06,0xdf,0xc4,0x6c,0x23,0x20,0x8d,
+ 0x03,0x0a,0x81,0xf1,0x31,0xce,0x65,0x59,0xc2,0x2e,0x46,0x47,0x20,0x8d,
+ 0x03,0x0a,0x82,0x9b,0xbe,0xc4,0x3b,0xbe,0x8d,0x70,0xda,0x1c,0x20,0x8d,
+ 0x03,0x0a,0x82,0xea,0xb2,0x5e,0x5f,0x7d,0x80,0x2d,0x17,0x81,0x20,0x8d,
+ 0x03,0x0a,0x83,0x8c,0x28,0x22,0x33,0xa4,0xc1,0xe8,0xae,0xe6,0x20,0x8d,
+ 0x03,0x0a,0x84,0x73,0x02,0xdd,0x47,0x8b,0x29,0xda,0xf6,0x2e,0x20,0x8d,
+ 0x03,0x0a,0x84,0xb0,0x90,0x4a,0x1c,0xf0,0x75,0x2c,0x23,0x12,0x20,0x8d,
+ 0x03,0x0a,0x85,0x29,0xc0,0xeb,0x29,0x0b,0x63,0xaa,0x13,0x98,0x20,0x8d,
+ 0x03,0x0a,0x85,0x30,0x22,0xa7,0x56,0x23,0x73,0xe0,0x97,0x03,0x20,0x8d,
+ 0x03,0x0a,0x85,0x47,0x8d,0x89,0x8e,0x13,0x57,0x5e,0xd7,0xe2,0x20,0x8d,
+ 0x03,0x0a,0x85,0x6c,0x77,0xc3,0x06,0x03,0x75,0x75,0x63,0xa7,0x20,0x8d,
+ 0x03,0x0a,0x86,0x29,0x3b,0x0b,0x5e,0xa2,0xd7,0x44,0x80,0xa1,0x20,0x8d,
+ 0x03,0x0a,0x8f,0x3b,0x03,0x68,0x7e,0x45,0x8a,0x33,0xc2,0xcb,0x20,0x8d,
+ 0x03,0x0a,0x8f,0x2f,0x41,0xc7,0xd4,0xe4,0x7a,0xdc,0x18,0x1c,0x20,0x8d,
+ 0x03,0x0a,0x8f,0x80,0xf0,0x76,0x52,0xa2,0x6e,0x1b,0x0f,0x7c,0x20,0x8d,
+ 0x03,0x0a,0x8f,0xb3,0xa3,0x0a,0x54,0xdf,0xd5,0xb3,0x00,0x07,0x20,0x8d,
+ 0x03,0x0a,0x88,0x62,0x93,0x14,0x42,0x07,0xab,0xd0,0xff,0x0e,0x20,0x8d,
+ 0x03,0x0a,0x88,0x90,0x5b,0xa0,0x20,0xb4,0x27,0xe8,0xdf,0x39,0x20,0x8d,
+ 0x03,0x0a,0x88,0xdd,0xbb,0x8a,0x6a,0xde,0x55,0x94,0xd5,0x6d,0x20,0x8d,
+ 0x03,0x0a,0x88,0xea,0xb2,0x3f,0x1e,0x31,0xcc,0xf0,0x3f,0x2e,0x20,0x8d,
+ 0x03,0x0a,0x89,0x05,0x2d,0x83,0x5f,0x11,0xeb,0xa5,0x9b,0xdd,0x20,0x8d,
+ 0x03,0x0a,0x89,0x58,0x14,0x63,0xb5,0xcc,0xea,0xdf,0x1f,0x0d,0x20,0x8d,
+ 0x03,0x0a,0x8a,0xd1,0xd5,0x85,0x24,0xe2,0xbf,0xf4,0x37,0x36,0x20,0x8d,
+ 0x03,0x0a,0x8b,0xa1,0x66,0xb0,0x8f,0x12,0x79,0xdd,0xd4,0xa7,0x20,0x8d,
+ 0x03,0x0a,0x8b,0xc2,0xdb,0xf7,0x90,0x6a,0x11,0x58,0xb0,0xfb,0x20,0x8d,
+ 0x03,0x0a,0x8c,0xab,0x57,0x1a,0x03,0x5a,0x12,0xff,0xfc,0xf5,0x20,0x8d,
+ 0x03,0x0a,0x8d,0x99,0xd1,0xf0,0xe6,0xd9,0xc5,0xff,0xa8,0x73,0x20,0x8d,
+ 0x03,0x0a,0x96,0xf0,0x45,0xaa,0xa2,0xe9,0x7b,0x72,0x62,0x56,0x20,0x8d,
+ 0x03,0x0a,0x97,0xa3,0x7e,0xe8,0xe8,0x9b,0x1e,0xfe,0x2c,0xc4,0x20,0x8d,
+ 0x03,0x0a,0x90,0x3c,0xcd,0xc6,0xb8,0x12,0x1e,0x62,0x31,0x58,0x20,0x8d,
+ 0x03,0x0a,0x90,0x2a,0x40,0x90,0x92,0x62,0x91,0x56,0x14,0x2e,0x20,0x8d,
+ 0x03,0x0a,0x90,0x70,0x98,0xf5,0xaf,0x56,0x98,0xb6,0x16,0xdf,0x20,0x8d,
+ 0x03,0x0a,0x91,0x23,0x64,0xf3,0x49,0x61,0x3b,0x73,0x9d,0x96,0x20,0x8d,
+ 0x03,0x0a,0x91,0xb9,0x56,0x50,0x35,0xd8,0xd3,0x1c,0xd6,0x87,0x20,0x8d,
+ 0x03,0x0a,0x91,0xe4,0x65,0x49,0x74,0xcf,0x92,0xa3,0x3f,0xc6,0x20,0x8d,
+ 0x03,0x0a,0x92,0x71,0x96,0x5a,0xd4,0xf0,0xd0,0x84,0x4f,0x71,0x20,0x8d,
+ 0x03,0x0a,0x92,0xb6,0x46,0xee,0x24,0xa0,0xcd,0xb9,0x0c,0xdd,0x20,0x8d,
+ 0x03,0x0a,0x92,0x9c,0x82,0xbf,0x8e,0x4f,0xd7,0xc7,0x4a,0x9d,0x20,0x8d,
+ 0x03,0x0a,0x92,0xc9,0xa1,0x01,0xeb,0x52,0xdb,0xbd,0x93,0xf8,0x20,0x8d,
+ 0x03,0x0a,0x93,0x06,0x3f,0xc3,0xe6,0x73,0x40,0x91,0xb1,0x30,0x20,0x8d,
+ 0x03,0x0a,0x93,0xd8,0x7a,0x5d,0x21,0xd0,0x87,0xf5,0x92,0x8d,0x20,0x8d,
+ 0x03,0x0a,0x94,0x54,0x6c,0x57,0xa4,0x1b,0x74,0xf0,0x7d,0x0b,0x20,0x8d,
+ 0x03,0x0a,0x94,0x96,0xd4,0xa4,0xed,0x65,0x96,0xbc,0x4a,0xbc,0x20,0x8d,
+ 0x03,0x0a,0x95,0x3d,0xec,0x1a,0x20,0x97,0xa2,0xa1,0xcd,0xab,0x20,0x8d,
+ 0x03,0x0a,0x95,0x1a,0x3a,0xb0,0x29,0x8c,0xcc,0x32,0x80,0xf7,0x20,0x8d,
+ 0x03,0x0a,0x95,0x47,0xee,0xab,0xa9,0x78,0x17,0xa7,0xed,0x73,0x20,0x8d,
+ 0x03,0x0a,0x95,0x68,0x0e,0x9d,0x10,0x5d,0x2d,0xf7,0x6a,0x56,0x20,0x8d,
+ 0x03,0x0a,0x95,0xe0,0x9a,0x05,0x94,0x67,0x22,0xc2,0x99,0xf4,0x20,0x8d,
+ 0x03,0x0a,0x9e,0xb9,0xda,0xa3,0xfc,0xd4,0xd1,0xb9,0xb5,0x40,0x20,0x8d,
+ 0x03,0x0a,0x9f,0x0a,0x17,0x56,0xa6,0xcb,0xda,0x86,0x0f,0x4f,0x20,0x8d,
+ 0x03,0x0a,0x9f,0x17,0xcb,0x57,0x64,0x8a,0x8e,0xf1,0x93,0x4f,0x20,0x8d,
+ 0x03,0x0a,0x9f,0x60,0x23,0xd8,0x31,0xf5,0x3b,0x5d,0x00,0xca,0x20,0x8d,
+ 0x03,0x0a,0x9f,0xd2,0xb0,0x27,0xc6,0x36,0x2f,0xf9,0x76,0xb8,0x20,0x8d,
+ 0x03,0x0a,0x98,0x3d,0x24,0x92,0x18,0x0e,0xbe,0x5e,0x37,0x80,0x20,0x8d,
+ 0x03,0x0a,0x98,0x2b,0xfa,0x4d,0xf6,0xe3,0xcb,0x8f,0xa7,0xca,0x20,0x8d,
+ 0x03,0x0a,0x98,0x2e,0x6e,0xe7,0x52,0xb9,0x59,0xd1,0x70,0x7e,0x20,0x8d,
+ 0x03,0x0a,0x99,0x15,0x6a,0xb4,0x2e,0x18,0x73,0x15,0xd0,0xb2,0x20,0x8d,
+ 0x03,0x0a,0x99,0xb9,0x4b,0x45,0x2c,0x9c,0x74,0x95,0x85,0x38,0x20,0x8d,
+ 0x03,0x0a,0x99,0xf8,0x24,0xd4,0xa5,0x4c,0xed,0xea,0xb9,0x94,0x20,0x8d,
+ 0x03,0x0a,0x99,0xfc,0x5b,0xe1,0x93,0xb3,0x4a,0x82,0xc0,0x94,0x20,0x8d,
+ 0x03,0x0a,0x99,0xe6,0x23,0x9d,0x7a,0xed,0x35,0xe6,0x99,0x70,0x20,0x8d,
+ 0x03,0x0a,0x9a,0x10,0x03,0xfc,0x52,0xa3,0x94,0xb1,0x55,0x1e,0x20,0x8d,
+ 0x03,0x0a,0x9a,0xbd,0xbb,0xf4,0xaa,0xde,0xf7,0xfc,0xee,0x83,0x20,0x8d,
+ 0x03,0x0a,0x9a,0x8c,0xe7,0x4c,0x13,0xf0,0xa0,0xdf,0xd7,0x18,0x20,0x8d,
+ 0x03,0x0a,0x9b,0x53,0xdf,0x76,0xd6,0x86,0x7b,0x67,0xa6,0xb2,0x20,0x8d,
+ 0x03,0x0a,0x9c,0xbd,0x0b,0xef,0xec,0x63,0xe9,0xe6,0xa7,0xb8,0x20,0x8d,
+ 0x03,0x0a,0x9c,0xd2,0x89,0x56,0xf8,0x19,0x83,0x37,0xf7,0xc5,0x20,0x8d,
+ 0x03,0x0a,0x9d,0x9b,0xde,0x57,0xf1,0x06,0xae,0x93,0x0f,0xbd,0x20,0x8d,
+ 0x03,0x0a,0x9d,0xc8,0xce,0xb0,0x94,0x36,0xb8,0x6d,0x13,0x23,0x20,0x8d,
+ 0x03,0x0a,0x9e,0x11,0x46,0xb7,0x7e,0x5b,0x0a,0x28,0x75,0x71,0x20,0x8d,
+ 0x03,0x0a,0x9e,0x2b,0xdf,0x5e,0x5e,0x37,0x9a,0x3c,0xc2,0x97,0x20,0x8d,
+ 0x03,0x0a,0xa7,0x3e,0x5d,0x9e,0xf6,0x87,0xbb,0x23,0x4b,0x8e,0x20,0x8d,
+ 0x03,0x0a,0xa7,0x23,0xf2,0xb4,0xee,0x5c,0x47,0x6b,0x2d,0xa8,0x20,0x8d,
+ 0x03,0x0a,0xa7,0x7b,0xe7,0x14,0x3b,0x66,0x01,0x10,0x16,0xcd,0x20,0x8d,
+ 0x03,0x0a,0xa7,0x61,0xb3,0x07,0x3c,0x83,0xf3,0xcb,0x55,0x71,0x20,0x8d,
+ 0x03,0x0a,0xa0,0x14,0xbc,0x6f,0x03,0x89,0x2b,0x57,0xde,0xc8,0x20,0x8d,
+ 0x03,0x0a,0xa1,0xbc,0x70,0x3d,0x1c,0x84,0xc8,0xac,0x8b,0xf5,0x20,0x8d,
+ 0x03,0x0a,0xa2,0x3b,0xdd,0xc1,0xd3,0x1f,0xa2,0xe6,0xee,0x25,0x20,0x8d,
+ 0x03,0x0a,0xa2,0x23,0xf2,0xee,0xcb,0x9b,0x94,0x0f,0x04,0x21,0x20,0x8d,
+ 0x03,0x0a,0xa2,0xa2,0x94,0x9e,0xce,0x1a,0xf9,0xcb,0x31,0xc5,0x20,0x8d,
+ 0x03,0x0a,0xa2,0xfa,0x66,0x69,0x17,0xc7,0xd5,0x01,0x96,0xc6,0x20,0x8d,
+ 0x03,0x0a,0xa3,0x46,0x3f,0xc6,0x49,0xe3,0xc8,0xdd,0xd9,0xdc,0x20,0x8d,
+ 0x03,0x0a,0xa3,0xa3,0x67,0xe4,0xa4,0x3c,0xf0,0xa8,0x9b,0x9b,0x20,0x8d,
+ 0x03,0x0a,0xa3,0xab,0x27,0xeb,0x0b,0x9b,0x40,0xe4,0xc3,0xcb,0x20,0x8d,
+ 0x03,0x0a,0xa4,0x81,0x96,0x0c,0x52,0xde,0x9b,0x8d,0x70,0x78,0x20,0x8d,
+ 0x03,0x0a,0xa4,0x81,0x99,0x7c,0xcb,0x67,0xcc,0x4c,0x5d,0x4b,0x20,0x8d,
+ 0x03,0x0a,0xa4,0xa5,0xa5,0x10,0x66,0xfc,0x15,0x63,0x0e,0x3d,0x20,0x8d,
+ 0x03,0x0a,0xa4,0xcd,0x88,0xd6,0xdf,0xed,0xab,0xa6,0xe1,0x88,0x20,0x8d,
+ 0x03,0x0a,0xa6,0x6c,0x01,0x32,0x5f,0x56,0x32,0x72,0x1c,0x2b,0x20,0x8d,
+ 0x03,0x0a,0xae,0x94,0x31,0x12,0x75,0x92,0xd8,0x32,0x8a,0xd1,0x20,0x8d,
+ 0x03,0x0a,0xaf,0x56,0x76,0xe7,0x35,0xf3,0x5a,0x62,0x9b,0xa3,0x20,0x8d,
+ 0x03,0x0a,0xa8,0xb9,0xc3,0x07,0x95,0x23,0xde,0xe0,0xc6,0x7b,0x20,0x8d,
+ 0x03,0x0a,0xa9,0x6d,0x83,0xa6,0x9c,0xdd,0xae,0x7c,0xd6,0x97,0x20,0x8d,
+ 0x03,0x0a,0xa9,0xa8,0x9a,0x15,0x5d,0xda,0xe1,0x87,0x2d,0x0e,0x20,0x8d,
+ 0x03,0x0a,0xa9,0xc8,0x44,0xc2,0x1a,0xaf,0x46,0xa0,0xf2,0xf1,0x20,0x8d,
+ 0x03,0x0a,0xaa,0x7d,0xc2,0x0c,0x95,0xe2,0x5b,0x02,0x8e,0x41,0x20,0x8d,
+ 0x03,0x0a,0xab,0x00,0x8e,0xd1,0x06,0x26,0x63,0xa5,0x1d,0x49,0x20,0x8d,
+ 0x03,0x0a,0xab,0x29,0x85,0x0f,0xf2,0xb8,0x58,0x8f,0xdb,0xbf,0x20,0x8d,
+ 0x03,0x0a,0xab,0x98,0x40,0x0a,0x73,0x43,0x6f,0xb6,0x3d,0x8b,0x20,0x8d,
+ 0x03,0x0a,0xab,0xdd,0x6d,0x5d,0xc5,0x36,0xcb,0x6c,0xc8,0x70,0x20,0x8d,
+ 0x03,0x0a,0xac,0x81,0x65,0xa3,0x8b,0xea,0x0b,0x71,0xe4,0x16,0x20,0x8d,
+ 0x03,0x0a,0xad,0x1b,0x40,0xc1,0x45,0x64,0xbf,0x24,0x15,0xca,0x20,0x8d,
+ 0x03,0x0a,0xad,0x1c,0xc0,0xb4,0x95,0xb5,0x17,0xc0,0xc2,0x41,0x20,0x8d,
+ 0x03,0x0a,0xad,0xc4,0xfa,0x8d,0xa6,0xf7,0x40,0x42,0xe7,0xd3,0x20,0x8d,
+ 0x03,0x0a,0xae,0x2e,0xe4,0x64,0x79,0x05,0x5f,0xb7,0x04,0x14,0x20,0x8d,
+ 0x03,0x0a,0xb0,0x48,0xe6,0xe8,0x48,0xfa,0xca,0x87,0x78,0x18,0x20,0x8d,
+ 0x03,0x0a,0xb0,0x6c,0x4a,0x92,0xde,0xd3,0x0d,0x28,0xc4,0x79,0x20,0x8d,
+ 0x03,0x0a,0xb1,0x41,0x81,0xac,0xde,0xce,0x0b,0x94,0x8a,0x9d,0x20,0x8d,
+ 0x03,0x0a,0xb1,0x73,0xdf,0x4b,0xab,0xc3,0x7a,0x3c,0x48,0x99,0x20,0x8d,
+ 0x03,0x0a,0xb1,0xb6,0xc8,0x72,0x86,0xc6,0x34,0x6b,0xef,0x41,0x20,0x8d,
+ 0x03,0x0a,0xb1,0xd5,0x8e,0xf0,0x22,0x9a,0x8b,0xa6,0xf1,0xfb,0x20,0x8d,
+ 0x03,0x0a,0xb1,0xd8,0x90,0x36,0x0e,0xc6,0x51,0x9c,0x8b,0x93,0x20,0x8d,
+ 0x03,0x0a,0xb2,0xce,0xea,0x6a,0xd7,0x34,0x30,0x8d,0xdf,0x65,0x20,0x8d,
+ 0x03,0x0a,0xb2,0xea,0xa2,0xc5,0xeb,0x2a,0x10,0xec,0xeb,0x4e,0x20,0x8d,
+ 0x03,0x0a,0xbe,0xda,0x60,0xee,0xa0,0xf8,0xdd,0x5a,0x11,0xb6,0x20,0x8d,
+ 0x03,0x0a,0xbf,0x7f,0x7f,0x68,0x2c,0x63,0x70,0xba,0xbb,0xf1,0x20,0x8d,
+ 0x03,0x0a,0xb9,0xaa,0xce,0xfd,0x87,0x35,0x7b,0xee,0x0d,0x40,0x20,0x8d,
+ 0x03,0x0a,0xb9,0xe5,0xb3,0x2c,0xb6,0x6d,0x91,0x46,0x22,0xad,0x20,0x8d,
+ 0x03,0x0a,0xba,0x49,0xd2,0xda,0xb8,0x28,0xe8,0x4d,0x53,0xca,0x20,0x8d,
+ 0x03,0x0a,0xba,0xcd,0x40,0x9b,0x0b,0xc6,0x82,0xba,0xc8,0xdd,0x20,0x8d,
+ 0x03,0x0a,0xbb,0x57,0x4d,0xce,0xa0,0x53,0x4d,0x8f,0xcd,0x4f,0x20,0x8d,
+ 0x03,0x0a,0xbb,0xba,0xc0,0x45,0x0b,0x3d,0x30,0xef,0x86,0x93,0x20,0x8d,
+ 0x03,0x0a,0xbc,0x80,0x0b,0xa0,0xe3,0xc1,0x9b,0x6b,0xc5,0x17,0x20,0x8d,
+ 0x03,0x0a,0xbd,0x3a,0xc5,0xd0,0xc3,0x93,0x32,0x55,0x57,0x27,0x20,0x8d,
+ 0x03,0x0a,0xbd,0x63,0x78,0x09,0xf3,0x85,0x50,0x42,0x0c,0x3a,0x20,0x8d,
+ 0x03,0x0a,0xbd,0xb2,0x78,0xc7,0x06,0x2c,0xe1,0xb8,0x72,0xdc,0x20,0x8d,
+ 0x03,0x0a,0xc7,0x25,0x66,0x48,0x17,0x18,0x9d,0x2d,0x05,0xb4,0x20,0x8d,
+ 0x03,0x0a,0xc7,0x66,0xbe,0x2e,0x08,0xdf,0xba,0xf7,0xae,0x83,0x20,0x8d,
+ 0x03,0x0a,0xc7,0x6d,0x92,0x43,0x00,0x24,0xe5,0xd6,0x83,0xd3,0x20,0x8d,
+ 0x03,0x0a,0xc7,0xf7,0x05,0x69,0x99,0x52,0x54,0x77,0x2b,0x1f,0x20,0x8d,
+ 0x03,0x0a,0xc7,0xdd,0x9d,0xe0,0x6d,0xaa,0x03,0xcb,0x9c,0x21,0x20,0x8d,
+ 0x03,0x0a,0xc0,0x0f,0xf8,0x18,0xb0,0x84,0x66,0x47,0x08,0xe4,0x20,0x8d,
+ 0x03,0x0a,0xc0,0x41,0xc0,0xc5,0x9d,0xef,0x46,0x46,0xae,0x7f,0x20,0x8d,
+ 0x03,0x0a,0xc1,0x89,0x05,0x1b,0x88,0x6b,0xd7,0x20,0x08,0x9b,0x20,0x8d,
+ 0x03,0x0a,0xc2,0x4e,0xd2,0xd3,0xfd,0x58,0x32,0x14,0x6f,0x87,0x20,0x8d,
+ 0x03,0x0a,0xc2,0x6d,0xf5,0x40,0x0f,0xbd,0xfb,0x53,0x19,0xc9,0x20,0x8d,
+ 0x03,0x0a,0xc3,0x3e,0x86,0xb1,0xd5,0x0c,0x5a,0x0e,0x18,0x4e,0x20,0x8d,
+ 0x03,0x0a,0xc4,0x3a,0x2a,0x49,0xb4,0x72,0xa4,0x2c,0x7b,0x99,0x20,0x8d,
+ 0x03,0x0a,0xc4,0x44,0x04,0x3a,0x11,0x84,0x47,0x67,0x2a,0x13,0x20,0x8d,
+ 0x03,0x0a,0xc4,0x45,0x1f,0xbc,0xc9,0xa0,0x32,0x01,0xeb,0xbc,0x20,0x8d,
+ 0x03,0x0a,0xc4,0x55,0x2a,0xb9,0xbb,0x9b,0x2a,0xe7,0x1c,0x75,0x20,0x8d,
+ 0x03,0x0a,0xc4,0xdf,0x49,0x72,0xb7,0xed,0xbe,0x9f,0x59,0xfa,0x20,0x8d,
+ 0x03,0x0a,0xc4,0xe0,0x24,0x19,0x5a,0x39,0xc6,0xbe,0x74,0xee,0x20,0x8d,
+ 0x03,0x0a,0xc5,0xdc,0x95,0xee,0xec,0x4d,0x25,0xb1,0xa1,0x5a,0x20,0x8d,
+ 0x03,0x0a,0xc6,0x47,0x01,0xca,0x17,0xe1,0x47,0x46,0x9b,0xd6,0x20,0x8d,
+ 0x03,0x0a,0xce,0xf6,0xda,0x2a,0x7f,0x69,0x90,0xad,0x89,0xe4,0x20,0x8d,
+ 0x03,0x0a,0xce,0xf1,0x60,0x80,0x76,0xe7,0x9a,0x36,0xdc,0xc7,0x20,0x8d,
+ 0x03,0x0a,0xcf,0x98,0x18,0x43,0xeb,0x5d,0xd7,0x16,0xf1,0x50,0x20,0x8d,
+ 0x03,0x0a,0xc8,0x76,0xb8,0x89,0x52,0x6f,0x23,0x93,0xe5,0x24,0x20,0x8d,
+ 0x03,0x0a,0xc9,0x3e,0xe1,0xbf,0xef,0xc8,0x22,0x97,0xae,0x51,0x20,0x8d,
+ 0x03,0x0a,0xc9,0x82,0xc3,0xcc,0x29,0x07,0x0b,0x8d,0x6f,0xfb,0x20,0x8d,
+ 0x03,0x0a,0xc9,0xfe,0x7a,0x81,0x62,0x35,0x52,0xf7,0x02,0x0c,0x20,0x8d,
+ 0x03,0x0a,0xca,0x33,0x3a,0xdc,0x87,0x62,0x7a,0xc2,0x1d,0xe6,0x20,0x8d,
+ 0x03,0x0a,0xca,0x50,0x8d,0xe0,0x82,0x1c,0x59,0x0f,0xef,0x1b,0x20,0x8d,
+ 0x03,0x0a,0xca,0xa3,0x66,0x19,0x34,0xac,0xb2,0x0f,0x60,0x9a,0x20,0x8d,
+ 0x03,0x0a,0xcb,0xb3,0xa0,0x39,0xf6,0x46,0xec,0x5a,0x42,0xc6,0x20,0x8d,
+ 0x03,0x0a,0xcc,0xc6,0x22,0xb4,0xfc,0xf7,0xff,0xb0,0xa2,0xb4,0x20,0x8d,
+ 0x03,0x0a,0xcd,0x2e,0x71,0x78,0x7b,0x6d,0x9e,0x61,0x70,0x05,0x20,0x8d,
+ 0x03,0x0a,0xcd,0x31,0x38,0x94,0x95,0xca,0x44,0xf4,0x65,0x68,0x20,0x8d,
+ 0x03,0x0a,0xcd,0x61,0xe1,0xbe,0x7b,0x46,0x9c,0x51,0xbf,0x66,0x20,0x8d,
+ 0x03,0x0a,0xcd,0xac,0xcf,0x18,0x1f,0xa6,0x8f,0x02,0x6a,0x43,0x20,0x8d,
+ 0x03,0x0a,0xce,0x20,0x1e,0x2c,0x8d,0x2c,0x9e,0xd9,0xa7,0xac,0x20,0x8d,
+ 0x04,0x20,0xd1,0xbb,0x02,0x8d,0x4d,0xd5,0x6a,0x20,0xc0,0xf9,0x16,0x2b,0x84,0x22,0x66,0xe0,0x89,0x45,0x60,0x37,0x52,0xe2,0x0b,0xa5,0xb4,0xf8,0x26,0xb3,0x8f,0x5a,0x30,0xed,0x20,0x8d,
+ 0x04,0x20,0xd2,0x59,0x3b,0xd7,0x14,0x7e,0xd0,0x98,0xfe,0x9e,0xa5,0x69,0xf4,0x26,0x6d,0x72,0x6f,0xc3,0x76,0xce,0x1d,0x40,0x41,0xa2,0xa1,0xaf,0xf9,0x6e,0x57,0x2d,0x9d,0xc3,0x20,0x8d,
+ 0x04,0x20,0xdf,0xd9,0xed,0x59,0xbf,0x1e,0x77,0x48,0x3c,0x13,0x3b,0xc5,0xc8,0x15,0x86,0x88,0x68,0xf0,0x08,0xe9,0xee,0x9b,0x3d,0xa4,0x33,0x0a,0x68,0x67,0x86,0x9d,0xe2,0x83,0x20,0x8d,
+ 0x04,0x20,0xe9,0xbf,0xa7,0xbd,0x9b,0x54,0x54,0xe8,0xc8,0xae,0x78,0x99,0xa0,0xa3,0xf6,0x5d,0x78,0xe3,0x9e,0x5c,0xa7,0x18,0xb9,0x13,0x0c,0x04,0x9b,0xf3,0x7f,0x27,0x18,0xb0,0x20,0x8d,
+ 0x04,0x20,0xf8,0x8d,0x64,0xd2,0xc8,0xe9,0x0f,0x51,0x03,0x1c,0x98,0x33,0x8f,0xe0,0x1e,0xe7,0xb6,0x16,0x8d,0x2a,0xf5,0xf3,0x19,0xce,0xdd,0x9e,0xee,0x17,0xc3,0x8f,0xd6,0xa1,0x20,0x8d,
+ 0x04,0x20,0xfb,0xf1,0x17,0xd6,0x03,0x3b,0x01,0x8b,0x98,0xcf,0x16,0x20,0xde,0xaf,0x6c,0xed,0x60,0xab,0x6e,0x14,0x0b,0x58,0x6b,0x2d,0xf8,0x06,0x98,0x37,0x7a,0xff,0x7a,0x0f,0x20,0x8d,
+ 0x04,0x20,0x0f,0xb9,0x71,0x05,0x64,0x83,0x2c,0x68,0x6a,0x9c,0xf0,0x4f,0xc3,0x90,0xcd,0x5c,0x73,0x9a,0xdd,0xb3,0xc6,0x42,0xca,0x09,0xbb,0xcc,0xfe,0x29,0x49,0x9f,0xc7,0x28,0x20,0x8d,
+ 0x04,0x20,0x22,0x6e,0x42,0xe4,0xbd,0x2b,0xe5,0x3e,0x30,0xda,0x8a,0x03,0xf3,0x45,0x52,0xac,0x84,0xbf,0xbf,0xc5,0xaa,0x5f,0xe0,0x1b,0x26,0x28,0xb5,0x83,0x2e,0xed,0x4c,0xee,0x20,0x8d,
+ 0x04,0x20,0x2a,0x47,0x8b,0xa0,0x4f,0x67,0x1d,0xcd,0x5d,0x84,0x1a,0xec,0xbd,0xd2,0xaa,0xe9,0x99,0x01,0x96,0x5d,0x4e,0xff,0x64,0x47,0xba,0xde,0xbf,0x56,0x89,0x39,0xac,0xde,0x20,0x8d,
+ 0x04,0x20,0x2b,0xf3,0xe8,0xf5,0xef,0x90,0x14,0xab,0x61,0xe9,0x11,0x97,0x9f,0x18,0x4d,0xb4,0xff,0x89,0x94,0xf7,0x92,0x94,0x53,0xe6,0x9e,0xd4,0xdb,0x85,0x89,0x4d,0x3e,0xc9,0x20,0x8d,
+ 0x04,0x20,0x2e,0x4e,0xde,0x51,0xd7,0x28,0x4b,0x29,0x7c,0xff,0x1f,0x8a,0x50,0xb7,0x5e,0xf0,0x81,0xcd,0xe8,0x8a,0x08,0x73,0x58,0x4e,0x43,0x1f,0x7b,0x85,0x9a,0xed,0xe2,0x68,0x20,0x8d,
+ 0x04,0x20,0x35,0xdd,0xd0,0x36,0xa5,0x69,0x4a,0xd2,0xcc,0xb8,0xe9,0x62,0xa3,0x55,0xeb,0x86,0xe2,0xf3,0x03,0x48,0x26,0xe6,0x20,0xad,0xda,0xaa,0xff,0xde,0x16,0xad,0x39,0x9d,0x20,0x8d,
+ 0x04,0x20,0x41,0x47,0x4e,0xc2,0xa1,0x71,0x63,0x3e,0x11,0x54,0x46,0x91,0x80,0xed,0x41,0x16,0x32,0x29,0x19,0x60,0xc9,0xef,0xa3,0xb7,0x96,0x2c,0x94,0xa8,0xdf,0x55,0xd7,0x21,0x20,0x8d,
+ 0x04,0x20,0x44,0xf3,0xb7,0x5e,0x48,0x3c,0xbd,0xa6,0x52,0xaa,0x68,0xb5,0xbf,0xdc,0x01,0x5f,0x4b,0xeb,0x7a,0x25,0xcb,0x4a,0x70,0xbc,0x18,0x8c,0x97,0x5d,0x27,0x54,0x09,0x17,0x20,0x8d,
+ 0x04,0x20,0x5c,0x52,0x7f,0x17,0x16,0x4c,0x27,0x36,0x2d,0x05,0xa1,0x19,0x0d,0xbe,0x87,0xab,0x24,0x7b,0xe7,0x38,0x3b,0xa1,0x7f,0xd1,0xd4,0x28,0x16,0x8e,0xfc,0x98,0x7d,0x08,0x20,0x8d,
+ 0x04,0x20,0x67,0xc4,0x17,0xa5,0xcb,0x77,0xbd,0xaa,0x11,0x7f,0x8b,0xc0,0x81,0xf3,0xc0,0x96,0x9d,0x31,0x27,0x9c,0xad,0x6c,0x6d,0x98,0x42,0x70,0xdb,0x50,0x12,0x96,0x0b,0x36,0x20,0x8d,
+ 0x04,0x20,0x73,0xdb,0x82,0xe0,0x88,0x40,0x49,0xd8,0x3b,0xa0,0xdd,0x83,0x7c,0x84,0x3c,0xb8,0xd0,0x03,0x0b,0x7a,0x08,0x44,0x4e,0x79,0xd6,0x61,0x23,0x31,0xa9,0xb3,0x07,0x58,0x20,0x8d,
+ 0x04,0x20,0x75,0x93,0x21,0xdd,0x99,0x58,0x3c,0x3f,0xae,0x36,0x50,0x58,0x49,0xe2,0xd0,0xc3,0x3a,0x2c,0x4a,0xcf,0x41,0xc4,0x82,0x48,0xab,0xec,0x07,0x5d,0x56,0x2c,0xb4,0x8d,0x20,0x8d,
+ 0x04,0x20,0x87,0xd4,0x66,0x0f,0xed,0xf9,0xf5,0xf1,0xcb,0x85,0x37,0xec,0xe1,0x19,0xa8,0xa4,0x03,0xb7,0x13,0x59,0xbb,0xf8,0xd2,0x93,0x92,0x50,0xfa,0x30,0x7a,0xd8,0x43,0xd0,0x20,0x8d,
+ 0x04,0x20,0x8b,0xfe,0xad,0x19,0xdb,0x97,0x57,0x84,0xec,0xad,0x4f,0xb2,0xdf,0x69,0x53,0x04,0x57,0x19,0x16,0x7a,0x71,0xd7,0x2b,0xab,0x03,0xfd,0x76,0x4d,0xa0,0x70,0xc3,0xe7,0x20,0x8d,
+ 0x04,0x20,0x96,0x25,0xde,0x4a,0xbc,0xbd,0x76,0x76,0xee,0x43,0x45,0x76,0xe0,0x0d,0x99,0x83,0xcd,0x83,0x8f,0x94,0xe5,0xde,0x7a,0xf2,0xf0,0x57,0xb8,0x25,0x54,0x17,0xcb,0x3b,0x20,0x8d,
+ 0x04,0x20,0x98,0xc6,0x44,0x27,0x90,0x41,0xa6,0x98,0xf9,0x25,0x6c,0x59,0x0f,0x06,0x6d,0x44,0x59,0x0e,0xb2,0x46,0xb0,0xa4,0x37,0x88,0x69,0x8f,0xc1,0x32,0xcd,0x9f,0x15,0xd7,0x20,0x8d,
+ 0x04,0x20,0xaa,0x3a,0x16,0x86,0xea,0x59,0x09,0x04,0x78,0xe5,0x10,0x92,0xe1,0x1d,0xad,0xf7,0x56,0x2b,0xac,0xb0,0x97,0x29,0x63,0x30,0xf4,0x1b,0xcf,0xde,0xf3,0x28,0x0a,0x29,0x20,0x8d,
+ 0x04,0x20,0xbc,0x27,0xae,0x89,0xc1,0x67,0x73,0x0a,0x08,0x02,0xdf,0xb7,0xcc,0x94,0xc7,0x9f,0xf4,0x72,0x7a,0x9b,0x20,0x0c,0x5c,0x11,0x3d,0x22,0xd6,0x13,0x88,0x66,0x74,0xbf,0x20,0x8d,
};
-static SeedSpec6 pnSeed6_test[] = {
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x99,0xcb,0x26,0x31,0xba,0x48,0x51,0x31,0x39,0x0d}, 18333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x44,0xf4,0xf4,0xf0,0xbf,0xf7,0x7e,0x6d,0xc4,0xe8}, 18333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x6a,0x8b,0xd2,0x78,0x3f,0x7a,0xf8,0x92,0x8f,0x80}, 18333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xe6,0x4e,0xa4,0x47,0x4e,0x2a,0xfe,0xe8,0x95,0xcc}, 18333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x9f,0xae,0x9f,0x59,0x0b,0x3f,0x31,0x3a,0x8a,0x5f}, 18333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x47,0xb1,0xe4,0x55,0xd1,0xb0,0x14,0x3f,0xb6,0xdb}, 18333},
- {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xa0,0x60,0x9e,0x46,0x54,0xdb,0x61,0x3b,0xb2,0x6f}, 18333}
+static const uint8_t chainparams_seed_test[] = {
+ 0x03,0x0a,0x99,0xcb,0x26,0x31,0xba,0x48,0x51,0x31,0x39,0x0d,0x47,0x9d,
+ 0x03,0x0a,0x44,0xf4,0xf4,0xf0,0xbf,0xf7,0x7e,0x6d,0xc4,0xe8,0x47,0x9d,
+ 0x03,0x0a,0x6a,0x8b,0xd2,0x78,0x3f,0x7a,0xf8,0x92,0x8f,0x80,0x47,0x9d,
+ 0x03,0x0a,0xe6,0x4e,0xa4,0x47,0x4e,0x2a,0xfe,0xe8,0x95,0xcc,0x47,0x9d,
+ 0x03,0x0a,0x9f,0xae,0x9f,0x59,0x0b,0x3f,0x31,0x3a,0x8a,0x5f,0x47,0x9d,
+ 0x03,0x0a,0x47,0xb1,0xe4,0x55,0xd1,0xb0,0x14,0x3f,0xb6,0xdb,0x47,0x9d,
+ 0x03,0x0a,0xa0,0x60,0x9e,0x46,0x54,0xdb,0x61,0x3b,0xb2,0x6f,0x47,0x9d,
};
#endif // BITCOIN_CHAINPARAMSSEEDS_H
diff --git a/src/consensus/params.h b/src/consensus/params.h
index 217cb019e1..28c95e0884 100644
--- a/src/consensus/params.h
+++ b/src/consensus/params.h
@@ -29,6 +29,11 @@ struct BIP9Deployment {
int64_t nStartTime;
/** Timeout/expiry MedianTime for the deployment attempt. */
int64_t nTimeout;
+ /** If lock in occurs, delay activation until at least this block
+ * height. Note that activation will only occur on a retarget
+ * boundary.
+ */
+ int min_activation_height{0};
/** Constant for nTimeout very far in the future. */
static constexpr int64_t NO_TIMEOUT = std::numeric_limits<int64_t>::max();
@@ -38,6 +43,11 @@ struct BIP9Deployment {
* process (which takes at least 3 BIP9 intervals). Only tests that specifically test the
* behaviour during activation cannot use this. */
static constexpr int64_t ALWAYS_ACTIVE = -1;
+
+ /** Special value for nStartTime indicating that the deployment is never active.
+ * This is useful for integrating the code changes for a new feature
+ * prior to deploying it on some or all networks. */
+ static constexpr int64_t NEVER_ACTIVE = -2;
};
/**
diff --git a/src/dummywallet.cpp b/src/dummywallet.cpp
index bb06c95e7d..95886d3138 100644
--- a/src/dummywallet.cpp
+++ b/src/dummywallet.cpp
@@ -50,6 +50,7 @@ void DummyWalletInit::AddWalletOptions(ArgsManager& argsman) const
"-flushwallet",
"-privdb",
"-walletrejectlongchains",
+ "-unsafesqlitesync",
});
}
diff --git a/src/wallet/external_signer.cpp b/src/external_signer.cpp
index 3396111760..f16d21fa60 100644
--- a/src/wallet/external_signer.cpp
+++ b/src/external_signer.cpp
@@ -7,45 +7,46 @@
#include <psbt.h>
#include <util/strencodings.h>
#include <util/system.h>
-#include <wallet/external_signer.h>
+#include <external_signer.h>
-ExternalSigner::ExternalSigner(const std::string& command, const std::string& fingerprint, std::string chain, std::string name): m_command(command), m_fingerprint(fingerprint), m_chain(chain), m_name(name) {}
+#include <stdexcept>
+#include <string>
+#include <vector>
+
+#ifdef ENABLE_EXTERNAL_SIGNER
+
+ExternalSigner::ExternalSigner(const std::string& command, const std::string& fingerprint, const std::string chain, const std::string name): m_command(command), m_fingerprint(fingerprint), m_chain(chain), m_name(name) {}
const std::string ExternalSigner::NetworkArg() const
{
return " --chain " + m_chain;
}
-#ifdef ENABLE_EXTERNAL_SIGNER
-
-bool ExternalSigner::Enumerate(const std::string& command, std::vector<ExternalSigner>& signers, std::string chain, bool ignore_errors)
+bool ExternalSigner::Enumerate(const std::string& command, std::vector<ExternalSigner>& signers, const std::string chain)
{
// Call <command> enumerate
const UniValue result = RunCommandParseJSON(command + " enumerate");
if (!result.isArray()) {
- if (ignore_errors) return false;
- throw ExternalSignerException(strprintf("'%s' received invalid response, expected array of signers", command));
+ throw std::runtime_error(strprintf("'%s' received invalid response, expected array of signers", command));
}
for (UniValue signer : result.getValues()) {
// Check for error
const UniValue& error = find_value(signer, "error");
if (!error.isNull()) {
- if (ignore_errors) return false;
if (!error.isStr()) {
- throw ExternalSignerException(strprintf("'%s' error", command));
+ throw std::runtime_error(strprintf("'%s' error", command));
}
- throw ExternalSignerException(strprintf("'%s' error: %s", command, error.getValStr()));
+ throw std::runtime_error(strprintf("'%s' error: %s", command, error.getValStr()));
}
// Check if fingerprint is present
const UniValue& fingerprint = find_value(signer, "fingerprint");
if (fingerprint.isNull()) {
- if (ignore_errors) return false;
- throw ExternalSignerException(strprintf("'%s' received invalid response, missing signer fingerprint", command));
+ throw std::runtime_error(strprintf("'%s' received invalid response, missing signer fingerprint", command));
}
- std::string fingerprintStr = fingerprint.get_str();
+ const std::string fingerprintStr = fingerprint.get_str();
// Skip duplicate signer
bool duplicate = false;
- for (ExternalSigner signer : signers) {
+ for (const ExternalSigner& signer : signers) {
if (signer.m_fingerprint.compare(fingerprintStr) == 0) duplicate = true;
}
if (duplicate) break;
@@ -64,7 +65,7 @@ UniValue ExternalSigner::DisplayAddress(const std::string& descriptor) const
return RunCommandParseJSON(m_command + " --fingerprint \"" + m_fingerprint + "\"" + NetworkArg() + " displayaddress --desc \"" + descriptor + "\"");
}
-UniValue ExternalSigner::GetDescriptors(int account)
+UniValue ExternalSigner::GetDescriptors(const int account)
{
return RunCommandParseJSON(m_command + " --fingerprint \"" + m_fingerprint + "\"" + NetworkArg() + " getdescriptors --account " + strprintf("%d", account));
}
@@ -79,7 +80,7 @@ bool ExternalSigner::SignTransaction(PartiallySignedTransaction& psbtx, std::str
bool match = false;
for (unsigned int i = 0; i < psbtx.inputs.size(); ++i) {
const PSBTInput& input = psbtx.inputs[i];
- for (auto entry : input.hd_keypaths) {
+ for (const auto& entry : input.hd_keypaths) {
if (m_fingerprint == strprintf("%08x", ReadBE32(entry.second.fingerprint))) match = true;
}
}
@@ -89,8 +90,8 @@ bool ExternalSigner::SignTransaction(PartiallySignedTransaction& psbtx, std::str
return false;
}
- std::string command = m_command + " --stdin --fingerprint \"" + m_fingerprint + "\"" + NetworkArg();
- std::string stdinStr = "signtx \"" + EncodeBase64(ssTx.str()) + "\"";
+ const std::string command = m_command + " --stdin --fingerprint \"" + m_fingerprint + "\"" + NetworkArg();
+ const std::string stdinStr = "signtx \"" + EncodeBase64(ssTx.str()) + "\"";
const UniValue signer_result = RunCommandParseJSON(command, stdinStr);
@@ -116,4 +117,4 @@ bool ExternalSigner::SignTransaction(PartiallySignedTransaction& psbtx, std::str
return true;
}
-#endif
+#endif // ENABLE_EXTERNAL_SIGNER
diff --git a/src/wallet/external_signer.h b/src/external_signer.h
index 4b9711107b..b3b202091a 100644
--- a/src/wallet/external_signer.h
+++ b/src/external_signer.h
@@ -2,20 +2,18 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#ifndef BITCOIN_WALLET_EXTERNAL_SIGNER_H
-#define BITCOIN_WALLET_EXTERNAL_SIGNER_H
+#ifndef BITCOIN_EXTERNAL_SIGNER_H
+#define BITCOIN_EXTERNAL_SIGNER_H
-#include <stdexcept>
-#include <string>
#include <univalue.h>
#include <util/system.h>
-struct PartiallySignedTransaction;
+#include <string>
+#include <vector>
-class ExternalSignerException : public std::runtime_error {
-public:
- using std::runtime_error::runtime_error;
-};
+#ifdef ENABLE_EXTERNAL_SIGNER
+
+struct PartiallySignedTransaction;
//! Enables interaction with an external signing device or service, such as
//! a hardware wallet. See doc/external-signer.md
@@ -30,7 +28,7 @@ public:
//! @param[in] fingerprint master key fingerprint of the signer
//! @param[in] chain "main", "test", "regtest" or "signet"
//! @param[in] name device name
- ExternalSigner(const std::string& command, const std::string& fingerprint, std::string chain, std::string name);
+ ExternalSigner(const std::string& command, const std::string& fingerprint, const std::string chain, const std::string name);
//! Master key fingerprint of the signer
std::string m_fingerprint;
@@ -43,13 +41,12 @@ public:
const std::string NetworkArg() const;
-#ifdef ENABLE_EXTERNAL_SIGNER
//! Obtain a list of signers. Calls `<command> enumerate`.
//! @param[in] command the command which handles interaction with the external signer
//! @param[in,out] signers vector to which new signers (with a unique master key fingerprint) are added
//! @param chain "main", "test", "regtest" or "signet"
- //! @param[out] success Boolean
- static bool Enumerate(const std::string& command, std::vector<ExternalSigner>& signers, std::string chain, bool ignore_errors = false);
+ //! @returns success
+ static bool Enumerate(const std::string& command, std::vector<ExternalSigner>& signers, const std::string chain);
//! Display address on the device. Calls `<command> displayaddress --desc <descriptor>`.
//! @param[in] descriptor Descriptor specifying which address to display.
@@ -59,15 +56,15 @@ public:
//! Get receive and change Descriptor(s) from device for a given account.
//! Calls `<command> getdescriptors --account <account>`
//! @param[in] account which BIP32 account to use (e.g. `m/44'/0'/account'`)
- //! @param[out] UniValue see doc/external-signer.md
- UniValue GetDescriptors(int account);
+ //! @returns see doc/external-signer.md
+ UniValue GetDescriptors(const int account);
//! Sign PartiallySignedTransaction on the device.
//! Calls `<command> signtransaction` and passes the PSBT via stdin.
//! @param[in,out] psbt PartiallySignedTransaction to be signed
bool SignTransaction(PartiallySignedTransaction& psbt, std::string& error);
-
-#endif
};
-#endif // BITCOIN_WALLET_EXTERNAL_SIGNER_H
+#endif // ENABLE_EXTERNAL_SIGNER
+
+#endif // BITCOIN_EXTERNAL_SIGNER_H
diff --git a/src/httprpc.cpp b/src/httprpc.cpp
index 16ab38e0b2..e11e4acb5c 100644
--- a/src/httprpc.cpp
+++ b/src/httprpc.cpp
@@ -159,7 +159,8 @@ static bool HTTPReq_JSONRPC(const std::any& context, HTTPRequest* req)
return false;
}
- JSONRPCRequest jreq(context);
+ JSONRPCRequest jreq;
+ jreq.context = context;
jreq.peerAddr = req->GetPeer().ToString();
if (!RPCAuthorized(authHeader.second, jreq.authUser)) {
LogPrintf("ThreadRPCServer incorrect password attempt from %s\n", jreq.peerAddr);
@@ -294,7 +295,7 @@ bool StartHTTPRPC(const std::any& context)
if (!InitRPCAuthentication())
return false;
- auto handle_rpc = [&context](HTTPRequest* req, const std::string&) { return HTTPReq_JSONRPC(context, req); };
+ auto handle_rpc = [context](HTTPRequest* req, const std::string&) { return HTTPReq_JSONRPC(context, req); };
RegisterHTTPHandler("/", true, handle_rpc);
if (g_wallet_init_interface.HasWalletSupport()) {
RegisterHTTPHandler("/wallet/", false, handle_rpc);
diff --git a/src/i2p.cpp b/src/i2p.cpp
index a44f09f043..2ae164633b 100644
--- a/src/i2p.cpp
+++ b/src/i2p.cpp
@@ -147,7 +147,9 @@ bool Session::Accept(Connection& conn)
try {
while (!*m_interrupt) {
Sock::Event occurred;
- conn.sock->Wait(MAX_WAIT_FOR_IO, Sock::RECV, &occurred);
+ if (!conn.sock->Wait(MAX_WAIT_FOR_IO, Sock::RECV, &occurred)) {
+ throw std::runtime_error("wait on socket failed");
+ }
if ((occurred & Sock::RECV) == 0) {
// Timeout, no incoming connections within MAX_WAIT_FOR_IO.
diff --git a/src/index/base.cpp b/src/index/base.cpp
index 25644c3b41..9e637c9c6f 100644
--- a/src/index/base.cpp
+++ b/src/index/base.cpp
@@ -4,12 +4,13 @@
#include <chainparams.h>
#include <index/base.h>
+#include <node/blockstorage.h>
#include <node/ui_interface.h>
#include <shutdown.h>
#include <tinyformat.h>
#include <util/system.h>
#include <util/translation.h>
-#include <validation.h>
+#include <validation.h> // For g_chainman
#include <warnings.h>
constexpr char DB_BEST_BLOCK = 'B';
diff --git a/src/index/base.h b/src/index/base.h
index 8559e3cb64..ac3c429a5a 100644
--- a/src/index/base.h
+++ b/src/index/base.h
@@ -109,7 +109,7 @@ public:
/// sync once and only needs to process blocks in the ValidationInterface
/// queue. If the index is catching up from far behind, this method does
/// not block and immediately returns false.
- bool BlockUntilSyncedToCurrentChain() const;
+ bool BlockUntilSyncedToCurrentChain() const LOCKS_EXCLUDED(::cs_main);
void Interrupt();
diff --git a/src/index/blockfilterindex.cpp b/src/index/blockfilterindex.cpp
index 32271fb7ab..154d7a7027 100644
--- a/src/index/blockfilterindex.cpp
+++ b/src/index/blockfilterindex.cpp
@@ -6,8 +6,8 @@
#include <dbwrapper.h>
#include <index/blockfilterindex.h>
+#include <node/blockstorage.h>
#include <util/system.h>
-#include <validation.h>
/* The index database stores three items for each block: the disk location of the encoded filter,
* its dSHA256 hash, and the header. Those belonging to blocks on the active chain are indexed by
diff --git a/src/init.cpp b/src/init.cpp
index 17b216573f..07e882c9df 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -16,7 +16,6 @@
#include <chain.h>
#include <chainparams.h>
#include <compat/sanity.h>
-#include <consensus/validation.h>
#include <fs.h>
#include <hash.h>
#include <httprpc.h>
@@ -32,6 +31,7 @@
#include <net_permissions.h>
#include <net_processing.h>
#include <netbase.h>
+#include <node/blockstorage.h>
#include <node/context.h>
#include <node/ui_interface.h>
#include <policy/feerate.h>
@@ -61,7 +61,6 @@
#include <util/threadnames.h>
#include <util/translation.h>
#include <validation.h>
-
#include <validationinterface.h>
#include <walletinitinterface.h>
@@ -90,7 +89,6 @@
static const bool DEFAULT_PROXYRANDOMIZE = true;
static const bool DEFAULT_REST_ENABLE = false;
-static const bool DEFAULT_STOPAFTERBLOCKIMPORT = false;
#ifdef WIN32
// Win32 LevelDB doesn't use filedescriptors, and the ones used for
@@ -155,8 +153,6 @@ static fs::path GetPidFile(const ArgsManager& args)
static std::unique_ptr<ECCVerifyHandle> globalVerifyHandle;
-static std::thread g_load_block;
-
void Interrupt(NodeContext& node)
{
InterruptHTTPServer();
@@ -220,7 +216,7 @@ void Shutdown(NodeContext& node)
// After everything has been shut down, but before things get flushed, stop the
// CScheduler/checkqueue, scheduler and load block thread.
if (node.scheduler) node.scheduler->stop();
- if (g_load_block.joinable()) g_load_block.join();
+ if (node.chainman && node.chainman->m_load_block.joinable()) node.chainman->m_load_block.join();
StopScriptCheckWorkerThreads();
// After the threads that potentially access these pointers have been stopped,
@@ -627,20 +623,6 @@ static void BlockNotifyGenesisWait(const CBlockIndex* pBlockIndex)
}
}
-struct CImportingNow
-{
- CImportingNow() {
- assert(fImporting == false);
- fImporting = true;
- }
-
- ~CImportingNow() {
- assert(fImporting == true);
- fImporting = false;
- }
-};
-
-
// If we're using -prune with -reindex, then delete block files that will be ignored by the
// reindex. Since reindexing works by starting at block file 0 and looping until a blockfile
// is missing, do the same here to delete any later block files after a gap. Also delete all
@@ -693,77 +675,6 @@ static void StartupNotify(const ArgsManager& args)
}
#endif
-static void ThreadImport(ChainstateManager& chainman, std::vector<fs::path> vImportFiles, const ArgsManager& args)
-{
- const CChainParams& chainparams = Params();
- ScheduleBatchPriority();
-
- {
- CImportingNow imp;
-
- // -reindex
- if (fReindex) {
- int nFile = 0;
- while (true) {
- FlatFilePos pos(nFile, 0);
- if (!fs::exists(GetBlockPosFilename(pos)))
- break; // No block files left to reindex
- FILE *file = OpenBlockFile(pos, true);
- if (!file)
- break; // This error is logged in OpenBlockFile
- LogPrintf("Reindexing block file blk%05u.dat...\n", (unsigned int)nFile);
- ::ChainstateActive().LoadExternalBlockFile(chainparams, file, &pos);
- if (ShutdownRequested()) {
- LogPrintf("Shutdown requested. Exit %s\n", __func__);
- return;
- }
- nFile++;
- }
- pblocktree->WriteReindexing(false);
- fReindex = false;
- LogPrintf("Reindexing finished\n");
- // To avoid ending up in a situation without genesis block, re-try initializing (no-op if reindexing worked):
- ::ChainstateActive().LoadGenesisBlock(chainparams);
- }
-
- // -loadblock=
- for (const fs::path& path : vImportFiles) {
- FILE *file = fsbridge::fopen(path, "rb");
- if (file) {
- LogPrintf("Importing blocks file %s...\n", path.string());
- ::ChainstateActive().LoadExternalBlockFile(chainparams, file);
- if (ShutdownRequested()) {
- LogPrintf("Shutdown requested. Exit %s\n", __func__);
- return;
- }
- } else {
- LogPrintf("Warning: Could not open blocks file %s\n", path.string());
- }
- }
-
- // scan for better chains in the block chain database, that are not yet connected in the active best chain
-
- // We can't hold cs_main during ActivateBestChain even though we're accessing
- // the chainman unique_ptrs since ABC requires us not to be holding cs_main, so retrieve
- // the relevant pointers before the ABC call.
- for (CChainState* chainstate : WITH_LOCK(::cs_main, return chainman.GetAll())) {
- BlockValidationState state;
- if (!chainstate->ActivateBestChain(state, chainparams, nullptr)) {
- LogPrintf("Failed to connect best block (%s)\n", state.ToString());
- StartShutdown();
- return;
- }
- }
-
- if (args.GetBoolArg("-stopafterblockimport", DEFAULT_STOPAFTERBLOCKIMPORT)) {
- LogPrintf("Stopping after block import\n");
- StartShutdown();
- return;
- }
- } // End scope of CImportingNow
- chainman.ActiveChainstate().LoadMempool(args);
-}
-
/** Sanity checks
* Ensure that Bitcoin is running in a usable environment with all
* necessary library support.
@@ -788,7 +699,7 @@ static bool InitSanityCheck()
return true;
}
-static bool AppInitServers(const std::any& context, NodeContext& node)
+static bool AppInitServers(NodeContext& node)
{
const ArgsManager& args = *Assert(node.args);
RPCServer::OnStarted(&OnRPCStarted);
@@ -797,9 +708,9 @@ static bool AppInitServers(const std::any& context, NodeContext& node)
return false;
StartRPC();
node.rpc_interruption_point = RpcInterruptionPoint;
- if (!StartHTTPRPC(context))
+ if (!StartHTTPRPC(&node))
return false;
- if (args.GetBoolArg("-rest", DEFAULT_REST_ENABLE)) StartREST(context);
+ if (args.GetBoolArg("-rest", DEFAULT_REST_ENABLE)) StartREST(&node);
StartHTTPServer();
return true;
}
@@ -1277,7 +1188,7 @@ bool AppInitInterfaces(NodeContext& node)
return true;
}
-bool AppInitMain(const std::any& context, NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
+bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
{
const ArgsManager& args = *Assert(node.args);
const CChainParams& chainparams = Params();
@@ -1382,7 +1293,7 @@ bool AppInitMain(const std::any& context, NodeContext& node, interfaces::BlockAn
*/
if (args.GetBoolArg("-server", false)) {
uiInterface.InitMessage_connect(SetRPCWarmupStatus);
- if (!AppInitServers(context, node))
+ if (!AppInitServers(node))
return InitError(_("Unable to start HTTP server. See debug log for details."));
}
@@ -1880,7 +1791,7 @@ bool AppInitMain(const std::any& context, NodeContext& node, interfaces::BlockAn
vImportFiles.push_back(strFile);
}
- g_load_block = std::thread(&TraceThread<std::function<void()>>, "loadblk", [=, &chainman, &args] {
+ chainman.m_load_block = std::thread(&TraceThread<std::function<void()>>, "loadblk", [=, &chainman, &args] {
ThreadImport(chainman, vImportFiles, args);
});
diff --git a/src/init.h b/src/init.h
index 5d01d4c1ac..328eda9c7e 100644
--- a/src/init.h
+++ b/src/init.h
@@ -64,7 +64,7 @@ bool AppInitInterfaces(NodeContext& node);
* @note This should only be done after daemonization. Call Shutdown() if this function fails.
* @pre Parameters should be parsed and config file should be read, AppInitLockDataDirectory should have been called.
*/
-bool AppInitMain(const std::any& context, NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info = nullptr);
+bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info = nullptr);
/**
* Register all arguments with the ArgsManager
diff --git a/src/net.cpp b/src/net.cpp
index c43c53795e..ae38acdc3c 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -145,8 +145,8 @@ bool GetLocal(CService& addr, const CNetAddr *paddrPeer)
return nBestScore >= 0;
}
-//! Convert the pnSeed6 array into usable address objects.
-static std::vector<CAddress> convertSeed6(const std::vector<SeedSpec6> &vSeedsIn)
+//! Convert the serialized seeds into usable address objects.
+static std::vector<CAddress> ConvertSeeds(const std::vector<uint8_t> &vSeedsIn)
{
// It'll only connect to one or two seed nodes because once it connects,
// it'll get a pile of addresses with newer timestamps.
@@ -154,13 +154,14 @@ static std::vector<CAddress> convertSeed6(const std::vector<SeedSpec6> &vSeedsIn
// weeks ago.
const int64_t nOneWeek = 7*24*60*60;
std::vector<CAddress> vSeedsOut;
- vSeedsOut.reserve(vSeedsIn.size());
FastRandomContext rng;
- for (const auto& seed_in : vSeedsIn) {
- struct in6_addr ip;
- memcpy(&ip, seed_in.addr, sizeof(ip));
- CAddress addr(CService(ip, seed_in.port), GetDesirableServiceFlags(NODE_NONE));
+ CDataStream s(vSeedsIn, SER_NETWORK, PROTOCOL_VERSION | ADDRV2_FORMAT);
+ while (!s.eof()) {
+ CService endpoint;
+ s >> endpoint;
+ CAddress addr{endpoint, GetDesirableServiceFlags(NODE_NONE)};
addr.nTime = GetTime() - rng.randrange(nOneWeek) - nOneWeek;
+ LogPrint(BCLog::NET, "Added hardcoded seed: %s\n", addr.ToString());
vSeedsOut.push_back(addr);
}
return vSeedsOut;
@@ -1847,7 +1848,7 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
if (add_fixed_seeds_now) {
CNetAddr local;
local.SetInternal("fixedseeds");
- addrman.Add(convertSeed6(Params().FixedSeeds()), local);
+ addrman.Add(ConvertSeeds(Params().FixedSeeds()), local);
add_fixed_seeds = false;
}
}
diff --git a/src/net_processing.cpp b/src/net_processing.cpp
index 4108de2c8a..a5bcf9eaa8 100644
--- a/src/net_processing.cpp
+++ b/src/net_processing.cpp
@@ -16,6 +16,7 @@
#include <merkleblock.h>
#include <netbase.h>
#include <netmessagemaker.h>
+#include <node/blockstorage.h>
#include <policy/fees.h>
#include <policy/policy.h>
#include <primitives/block.h>
@@ -448,7 +449,7 @@ private:
/** Determine whether or not a peer can request a transaction, and return it (or nullptr if not found or not allowed). */
CTransactionRef FindTxForGetData(const CNode& peer, const GenTxid& gtxid, const std::chrono::seconds mempool_req, const std::chrono::seconds now) LOCKS_EXCLUDED(cs_main);
- void ProcessGetData(CNode& pfrom, Peer& peer, const std::atomic<bool>& interruptMsgProc) EXCLUSIVE_LOCKS_REQUIRED(!cs_main, peer.m_getdata_requests_mutex);
+ void ProcessGetData(CNode& pfrom, Peer& peer, const std::atomic<bool>& interruptMsgProc) EXCLUSIVE_LOCKS_REQUIRED(peer.m_getdata_requests_mutex) LOCKS_EXCLUDED(::cs_main);
/** Relay map (txid or wtxid -> CTransactionRef) */
typedef std::map<uint256, CTransactionRef> MapRelay;
@@ -2062,7 +2063,7 @@ void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, const Peer& peer,
/**
* Reconsider orphan transactions after a parent has been accepted to the mempool.
*
- * @param[in/out] orphan_work_set The set of orphan transactions to reconsider. Generally only one
+ * @param[in,out] orphan_work_set The set of orphan transactions to reconsider. Generally only one
* orphan will be reconsidered on each call of this function. This set
* may be added to if accepting an orphan causes its children to be
* reconsidered.
diff --git a/src/netbase.h b/src/netbase.h
index 1f35c29dcb..6a87c338a0 100644
--- a/src/netbase.h
+++ b/src/netbase.h
@@ -172,7 +172,6 @@ CService LookupNumeric(const std::string& name, uint16_t portDefault = 0, DNSLoo
* @param strSubnet A string representation of a subnet of the form `network
* address [ "/", ( CIDR-style suffix | netmask ) ]`(e.g.
* `2001:db8::/32`, `192.0.2.0/255.255.255.0`, or `8.8.8.8`).
- * @param ret The resulting internal representation of a subnet.
*
* @returns Whether the operation succeeded or not.
*/
@@ -235,7 +234,7 @@ void InterruptSocks5(bool interrupt);
* @param port The destination port.
* @param auth The credentials with which to authenticate with the specified
* SOCKS5 proxy.
- * @param sock The SOCKS5 proxy socket.
+ * @param socket The SOCKS5 proxy socket.
*
* @returns Whether or not the operation succeeded.
*
diff --git a/src/node/README.md b/src/node/README.md
index e99a717534..ab5979594d 100644
--- a/src/node/README.md
+++ b/src/node/README.md
@@ -15,8 +15,7 @@ As a rule of thumb, code in one of the [`src/node/`](./),
calling code in the other directories directly, and only invoke it indirectly
through the more limited [`src/interfaces/`](../interfaces/) classes.
-The [`src/node/`](./) directory is a new directory introduced in
-[#14978](https://github.com/bitcoin/bitcoin/pull/14978) and at the moment is
+This directory is at the moment
sparsely populated. Eventually more substantial files like
[`src/validation.cpp`](../validation.cpp) and
[`src/txmempool.cpp`](../txmempool.cpp) might be moved there.
diff --git a/src/node/blockstorage.cpp b/src/node/blockstorage.cpp
new file mode 100644
index 0000000000..daed6605e8
--- /dev/null
+++ b/src/node/blockstorage.cpp
@@ -0,0 +1,244 @@
+// Copyright (c) 2011-2021 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 <node/blockstorage.h>
+
+#include <chain.h>
+#include <chainparams.h>
+#include <flatfile.h>
+#include <fs.h>
+#include <pow.h>
+#include <shutdown.h>
+#include <signet.h>
+#include <streams.h>
+#include <util/system.h>
+#include <validation.h>
+
+// From validation. TODO move here
+bool FindBlockPos(FlatFilePos& pos, unsigned int nAddSize, unsigned int nHeight, CChain& active_chain, uint64_t nTime, bool fKnown = false);
+
+static bool WriteBlockToDisk(const CBlock& block, FlatFilePos& pos, const CMessageHeader::MessageStartChars& messageStart)
+{
+ // Open history file to append
+ CAutoFile fileout(OpenBlockFile(pos), SER_DISK, CLIENT_VERSION);
+ if (fileout.IsNull()) {
+ return error("WriteBlockToDisk: OpenBlockFile failed");
+ }
+
+ // Write index header
+ unsigned int nSize = GetSerializeSize(block, fileout.GetVersion());
+ fileout << messageStart << nSize;
+
+ // Write block
+ long fileOutPos = ftell(fileout.Get());
+ if (fileOutPos < 0) {
+ return error("WriteBlockToDisk: ftell failed");
+ }
+ pos.nPos = (unsigned int)fileOutPos;
+ fileout << block;
+
+ return true;
+}
+
+bool ReadBlockFromDisk(CBlock& block, const FlatFilePos& pos, const Consensus::Params& consensusParams)
+{
+ block.SetNull();
+
+ // Open history file to read
+ CAutoFile filein(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION);
+ if (filein.IsNull()) {
+ return error("ReadBlockFromDisk: OpenBlockFile failed for %s", pos.ToString());
+ }
+
+ // Read block
+ try {
+ filein >> block;
+ } catch (const std::exception& e) {
+ return error("%s: Deserialize or I/O error - %s at %s", __func__, e.what(), pos.ToString());
+ }
+
+ // Check the header
+ if (!CheckProofOfWork(block.GetHash(), block.nBits, consensusParams)) {
+ return error("ReadBlockFromDisk: Errors in block header at %s", pos.ToString());
+ }
+
+ // Signet only: check block solution
+ if (consensusParams.signet_blocks && !CheckSignetBlockSolution(block, consensusParams)) {
+ return error("ReadBlockFromDisk: Errors in block solution at %s", pos.ToString());
+ }
+
+ return true;
+}
+
+bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex, const Consensus::Params& consensusParams)
+{
+ FlatFilePos blockPos;
+ {
+ LOCK(cs_main);
+ blockPos = pindex->GetBlockPos();
+ }
+
+ if (!ReadBlockFromDisk(block, blockPos, consensusParams)) {
+ return false;
+ }
+ if (block.GetHash() != pindex->GetBlockHash()) {
+ return error("ReadBlockFromDisk(CBlock&, CBlockIndex*): GetHash() doesn't match index for %s at %s",
+ pindex->ToString(), pindex->GetBlockPos().ToString());
+ }
+ return true;
+}
+
+bool ReadRawBlockFromDisk(std::vector<uint8_t>& block, const FlatFilePos& pos, const CMessageHeader::MessageStartChars& message_start)
+{
+ FlatFilePos hpos = pos;
+ hpos.nPos -= 8; // Seek back 8 bytes for meta header
+ CAutoFile filein(OpenBlockFile(hpos, true), SER_DISK, CLIENT_VERSION);
+ if (filein.IsNull()) {
+ return error("%s: OpenBlockFile failed for %s", __func__, pos.ToString());
+ }
+
+ try {
+ CMessageHeader::MessageStartChars blk_start;
+ unsigned int blk_size;
+
+ filein >> blk_start >> blk_size;
+
+ if (memcmp(blk_start, message_start, CMessageHeader::MESSAGE_START_SIZE)) {
+ return error("%s: Block magic mismatch for %s: %s versus expected %s", __func__, pos.ToString(),
+ HexStr(blk_start),
+ HexStr(message_start));
+ }
+
+ if (blk_size > MAX_SIZE) {
+ return error("%s: Block data is larger than maximum deserialization size for %s: %s versus %s", __func__, pos.ToString(),
+ blk_size, MAX_SIZE);
+ }
+
+ block.resize(blk_size); // Zeroing of memory is intentional here
+ filein.read((char*)block.data(), blk_size);
+ } catch (const std::exception& e) {
+ return error("%s: Read from block file failed: %s for %s", __func__, e.what(), pos.ToString());
+ }
+
+ return true;
+}
+
+bool ReadRawBlockFromDisk(std::vector<uint8_t>& block, const CBlockIndex* pindex, const CMessageHeader::MessageStartChars& message_start)
+{
+ FlatFilePos block_pos;
+ {
+ LOCK(cs_main);
+ block_pos = pindex->GetBlockPos();
+ }
+
+ return ReadRawBlockFromDisk(block, block_pos, message_start);
+}
+
+/** Store block on disk. If dbp is non-nullptr, the file is known to already reside on disk */
+FlatFilePos SaveBlockToDisk(const CBlock& block, int nHeight, CChain& active_chain, const CChainParams& chainparams, const FlatFilePos* dbp)
+{
+ unsigned int nBlockSize = ::GetSerializeSize(block, CLIENT_VERSION);
+ FlatFilePos blockPos;
+ if (dbp != nullptr) {
+ blockPos = *dbp;
+ }
+ if (!FindBlockPos(blockPos, nBlockSize + 8, nHeight, active_chain, block.GetBlockTime(), dbp != nullptr)) {
+ error("%s: FindBlockPos failed", __func__);
+ return FlatFilePos();
+ }
+ if (dbp == nullptr) {
+ if (!WriteBlockToDisk(block, blockPos, chainparams.MessageStart())) {
+ AbortNode("Failed to write block");
+ return FlatFilePos();
+ }
+ }
+ return blockPos;
+}
+
+struct CImportingNow {
+ CImportingNow()
+ {
+ assert(fImporting == false);
+ fImporting = true;
+ }
+
+ ~CImportingNow()
+ {
+ assert(fImporting == true);
+ fImporting = false;
+ }
+};
+
+void ThreadImport(ChainstateManager& chainman, std::vector<fs::path> vImportFiles, const ArgsManager& args)
+{
+ const CChainParams& chainparams = Params();
+ ScheduleBatchPriority();
+
+ {
+ CImportingNow imp;
+
+ // -reindex
+ if (fReindex) {
+ int nFile = 0;
+ while (true) {
+ FlatFilePos pos(nFile, 0);
+ if (!fs::exists(GetBlockPosFilename(pos))) {
+ break; // No block files left to reindex
+ }
+ FILE* file = OpenBlockFile(pos, true);
+ if (!file) {
+ break; // This error is logged in OpenBlockFile
+ }
+ LogPrintf("Reindexing block file blk%05u.dat...\n", (unsigned int)nFile);
+ chainman.ActiveChainstate().LoadExternalBlockFile(chainparams, file, &pos);
+ if (ShutdownRequested()) {
+ LogPrintf("Shutdown requested. Exit %s\n", __func__);
+ return;
+ }
+ nFile++;
+ }
+ pblocktree->WriteReindexing(false);
+ fReindex = false;
+ LogPrintf("Reindexing finished\n");
+ // To avoid ending up in a situation without genesis block, re-try initializing (no-op if reindexing worked):
+ chainman.ActiveChainstate().LoadGenesisBlock(chainparams);
+ }
+
+ // -loadblock=
+ for (const fs::path& path : vImportFiles) {
+ FILE* file = fsbridge::fopen(path, "rb");
+ if (file) {
+ LogPrintf("Importing blocks file %s...\n", path.string());
+ chainman.ActiveChainstate().LoadExternalBlockFile(chainparams, file);
+ if (ShutdownRequested()) {
+ LogPrintf("Shutdown requested. Exit %s\n", __func__);
+ return;
+ }
+ } else {
+ LogPrintf("Warning: Could not open blocks file %s\n", path.string());
+ }
+ }
+
+ // scan for better chains in the block chain database, that are not yet connected in the active best chain
+
+ // We can't hold cs_main during ActivateBestChain even though we're accessing
+ // the chainman unique_ptrs since ABC requires us not to be holding cs_main, so retrieve
+ // the relevant pointers before the ABC call.
+ for (CChainState* chainstate : WITH_LOCK(::cs_main, return chainman.GetAll())) {
+ BlockValidationState state;
+ if (!chainstate->ActivateBestChain(state, chainparams, nullptr)) {
+ LogPrintf("Failed to connect best block (%s)\n", state.ToString());
+ StartShutdown();
+ return;
+ }
+ }
+
+ if (args.GetBoolArg("-stopafterblockimport", DEFAULT_STOPAFTERBLOCKIMPORT)) {
+ LogPrintf("Stopping after block import\n");
+ StartShutdown();
+ return;
+ }
+ } // End scope of CImportingNow
+ chainman.ActiveChainstate().LoadMempool(args);
+}
diff --git a/src/node/blockstorage.h b/src/node/blockstorage.h
new file mode 100644
index 0000000000..3b546f0719
--- /dev/null
+++ b/src/node/blockstorage.h
@@ -0,0 +1,40 @@
+// Copyright (c) 2011-2021 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_NODE_BLOCKSTORAGE_H
+#define BITCOIN_NODE_BLOCKSTORAGE_H
+
+#include <cstdint>
+#include <vector>
+
+#include <fs.h>
+#include <protocol.h> // For CMessageHeader::MessageStartChars
+
+class ArgsManager;
+class CBlock;
+class CBlockIndex;
+class CBlockUndo;
+class CChain;
+class CChainParams;
+class ChainstateManager;
+struct FlatFilePos;
+namespace Consensus {
+struct Params;
+}
+
+static constexpr bool DEFAULT_STOPAFTERBLOCKIMPORT{false};
+
+/** Functions for disk access for blocks */
+bool ReadBlockFromDisk(CBlock& block, const FlatFilePos& pos, const Consensus::Params& consensusParams);
+bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex, const Consensus::Params& consensusParams);
+bool ReadRawBlockFromDisk(std::vector<uint8_t>& block, const FlatFilePos& pos, const CMessageHeader::MessageStartChars& message_start);
+bool ReadRawBlockFromDisk(std::vector<uint8_t>& block, const CBlockIndex* pindex, const CMessageHeader::MessageStartChars& message_start);
+
+bool UndoReadFromDisk(CBlockUndo& blockundo, const CBlockIndex* pindex);
+
+FlatFilePos SaveBlockToDisk(const CBlock& block, int nHeight, CChain& active_chain, const CChainParams& chainparams, const FlatFilePos* dbp);
+
+void ThreadImport(ChainstateManager& chainman, std::vector<fs::path> vImportFiles, const ArgsManager& args);
+
+#endif // BITCOIN_NODE_BLOCKSTORAGE_H
diff --git a/src/node/coinstats.cpp b/src/node/coinstats.cpp
index 268580c6e6..f8f0fff43f 100644
--- a/src/node/coinstats.cpp
+++ b/src/node/coinstats.cpp
@@ -94,7 +94,8 @@ static bool GetUTXOStats(CCoinsView* view, BlockManager& blockman, CCoinsStats&
{
LOCK(cs_main);
assert(std::addressof(g_chainman.m_blockman) == std::addressof(blockman));
- stats.nHeight = blockman.LookupBlockIndex(stats.hashBlock)->nHeight;
+ const CBlockIndex* block = blockman.LookupBlockIndex(stats.hashBlock);
+ stats.nHeight = Assert(block)->nHeight;
}
PrepareHash(hash_obj, stats);
diff --git a/src/node/interfaces.cpp b/src/node/interfaces.cpp
index 7ad02f81dc..8befbf5e30 100644
--- a/src/node/interfaces.cpp
+++ b/src/node/interfaces.cpp
@@ -4,7 +4,6 @@
#include <addrdb.h>
#include <banman.h>
-#include <boost/signals2/signal.hpp>
#include <chain.h>
#include <chainparams.h>
#include <init.h>
@@ -17,6 +16,7 @@
#include <net_processing.h>
#include <netaddress.h>
#include <netbase.h>
+#include <node/blockstorage.h>
#include <node/coin.h>
#include <node/context.h>
#include <node/transaction.h>
@@ -53,6 +53,8 @@
#include <optional>
#include <utility>
+#include <boost/signals2/signal.hpp>
+
using interfaces::BlockTip;
using interfaces::Chain;
using interfaces::FoundBlock;
@@ -80,7 +82,7 @@ public:
}
bool appInitMain(interfaces::BlockAndHeaderTipInfo* tip_info) override
{
- return AppInitMain(m_context_ref, *m_context, tip_info);
+ return AppInitMain(*m_context, tip_info);
}
void appShutdown() override
{
@@ -244,7 +246,8 @@ public:
CFeeRate getDustRelayFee() override { return ::dustRelayFee; }
UniValue executeRpc(const std::string& command, const UniValue& params, const std::string& uri) override
{
- JSONRPCRequest req(m_context_ref);
+ JSONRPCRequest req;
+ req.context = m_context;
req.params = params;
req.strMethod = command;
req.URI = uri;
@@ -314,14 +317,8 @@ public:
void setContext(NodeContext* context) override
{
m_context = context;
- if (context) {
- m_context_ref = context;
- } else {
- m_context_ref.reset();
- }
}
NodeContext* m_context{nullptr};
- std::any m_context_ref;
};
bool FillBlock(const CBlockIndex* index, const FoundBlock& block, UniqueLock<RecursiveMutex>& lock, const CChain& active)
diff --git a/src/policy/feerate.h b/src/policy/feerate.h
index 86ae507957..0e4f9914b8 100644
--- a/src/policy/feerate.h
+++ b/src/policy/feerate.h
@@ -47,7 +47,6 @@ public:
*
* @param[in] nFeePaid CAmount fee rate to construct with
* @param[in] nBytes size_t bytes (units) to construct with
- * @returns fee rate
*/
CFeeRate(const CAmount& nFeePaid, size_t nBytes);
/**
diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp
index fc6d0febc2..de71b7dea7 100644
--- a/src/qt/bitcoin.cpp
+++ b/src/qt/bitcoin.cpp
@@ -45,10 +45,12 @@
#include <QApplication>
#include <QDebug>
#include <QFontDatabase>
+#include <QLatin1String>
#include <QLibraryInfo>
#include <QLocale>
#include <QMessageBox>
#include <QSettings>
+#include <QStringBuilder>
#include <QThread>
#include <QTimer>
#include <QTranslator>
@@ -417,10 +419,23 @@ void BitcoinApplication::shutdownResult()
void BitcoinApplication::handleRunawayException(const QString &message)
{
- QMessageBox::critical(nullptr, "Runaway exception", BitcoinGUI::tr("A fatal error occurred. %1 can no longer continue safely and will quit.").arg(PACKAGE_NAME) + QString("<br><br>") + message);
+ QMessageBox::critical(
+ nullptr, tr("Runaway exception"),
+ tr("A fatal error occurred. %1 can no longer continue safely and will quit.").arg(PACKAGE_NAME) %
+ QLatin1String("<br><br>") % GUIUtil::MakeHtmlLink(message, PACKAGE_BUGREPORT));
::exit(EXIT_FAILURE);
}
+void BitcoinApplication::handleNonFatalException(const QString& message)
+{
+ assert(QThread::currentThread() == thread());
+ QMessageBox::warning(
+ nullptr, tr("Internal error"),
+ tr("An internal error occurred. %1 will attempt to continue safely. This is "
+ "an unexpected bug which can be reported as described below.").arg(PACKAGE_NAME) %
+ QLatin1String("<br><br>") % GUIUtil::MakeHtmlLink(message, PACKAGE_BUGREPORT));
+}
+
WId BitcoinApplication::getMainWinId() const
{
if (!window)
diff --git a/src/qt/bitcoin.h b/src/qt/bitcoin.h
index 69e0a5921e..5fd6bd607f 100644
--- a/src/qt/bitcoin.h
+++ b/src/qt/bitcoin.h
@@ -99,6 +99,12 @@ public Q_SLOTS:
/// Handle runaway exceptions. Shows a message box with the problem and quits the program.
void handleRunawayException(const QString &message);
+ /**
+ * A helper function that shows a message box
+ * with details about a non-fatal exception.
+ */
+ void handleNonFatalException(const QString& message);
+
Q_SIGNALS:
void requestedInitialize();
void requestedShutdown();
diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp
index 6677c9e3b5..3abca7dcff 100644
--- a/src/qt/bitcoingui.cpp
+++ b/src/qt/bitcoingui.cpp
@@ -654,7 +654,7 @@ void BitcoinGUI::setWalletController(WalletController* wallet_controller)
m_open_wallet_action->setEnabled(true);
m_open_wallet_action->setMenu(m_open_wallet_menu);
- connect(wallet_controller, &WalletController::walletAdded, this, &BitcoinGUI::addWallet);
+ GUIUtil::ExceptionSafeConnect(wallet_controller, &WalletController::walletAdded, this, &BitcoinGUI::addWallet);
connect(wallet_controller, &WalletController::walletRemoved, this, &BitcoinGUI::removeWallet);
for (WalletModel* wallet_model : m_wallet_controller->getOpenWallets()) {
diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp
index b4afdbcc22..d10bf9f9ae 100644
--- a/src/qt/guiutil.cpp
+++ b/src/qt/guiutil.cpp
@@ -42,6 +42,7 @@
#include <QGuiApplication>
#include <QJsonObject>
#include <QKeyEvent>
+#include <QLatin1String>
#include <QLineEdit>
#include <QList>
#include <QLocale>
@@ -54,6 +55,7 @@
#include <QShortcut>
#include <QSize>
#include <QString>
+#include <QStringBuilder>
#include <QTextDocument> // for Qt::mightBeRichText
#include <QThread>
#include <QUrlQuery>
@@ -628,8 +630,11 @@ bool SetStartOnSystemStartup(bool fAutoStart) { return false; }
void setClipboard(const QString& str)
{
- QApplication::clipboard()->setText(str, QClipboard::Clipboard);
- QApplication::clipboard()->setText(str, QClipboard::Selection);
+ QClipboard* clipboard = QApplication::clipboard();
+ clipboard->setText(str, QClipboard::Clipboard);
+ if (clipboard->supportsSelection()) {
+ clipboard->setText(str, QClipboard::Selection);
+ }
}
fs::path qstringToBoostPath(const QString &path)
@@ -893,4 +898,22 @@ QImage GetImage(const QLabel* label)
#endif
}
+QString MakeHtmlLink(const QString& source, const QString& link)
+{
+ return QString(source).replace(
+ link,
+ QLatin1String("<a href=\"") % link % QLatin1String("\">") % link % QLatin1String("</a>"));
+}
+
+void PrintSlotException(
+ const std::exception* exception,
+ const QObject* sender,
+ const QObject* receiver)
+{
+ std::string description = sender->metaObject()->className();
+ description += "->";
+ description += receiver->metaObject()->className();
+ PrintExceptionContinue(exception, description.c_str());
+}
+
} // namespace GUIUtil
diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h
index 6395ec6abd..a1cf274354 100644
--- a/src/qt/guiutil.h
+++ b/src/qt/guiutil.h
@@ -9,18 +9,23 @@
#include <fs.h>
#include <net.h>
#include <netaddress.h>
+#include <util/check.h>
+#include <QApplication>
#include <QEvent>
#include <QHeaderView>
#include <QItemDelegate>
#include <QLabel>
#include <QMessageBox>
+#include <QMetaObject>
#include <QObject>
#include <QProgressBar>
#include <QString>
#include <QTableView>
+#include <cassert>
#include <chrono>
+#include <utility>
class QValidatedLineEdit;
class SendCoinsRecipient;
@@ -327,6 +332,58 @@ namespace GUIUtil
QObject::connect(&source, &QObject::destroyed, object, std::forward<Fn>(function), connection);
}
+ /**
+ * Replaces a plain text link with an HTML tagged one.
+ */
+ QString MakeHtmlLink(const QString& source, const QString& link);
+
+ void PrintSlotException(
+ const std::exception* exception,
+ const QObject* sender,
+ const QObject* receiver);
+
+ /**
+ * A drop-in replacement of QObject::connect function
+ * (see: https://doc.qt.io/qt-5/qobject.html#connect-3), that
+ * guaranties that all exceptions are handled within the slot.
+ *
+ * NOTE: This function is incompatible with Qt private signals.
+ */
+ template <typename Sender, typename Signal, typename Receiver, typename Slot>
+ auto ExceptionSafeConnect(
+ Sender sender, Signal signal, Receiver receiver, Slot method,
+ Qt::ConnectionType type = Qt::AutoConnection)
+ {
+ return QObject::connect(
+ sender, signal, receiver,
+ [sender, receiver, method](auto&&... args) {
+ bool ok{true};
+ try {
+ (receiver->*method)(std::forward<decltype(args)>(args)...);
+ } catch (const NonFatalCheckError& e) {
+ PrintSlotException(&e, sender, receiver);
+ ok = QMetaObject::invokeMethod(
+ qApp, "handleNonFatalException",
+ blockingGUIThreadConnection(),
+ Q_ARG(QString, QString::fromStdString(e.what())));
+ } catch (const std::exception& e) {
+ PrintSlotException(&e, sender, receiver);
+ ok = QMetaObject::invokeMethod(
+ qApp, "handleRunawayException",
+ blockingGUIThreadConnection(),
+ Q_ARG(QString, QString::fromStdString(e.what())));
+ } catch (...) {
+ PrintSlotException(nullptr, sender, receiver);
+ ok = QMetaObject::invokeMethod(
+ qApp, "handleRunawayException",
+ blockingGUIThreadConnection(),
+ Q_ARG(QString, "Unknown failure occurred."));
+ }
+ assert(ok);
+ },
+ type);
+ }
+
} // namespace GUIUtil
#endif // BITCOIN_QT_GUIUTIL_H
diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp
index 95e1ce2210..f0e720617c 100644
--- a/src/qt/sendcoinsdialog.cpp
+++ b/src/qt/sendcoinsdialog.cpp
@@ -129,6 +129,8 @@ SendCoinsDialog::SendCoinsDialog(const PlatformStyle *_platformStyle, QWidget *p
ui->customFee->SetAllowEmpty(false);
ui->customFee->setValue(settings.value("nTransactionFee").toLongLong());
minimizeFeeSection(settings.value("fFeeSectionMinimized").toBool());
+
+ GUIUtil::ExceptionSafeConnect(ui->sendButton, &QPushButton::clicked, this, &SendCoinsDialog::sendButtonClicked);
}
void SendCoinsDialog::setClientModel(ClientModel *_clientModel)
@@ -375,7 +377,7 @@ bool SendCoinsDialog::PrepareSendText(QString& question_string, QString& informa
return true;
}
-void SendCoinsDialog::on_sendButton_clicked()
+void SendCoinsDialog::sendButtonClicked([[maybe_unused]] bool checked)
{
if(!model || !model->getOptionsModel())
return;
diff --git a/src/qt/sendcoinsdialog.h b/src/qt/sendcoinsdialog.h
index 4fc2f57cd6..3e276201ba 100644
--- a/src/qt/sendcoinsdialog.h
+++ b/src/qt/sendcoinsdialog.h
@@ -80,7 +80,7 @@ private:
void updateCoinControlState(CCoinControl& ctrl);
private Q_SLOTS:
- void on_sendButton_clicked();
+ void sendButtonClicked(bool checked);
void on_buttonChooseFee_clicked();
void on_buttonMinimizeFee_clicked();
void removeEntry(SendCoinsEntry* entry);
diff --git a/src/qt/test/rpcnestedtests.cpp b/src/qt/test/rpcnestedtests.cpp
index 0d9928d363..9e6e98b274 100644
--- a/src/qt/test/rpcnestedtests.cpp
+++ b/src/qt/test/rpcnestedtests.cpp
@@ -11,8 +11,10 @@
#include <univalue.h>
#include <util/system.h>
-#include <QDir>
-#include <QtGlobal>
+#include <QTest>
+
+#include <string>
+#include <stdexcept>
static RPCHelpMan rpcNestedTest_rpc()
{
@@ -24,9 +26,9 @@ static RPCHelpMan rpcNestedTest_rpc()
{"arg2", RPCArg::Type::STR, RPCArg::Optional::OMITTED, ""},
{"arg3", RPCArg::Type::STR, RPCArg::Optional::OMITTED, ""},
},
- {},
+ RPCResult{RPCResult::Type::ANY, "", ""},
RPCExamples{""},
- [](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue {
+ [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue {
return request.params.write(0, 0);
},
};
@@ -68,13 +70,13 @@ void RPCNestedTests::rpcNestedTests()
RPCConsole::RPCExecuteCommandLine(m_node, result, "getblockchaininfo "); //whitespace at the end will be tolerated
QVERIFY(result.substr(0,1) == "{");
- (RPCConsole::RPCExecuteCommandLine(m_node, result, "getblockchaininfo()[\"chain\"]")); //Quote path identifier are allowed, but look after a child containing the quotes in the key
+ RPCConsole::RPCExecuteCommandLine(m_node, result, "getblockchaininfo()[\"chain\"]"); //Quote path identifier are allowed, but look after a child containing the quotes in the key
QVERIFY(result == "null");
- (RPCConsole::RPCExecuteCommandLine(m_node, result, "createrawtransaction [] {} 0")); //parameter not in brackets are allowed
- (RPCConsole::RPCExecuteCommandLine(m_node, result2, "createrawtransaction([],{},0)")); //parameter in brackets are allowed
+ RPCConsole::RPCExecuteCommandLine(m_node, result, "createrawtransaction [] {} 0"); //parameter not in brackets are allowed
+ RPCConsole::RPCExecuteCommandLine(m_node, result2, "createrawtransaction([],{},0)"); //parameter in brackets are allowed
QVERIFY(result == result2);
- (RPCConsole::RPCExecuteCommandLine(m_node, result2, "createrawtransaction( [], {} , 0 )")); //whitespace between parameters is allowed
+ RPCConsole::RPCExecuteCommandLine(m_node, result2, "createrawtransaction( [], {} , 0 )"); //whitespace between parameters is allowed
QVERIFY(result == result2);
RPCConsole::RPCExecuteCommandLine(m_node, result, "getblock(getbestblockhash())[tx][0]", &filtered);
@@ -123,11 +125,10 @@ void RPCNestedTests::rpcNestedTests()
RPCConsole::RPCExecuteCommandLine(m_node, result, "rpcNestedTest( abc , cba )");
QVERIFY(result == "[\"abc\",\"cba\"]");
- // do the QVERIFY_EXCEPTION_THROWN checks only with Qt5.3 and higher (QVERIFY_EXCEPTION_THROWN was introduced in Qt5.3)
QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(m_node, result, "getblockchaininfo() .\n"), std::runtime_error); //invalid syntax
QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(m_node, result, "getblockchaininfo() getblockchaininfo()"), std::runtime_error); //invalid syntax
- (RPCConsole::RPCExecuteCommandLine(m_node, result, "getblockchaininfo(")); //tolerate non closing brackets if we have no arguments
- (RPCConsole::RPCExecuteCommandLine(m_node, result, "getblockchaininfo()()()")); //tolerate non command brackets
+ RPCConsole::RPCExecuteCommandLine(m_node, result, "getblockchaininfo("); //tolerate non closing brackets if we have no arguments
+ RPCConsole::RPCExecuteCommandLine(m_node, result, "getblockchaininfo()()()"); //tolerate non command brackets
QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(m_node, result, "getblockchaininfo(True)"), UniValue); //invalid argument
QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(m_node, result, "a(getblockchaininfo(True))"), UniValue); //method not found
QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(m_node, result, "rpcNestedTest abc,,abc"), std::runtime_error); //don't tolerate empty arguments when using ,
diff --git a/src/qt/test/wallettests.cpp b/src/qt/test/wallettests.cpp
index 1107c44dc9..03460cd6eb 100644
--- a/src/qt/test/wallettests.cpp
+++ b/src/qt/test/wallettests.cpp
@@ -73,7 +73,7 @@ uint256 SendCoins(CWallet& wallet, SendCoinsDialog& sendCoinsDialog, const CTxDe
if (status == CT_NEW) txid = hash;
}));
ConfirmSend();
- bool invoked = QMetaObject::invokeMethod(&sendCoinsDialog, "on_sendButton_clicked");
+ bool invoked = QMetaObject::invokeMethod(&sendCoinsDialog, "sendButtonClicked", Q_ARG(bool, false));
assert(invoked);
return txid;
}
diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp
index 42e08c6af7..1511410129 100644
--- a/src/qt/transactionview.cpp
+++ b/src/qt/transactionview.cpp
@@ -199,7 +199,7 @@ TransactionView::TransactionView(const PlatformStyle *platformStyle, QWidget *pa
connect(transactionView, &QTableView::doubleClicked, this, &TransactionView::doubleClicked);
connect(transactionView, &QTableView::customContextMenuRequested, this, &TransactionView::contextualMenu);
- connect(bumpFeeAction, &QAction::triggered, this, &TransactionView::bumpFee);
+ GUIUtil::ExceptionSafeConnect(bumpFeeAction, &QAction::triggered, this, &TransactionView::bumpFee);
connect(abandonAction, &QAction::triggered, this, &TransactionView::abandonTx);
connect(copyAddressAction, &QAction::triggered, this, &TransactionView::copyAddress);
connect(copyLabelAction, &QAction::triggered, this, &TransactionView::copyLabel);
@@ -424,7 +424,7 @@ void TransactionView::abandonTx()
model->getTransactionTableModel()->updateTransaction(hashQStr, CT_UPDATED, false);
}
-void TransactionView::bumpFee()
+void TransactionView::bumpFee([[maybe_unused]] bool checked)
{
if(!transactionView || !transactionView->selectionModel())
return;
diff --git a/src/qt/transactionview.h b/src/qt/transactionview.h
index 35ada4aa7a..66350bdc02 100644
--- a/src/qt/transactionview.h
+++ b/src/qt/transactionview.h
@@ -99,7 +99,7 @@ private Q_SLOTS:
void openThirdPartyTxUrl(QString url);
void updateWatchOnlyColumn(bool fHaveWatchOnly);
void abandonTx();
- void bumpFee();
+ void bumpFee(bool checked);
Q_SIGNALS:
void doubleClicked(const QModelIndex&);
diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp
index 02254da3ce..c6dd0c2ad6 100644
--- a/src/qt/walletmodel.cpp
+++ b/src/qt/walletmodel.cpp
@@ -65,7 +65,10 @@ WalletModel::~WalletModel()
void WalletModel::startPollBalance()
{
// This timer will be fired repeatedly to update the balance
- connect(timer, &QTimer::timeout, this, &WalletModel::pollBalanceChanged);
+ // Since the QTimer::timeout is a private signal, it cannot be used
+ // in the GUIUtil::ExceptionSafeConnect directly.
+ connect(timer, &QTimer::timeout, this, &WalletModel::timerTimeout);
+ GUIUtil::ExceptionSafeConnect(this, &WalletModel::timerTimeout, this, &WalletModel::pollBalanceChanged);
timer->start(MODEL_UPDATE_DELAY);
}
diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h
index 9a3c3f2f66..4ca8643444 100644
--- a/src/qt/walletmodel.h
+++ b/src/qt/walletmodel.h
@@ -223,6 +223,8 @@ Q_SIGNALS:
// Notify that there are now keys in the keypool
void canGetAddressesChanged();
+ void timerTimeout();
+
public Q_SLOTS:
/* Starts a timer to periodically update the balance */
void startPollBalance();
diff --git a/src/rest.cpp b/src/rest.cpp
index 9b9f414e6c..d41f374c49 100644
--- a/src/rest.cpp
+++ b/src/rest.cpp
@@ -8,6 +8,7 @@
#include <core_io.h>
#include <httpserver.h>
#include <index/txindex.h>
+#include <node/blockstorage.h>
#include <node/context.h>
#include <primitives/block.h>
#include <primitives/transaction.h>
@@ -321,7 +322,8 @@ static bool rest_chaininfo(const std::any& context, HTTPRequest* req, const std:
switch (rf) {
case RetFormat::JSON: {
- JSONRPCRequest jsonRequest(context);
+ JSONRPCRequest jsonRequest;
+ jsonRequest.context = context;
jsonRequest.params = UniValue(UniValue::VARR);
UniValue chainInfoObject = getblockchaininfo().HandleRequest(jsonRequest);
std::string strJSON = chainInfoObject.write() + "\n";
@@ -694,7 +696,7 @@ static const struct {
void StartREST(const std::any& context)
{
for (const auto& up : uri_prefixes) {
- auto handler = [&context, up](HTTPRequest* req, const std::string& prefix) { return up.handler(context, req, prefix); };
+ auto handler = [context, up](HTTPRequest* req, const std::string& prefix) { return up.handler(context, req, prefix); };
RegisterHTTPHandler(up.prefix, false, handler);
}
}
diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp
index 053b6913dc..7cf6a413e1 100644
--- a/src/rpc/blockchain.cpp
+++ b/src/rpc/blockchain.cpp
@@ -14,6 +14,7 @@
#include <core_io.h>
#include <hash.h>
#include <index/blockfilterindex.h>
+#include <node/blockstorage.h>
#include <node/coinstats.h>
#include <node/context.h>
#include <node/utxo_snapshot.h>
@@ -1263,10 +1264,8 @@ static void BuriedForkDescPushBack(UniValue& softforks, const std::string &name,
static void BIP9SoftForkDescPushBack(const CBlockIndex* active_chain_tip, UniValue& softforks, const std::string &name, const Consensus::Params& consensusParams, Consensus::DeploymentPos id) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
{
// For BIP9 deployments.
- // Deployments (e.g. testdummy) with timeout value before Jan 1, 2009 are hidden.
- // A timeout value of 0 guarantees a softfork will never be activated.
- // This is used when merging logic to implement a proposed softfork without a specified deployment schedule.
- if (consensusParams.vDeployments[id].nTimeout <= 1230768000) return;
+ // Deployments that are never active are hidden.
+ if (consensusParams.vDeployments[id].nStartTime == Consensus::BIP9Deployment::NEVER_ACTIVE) return;
UniValue bip9(UniValue::VOBJ);
const ThresholdState thresholdState = VersionBitsState(active_chain_tip, consensusParams, id, versionbitscache);
@@ -1296,6 +1295,7 @@ static void BIP9SoftForkDescPushBack(const CBlockIndex* active_chain_tip, UniVal
statsUV.pushKV("possible", statsStruct.possible);
bip9.pushKV("statistics", statsUV);
}
+ bip9.pushKV("min_activation_height", consensusParams.vDeployments[id].min_activation_height);
UniValue rv(UniValue::VOBJ);
rv.pushKV("type", "bip9");
@@ -1342,6 +1342,7 @@ RPCHelpMan getblockchaininfo()
{RPCResult::Type::NUM_TIME, "start_time", "the minimum median time past of a block at which the bit gains its meaning"},
{RPCResult::Type::NUM_TIME, "timeout", "the median time past of a block at which the deployment is considered failed if not yet locked in"},
{RPCResult::Type::NUM, "since", "height of the first block to which the status applies"},
+ {RPCResult::Type::NUM, "min_activation_height", "minimum height of blocks for which the rules may be enforced"},
{RPCResult::Type::OBJ, "statistics", "numeric statistics about BIP9 signalling for a softfork (only for \"started\" status)",
{
{RPCResult::Type::NUM, "period", "the length in blocks of the BIP9 signalling period"},
diff --git a/src/rpc/external_signer.cpp b/src/rpc/external_signer.cpp
new file mode 100644
index 0000000000..6ec2b1a07f
--- /dev/null
+++ b/src/rpc/external_signer.cpp
@@ -0,0 +1,76 @@
+// Copyright (c) 2018-2021 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 <chainparamsbase.h>
+#include <external_signer.h>
+#include <rpc/server.h>
+#include <rpc/util.h>
+#include <util/strencodings.h>
+#include <rpc/protocol.h>
+
+#include <string>
+#include <vector>
+
+#ifdef ENABLE_EXTERNAL_SIGNER
+
+static RPCHelpMan enumeratesigners()
+{
+ return RPCHelpMan{"enumeratesigners",
+ "Returns a list of external signers from -signer.",
+ {},
+ RPCResult{
+ RPCResult::Type::OBJ, "", "",
+ {
+ {RPCResult::Type::ARR, "signers", /* optional */ false, "",
+ {
+ {RPCResult::Type::STR_HEX, "masterkeyfingerprint", "Master key fingerprint"},
+ {RPCResult::Type::STR, "name", "Device name"},
+ },
+ }
+ }
+ },
+ RPCExamples{
+ HelpExampleCli("enumeratesigners", "")
+ + HelpExampleRpc("enumeratesigners", "")
+ },
+ [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
+ {
+ const std::string command = gArgs.GetArg("-signer", "");
+ if (command == "") throw JSONRPCError(RPC_MISC_ERROR, "Error: restart bitcoind with -signer=<cmd>");
+ const std::string chain = gArgs.GetChainName();
+ UniValue signers_res = UniValue::VARR;
+ try {
+ std::vector<ExternalSigner> signers;
+ ExternalSigner::Enumerate(command, signers, chain);
+ for (const ExternalSigner& signer : signers) {
+ UniValue signer_res = UniValue::VOBJ;
+ signer_res.pushKV("fingerprint", signer.m_fingerprint);
+ signer_res.pushKV("name", signer.m_name);
+ signers_res.push_back(signer_res);
+ }
+ } catch (const std::exception& e) {
+ throw JSONRPCError(RPC_MISC_ERROR, e.what());
+ }
+ UniValue result(UniValue::VOBJ);
+ result.pushKV("signers", signers_res);
+ return result;
+ }
+ };
+}
+
+void RegisterSignerRPCCommands(CRPCTable &t)
+{
+// clang-format off
+static const CRPCCommand commands[] =
+{ // category actor (function)
+ // --------------------- ------------------------
+ { "signer", &enumeratesigners, },
+};
+// clang-format on
+ for (const auto& c : commands) {
+ t.appendCommand(c.name, &c);
+ }
+}
+
+#endif // ENABLE_EXTERNAL_SIGNER
diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp
index 1df5c51718..8e98919391 100644
--- a/src/rpc/misc.cpp
+++ b/src/rpc/misc.cpp
@@ -628,7 +628,7 @@ static RPCHelpMan echo(const std::string& name)
{"arg8", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, ""},
{"arg9", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, ""},
},
- RPCResult{RPCResult::Type::NONE, "", "Returns whatever was passed in"},
+ RPCResult{RPCResult::Type::ANY, "", "Returns whatever was passed in"},
RPCExamples{""},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp
index cd354f46c2..a5159fb792 100644
--- a/src/rpc/net.cpp
+++ b/src/rpc/net.cpp
@@ -749,9 +749,11 @@ static RPCHelpMan listbanned()
{
{RPCResult::Type::OBJ, "", "",
{
- {RPCResult::Type::STR, "address", ""},
- {RPCResult::Type::NUM_TIME, "banned_until", ""},
- {RPCResult::Type::NUM_TIME, "ban_created", ""},
+ {RPCResult::Type::STR, "address", "The IP/Subnet of the banned node"},
+ {RPCResult::Type::NUM_TIME, "ban_created", "The " + UNIX_EPOCH_TIME + " the ban was created"},
+ {RPCResult::Type::NUM_TIME, "banned_until", "The " + UNIX_EPOCH_TIME + " the ban expires"},
+ {RPCResult::Type::NUM_TIME, "ban_duration", "The ban duration, in seconds"},
+ {RPCResult::Type::NUM_TIME, "time_remaining", "The time remaining until the ban expires, in seconds"},
}},
}},
RPCExamples{
@@ -767,6 +769,7 @@ static RPCHelpMan listbanned()
banmap_t banMap;
node.banman->GetBanned(banMap);
+ const int64_t current_time{GetTime()};
UniValue bannedAddresses(UniValue::VARR);
for (const auto& entry : banMap)
@@ -774,8 +777,10 @@ static RPCHelpMan listbanned()
const CBanEntry& banEntry = entry.second;
UniValue rec(UniValue::VOBJ);
rec.pushKV("address", entry.first.ToString());
- rec.pushKV("banned_until", banEntry.nBanUntil);
rec.pushKV("ban_created", banEntry.nCreateTime);
+ rec.pushKV("banned_until", banEntry.nBanUntil);
+ rec.pushKV("ban_duration", (banEntry.nBanUntil - banEntry.nCreateTime));
+ rec.pushKV("time_remaining", (banEntry.nBanUntil - current_time));
bannedAddresses.push_back(rec);
}
@@ -835,7 +840,7 @@ static RPCHelpMan setnetworkactive()
static RPCHelpMan getnodeaddresses()
{
return RPCHelpMan{"getnodeaddresses",
- "\nReturn known addresses which can potentially be used to find new nodes in the network\n",
+ "\nReturn known addresses, which can potentially be used to find new nodes in the network.\n",
{
{"count", RPCArg::Type::NUM, /* default */ "1", "The maximum number of addresses to return. Specify 0 to return all known addresses."},
},
@@ -844,10 +849,11 @@ static RPCHelpMan getnodeaddresses()
{
{RPCResult::Type::OBJ, "", "",
{
- {RPCResult::Type::NUM_TIME, "time", "The " + UNIX_EPOCH_TIME + " of when the node was last seen"},
- {RPCResult::Type::NUM, "services", "The services offered"},
+ {RPCResult::Type::NUM_TIME, "time", "The " + UNIX_EPOCH_TIME + " when the node was last seen"},
+ {RPCResult::Type::NUM, "services", "The services offered by the node"},
{RPCResult::Type::STR, "address", "The address of the node"},
- {RPCResult::Type::NUM, "port", "The port of the node"},
+ {RPCResult::Type::NUM, "port", "The port number of the node"},
+ {RPCResult::Type::STR, "network", "The network (" + Join(GetNetworkNames(), ", ") + ") the node connected through"},
}},
}
},
@@ -862,15 +868,11 @@ static RPCHelpMan getnodeaddresses()
throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
}
- int count = 1;
- if (!request.params[0].isNull()) {
- count = request.params[0].get_int();
- if (count < 0) {
- throw JSONRPCError(RPC_INVALID_PARAMETER, "Address count out of range");
- }
- }
+ const int count{request.params[0].isNull() ? 1 : request.params[0].get_int()};
+ if (count < 0) throw JSONRPCError(RPC_INVALID_PARAMETER, "Address count out of range");
+
// returns a shuffled list of CAddress
- std::vector<CAddress> vAddr = node.connman->GetAddresses(count, /* max_pct */ 0);
+ const std::vector<CAddress> vAddr{node.connman->GetAddresses(count, /* max_pct */ 0)};
UniValue ret(UniValue::VARR);
for (const CAddress& addr : vAddr) {
@@ -879,6 +881,7 @@ static RPCHelpMan getnodeaddresses()
obj.pushKV("services", (uint64_t)addr.nServices);
obj.pushKV("address", addr.ToStringIP());
obj.pushKV("port", addr.GetPort());
+ obj.pushKV("network", GetNetworkName(addr.GetNetClass()));
ret.push_back(obj);
}
return ret;
diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp
index 19e9c75e32..ecdd00dcca 100644
--- a/src/rpc/rawtransaction.cpp
+++ b/src/rpc/rawtransaction.cpp
@@ -10,6 +10,7 @@
#include <index/txindex.h>
#include <key_io.h>
#include <merkleblock.h>
+#include <node/blockstorage.h>
#include <node/coin.h>
#include <node/context.h>
#include <node/psbt.h>
diff --git a/src/rpc/register.h b/src/rpc/register.h
index 374a1e3db8..6724203ffe 100644
--- a/src/rpc/register.h
+++ b/src/rpc/register.h
@@ -19,6 +19,8 @@ void RegisterMiscRPCCommands(CRPCTable &tableRPC);
void RegisterMiningRPCCommands(CRPCTable &tableRPC);
/** Register raw transaction RPC commands */
void RegisterRawTransactionRPCCommands(CRPCTable &tableRPC);
+/** Register raw transaction RPC commands */
+void RegisterSignerRPCCommands(CRPCTable &tableRPC);
static inline void RegisterAllCoreRPCCommands(CRPCTable &t)
{
@@ -27,6 +29,9 @@ static inline void RegisterAllCoreRPCCommands(CRPCTable &t)
RegisterMiscRPCCommands(t);
RegisterMiningRPCCommands(t);
RegisterRawTransactionRPCCommands(t);
+#ifdef ENABLE_EXTERNAL_SIGNER
+ RegisterSignerRPCCommands(t);
+#endif // ENABLE_EXTERNAL_SIGNER
}
#endif // BITCOIN_RPC_REGISTER_H
diff --git a/src/rpc/request.h b/src/rpc/request.h
index e1569673f6..bb091efea8 100644
--- a/src/rpc/request.h
+++ b/src/rpc/request.h
@@ -35,18 +35,7 @@ public:
std::string URI;
std::string authUser;
std::string peerAddr;
- const std::any& context;
-
- explicit JSONRPCRequest(const std::any& context) : id(NullUniValue), params(NullUniValue), context(context) {}
-
- //! Initializes request information from another request object and the
- //! given context. The implementation should be updated if any members are
- //! added or removed above.
- JSONRPCRequest(const JSONRPCRequest& other, const std::any& context)
- : id(other.id), strMethod(other.strMethod), params(other.params), mode(other.mode), URI(other.URI),
- authUser(other.authUser), peerAddr(other.peerAddr), context(context)
- {
- }
+ std::any context;
void parse(const UniValue& valRequest);
};
diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp
index 2f05c8842f..5d816ba5bb 100644
--- a/src/rpc/server.cpp
+++ b/src/rpc/server.cpp
@@ -137,8 +137,9 @@ static RPCHelpMan help()
{
{"command", RPCArg::Type::STR, /* default */ "all commands", "The command to get help on"},
},
- RPCResult{
- RPCResult::Type::STR, "", "The help text"
+ {
+ RPCResult{RPCResult::Type::STR, "", "The help text"},
+ RPCResult{RPCResult::Type::ANY, "", ""},
},
RPCExamples{""},
[&](const RPCHelpMan& self, const JSONRPCRequest& jsonRequest) -> UniValue
diff --git a/src/rpc/util.cpp b/src/rpc/util.cpp
index 44e58cb75f..ba3105ca01 100644
--- a/src/rpc/util.cpp
+++ b/src/rpc/util.cpp
@@ -113,17 +113,80 @@ std::vector<unsigned char> ParseHexO(const UniValue& o, std::string strKey)
return ParseHexV(find_value(o, strKey), strKey);
}
+namespace {
+
+/**
+ * Quote an argument for shell.
+ *
+ * @note This is intended for help, not for security-sensitive purposes.
+ */
+std::string ShellQuote(const std::string& s)
+{
+ std::string result;
+ result.reserve(s.size() * 2);
+ for (const char ch: s) {
+ if (ch == '\'') {
+ result += "'\''";
+ } else {
+ result += ch;
+ }
+ }
+ return "'" + result + "'";
+}
+
+/**
+ * Shell-quotes the argument if it needs quoting, else returns it literally, to save typing.
+ *
+ * @note This is intended for help, not for security-sensitive purposes.
+ */
+std::string ShellQuoteIfNeeded(const std::string& s)
+{
+ for (const char ch: s) {
+ if (ch == ' ' || ch == '\'' || ch == '"') {
+ return ShellQuote(s);
+ }
+ }
+
+ return s;
+}
+
+}
+
std::string HelpExampleCli(const std::string& methodname, const std::string& args)
{
return "> bitcoin-cli " + methodname + " " + args + "\n";
}
+std::string HelpExampleCliNamed(const std::string& methodname, const RPCArgList& args)
+{
+ std::string result = "> bitcoin-cli -named " + methodname;
+ for (const auto& argpair: args) {
+ const auto& value = argpair.second.isStr()
+ ? argpair.second.get_str()
+ : argpair.second.write();
+ result += " " + argpair.first + "=" + ShellQuoteIfNeeded(value);
+ }
+ result += "\n";
+ return result;
+}
+
std::string HelpExampleRpc(const std::string& methodname, const std::string& args)
{
return "> curl --user myusername --data-binary '{\"jsonrpc\": \"1.0\", \"id\": \"curltest\", "
"\"method\": \"" + methodname + "\", \"params\": [" + args + "]}' -H 'content-type: text/plain;' http://127.0.0.1:8332/\n";
}
+std::string HelpExampleRpcNamed(const std::string& methodname, const RPCArgList& args)
+{
+ UniValue params(UniValue::VOBJ);
+ for (const auto& param: args) {
+ params.pushKV(param.first, param.second);
+ }
+
+ return "> curl --user myusername --data-binary '{\"jsonrpc\": \"1.0\", \"id\": \"curltest\", "
+ "\"method\": \"" + methodname + "\", \"params\": " + params.write() + "}' -H 'content-type: text/plain;' http://127.0.0.1:8332/\n";
+}
+
// Converts a hex string to a public key if possible
CPubKey HexToPubKey(const std::string& hex_in)
{
@@ -442,6 +505,7 @@ std::string RPCResults::ToDescriptionString() const
{
std::string result;
for (const auto& r : m_results) {
+ if (r.m_type == RPCResult::Type::ANY) continue; // for testing only
if (r.m_cond.empty()) {
result += "\nResult:\n";
} else {
@@ -459,7 +523,7 @@ std::string RPCExamples::ToDescriptionString() const
return m_examples.empty() ? m_examples : "\nExamples:\n" + m_examples;
}
-UniValue RPCHelpMan::HandleRequest(const JSONRPCRequest& request)
+UniValue RPCHelpMan::HandleRequest(const JSONRPCRequest& request) const
{
if (request.mode == JSONRPCRequest::GET_ARGS) {
return GetArgMap();
@@ -471,7 +535,9 @@ UniValue RPCHelpMan::HandleRequest(const JSONRPCRequest& request)
if (request.mode == JSONRPCRequest::GET_HELP || !IsValidNumArgs(request.params.size())) {
throw std::runtime_error(ToString());
}
- return m_fun(*this, request);
+ const UniValue ret = m_fun(*this, request);
+ CHECK_NONFATAL(std::any_of(m_results.m_results.begin(), m_results.m_results.end(), [ret](const RPCResult& res) { return res.MatchesType(ret); }));
+ return ret;
}
bool RPCHelpMan::IsValidNumArgs(size_t num_args) const
@@ -677,6 +743,9 @@ void RPCResult::ToSections(Sections& sections, const OuterType outer_type, const
sections.PushSection({indent + "..." + maybe_separator, m_description});
return;
}
+ case Type::ANY: {
+ CHECK_NONFATAL(false); // Only for testing
+ }
case Type::NONE: {
sections.PushSection({indent + "null" + maybe_separator, Description("json null")});
return;
@@ -742,6 +811,42 @@ void RPCResult::ToSections(Sections& sections, const OuterType outer_type, const
CHECK_NONFATAL(false);
}
+bool RPCResult::MatchesType(const UniValue& result) const
+{
+ switch (m_type) {
+ case Type::ELISION: {
+ return false;
+ }
+ case Type::ANY: {
+ return true;
+ }
+ case Type::NONE: {
+ return UniValue::VNULL == result.getType();
+ }
+ case Type::STR:
+ case Type::STR_HEX: {
+ return UniValue::VSTR == result.getType();
+ }
+ case Type::NUM:
+ case Type::STR_AMOUNT:
+ case Type::NUM_TIME: {
+ return UniValue::VNUM == result.getType();
+ }
+ case Type::BOOL: {
+ return UniValue::VBOOL == result.getType();
+ }
+ case Type::ARR_FIXED:
+ case Type::ARR: {
+ return UniValue::VARR == result.getType();
+ }
+ case Type::OBJ_DYN:
+ case Type::OBJ: {
+ return UniValue::VOBJ == result.getType();
+ }
+ } // no default case, so the compiler can warn about missing cases
+ CHECK_NONFATAL(false);
+}
+
std::string RPCArg::ToStringObj(const bool oneline) const
{
std::string res;
diff --git a/src/rpc/util.h b/src/rpc/util.h
index 94c2d2d626..6e783e19fb 100644
--- a/src/rpc/util.h
+++ b/src/rpc/util.h
@@ -78,8 +78,12 @@ extern std::vector<unsigned char> ParseHexV(const UniValue& v, std::string strNa
extern std::vector<unsigned char> ParseHexO(const UniValue& o, std::string strKey);
extern CAmount AmountFromValue(const UniValue& value);
+
+using RPCArgList = std::vector<std::pair<std::string, UniValue>>;
extern std::string HelpExampleCli(const std::string& methodname, const std::string& args);
+extern std::string HelpExampleCliNamed(const std::string& methodname, const RPCArgList& args);
extern std::string HelpExampleRpc(const std::string& methodname, const std::string& args);
+extern std::string HelpExampleRpcNamed(const std::string& methodname, const RPCArgList& args);
CPubKey HexToPubKey(const std::string& hex_in);
CPubKey AddrToPubKey(const FillableSigningProvider& keystore, const std::string& addr_in);
@@ -223,6 +227,7 @@ struct RPCResult {
NUM,
BOOL,
NONE,
+ ANY, //!< Special type to disable type checks (for testing only)
STR_AMOUNT, //!< Special string to represent a floating point amount
STR_HEX, //!< Special string with only hex chars
OBJ_DYN, //!< Special dictionary with keys that are not literals
@@ -295,6 +300,8 @@ struct RPCResult {
std::string ToStringObj() const;
/** Return the description string, including the result type. */
std::string ToDescriptionString() const;
+ /** Check whether the result JSON type matches. */
+ bool MatchesType(const UniValue& result) const;
};
struct RPCResults {
@@ -333,7 +340,7 @@ public:
using RPCMethodImpl = std::function<UniValue(const RPCHelpMan&, const JSONRPCRequest&)>;
RPCHelpMan(std::string name, std::string description, std::vector<RPCArg> args, RPCResults results, RPCExamples examples, RPCMethodImpl fun);
- UniValue HandleRequest(const JSONRPCRequest& request);
+ UniValue HandleRequest(const JSONRPCRequest& request) const;
std::string ToString() const;
/** Return the named args that need to be converted from string to another JSON type */
UniValue GetArgMap() const;
diff --git a/src/script/bitcoinconsensus.cpp b/src/script/bitcoinconsensus.cpp
index 76609f01a7..a9aa6a0060 100644
--- a/src/script/bitcoinconsensus.cpp
+++ b/src/script/bitcoinconsensus.cpp
@@ -92,7 +92,7 @@ static int verify_script(const unsigned char *scriptPubKey, unsigned int scriptP
set_error(err, bitcoinconsensus_ERR_OK);
PrecomputedTransactionData txdata(tx);
- return VerifyScript(tx.vin[nIn].scriptSig, CScript(scriptPubKey, scriptPubKey + scriptPubKeyLen), &tx.vin[nIn].scriptWitness, flags, TransactionSignatureChecker(&tx, nIn, amount, txdata), nullptr);
+ return VerifyScript(tx.vin[nIn].scriptSig, CScript(scriptPubKey, scriptPubKey + scriptPubKeyLen), &tx.vin[nIn].scriptWitness, flags, TransactionSignatureChecker(&tx, nIn, amount, txdata, MissingDataBehavior::FAIL), nullptr);
} catch (const std::exception&) {
return set_error(err, bitcoinconsensus_ERR_TX_DESERIALIZE); // Error deserializing
}
diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp
index 20a4ce48b0..abc0625bb1 100644
--- a/src/script/interpreter.cpp
+++ b/src/script/interpreter.cpp
@@ -1488,8 +1488,20 @@ static const CHashWriter HASHER_TAPLEAF = TaggedHash("TapLeaf");
static const CHashWriter HASHER_TAPBRANCH = TaggedHash("TapBranch");
static const CHashWriter HASHER_TAPTWEAK = TaggedHash("TapTweak");
+static bool HandleMissingData(MissingDataBehavior mdb)
+{
+ switch (mdb) {
+ case MissingDataBehavior::ASSERT_FAIL:
+ assert(!"Missing data");
+ break;
+ case MissingDataBehavior::FAIL:
+ return false;
+ }
+ assert(!"Unknown MissingDataBehavior value");
+}
+
template<typename T>
-bool SignatureHashSchnorr(uint256& hash_out, const ScriptExecutionData& execdata, const T& tx_to, uint32_t in_pos, uint8_t hash_type, SigVersion sigversion, const PrecomputedTransactionData& cache)
+bool SignatureHashSchnorr(uint256& hash_out, const ScriptExecutionData& execdata, const T& tx_to, uint32_t in_pos, uint8_t hash_type, SigVersion sigversion, const PrecomputedTransactionData& cache, MissingDataBehavior mdb)
{
uint8_t ext_flag, key_version;
switch (sigversion) {
@@ -1509,7 +1521,9 @@ bool SignatureHashSchnorr(uint256& hash_out, const ScriptExecutionData& execdata
assert(false);
}
assert(in_pos < tx_to.vin.size());
- assert(cache.m_bip341_taproot_ready && cache.m_spent_outputs_ready);
+ if (!(cache.m_bip341_taproot_ready && cache.m_spent_outputs_ready)) {
+ return HandleMissingData(mdb);
+ }
CHashWriter ss = HASHER_TAPSIGHASH;
@@ -1667,6 +1681,9 @@ bool GenericTransactionSignatureChecker<T>::CheckECDSASignature(const std::vecto
int nHashType = vchSig.back();
vchSig.pop_back();
+ // Witness sighashes need the amount.
+ if (sigversion == SigVersion::WITNESS_V0 && amount < 0) return HandleMissingData(m_mdb);
+
uint256 sighash = SignatureHash(scriptCode, *txTo, nIn, nHashType, amount, sigversion, this->txdata);
if (!VerifyECDSASignature(vchSig, pubkey, sighash))
@@ -1696,7 +1713,7 @@ bool GenericTransactionSignatureChecker<T>::CheckSchnorrSignature(Span<const uns
}
uint256 sighash;
assert(this->txdata);
- if (!SignatureHashSchnorr(sighash, execdata, *txTo, nIn, hashtype, sigversion, *this->txdata)) {
+ if (!SignatureHashSchnorr(sighash, execdata, *txTo, nIn, hashtype, sigversion, *this->txdata, m_mdb)) {
return set_error(serror, SCRIPT_ERR_SCHNORR_SIG_HASHTYPE);
}
if (!VerifySchnorrSignature(sig, pubkey, sighash)) return set_error(serror, SCRIPT_ERR_SCHNORR_SIG);
diff --git a/src/script/interpreter.h b/src/script/interpreter.h
index b4c163c841..c76b3acb22 100644
--- a/src/script/interpreter.h
+++ b/src/script/interpreter.h
@@ -247,11 +247,21 @@ public:
virtual ~BaseSignatureChecker() {}
};
+/** Enum to specify what *TransactionSignatureChecker's behavior should be
+ * when dealing with missing transaction data.
+ */
+enum class MissingDataBehavior
+{
+ ASSERT_FAIL, //!< Abort execution through assertion failure (for consensus code)
+ FAIL, //!< Just act as if the signature was invalid
+};
+
template <class T>
class GenericTransactionSignatureChecker : public BaseSignatureChecker
{
private:
const T* txTo;
+ const MissingDataBehavior m_mdb;
unsigned int nIn;
const CAmount amount;
const PrecomputedTransactionData* txdata;
@@ -261,8 +271,8 @@ protected:
virtual bool VerifySchnorrSignature(Span<const unsigned char> sig, const XOnlyPubKey& pubkey, const uint256& sighash) const;
public:
- GenericTransactionSignatureChecker(const T* txToIn, unsigned int nInIn, const CAmount& amountIn) : txTo(txToIn), nIn(nInIn), amount(amountIn), txdata(nullptr) {}
- GenericTransactionSignatureChecker(const T* txToIn, unsigned int nInIn, const CAmount& amountIn, const PrecomputedTransactionData& txdataIn) : txTo(txToIn), nIn(nInIn), amount(amountIn), txdata(&txdataIn) {}
+ GenericTransactionSignatureChecker(const T* txToIn, unsigned int nInIn, const CAmount& amountIn, MissingDataBehavior mdb) : txTo(txToIn), m_mdb(mdb), nIn(nInIn), amount(amountIn), txdata(nullptr) {}
+ GenericTransactionSignatureChecker(const T* txToIn, unsigned int nInIn, const CAmount& amountIn, const PrecomputedTransactionData& txdataIn, MissingDataBehavior mdb) : txTo(txToIn), m_mdb(mdb), nIn(nInIn), amount(amountIn), txdata(&txdataIn) {}
bool CheckECDSASignature(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode, SigVersion sigversion) const override;
bool CheckSchnorrSignature(Span<const unsigned char> sig, Span<const unsigned char> pubkey, SigVersion sigversion, const ScriptExecutionData& execdata, ScriptError* serror = nullptr) const override;
bool CheckLockTime(const CScriptNum& nLockTime) const override;
@@ -272,6 +282,34 @@ public:
using TransactionSignatureChecker = GenericTransactionSignatureChecker<CTransaction>;
using MutableTransactionSignatureChecker = GenericTransactionSignatureChecker<CMutableTransaction>;
+class DeferringSignatureChecker : public BaseSignatureChecker
+{
+protected:
+ BaseSignatureChecker& m_checker;
+
+public:
+ DeferringSignatureChecker(BaseSignatureChecker& checker) : m_checker(checker) {}
+
+ bool CheckECDSASignature(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode, SigVersion sigversion) const override
+ {
+ return m_checker.CheckECDSASignature(scriptSig, vchPubKey, scriptCode, sigversion);
+ }
+
+ bool CheckSchnorrSignature(Span<const unsigned char> sig, Span<const unsigned char> pubkey, SigVersion sigversion, const ScriptExecutionData& execdata, ScriptError* serror = nullptr) const override
+ {
+ return m_checker.CheckSchnorrSignature(sig, pubkey, sigversion, execdata, serror);
+ }
+
+ bool CheckLockTime(const CScriptNum& nLockTime) const override
+ {
+ return m_checker.CheckLockTime(nLockTime);
+ }
+ bool CheckSequence(const CScriptNum& nSequence) const override
+ {
+ return m_checker.CheckSequence(nSequence);
+ }
+};
+
bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker, SigVersion sigversion, ScriptExecutionData& execdata, ScriptError* error = nullptr);
bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker, SigVersion sigversion, ScriptError* error = nullptr);
bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const CScriptWitness* witness, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* serror = nullptr);
diff --git a/src/script/sigcache.h b/src/script/sigcache.h
index bf0ba38c2d..7b6b91c963 100644
--- a/src/script/sigcache.h
+++ b/src/script/sigcache.h
@@ -27,7 +27,7 @@ private:
bool store;
public:
- CachingTransactionSignatureChecker(const CTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn, bool storeIn, PrecomputedTransactionData& txdataIn) : TransactionSignatureChecker(txToIn, nInIn, amountIn, txdataIn), store(storeIn) {}
+ CachingTransactionSignatureChecker(const CTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn, bool storeIn, PrecomputedTransactionData& txdataIn) : TransactionSignatureChecker(txToIn, nInIn, amountIn, txdataIn, MissingDataBehavior::ASSERT_FAIL), store(storeIn) {}
bool VerifyECDSASignature(const std::vector<unsigned char>& vchSig, const CPubKey& vchPubKey, const uint256& sighash) const override;
bool VerifySchnorrSignature(Span<const unsigned char> sig, const XOnlyPubKey& pubkey, const uint256& sighash) const override;
diff --git a/src/script/sign.cpp b/src/script/sign.cpp
index dba5ce621a..4d9026427e 100644
--- a/src/script/sign.cpp
+++ b/src/script/sign.cpp
@@ -14,7 +14,7 @@
typedef std::vector<unsigned char> valtype;
-MutableTransactionSignatureCreator::MutableTransactionSignatureCreator(const CMutableTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn, int nHashTypeIn) : txTo(txToIn), nIn(nInIn), nHashType(nHashTypeIn), amount(amountIn), checker(txTo, nIn, amountIn) {}
+MutableTransactionSignatureCreator::MutableTransactionSignatureCreator(const CMutableTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn, int nHashTypeIn) : txTo(txToIn), nIn(nInIn), nHashType(nHashTypeIn), amount(amountIn), checker(txTo, nIn, amountIn, MissingDataBehavior::FAIL) {}
bool MutableTransactionSignatureCreator::CreateSig(const SigningProvider& provider, std::vector<unsigned char>& vchSig, const CKeyID& address, const CScript& scriptCode, SigVersion sigversion) const
{
@@ -26,6 +26,9 @@ bool MutableTransactionSignatureCreator::CreateSig(const SigningProvider& provid
if (sigversion == SigVersion::WITNESS_V0 && !key.IsCompressed())
return false;
+ // Signing for witness scripts needs the amount.
+ if (sigversion == SigVersion::WITNESS_V0 && amount < 0) return false;
+
uint256 hash = SignatureHash(scriptCode, *txTo, nIn, nHashType, amount, sigversion);
if (!key.Sign(hash, vchSig))
return false;
@@ -250,17 +253,17 @@ bool ProduceSignature(const SigningProvider& provider, const BaseSignatureCreato
}
namespace {
-class SignatureExtractorChecker final : public BaseSignatureChecker
+class SignatureExtractorChecker final : public DeferringSignatureChecker
{
private:
SignatureData& sigdata;
- BaseSignatureChecker& checker;
public:
- SignatureExtractorChecker(SignatureData& sigdata, BaseSignatureChecker& checker) : sigdata(sigdata), checker(checker) {}
+ SignatureExtractorChecker(SignatureData& sigdata, BaseSignatureChecker& checker) : DeferringSignatureChecker(checker), sigdata(sigdata) {}
+
bool CheckECDSASignature(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode, SigVersion sigversion) const override
{
- if (checker.CheckECDSASignature(scriptSig, vchPubKey, scriptCode, sigversion)) {
+ if (m_checker.CheckECDSASignature(scriptSig, vchPubKey, scriptCode, sigversion)) {
CPubKey pubkey(vchPubKey);
sigdata.signatures.emplace(pubkey.GetID(), SigPair(pubkey, scriptSig));
return true;
@@ -292,7 +295,7 @@ SignatureData DataFromTransaction(const CMutableTransaction& tx, unsigned int nI
Stacks stack(data);
// Get signatures
- MutableTransactionSignatureChecker tx_checker(&tx, nIn, txout.nValue);
+ MutableTransactionSignatureChecker tx_checker(&tx, nIn, txout.nValue, MissingDataBehavior::FAIL);
SignatureExtractorChecker extractor_checker(data, tx_checker);
if (VerifyScript(data.scriptSig, txout.scriptPubKey, &data.scriptWitness, STANDARD_SCRIPT_VERIFY_FLAGS, extractor_checker)) {
data.complete = true;
@@ -499,7 +502,7 @@ bool SignTransaction(CMutableTransaction& mtx, const SigningProvider* keystore,
}
ScriptError serror = SCRIPT_ERR_OK;
- if (!VerifyScript(txin.scriptSig, prevPubKey, &txin.scriptWitness, STANDARD_SCRIPT_VERIFY_FLAGS, TransactionSignatureChecker(&txConst, i, amount), &serror)) {
+ if (!VerifyScript(txin.scriptSig, prevPubKey, &txin.scriptWitness, STANDARD_SCRIPT_VERIFY_FLAGS, TransactionSignatureChecker(&txConst, i, amount, MissingDataBehavior::FAIL), &serror)) {
if (serror == SCRIPT_ERR_INVALID_STACK_OPERATION) {
// Unable to sign input and verification failed (possible attempt to partially sign).
input_errors[i] = "Unable to sign input, invalid stack size (possibly missing key)";
diff --git a/src/shutdown.cpp b/src/shutdown.cpp
index 2fc195e2d1..35faf3c412 100644
--- a/src/shutdown.cpp
+++ b/src/shutdown.cpp
@@ -6,7 +6,9 @@
#include <shutdown.h>
#include <logging.h>
+#include <node/ui_interface.h>
#include <util/tokenpipe.h>
+#include <warnings.h>
#include <config/bitcoin-config.h>
@@ -16,6 +18,18 @@
#include <condition_variable>
#endif
+bool AbortNode(const std::string& strMessage, bilingual_str user_message)
+{
+ SetMiscWarning(Untranslated(strMessage));
+ LogPrintf("*** %s\n", strMessage);
+ if (user_message.empty()) {
+ user_message = _("A fatal internal error occurred, see debug.log for details");
+ }
+ AbortError(user_message);
+ StartShutdown();
+ return false;
+}
+
static std::atomic<bool> fRequestShutdown(false);
#ifdef WIN32
/** On windows it is possible to simply use a condition variable. */
diff --git a/src/shutdown.h b/src/shutdown.h
index b2fbdb8cfb..ff56c6bd87 100644
--- a/src/shutdown.h
+++ b/src/shutdown.h
@@ -6,6 +6,11 @@
#ifndef BITCOIN_SHUTDOWN_H
#define BITCOIN_SHUTDOWN_H
+#include <util/translation.h> // For bilingual_str
+
+/** Abort with a message */
+bool AbortNode(const std::string& strMessage, bilingual_str user_message = bilingual_str{});
+
/** Initialize shutdown state. This must be called before using either StartShutdown(),
* AbortShutdown() or WaitForShutdown(). Calling ShutdownRequested() is always safe.
*/
diff --git a/src/signet.cpp b/src/signet.cpp
index fb41e43752..1ba8502287 100644
--- a/src/signet.cpp
+++ b/src/signet.cpp
@@ -139,7 +139,9 @@ bool CheckSignetBlockSolution(const CBlock& block, const Consensus::Params& cons
const CScript& scriptSig = signet_txs->m_to_sign.vin[0].scriptSig;
const CScriptWitness& witness = signet_txs->m_to_sign.vin[0].scriptWitness;
- TransactionSignatureChecker sigcheck(&signet_txs->m_to_sign, /*nIn=*/ 0, /*amount=*/ signet_txs->m_to_spend.vout[0].nValue);
+ PrecomputedTransactionData txdata;
+ txdata.Init(signet_txs->m_to_sign, {signet_txs->m_to_spend.vout[0]});
+ TransactionSignatureChecker sigcheck(&signet_txs->m_to_sign, /*nIn=*/ 0, /*amount=*/ signet_txs->m_to_spend.vout[0].nValue, txdata, MissingDataBehavior::ASSERT_FAIL);
if (!VerifyScript(scriptSig, signet_txs->m_to_spend.vout[0].scriptPubKey, &witness, BLOCK_SCRIPT_VERIFY_FLAGS, sigcheck)) {
LogPrint(BCLog::VALIDATION, "CheckSignetBlockSolution: Errors in block (block solution invalid)\n");
diff --git a/src/sync.h b/src/sync.h
index 53213c2089..146c228592 100644
--- a/src/sync.h
+++ b/src/sync.h
@@ -56,7 +56,7 @@ std::string LocksHeld();
template <typename MutexType>
void AssertLockHeldInternal(const char* pszName, const char* pszFile, int nLine, MutexType* cs) EXCLUSIVE_LOCKS_REQUIRED(cs);
template <typename MutexType>
-void AssertLockNotHeldInternal(const char* pszName, const char* pszFile, int nLine, MutexType* cs) EXCLUSIVE_LOCKS_REQUIRED(!cs);
+void AssertLockNotHeldInternal(const char* pszName, const char* pszFile, int nLine, MutexType* cs) LOCKS_EXCLUDED(cs);
void DeleteLock(void* cs);
bool LockStackEmpty();
@@ -74,7 +74,7 @@ inline void CheckLastCritical(void* cs, std::string& lockname, const char* guard
template <typename MutexType>
inline void AssertLockHeldInternal(const char* pszName, const char* pszFile, int nLine, MutexType* cs) EXCLUSIVE_LOCKS_REQUIRED(cs) {}
template <typename MutexType>
-void AssertLockNotHeldInternal(const char* pszName, const char* pszFile, int nLine, MutexType* cs) EXCLUSIVE_LOCKS_REQUIRED(!cs) {}
+void AssertLockNotHeldInternal(const char* pszName, const char* pszFile, int nLine, MutexType* cs) LOCKS_EXCLUDED(cs) {}
inline void DeleteLock(void* cs) {}
inline bool LockStackEmpty() { return true; }
#endif
diff --git a/src/test/denialofservice_tests.cpp b/src/test/denialofservice_tests.cpp
index 7557d4618a..599e628685 100644
--- a/src/test/denialofservice_tests.cpp
+++ b/src/test/denialofservice_tests.cpp
@@ -22,6 +22,7 @@
#include <test/util/setup_common.h>
+#include <array>
#include <stdint.h>
#include <boost/test/unit_test.hpp>
@@ -115,7 +116,6 @@ BOOST_AUTO_TEST_CASE(outbound_slow_chain_eviction)
BOOST_CHECK(peerLogic->SendMessages(&dummyNode1)); // should result in disconnect
}
BOOST_CHECK(dummyNode1.fDisconnect == true);
- SetMockTime(0);
peerLogic->FinalizeNode(dummyNode1);
}
@@ -209,46 +209,94 @@ BOOST_AUTO_TEST_CASE(peer_discouragement)
{
const CChainParams& chainparams = Params();
auto banman = std::make_unique<BanMan>(GetDataDir() / "banlist.dat", nullptr, DEFAULT_MISBEHAVING_BANTIME);
- auto connman = std::make_unique<CConnman>(0x1337, 0x1337, *m_node.addrman);
+ auto connman = std::make_unique<CConnmanTest>(0x1337, 0x1337, *m_node.addrman);
auto peerLogic = PeerManager::make(chainparams, *connman, *m_node.addrman, banman.get(),
*m_node.scheduler, *m_node.chainman, *m_node.mempool, false);
+ CNetAddr tor_netaddr;
+ BOOST_REQUIRE(
+ tor_netaddr.SetSpecial("pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion"));
+ const CService tor_service{tor_netaddr, Params().GetDefaultPort()};
+
+ const std::array<CAddress, 3> addr{CAddress{ip(0xa0b0c001), NODE_NONE},
+ CAddress{ip(0xa0b0c002), NODE_NONE},
+ CAddress{tor_service, NODE_NONE}};
+
+ const CNetAddr other_addr{ip(0xa0b0ff01)}; // Not any of addr[].
+
+ std::array<CNode*, 3> nodes;
+
banman->ClearBanned();
- CAddress addr1(ip(0xa0b0c001), NODE_NONE);
- CNode dummyNode1(id++, NODE_NETWORK, INVALID_SOCKET, addr1, /* nKeyedNetGroupIn */ 0, /* nLocalHostNonceIn */ 0, CAddress(), /* pszDest */ "", ConnectionType::INBOUND, /* inbound_onion */ false);
- dummyNode1.SetCommonVersion(PROTOCOL_VERSION);
- peerLogic->InitializeNode(&dummyNode1);
- dummyNode1.fSuccessfullyConnected = true;
- peerLogic->Misbehaving(dummyNode1.GetId(), DISCOURAGEMENT_THRESHOLD, /* message */ ""); // Should be discouraged
+ nodes[0] = new CNode{id++, NODE_NETWORK, INVALID_SOCKET, addr[0], /* nKeyedNetGroupIn */ 0,
+ /* nLocalHostNonceIn */ 0, CAddress(), /* pszDest */ "",
+ ConnectionType::INBOUND, /* inbound_onion */ false};
+ nodes[0]->SetCommonVersion(PROTOCOL_VERSION);
+ peerLogic->InitializeNode(nodes[0]);
+ nodes[0]->fSuccessfullyConnected = true;
+ connman->AddNode(*nodes[0]);
+ peerLogic->Misbehaving(nodes[0]->GetId(), DISCOURAGEMENT_THRESHOLD, /* message */ ""); // Should be discouraged
{
- LOCK(dummyNode1.cs_sendProcessing);
- BOOST_CHECK(peerLogic->SendMessages(&dummyNode1));
+ LOCK(nodes[0]->cs_sendProcessing);
+ BOOST_CHECK(peerLogic->SendMessages(nodes[0]));
}
- BOOST_CHECK(banman->IsDiscouraged(addr1));
- BOOST_CHECK(!banman->IsDiscouraged(ip(0xa0b0c001|0x0000ff00))); // Different IP, not discouraged
-
- CAddress addr2(ip(0xa0b0c002), NODE_NONE);
- CNode dummyNode2(id++, NODE_NETWORK, INVALID_SOCKET, addr2, /* nKeyedNetGroupIn */ 1, /* nLocalHostNonceIn */ 1, CAddress(), /* pszDest */ "", ConnectionType::INBOUND, /* inbound_onion */ false);
- dummyNode2.SetCommonVersion(PROTOCOL_VERSION);
- peerLogic->InitializeNode(&dummyNode2);
- dummyNode2.fSuccessfullyConnected = true;
- peerLogic->Misbehaving(dummyNode2.GetId(), DISCOURAGEMENT_THRESHOLD - 1, /* message */ "");
+ BOOST_CHECK(banman->IsDiscouraged(addr[0]));
+ BOOST_CHECK(nodes[0]->fDisconnect);
+ BOOST_CHECK(!banman->IsDiscouraged(other_addr)); // Different address, not discouraged
+
+ nodes[1] = new CNode{id++, NODE_NETWORK, INVALID_SOCKET, addr[1], /* nKeyedNetGroupIn */ 1,
+ /* nLocalHostNonceIn */ 1, CAddress(), /* pszDest */ "",
+ ConnectionType::INBOUND, /* inbound_onion */ false};
+ nodes[1]->SetCommonVersion(PROTOCOL_VERSION);
+ peerLogic->InitializeNode(nodes[1]);
+ nodes[1]->fSuccessfullyConnected = true;
+ connman->AddNode(*nodes[1]);
+ peerLogic->Misbehaving(nodes[1]->GetId(), DISCOURAGEMENT_THRESHOLD - 1, /* message */ "");
{
- LOCK(dummyNode2.cs_sendProcessing);
- BOOST_CHECK(peerLogic->SendMessages(&dummyNode2));
+ LOCK(nodes[1]->cs_sendProcessing);
+ BOOST_CHECK(peerLogic->SendMessages(nodes[1]));
}
- BOOST_CHECK(!banman->IsDiscouraged(addr2)); // 2 not discouraged yet...
- BOOST_CHECK(banman->IsDiscouraged(addr1)); // ... but 1 still should be
- peerLogic->Misbehaving(dummyNode2.GetId(), 1, /* message */ ""); // 2 reaches discouragement threshold
+ // [0] is still discouraged/disconnected.
+ BOOST_CHECK(banman->IsDiscouraged(addr[0]));
+ BOOST_CHECK(nodes[0]->fDisconnect);
+ // [1] is not discouraged/disconnected yet.
+ BOOST_CHECK(!banman->IsDiscouraged(addr[1]));
+ BOOST_CHECK(!nodes[1]->fDisconnect);
+ peerLogic->Misbehaving(nodes[1]->GetId(), 1, /* message */ ""); // [1] reaches discouragement threshold
{
- LOCK(dummyNode2.cs_sendProcessing);
- BOOST_CHECK(peerLogic->SendMessages(&dummyNode2));
+ LOCK(nodes[1]->cs_sendProcessing);
+ BOOST_CHECK(peerLogic->SendMessages(nodes[1]));
}
- BOOST_CHECK(banman->IsDiscouraged(addr1)); // Expect both 1 and 2
- BOOST_CHECK(banman->IsDiscouraged(addr2)); // to be discouraged now
-
- peerLogic->FinalizeNode(dummyNode1);
- peerLogic->FinalizeNode(dummyNode2);
+ // Expect both [0] and [1] to be discouraged/disconnected now.
+ BOOST_CHECK(banman->IsDiscouraged(addr[0]));
+ BOOST_CHECK(nodes[0]->fDisconnect);
+ BOOST_CHECK(banman->IsDiscouraged(addr[1]));
+ BOOST_CHECK(nodes[1]->fDisconnect);
+
+ // Make sure non-IP peers are discouraged and disconnected properly.
+
+ nodes[2] = new CNode{id++, NODE_NETWORK, INVALID_SOCKET, addr[2], /* nKeyedNetGroupIn */ 1,
+ /* nLocalHostNonceIn */ 1, CAddress(), /* pszDest */ "",
+ ConnectionType::OUTBOUND_FULL_RELAY, /* inbound_onion */ false};
+ nodes[2]->SetCommonVersion(PROTOCOL_VERSION);
+ peerLogic->InitializeNode(nodes[2]);
+ nodes[2]->fSuccessfullyConnected = true;
+ connman->AddNode(*nodes[2]);
+ peerLogic->Misbehaving(nodes[2]->GetId(), DISCOURAGEMENT_THRESHOLD, /* message */ "");
+ {
+ LOCK(nodes[2]->cs_sendProcessing);
+ BOOST_CHECK(peerLogic->SendMessages(nodes[2]));
+ }
+ BOOST_CHECK(banman->IsDiscouraged(addr[0]));
+ BOOST_CHECK(banman->IsDiscouraged(addr[1]));
+ BOOST_CHECK(banman->IsDiscouraged(addr[2]));
+ BOOST_CHECK(nodes[0]->fDisconnect);
+ BOOST_CHECK(nodes[1]->fDisconnect);
+ BOOST_CHECK(nodes[2]->fDisconnect);
+
+ for (CNode* node : nodes) {
+ peerLogic->FinalizeNode(*node);
+ }
+ connman->ClearNodes();
}
BOOST_AUTO_TEST_CASE(DoS_bantime)
diff --git a/src/test/fuzz/psbt.cpp b/src/test/fuzz/psbt.cpp
index d1cc6f9c7e..6c62dd6e48 100644
--- a/src/test/fuzz/psbt.cpp
+++ b/src/test/fuzz/psbt.cpp
@@ -2,6 +2,7 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
#include <node/psbt.h>
@@ -9,6 +10,7 @@
#include <pubkey.h>
#include <script/script.h>
#include <streams.h>
+#include <util/check.h>
#include <version.h>
#include <cstdint>
@@ -23,10 +25,10 @@ void initialize_psbt()
FUZZ_TARGET_INIT(psbt, initialize_psbt)
{
+ FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
PartiallySignedTransaction psbt_mut;
- const std::string raw_psbt{buffer.begin(), buffer.end()};
std::string error;
- if (!DecodeRawPSBT(psbt_mut, raw_psbt, error)) {
+ if (!DecodeRawPSBT(psbt_mut, fuzzed_data_provider.ConsumeRandomLengthString(), error)) {
return;
}
const PartiallySignedTransaction psbt = psbt_mut;
@@ -49,6 +51,7 @@ FUZZ_TARGET_INIT(psbt, initialize_psbt)
(void)PSBTInputSigned(input);
(void)input.IsNull();
}
+ (void)CountPSBTUnsignedInputs(psbt);
for (const PSBTOutput& output : psbt.outputs) {
(void)output.IsNull();
@@ -71,6 +74,20 @@ FUZZ_TARGET_INIT(psbt, initialize_psbt)
const PartiallySignedTransaction psbt_from_tx{result};
}
+ PartiallySignedTransaction psbt_merge;
+ if (!DecodeRawPSBT(psbt_merge, fuzzed_data_provider.ConsumeRandomLengthString(), error)) {
+ psbt_merge = psbt;
+ }
+ psbt_mut = psbt;
+ (void)psbt_mut.Merge(psbt_merge);
+ psbt_mut = psbt;
+ (void)CombinePSBTs(psbt_mut, {psbt_mut, psbt_merge});
psbt_mut = psbt;
- (void)psbt_mut.Merge(psbt);
+ for (unsigned int i = 0; i < psbt_merge.tx->vin.size(); ++i) {
+ (void)psbt_mut.AddInput(psbt_merge.tx->vin[i], psbt_merge.inputs[i]);
+ }
+ for (unsigned int i = 0; i < psbt_merge.tx->vout.size(); ++i) {
+ Assert(psbt_mut.AddOutput(psbt_merge.tx->vout[i], psbt_merge.outputs[i]));
+ }
+ psbt_mut.unknown.insert(psbt_merge.unknown.begin(), psbt_merge.unknown.end());
}
diff --git a/src/test/fuzz/script_assets_test_minimizer.cpp b/src/test/fuzz/script_assets_test_minimizer.cpp
index 5f07acbcc7..cec5212f42 100644
--- a/src/test/fuzz/script_assets_test_minimizer.cpp
+++ b/src/test/fuzz/script_assets_test_minimizer.cpp
@@ -161,7 +161,7 @@ void Test(const std::string& str)
tx.vin[idx].scriptWitness = ScriptWitnessFromJSON(test["success"]["witness"]);
PrecomputedTransactionData txdata;
txdata.Init(tx, std::vector<CTxOut>(prevouts));
- MutableTransactionSignatureChecker txcheck(&tx, idx, prevouts[idx].nValue, txdata);
+ MutableTransactionSignatureChecker txcheck(&tx, idx, prevouts[idx].nValue, txdata, MissingDataBehavior::ASSERT_FAIL);
for (const auto flags : ALL_FLAGS) {
// "final": true tests are valid for all flags. Others are only valid with flags that are
// a subset of test_flags.
@@ -176,7 +176,7 @@ void Test(const std::string& str)
tx.vin[idx].scriptWitness = ScriptWitnessFromJSON(test["failure"]["witness"]);
PrecomputedTransactionData txdata;
txdata.Init(tx, std::vector<CTxOut>(prevouts));
- MutableTransactionSignatureChecker txcheck(&tx, idx, prevouts[idx].nValue, txdata);
+ MutableTransactionSignatureChecker txcheck(&tx, idx, prevouts[idx].nValue, txdata, MissingDataBehavior::ASSERT_FAIL);
for (const auto flags : ALL_FLAGS) {
// If a test is supposed to fail with test_flags, it should also fail with any superset thereof.
if ((flags & test_flags) == test_flags) {
diff --git a/src/test/fuzz/script_flags.cpp b/src/test/fuzz/script_flags.cpp
index 387f9c069c..aa911cdeda 100644
--- a/src/test/fuzz/script_flags.cpp
+++ b/src/test/fuzz/script_flags.cpp
@@ -48,7 +48,7 @@ FUZZ_TARGET_INIT(script_flags, initialize_script_flags)
for (unsigned i = 0; i < tx.vin.size(); ++i) {
const CTxOut& prevout = txdata.m_spent_outputs.at(i);
- const TransactionSignatureChecker checker{&tx, i, prevout.nValue, txdata};
+ const TransactionSignatureChecker checker{&tx, i, prevout.nValue, txdata, MissingDataBehavior::ASSERT_FAIL};
ScriptError serror;
const bool ret = VerifyScript(tx.vin.at(i).scriptSig, prevout.scriptPubKey, &tx.vin.at(i).scriptWitness, verify_flags, checker, &serror);
diff --git a/src/test/fuzz/tx_pool.cpp b/src/test/fuzz/tx_pool.cpp
index f84d6702a7..fe8d17b24a 100644
--- a/src/test/fuzz/tx_pool.cpp
+++ b/src/test/fuzz/tx_pool.cpp
@@ -34,7 +34,7 @@ void initialize_tx_pool()
for (int i = 0; i < 2 * COINBASE_MATURITY; ++i) {
CTxIn in = MineBlock(g_setup->m_node, P2WSH_OP_TRUE);
- // Remember the txids to avoid expensive disk acess later on
+ // Remember the txids to avoid expensive disk access later on
auto& outpoints = i < COINBASE_MATURITY ?
g_outpoints_coinbase_init_mature :
g_outpoints_coinbase_init_immature;
diff --git a/src/test/fuzz/util.cpp b/src/test/fuzz/util.cpp
index d786ac1db1..b8d846a995 100644
--- a/src/test/fuzz/util.cpp
+++ b/src/test/fuzz/util.cpp
@@ -7,6 +7,195 @@
#include <util/rbf.h>
#include <version.h>
+FuzzedSock::FuzzedSock(FuzzedDataProvider& fuzzed_data_provider)
+ : m_fuzzed_data_provider{fuzzed_data_provider}
+{
+ m_socket = fuzzed_data_provider.ConsumeIntegralInRange<SOCKET>(INVALID_SOCKET - 1, INVALID_SOCKET);
+}
+
+FuzzedSock::~FuzzedSock()
+{
+ // Sock::~Sock() will be called after FuzzedSock::~FuzzedSock() and it will call
+ // Sock::Reset() (not FuzzedSock::Reset()!) which will call CloseSocket(m_socket).
+ // Avoid closing an arbitrary file descriptor (m_socket is just a random very high number which
+ // theoretically may concide with a real opened file descriptor).
+ Reset();
+}
+
+FuzzedSock& FuzzedSock::operator=(Sock&& other)
+{
+ assert(false && "Move of Sock into FuzzedSock not allowed.");
+ return *this;
+}
+
+void FuzzedSock::Reset()
+{
+ m_socket = INVALID_SOCKET;
+}
+
+ssize_t FuzzedSock::Send(const void* data, size_t len, int flags) const
+{
+ constexpr std::array send_errnos{
+ EACCES,
+ EAGAIN,
+ EALREADY,
+ EBADF,
+ ECONNRESET,
+ EDESTADDRREQ,
+ EFAULT,
+ EINTR,
+ EINVAL,
+ EISCONN,
+ EMSGSIZE,
+ ENOBUFS,
+ ENOMEM,
+ ENOTCONN,
+ ENOTSOCK,
+ EOPNOTSUPP,
+ EPIPE,
+ EWOULDBLOCK,
+ };
+ if (m_fuzzed_data_provider.ConsumeBool()) {
+ return len;
+ }
+ const ssize_t r = m_fuzzed_data_provider.ConsumeIntegralInRange<ssize_t>(-1, len);
+ if (r == -1) {
+ SetFuzzedErrNo(m_fuzzed_data_provider, send_errnos);
+ }
+ return r;
+}
+
+ssize_t FuzzedSock::Recv(void* buf, size_t len, int flags) const
+{
+ // Have a permanent error at recv_errnos[0] because when the fuzzed data is exhausted
+ // SetFuzzedErrNo() will always return the first element and we want to avoid Recv()
+ // returning -1 and setting errno to EAGAIN repeatedly.
+ constexpr std::array recv_errnos{
+ ECONNREFUSED,
+ EAGAIN,
+ EBADF,
+ EFAULT,
+ EINTR,
+ EINVAL,
+ ENOMEM,
+ ENOTCONN,
+ ENOTSOCK,
+ EWOULDBLOCK,
+ };
+ assert(buf != nullptr || len == 0);
+ if (len == 0 || m_fuzzed_data_provider.ConsumeBool()) {
+ const ssize_t r = m_fuzzed_data_provider.ConsumeBool() ? 0 : -1;
+ if (r == -1) {
+ SetFuzzedErrNo(m_fuzzed_data_provider, recv_errnos);
+ }
+ return r;
+ }
+ std::vector<uint8_t> random_bytes;
+ bool pad_to_len_bytes{m_fuzzed_data_provider.ConsumeBool()};
+ if (m_peek_data.has_value()) {
+ // `MSG_PEEK` was used in the preceding `Recv()` call, return `m_peek_data`.
+ random_bytes.assign({m_peek_data.value()});
+ if ((flags & MSG_PEEK) == 0) {
+ m_peek_data.reset();
+ }
+ pad_to_len_bytes = false;
+ } else if ((flags & MSG_PEEK) != 0) {
+ // New call with `MSG_PEEK`.
+ random_bytes = m_fuzzed_data_provider.ConsumeBytes<uint8_t>(1);
+ if (!random_bytes.empty()) {
+ m_peek_data = random_bytes[0];
+ pad_to_len_bytes = false;
+ }
+ } else {
+ random_bytes = m_fuzzed_data_provider.ConsumeBytes<uint8_t>(
+ m_fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, len));
+ }
+ if (random_bytes.empty()) {
+ const ssize_t r = m_fuzzed_data_provider.ConsumeBool() ? 0 : -1;
+ if (r == -1) {
+ SetFuzzedErrNo(m_fuzzed_data_provider, recv_errnos);
+ }
+ return r;
+ }
+ std::memcpy(buf, random_bytes.data(), random_bytes.size());
+ if (pad_to_len_bytes) {
+ if (len > random_bytes.size()) {
+ std::memset((char*)buf + random_bytes.size(), 0, len - random_bytes.size());
+ }
+ return len;
+ }
+ if (m_fuzzed_data_provider.ConsumeBool() && std::getenv("FUZZED_SOCKET_FAKE_LATENCY") != nullptr) {
+ std::this_thread::sleep_for(std::chrono::milliseconds{2});
+ }
+ return random_bytes.size();
+}
+
+int FuzzedSock::Connect(const sockaddr*, socklen_t) const
+{
+ // Have a permanent error at connect_errnos[0] because when the fuzzed data is exhausted
+ // SetFuzzedErrNo() will always return the first element and we want to avoid Connect()
+ // returning -1 and setting errno to EAGAIN repeatedly.
+ constexpr std::array connect_errnos{
+ ECONNREFUSED,
+ EAGAIN,
+ ECONNRESET,
+ EHOSTUNREACH,
+ EINPROGRESS,
+ EINTR,
+ ENETUNREACH,
+ ETIMEDOUT,
+ };
+ if (m_fuzzed_data_provider.ConsumeBool()) {
+ SetFuzzedErrNo(m_fuzzed_data_provider, connect_errnos);
+ return -1;
+ }
+ return 0;
+}
+
+int FuzzedSock::GetSockOpt(int level, int opt_name, void* opt_val, socklen_t* opt_len) const
+{
+ constexpr std::array getsockopt_errnos{
+ ENOMEM,
+ ENOBUFS,
+ };
+ if (m_fuzzed_data_provider.ConsumeBool()) {
+ SetFuzzedErrNo(m_fuzzed_data_provider, getsockopt_errnos);
+ return -1;
+ }
+ if (opt_val == nullptr) {
+ return 0;
+ }
+ std::memcpy(opt_val,
+ ConsumeFixedLengthByteVector(m_fuzzed_data_provider, *opt_len).data(),
+ *opt_len);
+ return 0;
+}
+
+bool FuzzedSock::Wait(std::chrono::milliseconds timeout, Event requested, Event* occurred) const
+{
+ constexpr std::array wait_errnos{
+ EBADF,
+ EINTR,
+ EINVAL,
+ };
+ if (m_fuzzed_data_provider.ConsumeBool()) {
+ SetFuzzedErrNo(m_fuzzed_data_provider, wait_errnos);
+ return false;
+ }
+ if (occurred != nullptr) {
+ *occurred = m_fuzzed_data_provider.ConsumeBool() ? requested : 0;
+ }
+ return true;
+}
+
+bool FuzzedSock::IsConnected(std::string& errmsg) const
+{
+ if (m_fuzzed_data_provider.ConsumeBool()) {
+ return true;
+ }
+ errmsg = "disconnected at random by the fuzzer";
+ return false;
+}
void FillNode(FuzzedDataProvider& fuzzed_data_provider, CNode& node, bool init_version) noexcept
{
diff --git a/src/test/fuzz/util.h b/src/test/fuzz/util.h
index 50d3ac66e5..8f4f87fbdc 100644
--- a/src/test/fuzz/util.h
+++ b/src/test/fuzz/util.h
@@ -575,181 +575,25 @@ class FuzzedSock : public Sock
mutable std::optional<uint8_t> m_peek_data;
public:
- explicit FuzzedSock(FuzzedDataProvider& fuzzed_data_provider) : m_fuzzed_data_provider{fuzzed_data_provider}
- {
- m_socket = fuzzed_data_provider.ConsumeIntegral<SOCKET>();
- }
+ explicit FuzzedSock(FuzzedDataProvider& fuzzed_data_provider);
- ~FuzzedSock() override
- {
- // Sock::~Sock() will be called after FuzzedSock::~FuzzedSock() and it will call
- // Sock::Reset() (not FuzzedSock::Reset()!) which will call CloseSocket(m_socket).
- // Avoid closing an arbitrary file descriptor (m_socket is just a random number which
- // may concide with a real opened file descriptor).
- Reset();
- }
+ ~FuzzedSock() override;
- FuzzedSock& operator=(Sock&& other) override
- {
- assert(false && "Move of Sock into FuzzedSock not allowed.");
- return *this;
- }
+ FuzzedSock& operator=(Sock&& other) override;
- void Reset() override
- {
- m_socket = INVALID_SOCKET;
- }
+ void Reset() override;
- ssize_t Send(const void* data, size_t len, int flags) const override
- {
- constexpr std::array send_errnos{
- EACCES,
- EAGAIN,
- EALREADY,
- EBADF,
- ECONNRESET,
- EDESTADDRREQ,
- EFAULT,
- EINTR,
- EINVAL,
- EISCONN,
- EMSGSIZE,
- ENOBUFS,
- ENOMEM,
- ENOTCONN,
- ENOTSOCK,
- EOPNOTSUPP,
- EPIPE,
- EWOULDBLOCK,
- };
- if (m_fuzzed_data_provider.ConsumeBool()) {
- return len;
- }
- const ssize_t r = m_fuzzed_data_provider.ConsumeIntegralInRange<ssize_t>(-1, len);
- if (r == -1) {
- SetFuzzedErrNo(m_fuzzed_data_provider, send_errnos);
- }
- return r;
- }
+ ssize_t Send(const void* data, size_t len, int flags) const override;
- ssize_t Recv(void* buf, size_t len, int flags) const override
- {
- // Have a permanent error at recv_errnos[0] because when the fuzzed data is exhausted
- // SetFuzzedErrNo() will always return the first element and we want to avoid Recv()
- // returning -1 and setting errno to EAGAIN repeatedly.
- constexpr std::array recv_errnos{
- ECONNREFUSED,
- EAGAIN,
- EBADF,
- EFAULT,
- EINTR,
- EINVAL,
- ENOMEM,
- ENOTCONN,
- ENOTSOCK,
- EWOULDBLOCK,
- };
- assert(buf != nullptr || len == 0);
- if (len == 0 || m_fuzzed_data_provider.ConsumeBool()) {
- const ssize_t r = m_fuzzed_data_provider.ConsumeBool() ? 0 : -1;
- if (r == -1) {
- SetFuzzedErrNo(m_fuzzed_data_provider, recv_errnos);
- }
- return r;
- }
- std::vector<uint8_t> random_bytes;
- bool pad_to_len_bytes{m_fuzzed_data_provider.ConsumeBool()};
- if (m_peek_data.has_value()) {
- // `MSG_PEEK` was used in the preceding `Recv()` call, return `m_peek_data`.
- random_bytes.assign({m_peek_data.value()});
- if ((flags & MSG_PEEK) == 0) {
- m_peek_data.reset();
- }
- pad_to_len_bytes = false;
- } else if ((flags & MSG_PEEK) != 0) {
- // New call with `MSG_PEEK`.
- random_bytes = m_fuzzed_data_provider.ConsumeBytes<uint8_t>(1);
- if (!random_bytes.empty()) {
- m_peek_data = random_bytes[0];
- pad_to_len_bytes = false;
- }
- } else {
- random_bytes = m_fuzzed_data_provider.ConsumeBytes<uint8_t>(
- m_fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, len));
- }
- if (random_bytes.empty()) {
- const ssize_t r = m_fuzzed_data_provider.ConsumeBool() ? 0 : -1;
- if (r == -1) {
- SetFuzzedErrNo(m_fuzzed_data_provider, recv_errnos);
- }
- return r;
- }
- std::memcpy(buf, random_bytes.data(), random_bytes.size());
- if (pad_to_len_bytes) {
- if (len > random_bytes.size()) {
- std::memset((char*)buf + random_bytes.size(), 0, len - random_bytes.size());
- }
- return len;
- }
- if (m_fuzzed_data_provider.ConsumeBool() && std::getenv("FUZZED_SOCKET_FAKE_LATENCY") != nullptr) {
- std::this_thread::sleep_for(std::chrono::milliseconds{2});
- }
- return random_bytes.size();
- }
+ ssize_t Recv(void* buf, size_t len, int flags) const override;
- int Connect(const sockaddr*, socklen_t) const override
- {
- // Have a permanent error at connect_errnos[0] because when the fuzzed data is exhausted
- // SetFuzzedErrNo() will always return the first element and we want to avoid Connect()
- // returning -1 and setting errno to EAGAIN repeatedly.
- constexpr std::array connect_errnos{
- ECONNREFUSED,
- EAGAIN,
- ECONNRESET,
- EHOSTUNREACH,
- EINPROGRESS,
- EINTR,
- ENETUNREACH,
- ETIMEDOUT,
- };
- if (m_fuzzed_data_provider.ConsumeBool()) {
- SetFuzzedErrNo(m_fuzzed_data_provider, connect_errnos);
- return -1;
- }
- return 0;
- }
+ int Connect(const sockaddr*, socklen_t) const override;
- int GetSockOpt(int level, int opt_name, void* opt_val, socklen_t* opt_len) const override
- {
- constexpr std::array getsockopt_errnos{
- ENOMEM,
- ENOBUFS,
- };
- if (m_fuzzed_data_provider.ConsumeBool()) {
- SetFuzzedErrNo(m_fuzzed_data_provider, getsockopt_errnos);
- return -1;
- }
- if (opt_val == nullptr) {
- return 0;
- }
- std::memcpy(opt_val,
- ConsumeFixedLengthByteVector(m_fuzzed_data_provider, *opt_len).data(),
- *opt_len);
- return 0;
- }
+ int GetSockOpt(int level, int opt_name, void* opt_val, socklen_t* opt_len) const override;
- bool Wait(std::chrono::milliseconds timeout, Event requested, Event* occurred = nullptr) const override
- {
- return m_fuzzed_data_provider.ConsumeBool();
- }
+ bool Wait(std::chrono::milliseconds timeout, Event requested, Event* occurred = nullptr) const override;
- bool IsConnected(std::string& errmsg) const override {
- if (m_fuzzed_data_provider.ConsumeBool()) {
- return true;
- }
- errmsg = "disconnected at random by the fuzzer";
- return false;
- }
+ bool IsConnected(std::string& errmsg) const override;
};
[[nodiscard]] inline FuzzedSock ConsumeSock(FuzzedDataProvider& fuzzed_data_provider)
diff --git a/src/test/fuzz/versionbits.cpp b/src/test/fuzz/versionbits.cpp
index 88c1a1a9cb..9186821836 100644
--- a/src/test/fuzz/versionbits.cpp
+++ b/src/test/fuzz/versionbits.cpp
@@ -29,14 +29,16 @@ public:
const int64_t m_end;
const int m_period;
const int m_threshold;
+ const int m_min_activation_height;
const int m_bit;
- TestConditionChecker(int64_t begin, int64_t end, int period, int threshold, int bit)
- : m_begin{begin}, m_end{end}, m_period{period}, m_threshold{threshold}, m_bit{bit}
+ TestConditionChecker(int64_t begin, int64_t end, int period, int threshold, int min_activation_height, int bit)
+ : m_begin{begin}, m_end{end}, m_period{period}, m_threshold{threshold}, m_min_activation_height{min_activation_height}, m_bit{bit}
{
assert(m_period > 0);
assert(0 <= m_threshold && m_threshold <= m_period);
assert(0 <= m_bit && m_bit < 32 && m_bit < VERSIONBITS_NUM_BITS);
+ assert(0 <= m_min_activation_height);
}
bool Condition(const CBlockIndex* pindex, const Consensus::Params& params) const override { return Condition(pindex->nVersion); }
@@ -44,6 +46,7 @@ public:
int64_t EndTime(const Consensus::Params& params) const override { return m_end; }
int Period(const Consensus::Params& params) const override { return m_period; }
int Threshold(const Consensus::Params& params) const override { return m_threshold; }
+ int MinActivationHeight(const Consensus::Params& params) const override { return m_min_activation_height; }
ThresholdState GetStateFor(const CBlockIndex* pindexPrev) const { return AbstractThresholdConditionChecker::GetStateFor(pindexPrev, dummy_params, m_cache); }
int GetStateSinceHeightFor(const CBlockIndex* pindexPrev) const { return AbstractThresholdConditionChecker::GetStateSinceHeightFor(pindexPrev, dummy_params, m_cache); }
@@ -144,32 +147,27 @@ FUZZ_TARGET_INIT(versionbits, initialize)
// pick the timestamp to switch based on a block
// note states will change *after* these blocks because mediantime lags
int start_block = fuzzed_data_provider.ConsumeIntegralInRange<int>(0, period * (max_periods - 3));
- int end_block = fuzzed_data_provider.ConsumeIntegralInRange<int>(start_block, period * (max_periods - 3));
+ int end_block = fuzzed_data_provider.ConsumeIntegralInRange<int>(0, period * (max_periods - 3));
start_time = block_start_time + start_block * interval;
timeout = block_start_time + end_block * interval;
- assert(start_time <= timeout);
-
// allow for times to not exactly match a block
if (fuzzed_data_provider.ConsumeBool()) start_time += interval / 2;
if (fuzzed_data_provider.ConsumeBool()) timeout += interval / 2;
-
- // this may make timeout too early; if so, don't run the test
- if (start_time > timeout) return;
} else {
if (fuzzed_data_provider.ConsumeBool()) {
start_time = Consensus::BIP9Deployment::ALWAYS_ACTIVE;
- timeout = Consensus::BIP9Deployment::NO_TIMEOUT;
always_active_test = true;
} else {
- start_time = 1199145601; // January 1, 2008
- timeout = 1230767999; // December 31, 2008
+ start_time = Consensus::BIP9Deployment::NEVER_ACTIVE;
never_active_test = true;
}
+ timeout = fuzzed_data_provider.ConsumeBool() ? Consensus::BIP9Deployment::NO_TIMEOUT : fuzzed_data_provider.ConsumeIntegral<int64_t>();
}
+ int min_activation = fuzzed_data_provider.ConsumeIntegralInRange<int>(0, period * max_periods);
- TestConditionChecker checker(start_time, timeout, period, threshold, bit);
+ TestConditionChecker checker(start_time, timeout, period, threshold, min_activation, bit);
// Early exit if the versions don't signal sensibly for the deployment
if (!checker.Condition(ver_signal)) return;
@@ -294,28 +292,35 @@ FUZZ_TARGET_INIT(versionbits, initialize)
assert(since == 0);
assert(exp_state == ThresholdState::DEFINED);
assert(current_block->GetMedianTimePast() < checker.m_begin);
- assert(current_block->GetMedianTimePast() < checker.m_end);
break;
case ThresholdState::STARTED:
assert(current_block->GetMedianTimePast() >= checker.m_begin);
- assert(current_block->GetMedianTimePast() < checker.m_end);
if (exp_state == ThresholdState::STARTED) {
assert(blocks_sig < threshold);
+ assert(current_block->GetMedianTimePast() < checker.m_end);
} else {
assert(exp_state == ThresholdState::DEFINED);
}
break;
case ThresholdState::LOCKED_IN:
- assert(exp_state == ThresholdState::STARTED);
- assert(current_block->GetMedianTimePast() < checker.m_end);
- assert(blocks_sig >= threshold);
+ if (exp_state == ThresholdState::LOCKED_IN) {
+ assert(current_block->nHeight + 1 < min_activation);
+ } else {
+ assert(exp_state == ThresholdState::STARTED);
+ assert(blocks_sig >= threshold);
+ }
break;
case ThresholdState::ACTIVE:
+ assert(always_active_test || min_activation <= current_block->nHeight + 1);
assert(exp_state == ThresholdState::ACTIVE || exp_state == ThresholdState::LOCKED_IN);
break;
case ThresholdState::FAILED:
- assert(current_block->GetMedianTimePast() >= checker.m_end);
- assert(exp_state != ThresholdState::LOCKED_IN && exp_state != ThresholdState::ACTIVE);
+ assert(never_active_test || current_block->GetMedianTimePast() >= checker.m_end);
+ if (exp_state == ThresholdState::STARTED) {
+ assert(blocks_sig < threshold);
+ } else {
+ assert(exp_state == ThresholdState::FAILED);
+ }
break;
default:
assert(false);
@@ -326,26 +331,20 @@ FUZZ_TARGET_INIT(versionbits, initialize)
assert(state == ThresholdState::ACTIVE || state == ThresholdState::FAILED);
}
- // "always active" has additional restrictions
if (always_active_test) {
+ // "always active" has additional restrictions
assert(state == ThresholdState::ACTIVE);
assert(exp_state == ThresholdState::ACTIVE);
assert(since == 0);
+ } else if (never_active_test) {
+ // "never active" does too
+ assert(state == ThresholdState::FAILED);
+ assert(exp_state == ThresholdState::FAILED);
+ assert(since == 0);
} else {
- // except for always active, the initial state is always DEFINED
+ // for signalled deployments, the initial state is always DEFINED
assert(since > 0 || state == ThresholdState::DEFINED);
assert(exp_since > 0 || exp_state == ThresholdState::DEFINED);
}
-
- // "never active" does too
- if (never_active_test) {
- assert(state == ThresholdState::FAILED);
- assert(since == period);
- if (exp_since == 0) {
- assert(exp_state == ThresholdState::DEFINED);
- } else {
- assert(exp_state == ThresholdState::FAILED);
- }
- }
}
} // namespace
diff --git a/src/test/logging_tests.cpp b/src/test/logging_tests.cpp
index 25655b8894..e99c6e0fc8 100644
--- a/src/test/logging_tests.cpp
+++ b/src/test/logging_tests.cpp
@@ -14,7 +14,6 @@ BOOST_FIXTURE_TEST_SUITE(logging_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(logging_timer)
{
-
SetMockTime(1);
auto sec_timer = BCLog::Timer<std::chrono::seconds>("tests", "end_msg");
SetMockTime(2);
@@ -29,8 +28,6 @@ BOOST_AUTO_TEST_CASE(logging_timer)
auto micro_timer = BCLog::Timer<std::chrono::microseconds>("tests", "end_msg");
SetMockTime(2);
BOOST_CHECK_EQUAL(micro_timer.LogMsg("test micros"), "tests: test micros (1000000.00μs)");
-
- SetMockTime(0);
}
BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/mempool_tests.cpp b/src/test/mempool_tests.cpp
index 38fed51af2..bf36f8a6c9 100644
--- a/src/test/mempool_tests.cpp
+++ b/src/test/mempool_tests.cpp
@@ -571,8 +571,6 @@ BOOST_AUTO_TEST_CASE(MempoolSizeLimitTest)
SetMockTime(42 + 8*CTxMemPool::ROLLING_FEE_HALFLIFE + CTxMemPool::ROLLING_FEE_HALFLIFE/2 + CTxMemPool::ROLLING_FEE_HALFLIFE/4);
BOOST_CHECK_EQUAL(pool.GetMinFee(1).GetFeePerK(), 0);
// ... unless it has gone all the way to 0 (after getting past 1000/2)
-
- SetMockTime(0);
}
inline CTransactionRef make_tx(std::vector<CAmount>&& output_values, std::vector<CTransactionRef>&& inputs=std::vector<CTransactionRef>(), std::vector<uint32_t>&& input_indices=std::vector<uint32_t>())
diff --git a/src/test/multisig_tests.cpp b/src/test/multisig_tests.cpp
index e14d2dd72d..39f9b7ee28 100644
--- a/src/test/multisig_tests.cpp
+++ b/src/test/multisig_tests.cpp
@@ -77,20 +77,20 @@ BOOST_AUTO_TEST_CASE(multisig_verify)
keys.assign(1,key[0]);
keys.push_back(key[1]);
s = sign_multisig(a_and_b, keys, CTransaction(txTo[0]), 0);
- BOOST_CHECK(VerifyScript(s, a_and_b, nullptr, flags, MutableTransactionSignatureChecker(&txTo[0], 0, amount), &err));
+ BOOST_CHECK(VerifyScript(s, a_and_b, nullptr, flags, MutableTransactionSignatureChecker(&txTo[0], 0, amount, MissingDataBehavior::ASSERT_FAIL), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
for (int i = 0; i < 4; i++)
{
keys.assign(1,key[i]);
s = sign_multisig(a_and_b, keys, CTransaction(txTo[0]), 0);
- BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, nullptr, flags, MutableTransactionSignatureChecker(&txTo[0], 0, amount), &err), strprintf("a&b 1: %d", i));
+ BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, nullptr, flags, MutableTransactionSignatureChecker(&txTo[0], 0, amount, MissingDataBehavior::ASSERT_FAIL), &err), strprintf("a&b 1: %d", i));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_INVALID_STACK_OPERATION, ScriptErrorString(err));
keys.assign(1,key[1]);
keys.push_back(key[i]);
s = sign_multisig(a_and_b, keys, CTransaction(txTo[0]), 0);
- BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, nullptr, flags, MutableTransactionSignatureChecker(&txTo[0], 0, amount), &err), strprintf("a&b 2: %d", i));
+ BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, nullptr, flags, MutableTransactionSignatureChecker(&txTo[0], 0, amount, MissingDataBehavior::ASSERT_FAIL), &err), strprintf("a&b 2: %d", i));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
}
@@ -101,18 +101,18 @@ BOOST_AUTO_TEST_CASE(multisig_verify)
s = sign_multisig(a_or_b, keys, CTransaction(txTo[1]), 0);
if (i == 0 || i == 1)
{
- BOOST_CHECK_MESSAGE(VerifyScript(s, a_or_b, nullptr, flags, MutableTransactionSignatureChecker(&txTo[1], 0, amount), &err), strprintf("a|b: %d", i));
+ BOOST_CHECK_MESSAGE(VerifyScript(s, a_or_b, nullptr, flags, MutableTransactionSignatureChecker(&txTo[1], 0, amount, MissingDataBehavior::ASSERT_FAIL), &err), strprintf("a|b: %d", i));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
}
else
{
- BOOST_CHECK_MESSAGE(!VerifyScript(s, a_or_b, nullptr, flags, MutableTransactionSignatureChecker(&txTo[1], 0, amount), &err), strprintf("a|b: %d", i));
+ BOOST_CHECK_MESSAGE(!VerifyScript(s, a_or_b, nullptr, flags, MutableTransactionSignatureChecker(&txTo[1], 0, amount, MissingDataBehavior::ASSERT_FAIL), &err), strprintf("a|b: %d", i));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
}
}
s.clear();
s << OP_0 << OP_1;
- BOOST_CHECK(!VerifyScript(s, a_or_b, nullptr, flags, MutableTransactionSignatureChecker(&txTo[1], 0, amount), &err));
+ BOOST_CHECK(!VerifyScript(s, a_or_b, nullptr, flags, MutableTransactionSignatureChecker(&txTo[1], 0, amount, MissingDataBehavior::ASSERT_FAIL), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_SIG_DER, ScriptErrorString(err));
@@ -124,12 +124,12 @@ BOOST_AUTO_TEST_CASE(multisig_verify)
s = sign_multisig(escrow, keys, CTransaction(txTo[2]), 0);
if (i < j && i < 3 && j < 3)
{
- BOOST_CHECK_MESSAGE(VerifyScript(s, escrow, nullptr, flags, MutableTransactionSignatureChecker(&txTo[2], 0, amount), &err), strprintf("escrow 1: %d %d", i, j));
+ BOOST_CHECK_MESSAGE(VerifyScript(s, escrow, nullptr, flags, MutableTransactionSignatureChecker(&txTo[2], 0, amount, MissingDataBehavior::ASSERT_FAIL), &err), strprintf("escrow 1: %d %d", i, j));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
}
else
{
- BOOST_CHECK_MESSAGE(!VerifyScript(s, escrow, nullptr, flags, MutableTransactionSignatureChecker(&txTo[2], 0, amount), &err), strprintf("escrow 2: %d %d", i, j));
+ BOOST_CHECK_MESSAGE(!VerifyScript(s, escrow, nullptr, flags, MutableTransactionSignatureChecker(&txTo[2], 0, amount, MissingDataBehavior::ASSERT_FAIL), &err), strprintf("escrow 2: %d %d", i, j));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
}
}
diff --git a/src/test/net_tests.cpp b/src/test/net_tests.cpp
index 8eab26f3d5..1c397481dc 100644
--- a/src/test/net_tests.cpp
+++ b/src/test/net_tests.cpp
@@ -307,9 +307,6 @@ BOOST_AUTO_TEST_CASE(cnetaddr_basic)
BOOST_REQUIRE(addr.IsValid());
BOOST_REQUIRE(addr.IsIPv6());
BOOST_CHECK(!addr.IsBindAny());
- const std::string addr_str{addr.ToString()};
- BOOST_CHECK(addr_str == scoped_addr || addr_str == "fe80:0:0:0:0:0:0:1");
- // The fallback case "fe80:0:0:0:0:0:0:1" is needed for macOS 10.14/10.15 and (probably) later.
// Test that the delimiter "%" and default zone id of 0 can be omitted for the default scope.
BOOST_REQUIRE(LookupHost(link_local + "%0", addr, false));
BOOST_REQUIRE(addr.IsValid());
diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp
index 67e70b3bc3..67fbc9f8a2 100644
--- a/src/test/rpc_tests.cpp
+++ b/src/test/rpc_tests.cpp
@@ -33,8 +33,8 @@ UniValue RPCTestingSetup::CallRPC(std::string args)
boost::split(vArgs, args, boost::is_any_of(" \t"));
std::string strMethod = vArgs[0];
vArgs.erase(vArgs.begin());
- std::any context{&m_node};
- JSONRPCRequest request(context);
+ JSONRPCRequest request;
+ request.context = &m_node;
request.strMethod = strMethod;
request.params = RPCConvertValues(strMethod, vArgs);
if (RPCIsInWarmup(nullptr)) SetRPCWarmupFinished();
@@ -269,22 +269,29 @@ BOOST_AUTO_TEST_CASE(rpc_ban)
ar = r.get_array();
o1 = ar[0].get_obj();
adr = find_value(o1, "address");
- UniValue banned_until = find_value(o1, "banned_until");
+ int64_t banned_until{find_value(o1, "banned_until").get_int64()};
BOOST_CHECK_EQUAL(adr.get_str(), "127.0.0.0/24");
- BOOST_CHECK_EQUAL(banned_until.get_int64(), 9907731200); // absolute time check
+ BOOST_CHECK_EQUAL(banned_until, 9907731200); // absolute time check
BOOST_CHECK_NO_THROW(CallRPC(std::string("clearbanned")));
+ auto now = 10'000s;
+ SetMockTime(now);
BOOST_CHECK_NO_THROW(r = CallRPC(std::string("setban 127.0.0.0/24 add 200")));
+ SetMockTime(now += 2s);
+ const int64_t time_remaining_expected{198};
BOOST_CHECK_NO_THROW(r = CallRPC(std::string("listbanned")));
ar = r.get_array();
o1 = ar[0].get_obj();
adr = find_value(o1, "address");
- banned_until = find_value(o1, "banned_until");
+ banned_until = find_value(o1, "banned_until").get_int64();
+ const int64_t ban_created{find_value(o1, "ban_created").get_int64()};
+ const int64_t ban_duration{find_value(o1, "ban_duration").get_int64()};
+ const int64_t time_remaining{find_value(o1, "time_remaining").get_int64()};
BOOST_CHECK_EQUAL(adr.get_str(), "127.0.0.0/24");
- int64_t now = GetTime();
- BOOST_CHECK(banned_until.get_int64() > now);
- BOOST_CHECK(banned_until.get_int64()-now <= 200);
+ BOOST_CHECK_EQUAL(banned_until, time_remaining_expected + now.count());
+ BOOST_CHECK_EQUAL(ban_duration, banned_until - ban_created);
+ BOOST_CHECK_EQUAL(time_remaining, time_remaining_expected);
// must throw an exception because 127.0.0.1 is in already banned subnet range
BOOST_CHECK_THROW(r = CallRPC(std::string("setban 127.0.0.1 add")), std::runtime_error);
@@ -431,4 +438,39 @@ BOOST_AUTO_TEST_CASE(rpc_getblockstats_calculate_percentiles_by_weight)
}
}
+BOOST_AUTO_TEST_CASE(help_example)
+{
+ // test different argument types
+ const RPCArgList& args = {{"foo", "bar"}, {"b", true}, {"n", 1}};
+ BOOST_CHECK_EQUAL(HelpExampleCliNamed("test", args), "> bitcoin-cli -named test foo=bar b=true n=1\n");
+ BOOST_CHECK_EQUAL(HelpExampleRpcNamed("test", args), "> curl --user myusername --data-binary '{\"jsonrpc\": \"1.0\", \"id\": \"curltest\", \"method\": \"test\", \"params\": {\"foo\":\"bar\",\"b\":true,\"n\":1}}' -H 'content-type: text/plain;' http://127.0.0.1:8332/\n");
+
+ // test shell escape
+ BOOST_CHECK_EQUAL(HelpExampleCliNamed("test", {{"foo", "b'ar"}}), "> bitcoin-cli -named test foo='b'''ar'\n");
+ BOOST_CHECK_EQUAL(HelpExampleCliNamed("test", {{"foo", "b\"ar"}}), "> bitcoin-cli -named test foo='b\"ar'\n");
+ BOOST_CHECK_EQUAL(HelpExampleCliNamed("test", {{"foo", "b ar"}}), "> bitcoin-cli -named test foo='b ar'\n");
+
+ // test object params
+ UniValue obj_value(UniValue::VOBJ);
+ obj_value.pushKV("foo", "bar");
+ obj_value.pushKV("b", false);
+ obj_value.pushKV("n", 1);
+ BOOST_CHECK_EQUAL(HelpExampleCliNamed("test", {{"name", obj_value}}), "> bitcoin-cli -named test name='{\"foo\":\"bar\",\"b\":false,\"n\":1}'\n");
+ BOOST_CHECK_EQUAL(HelpExampleRpcNamed("test", {{"name", obj_value}}), "> curl --user myusername --data-binary '{\"jsonrpc\": \"1.0\", \"id\": \"curltest\", \"method\": \"test\", \"params\": {\"name\":{\"foo\":\"bar\",\"b\":false,\"n\":1}}}' -H 'content-type: text/plain;' http://127.0.0.1:8332/\n");
+
+ // test array params
+ UniValue arr_value(UniValue::VARR);
+ arr_value.push_back("bar");
+ arr_value.push_back(false);
+ arr_value.push_back(1);
+ BOOST_CHECK_EQUAL(HelpExampleCliNamed("test", {{"name", arr_value}}), "> bitcoin-cli -named test name='[\"bar\",false,1]'\n");
+ BOOST_CHECK_EQUAL(HelpExampleRpcNamed("test", {{"name", arr_value}}), "> curl --user myusername --data-binary '{\"jsonrpc\": \"1.0\", \"id\": \"curltest\", \"method\": \"test\", \"params\": {\"name\":[\"bar\",false,1]}}' -H 'content-type: text/plain;' http://127.0.0.1:8332/\n");
+
+ // test types don't matter for shell
+ BOOST_CHECK_EQUAL(HelpExampleCliNamed("foo", {{"arg", true}}), HelpExampleCliNamed("foo", {{"arg", "true"}}));
+
+ // test types matter for Rpc
+ BOOST_CHECK_NE(HelpExampleRpcNamed("foo", {{"arg", true}}), HelpExampleRpcNamed("foo", {{"arg", "true"}}));
+}
+
BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/script_p2sh_tests.cpp b/src/test/script_p2sh_tests.cpp
index 856ec6346d..d8a44a65dd 100644
--- a/src/test/script_p2sh_tests.cpp
+++ b/src/test/script_p2sh_tests.cpp
@@ -41,7 +41,7 @@ Verify(const CScript& scriptSig, const CScript& scriptPubKey, bool fStrict, Scri
txTo.vin[0].scriptSig = scriptSig;
txTo.vout[0].nValue = 1;
- return VerifyScript(scriptSig, scriptPubKey, nullptr, fStrict ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE, MutableTransactionSignatureChecker(&txTo, 0, txFrom.vout[0].nValue), &err);
+ return VerifyScript(scriptSig, scriptPubKey, nullptr, fStrict ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE, MutableTransactionSignatureChecker(&txTo, 0, txFrom.vout[0].nValue, MissingDataBehavior::ASSERT_FAIL), &err);
}
diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp
index 25ca171b33..14cfadf75d 100644
--- a/src/test/script_tests.cpp
+++ b/src/test/script_tests.cpp
@@ -135,7 +135,7 @@ void DoTest(const CScript& scriptPubKey, const CScript& scriptSig, const CScript
const CTransaction txCredit{BuildCreditingTransaction(scriptPubKey, nValue)};
CMutableTransaction tx = BuildSpendingTransaction(scriptSig, scriptWitness, txCredit);
CMutableTransaction tx2 = tx;
- BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, &scriptWitness, flags, MutableTransactionSignatureChecker(&tx, 0, txCredit.vout[0].nValue), &err) == expect, message);
+ BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, &scriptWitness, flags, MutableTransactionSignatureChecker(&tx, 0, txCredit.vout[0].nValue, MissingDataBehavior::ASSERT_FAIL), &err) == expect, message);
BOOST_CHECK_MESSAGE(err == scriptError, FormatScriptError(err) + " where " + FormatScriptError((ScriptError_t)scriptError) + " expected: " + message);
// Verify that removing flags from a passing test or adding flags to a failing test does not change the result.
@@ -145,7 +145,7 @@ void DoTest(const CScript& scriptPubKey, const CScript& scriptSig, const CScript
// Weed out some invalid flag combinations.
if (combined_flags & SCRIPT_VERIFY_CLEANSTACK && ~combined_flags & (SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS)) continue;
if (combined_flags & SCRIPT_VERIFY_WITNESS && ~combined_flags & SCRIPT_VERIFY_P2SH) continue;
- BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, &scriptWitness, combined_flags, MutableTransactionSignatureChecker(&tx, 0, txCredit.vout[0].nValue), &err) == expect, message + strprintf(" (with flags %x)", combined_flags));
+ BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, &scriptWitness, combined_flags, MutableTransactionSignatureChecker(&tx, 0, txCredit.vout[0].nValue, MissingDataBehavior::ASSERT_FAIL), &err) == expect, message + strprintf(" (with flags %x)", combined_flags));
}
#if defined(HAVE_CONSENSUS_LIB)
@@ -1071,18 +1071,18 @@ BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG12)
CMutableTransaction txTo12 = BuildSpendingTransaction(CScript(), CScriptWitness(), txFrom12);
CScript goodsig1 = sign_multisig(scriptPubKey12, key1, CTransaction(txTo12));
- BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey12, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue), &err));
+ BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey12, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue, MissingDataBehavior::ASSERT_FAIL), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
txTo12.vout[0].nValue = 2;
- BOOST_CHECK(!VerifyScript(goodsig1, scriptPubKey12, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue), &err));
+ BOOST_CHECK(!VerifyScript(goodsig1, scriptPubKey12, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue, MissingDataBehavior::ASSERT_FAIL), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
CScript goodsig2 = sign_multisig(scriptPubKey12, key2, CTransaction(txTo12));
- BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey12, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue), &err));
+ BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey12, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue, MissingDataBehavior::ASSERT_FAIL), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
CScript badsig1 = sign_multisig(scriptPubKey12, key3, CTransaction(txTo12));
- BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey12, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue), &err));
+ BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey12, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue, MissingDataBehavior::ASSERT_FAIL), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
}
@@ -1104,54 +1104,54 @@ BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG23)
std::vector<CKey> keys;
keys.push_back(key1); keys.push_back(key2);
CScript goodsig1 = sign_multisig(scriptPubKey23, keys, CTransaction(txTo23));
- BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey23, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err));
+ BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey23, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue, MissingDataBehavior::ASSERT_FAIL), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
keys.clear();
keys.push_back(key1); keys.push_back(key3);
CScript goodsig2 = sign_multisig(scriptPubKey23, keys, CTransaction(txTo23));
- BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey23, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err));
+ BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey23, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue, MissingDataBehavior::ASSERT_FAIL), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
keys.clear();
keys.push_back(key2); keys.push_back(key3);
CScript goodsig3 = sign_multisig(scriptPubKey23, keys, CTransaction(txTo23));
- BOOST_CHECK(VerifyScript(goodsig3, scriptPubKey23, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err));
+ BOOST_CHECK(VerifyScript(goodsig3, scriptPubKey23, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue, MissingDataBehavior::ASSERT_FAIL), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
keys.clear();
keys.push_back(key2); keys.push_back(key2); // Can't re-use sig
CScript badsig1 = sign_multisig(scriptPubKey23, keys, CTransaction(txTo23));
- BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey23, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err));
+ BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey23, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue, MissingDataBehavior::ASSERT_FAIL), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
keys.clear();
keys.push_back(key2); keys.push_back(key1); // sigs must be in correct order
CScript badsig2 = sign_multisig(scriptPubKey23, keys, CTransaction(txTo23));
- BOOST_CHECK(!VerifyScript(badsig2, scriptPubKey23, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err));
+ BOOST_CHECK(!VerifyScript(badsig2, scriptPubKey23, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue, MissingDataBehavior::ASSERT_FAIL), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
keys.clear();
keys.push_back(key3); keys.push_back(key2); // sigs must be in correct order
CScript badsig3 = sign_multisig(scriptPubKey23, keys, CTransaction(txTo23));
- BOOST_CHECK(!VerifyScript(badsig3, scriptPubKey23, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err));
+ BOOST_CHECK(!VerifyScript(badsig3, scriptPubKey23, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue, MissingDataBehavior::ASSERT_FAIL), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
keys.clear();
keys.push_back(key4); keys.push_back(key2); // sigs must match pubkeys
CScript badsig4 = sign_multisig(scriptPubKey23, keys, CTransaction(txTo23));
- BOOST_CHECK(!VerifyScript(badsig4, scriptPubKey23, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err));
+ BOOST_CHECK(!VerifyScript(badsig4, scriptPubKey23, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue, MissingDataBehavior::ASSERT_FAIL), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
keys.clear();
keys.push_back(key1); keys.push_back(key4); // sigs must match pubkeys
CScript badsig5 = sign_multisig(scriptPubKey23, keys, CTransaction(txTo23));
- BOOST_CHECK(!VerifyScript(badsig5, scriptPubKey23, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err));
+ BOOST_CHECK(!VerifyScript(badsig5, scriptPubKey23, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue, MissingDataBehavior::ASSERT_FAIL), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
keys.clear(); // Must have signatures
CScript badsig6 = sign_multisig(scriptPubKey23, keys, CTransaction(txTo23));
- BOOST_CHECK(!VerifyScript(badsig6, scriptPubKey23, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err));
+ BOOST_CHECK(!VerifyScript(badsig6, scriptPubKey23, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue, MissingDataBehavior::ASSERT_FAIL), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_INVALID_STACK_OPERATION, ScriptErrorString(err));
}
diff --git a/src/test/sigopcount_tests.cpp b/src/test/sigopcount_tests.cpp
index 7e5274450d..12fc575c1e 100644
--- a/src/test/sigopcount_tests.cpp
+++ b/src/test/sigopcount_tests.cpp
@@ -71,7 +71,7 @@ static ScriptError VerifyWithFlag(const CTransaction& output, const CMutableTran
{
ScriptError error;
CTransaction inputi(input);
- bool ret = VerifyScript(inputi.vin[0].scriptSig, output.vout[0].scriptPubKey, &inputi.vin[0].scriptWitness, flags, TransactionSignatureChecker(&inputi, 0, output.vout[0].nValue), &error);
+ bool ret = VerifyScript(inputi.vin[0].scriptSig, output.vout[0].scriptPubKey, &inputi.vin[0].scriptWitness, flags, TransactionSignatureChecker(&inputi, 0, output.vout[0].nValue, MissingDataBehavior::ASSERT_FAIL), &error);
BOOST_CHECK((ret == true) == (error == SCRIPT_ERR_OK));
return error;
diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp
index 8f1d99b199..aaa6caa4f1 100644
--- a/src/test/transaction_tests.cpp
+++ b/src/test/transaction_tests.cpp
@@ -108,7 +108,7 @@ bool CheckTxScripts(const CTransaction& tx, const std::map<COutPoint, CScript>&
const CAmount amount = map_prevout_values.count(input.prevout) ? map_prevout_values.at(input.prevout) : 0;
try {
tx_valid = VerifyScript(input.scriptSig, map_prevout_scriptPubKeys.at(input.prevout),
- &input.scriptWitness, flags, TransactionSignatureChecker(&tx, i, amount, txdata), &err);
+ &input.scriptWitness, flags, TransactionSignatureChecker(&tx, i, amount, txdata, MissingDataBehavior::ASSERT_FAIL), &err);
} catch (...) {
BOOST_ERROR("Bad test: " << strTest);
return true; // The test format is bad and an error is thrown. Return true to silence further error.
@@ -427,7 +427,7 @@ static void CheckWithFlag(const CTransactionRef& output, const CMutableTransacti
{
ScriptError error;
CTransaction inputi(input);
- bool ret = VerifyScript(inputi.vin[0].scriptSig, output->vout[0].scriptPubKey, &inputi.vin[0].scriptWitness, flags, TransactionSignatureChecker(&inputi, 0, output->vout[0].nValue), &error);
+ bool ret = VerifyScript(inputi.vin[0].scriptSig, output->vout[0].scriptPubKey, &inputi.vin[0].scriptWitness, flags, TransactionSignatureChecker(&inputi, 0, output->vout[0].nValue, MissingDataBehavior::ASSERT_FAIL), &error);
assert(ret == success);
}
diff --git a/src/test/util/blockfilter.cpp b/src/test/util/blockfilter.cpp
index bccff5e5a6..b8ab9d2344 100644
--- a/src/test/util/blockfilter.cpp
+++ b/src/test/util/blockfilter.cpp
@@ -5,6 +5,7 @@
#include <test/util/blockfilter.h>
#include <chainparams.h>
+#include <node/blockstorage.h>
#include <validation.h>
diff --git a/src/test/util/net.h b/src/test/util/net.h
index 2b7988413f..9268d60a1e 100644
--- a/src/test/util/net.h
+++ b/src/test/util/net.h
@@ -78,8 +78,7 @@ public:
explicit StaticContentsSock(const std::string& contents) : m_contents{contents}, m_consumed{0}
{
// Just a dummy number that is not INVALID_SOCKET.
- static_assert(INVALID_SOCKET != 1000);
- m_socket = 1000;
+ m_socket = INVALID_SOCKET - 1;
}
~StaticContentsSock() override { Reset(); }
diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp
index 46c7b781b0..2e7f64a444 100644
--- a/src/test/util/setup_common.cpp
+++ b/src/test/util/setup_common.cpp
@@ -120,6 +120,7 @@ BasicTestingSetup::BasicTestingSetup(const std::string& chainName, const std::ve
BasicTestingSetup::~BasicTestingSetup()
{
+ SetMockTime(0s); // Reset mocktime for following tests
LogInstance().DisconnectTestLogger();
fs::remove_all(m_path_root);
gArgs.ClearArgs();
@@ -202,43 +203,31 @@ TestingSetup::TestingSetup(const std::string& chainName, const std::vector<const
}
}
-TestChain100Setup::TestChain100Setup(bool deterministic)
+TestChain100Setup::TestChain100Setup()
{
- m_deterministic = deterministic;
-
- if (m_deterministic) {
- SetMockTime(1598887952);
- constexpr std::array<unsigned char, 32> vchKey = {
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
- }
- };
- coinbaseKey.Set(vchKey.begin(), vchKey.end(), false);
- } else {
- coinbaseKey.MakeNewKey(true);
- }
+ SetMockTime(1598887952);
+ constexpr std::array<unsigned char, 32> vchKey = {
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}};
+ coinbaseKey.Set(vchKey.begin(), vchKey.end(), true);
// Generate a 100-block chain:
this->mineBlocks(COINBASE_MATURITY);
- if (m_deterministic) {
+ {
LOCK(::cs_main);
assert(
m_node.chainman->ActiveChain().Tip()->GetBlockHash().ToString() ==
- "49c95db1e470fed04496d801c9d8fbb78155d2c7f855232c918823d2c17d0cf6");
+ "571d80a9967ae599cec0448b0b0ba1cfb606f584d8069bd7166b86854ba7a191");
}
}
void TestChain100Setup::mineBlocks(int num_blocks)
{
CScript scriptPubKey = CScript() << ToByteVector(coinbaseKey.GetPubKey()) << OP_CHECKSIG;
- for (int i = 0; i < num_blocks; i++)
- {
+ for (int i = 0; i < num_blocks; i++) {
std::vector<CMutableTransaction> noTxns;
CBlock b = CreateAndProcessBlock(noTxns, scriptPubKey);
- if (m_deterministic) {
- SetMockTime(GetTime() + 1);
- }
+ SetMockTime(GetTime() + 1);
m_coinbase_txns.push_back(b.vtx[0]);
}
}
@@ -316,9 +305,6 @@ CMutableTransaction TestChain100Setup::CreateValidMempoolTransaction(CTransactio
TestChain100Setup::~TestChain100Setup()
{
gArgs.ForceSetArg("-segwitheight", "0");
- if (m_deterministic) {
- SetMockTime(0);
- }
}
CTxMemPoolEntry TestMemPoolEntryHelper::FromTx(const CMutableTransaction& tx) const
diff --git a/src/test/util/setup_common.h b/src/test/util/setup_common.h
index 7323f1f0b6..a32f1f3805 100644
--- a/src/test/util/setup_common.h
+++ b/src/test/util/setup_common.h
@@ -112,7 +112,7 @@ class CScript;
* Testing fixture that pre-creates a 100-block REGTEST-mode block chain
*/
struct TestChain100Setup : public RegTestingSetup {
- TestChain100Setup(bool deterministic = false);
+ TestChain100Setup();
/**
* Create a new block with just given transactions, coinbase paying to
@@ -143,16 +143,10 @@ struct TestChain100Setup : public RegTestingSetup {
~TestChain100Setup();
- bool m_deterministic;
std::vector<CTransactionRef> m_coinbase_txns; // For convenience, coinbase transactions
CKey coinbaseKey; // private/public key needed to spend coinbase transactions
};
-
-struct TestChain100DeterministicSetup : public TestChain100Setup {
- TestChain100DeterministicSetup() : TestChain100Setup(true) { }
-};
-
/**
* Make a test setup that has disk access to the debug.log file disabled. Can
* be used in "hot loops", for example fuzzing or benchmarking.
diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp
index 5ac09b05db..a1ac9ead69 100644
--- a/src/test/util_tests.cpp
+++ b/src/test/util_tests.cpp
@@ -1766,7 +1766,7 @@ static constexpr char LockCommand = 'L';
static constexpr char UnlockCommand = 'U';
static constexpr char ExitCommand = 'X';
-static void TestOtherProcess(fs::path dirname, std::string lockname, int fd)
+[[noreturn]] static void TestOtherProcess(fs::path dirname, std::string lockname, int fd)
{
char ch;
while (true) {
diff --git a/src/test/validation_chainstatemanager_tests.cpp b/src/test/validation_chainstatemanager_tests.cpp
index 94d4277019..ab31662f97 100644
--- a/src/test/validation_chainstatemanager_tests.cpp
+++ b/src/test/validation_chainstatemanager_tests.cpp
@@ -200,7 +200,7 @@ CreateAndActivateUTXOSnapshot(NodeContext& node, const fs::path root, F malleati
}
//! Test basic snapshot activation.
-BOOST_FIXTURE_TEST_CASE(chainstatemanager_activate_snapshot, TestChain100DeterministicSetup)
+BOOST_FIXTURE_TEST_CASE(chainstatemanager_activate_snapshot, TestChain100Setup)
{
ChainstateManager& chainman = *Assert(m_node.chainman);
@@ -259,6 +259,11 @@ BOOST_FIXTURE_TEST_CASE(chainstatemanager_activate_snapshot, TestChain100Determi
// Coins count is smaller than coins in file
metadata.m_coins_count -= 1;
}));
+ BOOST_REQUIRE(!CreateAndActivateUTXOSnapshot(
+ m_node, m_path_root, [](CAutoFile& auto_infile, SnapshotMetadata& metadata) {
+ // Wrong hash
+ metadata.m_base_blockhash = uint256::ONE;
+ }));
BOOST_REQUIRE(CreateAndActivateUTXOSnapshot(m_node, m_path_root));
diff --git a/src/test/validation_tests.cpp b/src/test/validation_tests.cpp
index ecf9453094..d0317aca0a 100644
--- a/src/test/validation_tests.cpp
+++ b/src/test/validation_tests.cpp
@@ -135,7 +135,7 @@ BOOST_AUTO_TEST_CASE(test_assumeutxo)
}
const auto out110 = *ExpectedAssumeutxo(110, *params);
- BOOST_CHECK_EQUAL(out110.hash_serialized, uint256S("76fd7334ac7c1baf57ddc0c626f073a655a35d98a4258cd1382c8cc2b8392e10"));
+ BOOST_CHECK_EQUAL(out110.hash_serialized, uint256S("1ebbf5850204c0bdb15bf030f47c7fe91d45c44c712697e4509ba67adb01c618"));
BOOST_CHECK_EQUAL(out110.nChainTx, (unsigned int)110);
const auto out210 = *ExpectedAssumeutxo(210, *params);
diff --git a/src/test/versionbits_tests.cpp b/src/test/versionbits_tests.cpp
index 8841a540f2..05838ec19a 100644
--- a/src/test/versionbits_tests.cpp
+++ b/src/test/versionbits_tests.cpp
@@ -44,6 +44,12 @@ public:
int GetStateSinceHeightFor(const CBlockIndex* pindexPrev) const { return AbstractThresholdConditionChecker::GetStateSinceHeightFor(pindexPrev, paramsDummy, cache); }
};
+class TestDelayedActivationConditionChecker : public TestConditionChecker
+{
+public:
+ int MinActivationHeight(const Consensus::Params& params) const override { return 15000; }
+};
+
class TestAlwaysActiveConditionChecker : public TestConditionChecker
{
public:
@@ -53,8 +59,7 @@ public:
class TestNeverActiveConditionChecker : public TestConditionChecker
{
public:
- int64_t BeginTime(const Consensus::Params& params) const override { return 0; }
- int64_t EndTime(const Consensus::Params& params) const override { return 1230768000; }
+ int64_t BeginTime(const Consensus::Params& params) const override { return Consensus::BIP9Deployment::NEVER_ACTIVE; }
};
#define CHECKERS 6
@@ -68,6 +73,8 @@ class VersionBitsTester
// The first one performs all checks, the second only 50%, the third only 25%, etc...
// This is to test whether lack of cached information leads to the same results.
TestConditionChecker checker[CHECKERS];
+ // Another 6 that assume delayed activation
+ TestDelayedActivationConditionChecker checker_delayed[CHECKERS];
// Another 6 that assume always active activation
TestAlwaysActiveConditionChecker checker_always[CHECKERS];
// Another 6 that assume never active activation
@@ -77,14 +84,18 @@ class VersionBitsTester
int num;
public:
- VersionBitsTester() : num(0) {}
+ VersionBitsTester() : num(1000) {}
VersionBitsTester& Reset() {
+ // Have each group of tests be counted by the 1000s part, starting at 1000
+ num = num - (num % 1000) + 1000;
+
for (unsigned int i = 0; i < vpblock.size(); i++) {
delete vpblock[i];
}
for (unsigned int i = 0; i < CHECKERS; i++) {
checker[i] = TestConditionChecker();
+ checker_delayed[i] = TestDelayedActivationConditionChecker();
checker_always[i] = TestAlwaysActiveConditionChecker();
checker_never[i] = TestNeverActiveConditionChecker();
}
@@ -100,7 +111,7 @@ public:
while (vpblock.size() < height) {
CBlockIndex* pindex = new CBlockIndex();
pindex->nHeight = vpblock.size();
- pindex->pprev = vpblock.size() > 0 ? vpblock.back() : nullptr;
+ pindex->pprev = Tip();
pindex->nTime = nTime;
pindex->nVersion = nVersion;
pindex->BuildSkip();
@@ -109,34 +120,53 @@ public:
return *this;
}
- VersionBitsTester& TestStateSinceHeight(int height) {
+ VersionBitsTester& TestStateSinceHeight(int height)
+ {
+ return TestStateSinceHeight(height, height);
+ }
+
+ VersionBitsTester& TestStateSinceHeight(int height, int height_delayed)
+ {
+ const CBlockIndex* tip = Tip();
for (int i = 0; i < CHECKERS; i++) {
if (InsecureRandBits(i) == 0) {
- BOOST_CHECK_MESSAGE(checker[i].GetStateSinceHeightFor(vpblock.empty() ? nullptr : vpblock.back()) == height, strprintf("Test %i for StateSinceHeight", num));
- BOOST_CHECK_MESSAGE(checker_always[i].GetStateSinceHeightFor(vpblock.empty() ? nullptr : vpblock.back()) == 0, strprintf("Test %i for StateSinceHeight (always active)", num));
-
- // never active may go from DEFINED -> FAILED at the first period
- const auto never_height = checker_never[i].GetStateSinceHeightFor(vpblock.empty() ? nullptr : vpblock.back());
- BOOST_CHECK_MESSAGE(never_height == 0 || never_height == checker_never[i].Period(paramsDummy), strprintf("Test %i for StateSinceHeight (never active)", num));
+ BOOST_CHECK_MESSAGE(checker[i].GetStateSinceHeightFor(tip) == height, strprintf("Test %i for StateSinceHeight", num));
+ BOOST_CHECK_MESSAGE(checker_delayed[i].GetStateSinceHeightFor(tip) == height_delayed, strprintf("Test %i for StateSinceHeight (delayed)", num));
+ BOOST_CHECK_MESSAGE(checker_always[i].GetStateSinceHeightFor(tip) == 0, strprintf("Test %i for StateSinceHeight (always active)", num));
+ BOOST_CHECK_MESSAGE(checker_never[i].GetStateSinceHeightFor(tip) == 0, strprintf("Test %i for StateSinceHeight (never active)", num));
}
}
num++;
return *this;
}
- VersionBitsTester& TestState(ThresholdState exp) {
+ VersionBitsTester& TestState(ThresholdState exp)
+ {
+ return TestState(exp, exp);
+ }
+
+ VersionBitsTester& TestState(ThresholdState exp, ThresholdState exp_delayed)
+ {
+ if (exp != exp_delayed) {
+ // only expected differences are that delayed stays in locked_in longer
+ BOOST_CHECK_EQUAL(exp, ThresholdState::ACTIVE);
+ BOOST_CHECK_EQUAL(exp_delayed, ThresholdState::LOCKED_IN);
+ }
+
+ const CBlockIndex* pindex = Tip();
for (int i = 0; i < CHECKERS; i++) {
if (InsecureRandBits(i) == 0) {
- const CBlockIndex* pindex = vpblock.empty() ? nullptr : vpblock.back();
ThresholdState got = checker[i].GetStateFor(pindex);
+ ThresholdState got_delayed = checker_delayed[i].GetStateFor(pindex);
ThresholdState got_always = checker_always[i].GetStateFor(pindex);
ThresholdState got_never = checker_never[i].GetStateFor(pindex);
// nHeight of the next block. If vpblock is empty, the next (ie first)
// block should be the genesis block with nHeight == 0.
int height = pindex == nullptr ? 0 : pindex->nHeight + 1;
BOOST_CHECK_MESSAGE(got == exp, strprintf("Test %i for %s height %d (got %s)", num, StateName(exp), height, StateName(got)));
+ BOOST_CHECK_MESSAGE(got_delayed == exp_delayed, strprintf("Test %i for %s height %d (got %s; delayed case)", num, StateName(exp_delayed), height, StateName(got_delayed)));
BOOST_CHECK_MESSAGE(got_always == ThresholdState::ACTIVE, strprintf("Test %i for ACTIVE height %d (got %s; always active case)", num, height, StateName(got_always)));
- BOOST_CHECK_MESSAGE(got_never == ThresholdState::DEFINED|| got_never == ThresholdState::FAILED, strprintf("Test %i for DEFINED/FAILED height %d (got %s; never active case)", num, height, StateName(got_never)));
+ BOOST_CHECK_MESSAGE(got_never == ThresholdState::FAILED, strprintf("Test %i for FAILED height %d (got %s; never active case)", num, height, StateName(got_never)));
}
}
num++;
@@ -149,7 +179,10 @@ public:
VersionBitsTester& TestActive() { return TestState(ThresholdState::ACTIVE); }
VersionBitsTester& TestFailed() { return TestState(ThresholdState::FAILED); }
- CBlockIndex * Tip() { return vpblock.size() ? vpblock.back() : nullptr; }
+ // non-delayed should be active; delayed should still be locked in
+ VersionBitsTester& TestActiveDelayed() { return TestState(ThresholdState::ACTIVE, ThresholdState::LOCKED_IN); }
+
+ CBlockIndex* Tip() { return vpblock.empty() ? nullptr : vpblock.back(); }
};
BOOST_FIXTURE_TEST_SUITE(versionbits_tests, TestingSetup)
@@ -157,18 +190,19 @@ BOOST_FIXTURE_TEST_SUITE(versionbits_tests, TestingSetup)
BOOST_AUTO_TEST_CASE(versionbits_test)
{
for (int i = 0; i < 64; i++) {
- // DEFINED -> FAILED
+ // DEFINED -> STARTED after timeout reached -> FAILED
VersionBitsTester().TestDefined().TestStateSinceHeight(0)
.Mine(1, TestTime(1), 0x100).TestDefined().TestStateSinceHeight(0)
.Mine(11, TestTime(11), 0x100).TestDefined().TestStateSinceHeight(0)
.Mine(989, TestTime(989), 0x100).TestDefined().TestStateSinceHeight(0)
- .Mine(999, TestTime(20000), 0x100).TestDefined().TestStateSinceHeight(0)
- .Mine(1000, TestTime(20000), 0x100).TestFailed().TestStateSinceHeight(1000)
- .Mine(1999, TestTime(30001), 0x100).TestFailed().TestStateSinceHeight(1000)
- .Mine(2000, TestTime(30002), 0x100).TestFailed().TestStateSinceHeight(1000)
- .Mine(2001, TestTime(30003), 0x100).TestFailed().TestStateSinceHeight(1000)
- .Mine(2999, TestTime(30004), 0x100).TestFailed().TestStateSinceHeight(1000)
- .Mine(3000, TestTime(30005), 0x100).TestFailed().TestStateSinceHeight(1000)
+ .Mine(999, TestTime(20000), 0x100).TestDefined().TestStateSinceHeight(0) // Timeout and start time reached simultaneously
+ .Mine(1000, TestTime(20000), 0).TestStarted().TestStateSinceHeight(1000) // Hit started, stop signalling
+ .Mine(1999, TestTime(30001), 0).TestStarted().TestStateSinceHeight(1000)
+ .Mine(2000, TestTime(30002), 0x100).TestFailed().TestStateSinceHeight(2000) // Hit failed, start signalling again
+ .Mine(2001, TestTime(30003), 0x100).TestFailed().TestStateSinceHeight(2000)
+ .Mine(2999, TestTime(30004), 0x100).TestFailed().TestStateSinceHeight(2000)
+ .Mine(3000, TestTime(30005), 0x100).TestFailed().TestStateSinceHeight(2000)
+ .Mine(4000, TestTime(30006), 0x100).TestFailed().TestStateSinceHeight(2000)
// DEFINED -> STARTED -> FAILED
.Reset().TestDefined().TestStateSinceHeight(0)
@@ -180,19 +214,19 @@ BOOST_AUTO_TEST_CASE(versionbits_test)
.Mine(3000, TestTime(20000), 0).TestFailed().TestStateSinceHeight(3000) // 50 old blocks (so 899 out of the past 1000)
.Mine(4000, TestTime(20010), 0x100).TestFailed().TestStateSinceHeight(3000)
- // DEFINED -> STARTED -> FAILED while threshold reached
+ // DEFINED -> STARTED -> LOCKEDIN after timeout reached -> ACTIVE
.Reset().TestDefined().TestStateSinceHeight(0)
.Mine(1, TestTime(1), 0).TestDefined().TestStateSinceHeight(0)
.Mine(1000, TestTime(10000) - 1, 0x101).TestDefined().TestStateSinceHeight(0) // One second more and it would be defined
.Mine(2000, TestTime(10000), 0x101).TestStarted().TestStateSinceHeight(2000) // So that's what happens the next period
.Mine(2999, TestTime(30000), 0x100).TestStarted().TestStateSinceHeight(2000) // 999 new blocks
- .Mine(3000, TestTime(30000), 0x100).TestFailed().TestStateSinceHeight(3000) // 1 new block (so 1000 out of the past 1000 are new)
- .Mine(3999, TestTime(30001), 0).TestFailed().TestStateSinceHeight(3000)
- .Mine(4000, TestTime(30002), 0).TestFailed().TestStateSinceHeight(3000)
- .Mine(14333, TestTime(30003), 0).TestFailed().TestStateSinceHeight(3000)
- .Mine(24000, TestTime(40000), 0).TestFailed().TestStateSinceHeight(3000)
+ .Mine(3000, TestTime(30000), 0x100).TestLockedIn().TestStateSinceHeight(3000) // 1 new block (so 1000 out of the past 1000 are new)
+ .Mine(3999, TestTime(30001), 0).TestLockedIn().TestStateSinceHeight(3000)
+ .Mine(4000, TestTime(30002), 0).TestActiveDelayed().TestStateSinceHeight(4000, 3000)
+ .Mine(14333, TestTime(30003), 0).TestActiveDelayed().TestStateSinceHeight(4000, 3000)
+ .Mine(24000, TestTime(40000), 0).TestActive().TestStateSinceHeight(4000, 15000)
- // DEFINED -> STARTED -> LOCKEDIN at the last minute -> ACTIVE
+ // DEFINED -> STARTED -> LOCKEDIN before timeout -> ACTIVE
.Reset().TestDefined()
.Mine(1, TestTime(1), 0).TestDefined().TestStateSinceHeight(0)
.Mine(1000, TestTime(10000) - 1, 0x101).TestDefined().TestStateSinceHeight(0) // One second more and it would be defined
@@ -202,9 +236,10 @@ BOOST_AUTO_TEST_CASE(versionbits_test)
.Mine(2999, TestTime(19999), 0x200).TestStarted().TestStateSinceHeight(2000) // 49 old blocks
.Mine(3000, TestTime(29999), 0x200).TestLockedIn().TestStateSinceHeight(3000) // 1 old block (so 900 out of the past 1000)
.Mine(3999, TestTime(30001), 0).TestLockedIn().TestStateSinceHeight(3000)
- .Mine(4000, TestTime(30002), 0).TestActive().TestStateSinceHeight(4000)
- .Mine(14333, TestTime(30003), 0).TestActive().TestStateSinceHeight(4000)
- .Mine(24000, TestTime(40000), 0).TestActive().TestStateSinceHeight(4000)
+ .Mine(4000, TestTime(30002), 0).TestActiveDelayed().TestStateSinceHeight(4000, 3000) // delayed will not become active until height=15000
+ .Mine(14333, TestTime(30003), 0).TestActiveDelayed().TestStateSinceHeight(4000, 3000)
+ .Mine(15000, TestTime(40000), 0).TestActive().TestStateSinceHeight(4000, 15000)
+ .Mine(24000, TestTime(40000), 0).TestActive().TestStateSinceHeight(4000, 15000)
// DEFINED multiple periods -> STARTED multiple periods -> FAILED
.Reset().TestDefined().TestStateSinceHeight(0)
@@ -214,10 +249,16 @@ BOOST_AUTO_TEST_CASE(versionbits_test)
.Mine(3000, TestTime(10000), 0).TestStarted().TestStateSinceHeight(3000)
.Mine(4000, TestTime(10000), 0).TestStarted().TestStateSinceHeight(3000)
.Mine(5000, TestTime(10000), 0).TestStarted().TestStateSinceHeight(3000)
+ .Mine(5999, TestTime(20000), 0).TestStarted().TestStateSinceHeight(3000)
.Mine(6000, TestTime(20000), 0).TestFailed().TestStateSinceHeight(6000)
- .Mine(7000, TestTime(20000), 0x100).TestFailed().TestStateSinceHeight(6000);
+ .Mine(7000, TestTime(20000), 0x100).TestFailed().TestStateSinceHeight(6000)
+ .Mine(24000, TestTime(20000), 0x100).TestFailed().TestStateSinceHeight(6000) // stay in FAILED no matter how much we signal
+ ;
}
+}
+BOOST_AUTO_TEST_CASE(versionbits_sanity)
+{
// Sanity checks of version bit deployments
const auto chainParams = CreateChainParams(*m_node.args, CBaseChainParams::MAIN);
const Consensus::Params &mainnetParams = chainParams->GetConsensus();
@@ -226,6 +267,13 @@ BOOST_AUTO_TEST_CASE(versionbits_test)
// Make sure that no deployment tries to set an invalid bit.
BOOST_CHECK_EQUAL(bitmask & ~(uint32_t)VERSIONBITS_TOP_MASK, bitmask);
+ // Check min_activation_height is on a retarget boundary
+ BOOST_CHECK_EQUAL(mainnetParams.vDeployments[i].min_activation_height % mainnetParams.nMinerConfirmationWindow, 0);
+ // Check min_activation_height is 0 for ALWAYS_ACTIVE and never active deployments
+ if (mainnetParams.vDeployments[i].nStartTime == Consensus::BIP9Deployment::ALWAYS_ACTIVE || mainnetParams.vDeployments[i].nStartTime == Consensus::BIP9Deployment::NEVER_ACTIVE) {
+ BOOST_CHECK_EQUAL(mainnetParams.vDeployments[i].min_activation_height, 0);
+ }
+
// Verify that the deployment windows of different deployment using the
// same bit are disjoint.
// This test may need modification at such time as a new deployment
@@ -242,81 +290,118 @@ BOOST_AUTO_TEST_CASE(versionbits_test)
}
}
-BOOST_AUTO_TEST_CASE(versionbits_computeblockversion)
+/** Check that ComputeBlockVersion will set the appropriate bit correctly */
+static void check_computeblockversion(const Consensus::Params& params, Consensus::DeploymentPos dep)
{
- // Check that ComputeBlockVersion will set the appropriate bit correctly
- // on mainnet.
- const auto chainParams = CreateChainParams(*m_node.args, CBaseChainParams::MAIN);
- const Consensus::Params &mainnetParams = chainParams->GetConsensus();
+ // This implicitly uses versionbitscache, so clear it every time
+ versionbitscache.Clear();
+
+ int64_t bit = params.vDeployments[dep].bit;
+ int64_t nStartTime = params.vDeployments[dep].nStartTime;
+ int64_t nTimeout = params.vDeployments[dep].nTimeout;
+ int min_activation_height = params.vDeployments[dep].min_activation_height;
+
+ // should not be any signalling for first block
+ BOOST_CHECK_EQUAL(ComputeBlockVersion(nullptr, params), VERSIONBITS_TOP_BITS);
- // Use the TESTDUMMY deployment for testing purposes.
- int64_t bit = mainnetParams.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit;
- int64_t nStartTime = mainnetParams.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime;
- int64_t nTimeout = mainnetParams.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout;
+ // always/never active deployments shouldn't need to be tested further
+ if (nStartTime == Consensus::BIP9Deployment::ALWAYS_ACTIVE) return;
+ if (nStartTime == Consensus::BIP9Deployment::NEVER_ACTIVE) return;
- assert(nStartTime < nTimeout);
+ BOOST_REQUIRE(nStartTime < nTimeout);
+ BOOST_REQUIRE(nStartTime >= 0);
+ BOOST_REQUIRE(nTimeout <= std::numeric_limits<uint32_t>::max() || nTimeout == Consensus::BIP9Deployment::NO_TIMEOUT);
+ BOOST_REQUIRE(0 <= bit && bit < 32);
+ BOOST_REQUIRE(((1 << bit) & VERSIONBITS_TOP_MASK) == 0);
+ BOOST_REQUIRE(min_activation_height >= 0);
+ BOOST_REQUIRE_EQUAL(min_activation_height % params.nMinerConfirmationWindow, 0);
// In the first chain, test that the bit is set by CBV until it has failed.
// In the second chain, test the bit is set by CBV while STARTED and
// LOCKED-IN, and then no longer set while ACTIVE.
VersionBitsTester firstChain, secondChain;
- // Start generating blocks before nStartTime
- int64_t nTime = nStartTime - 1;
+ int64_t nTime = nStartTime;
+
+ const CBlockIndex *lastBlock = nullptr;
// Before MedianTimePast of the chain has crossed nStartTime, the bit
// should not be set.
- CBlockIndex *lastBlock = nullptr;
- lastBlock = firstChain.Mine(mainnetParams.nMinerConfirmationWindow, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
- BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, mainnetParams) & (1<<bit), 0);
-
- // Mine more blocks (4 less than the adjustment period) at the old time, and check that CBV isn't setting the bit yet.
- for (uint32_t i = 1; i < mainnetParams.nMinerConfirmationWindow - 4; i++) {
- lastBlock = firstChain.Mine(mainnetParams.nMinerConfirmationWindow + i, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
- // This works because VERSIONBITS_LAST_OLD_BLOCK_VERSION happens
- // to be 4, and the bit we're testing happens to be bit 28.
- BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, mainnetParams) & (1<<bit), 0);
- }
- // Now mine 5 more blocks at the start time -- MTP should not have passed yet, so
- // CBV should still not yet set the bit.
- nTime = nStartTime;
- for (uint32_t i = mainnetParams.nMinerConfirmationWindow - 4; i <= mainnetParams.nMinerConfirmationWindow; i++) {
- lastBlock = firstChain.Mine(mainnetParams.nMinerConfirmationWindow + i, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
- BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, mainnetParams) & (1<<bit), 0);
+ if (nTime == 0) {
+ // since CBlockIndex::nTime is uint32_t we can't represent any
+ // earlier time, so will transition from DEFINED to STARTED at the
+ // end of the first period by mining blocks at nTime == 0
+ lastBlock = firstChain.Mine(params.nMinerConfirmationWindow - 1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
+ BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, params) & (1<<bit), 0);
+ lastBlock = firstChain.Mine(params.nMinerConfirmationWindow, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
+ BOOST_CHECK((ComputeBlockVersion(lastBlock, params) & (1<<bit)) != 0);
+ // then we'll keep mining at nStartTime...
+ } else {
+ // use a time 1s earlier than start time to check we stay DEFINED
+ --nTime;
+
+ // Start generating blocks before nStartTime
+ lastBlock = firstChain.Mine(params.nMinerConfirmationWindow, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
+ BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, params) & (1<<bit), 0);
+
+ // Mine more blocks (4 less than the adjustment period) at the old time, and check that CBV isn't setting the bit yet.
+ for (uint32_t i = 1; i < params.nMinerConfirmationWindow - 4; i++) {
+ lastBlock = firstChain.Mine(params.nMinerConfirmationWindow + i, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
+ BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, params) & (1<<bit), 0);
+ }
+ // Now mine 5 more blocks at the start time -- MTP should not have passed yet, so
+ // CBV should still not yet set the bit.
+ nTime = nStartTime;
+ for (uint32_t i = params.nMinerConfirmationWindow - 4; i <= params.nMinerConfirmationWindow; i++) {
+ lastBlock = firstChain.Mine(params.nMinerConfirmationWindow + i, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
+ BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, params) & (1<<bit), 0);
+ }
+ // Next we will advance to the next period and transition to STARTED,
}
- // Advance to the next period and transition to STARTED,
- lastBlock = firstChain.Mine(mainnetParams.nMinerConfirmationWindow * 3, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
+ lastBlock = firstChain.Mine(params.nMinerConfirmationWindow * 3, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
// so ComputeBlockVersion should now set the bit,
- BOOST_CHECK((ComputeBlockVersion(lastBlock, mainnetParams) & (1<<bit)) != 0);
+ BOOST_CHECK((ComputeBlockVersion(lastBlock, params) & (1<<bit)) != 0);
// and should also be using the VERSIONBITS_TOP_BITS.
- BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, mainnetParams) & VERSIONBITS_TOP_MASK, VERSIONBITS_TOP_BITS);
+ BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, params) & VERSIONBITS_TOP_MASK, VERSIONBITS_TOP_BITS);
// Check that ComputeBlockVersion will set the bit until nTimeout
nTime += 600;
- uint32_t blocksToMine = mainnetParams.nMinerConfirmationWindow * 2; // test blocks for up to 2 time periods
- uint32_t nHeight = mainnetParams.nMinerConfirmationWindow * 3;
+ uint32_t blocksToMine = params.nMinerConfirmationWindow * 2; // test blocks for up to 2 time periods
+ uint32_t nHeight = params.nMinerConfirmationWindow * 3;
// These blocks are all before nTimeout is reached.
while (nTime < nTimeout && blocksToMine > 0) {
lastBlock = firstChain.Mine(nHeight+1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
- BOOST_CHECK((ComputeBlockVersion(lastBlock, mainnetParams) & (1<<bit)) != 0);
- BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, mainnetParams) & VERSIONBITS_TOP_MASK, VERSIONBITS_TOP_BITS);
+ BOOST_CHECK((ComputeBlockVersion(lastBlock, params) & (1<<bit)) != 0);
+ BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, params) & VERSIONBITS_TOP_MASK, VERSIONBITS_TOP_BITS);
blocksToMine--;
nTime += 600;
nHeight += 1;
}
- nTime = nTimeout;
- // FAILED is only triggered at the end of a period, so CBV should be setting
- // the bit until the period transition.
- for (uint32_t i = 0; i < mainnetParams.nMinerConfirmationWindow - 1; i++) {
+ if (nTimeout != Consensus::BIP9Deployment::NO_TIMEOUT) {
+ // can reach any nTimeout other than NO_TIMEOUT due to earlier BOOST_REQUIRE
+
+ nTime = nTimeout;
+
+ // finish the last period before we start timing out
+ while (nHeight % params.nMinerConfirmationWindow != 0) {
+ lastBlock = firstChain.Mine(nHeight+1, nTime - 1, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
+ BOOST_CHECK((ComputeBlockVersion(lastBlock, params) & (1<<bit)) != 0);
+ nHeight += 1;
+ }
+
+ // FAILED is only triggered at the end of a period, so CBV should be setting
+ // the bit until the period transition.
+ for (uint32_t i = 0; i < params.nMinerConfirmationWindow - 1; i++) {
+ lastBlock = firstChain.Mine(nHeight+1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
+ BOOST_CHECK((ComputeBlockVersion(lastBlock, params) & (1<<bit)) != 0);
+ nHeight += 1;
+ }
+ // The next block should trigger no longer setting the bit.
lastBlock = firstChain.Mine(nHeight+1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
- BOOST_CHECK((ComputeBlockVersion(lastBlock, mainnetParams) & (1<<bit)) != 0);
- nHeight += 1;
+ BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, params) & (1<<bit), 0);
}
- // The next block should trigger no longer setting the bit.
- lastBlock = firstChain.Mine(nHeight+1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
- BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, mainnetParams) & (1<<bit), 0);
// On a new chain:
// verify that the bit will be set after lock-in, and then stop being set
@@ -325,26 +410,62 @@ BOOST_AUTO_TEST_CASE(versionbits_computeblockversion)
// Mine one period worth of blocks, and check that the bit will be on for the
// next period.
- lastBlock = secondChain.Mine(mainnetParams.nMinerConfirmationWindow, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
- BOOST_CHECK((ComputeBlockVersion(lastBlock, mainnetParams) & (1<<bit)) != 0);
+ lastBlock = secondChain.Mine(params.nMinerConfirmationWindow, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
+ BOOST_CHECK((ComputeBlockVersion(lastBlock, params) & (1<<bit)) != 0);
// Mine another period worth of blocks, signaling the new bit.
- lastBlock = secondChain.Mine(mainnetParams.nMinerConfirmationWindow * 2, nTime, VERSIONBITS_TOP_BITS | (1<<bit)).Tip();
+ lastBlock = secondChain.Mine(params.nMinerConfirmationWindow * 2, nTime, VERSIONBITS_TOP_BITS | (1<<bit)).Tip();
// After one period of setting the bit on each block, it should have locked in.
// We keep setting the bit for one more period though, until activation.
- BOOST_CHECK((ComputeBlockVersion(lastBlock, mainnetParams) & (1<<bit)) != 0);
+ BOOST_CHECK((ComputeBlockVersion(lastBlock, params) & (1<<bit)) != 0);
// Now check that we keep mining the block until the end of this period, and
// then stop at the beginning of the next period.
- lastBlock = secondChain.Mine((mainnetParams.nMinerConfirmationWindow * 3) - 1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
- BOOST_CHECK((ComputeBlockVersion(lastBlock, mainnetParams) & (1 << bit)) != 0);
- lastBlock = secondChain.Mine(mainnetParams.nMinerConfirmationWindow * 3, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
- BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, mainnetParams) & (1<<bit), 0);
-
- // Finally, verify that after a soft fork has activated, CBV no longer uses
- // VERSIONBITS_LAST_OLD_BLOCK_VERSION.
- //BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, mainnetParams) & VERSIONBITS_TOP_MASK, VERSIONBITS_TOP_BITS);
+ lastBlock = secondChain.Mine((params.nMinerConfirmationWindow * 3) - 1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
+ BOOST_CHECK((ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
+ lastBlock = secondChain.Mine(params.nMinerConfirmationWindow * 3, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
+
+ if (lastBlock->nHeight + 1 < min_activation_height) {
+ // check signalling continues while min_activation_height is not reached
+ lastBlock = secondChain.Mine(min_activation_height - 1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
+ BOOST_CHECK((ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
+ // then reach min_activation_height, which was already REQUIRE'd to start a new period
+ lastBlock = secondChain.Mine(min_activation_height, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
+ }
+
+ // Check that we don't signal after activation
+ BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, params) & (1<<bit), 0);
}
+BOOST_AUTO_TEST_CASE(versionbits_computeblockversion)
+{
+ // check that any deployment on any chain can conceivably reach both
+ // ACTIVE and FAILED states in roughly the way we expect
+ for (const auto& chain_name : {CBaseChainParams::MAIN, CBaseChainParams::TESTNET, CBaseChainParams::SIGNET, CBaseChainParams::REGTEST}) {
+ const auto chainParams = CreateChainParams(*m_node.args, chain_name);
+ for (int i = 0; i < (int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++i) {
+ check_computeblockversion(chainParams->GetConsensus(), static_cast<Consensus::DeploymentPos>(i));
+ }
+ }
+
+ {
+ // Use regtest/testdummy to ensure we always exercise some
+ // deployment that's not always/never active
+ ArgsManager args;
+ args.ForceSetArg("-vbparams", "testdummy:1199145601:1230767999"); // January 1, 2008 - December 31, 2008
+ const auto chainParams = CreateChainParams(args, CBaseChainParams::REGTEST);
+ check_computeblockversion(chainParams->GetConsensus(), Consensus::DEPLOYMENT_TESTDUMMY);
+ }
+
+ {
+ // Use regtest/testdummy to ensure we always exercise the
+ // min_activation_height test, even if we're not using that in a
+ // live deployment
+ ArgsManager args;
+ args.ForceSetArg("-vbparams", "testdummy:1199145601:1230767999:403200"); // January 1, 2008 - December 31, 2008, min act height 403200
+ const auto chainParams = CreateChainParams(args, CBaseChainParams::REGTEST);
+ check_computeblockversion(chainParams->GetConsensus(), Consensus::DEPLOYMENT_TESTDUMMY);
+ }
+}
BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/txorphanage.h b/src/txorphanage.h
index df55cdb3be..e4266e470a 100644
--- a/src/txorphanage.h
+++ b/src/txorphanage.h
@@ -24,9 +24,9 @@ public:
bool AddTx(const CTransactionRef& tx, NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(g_cs_orphans);
/** Check if we already have an orphan transaction (by txid or wtxid) */
- bool HaveTx(const GenTxid& gtxid) const EXCLUSIVE_LOCKS_REQUIRED(!g_cs_orphans);
+ bool HaveTx(const GenTxid& gtxid) const LOCKS_EXCLUDED(::g_cs_orphans);
- /** Get an orphan transaction and its orginating peer
+ /** Get an orphan transaction and its originating peer
* (Transaction ref will be nullptr if not found)
*/
std::pair<CTransactionRef, NodeId> GetTx(const uint256& txid) const EXCLUSIVE_LOCKS_REQUIRED(g_cs_orphans);
@@ -38,7 +38,7 @@ public:
void EraseForPeer(NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(g_cs_orphans);
/** Erase all orphans included in or invalidated by a new block */
- void EraseForBlock(const CBlock& block) EXCLUSIVE_LOCKS_REQUIRED(!g_cs_orphans);
+ void EraseForBlock(const CBlock& block) LOCKS_EXCLUDED(::g_cs_orphans);
/** Limit the orphanage to the given maximum */
unsigned int LimitOrphans(unsigned int max_orphans) EXCLUSIVE_LOCKS_REQUIRED(g_cs_orphans);
diff --git a/src/txrequest.cpp b/src/txrequest.cpp
index 58424134b0..f8d7a1ece8 100644
--- a/src/txrequest.cpp
+++ b/src/txrequest.cpp
@@ -486,7 +486,7 @@ private:
}
//! Make the data structure consistent with a given point in time:
- //! - REQUESTED annoucements with expiry <= now are turned into COMPLETED.
+ //! - REQUESTED announcements with expiry <= now are turned into COMPLETED.
//! - CANDIDATE_DELAYED announcements with reqtime <= now are turned into CANDIDATE_{READY,BEST}.
//! - CANDIDATE_{READY,BEST} announcements with reqtime > now are turned into CANDIDATE_DELAYED.
void SetTimePoint(std::chrono::microseconds now, std::vector<std::pair<NodeId, GenTxid>>* expired)
diff --git a/src/util/sock.h b/src/util/sock.h
index c4ad0cbc43..a4df7cd21b 100644
--- a/src/util/sock.h
+++ b/src/util/sock.h
@@ -161,7 +161,7 @@ public:
/**
* Check if still connected.
- * @param[out] err The error string, if the socket has been disconnected.
+ * @param[out] errmsg The error string, if the socket has been disconnected.
* @return true if connected
*/
virtual bool IsConnected(std::string& errmsg) const;
diff --git a/src/validation.cpp b/src/validation.cpp
index 19363c0efb..332cb581b8 100644
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -21,6 +21,7 @@
#include <index/txindex.h>
#include <logging.h>
#include <logging/timer.h>
+#include <node/blockstorage.h>
#include <node/coinstats.h>
#include <node/ui_interface.h>
#include <policy/policy.h>
@@ -1148,123 +1149,6 @@ CTransactionRef GetTransaction(const CBlockIndex* const block_index, const CTxMe
return nullptr;
}
-//////////////////////////////////////////////////////////////////////////////
-//
-// CBlock and CBlockIndex
-//
-
-static bool WriteBlockToDisk(const CBlock& block, FlatFilePos& pos, const CMessageHeader::MessageStartChars& messageStart)
-{
- // Open history file to append
- CAutoFile fileout(OpenBlockFile(pos), SER_DISK, CLIENT_VERSION);
- if (fileout.IsNull())
- return error("WriteBlockToDisk: OpenBlockFile failed");
-
- // Write index header
- unsigned int nSize = GetSerializeSize(block, fileout.GetVersion());
- fileout << messageStart << nSize;
-
- // Write block
- long fileOutPos = ftell(fileout.Get());
- if (fileOutPos < 0)
- return error("WriteBlockToDisk: ftell failed");
- pos.nPos = (unsigned int)fileOutPos;
- fileout << block;
-
- return true;
-}
-
-bool ReadBlockFromDisk(CBlock& block, const FlatFilePos& pos, const Consensus::Params& consensusParams)
-{
- block.SetNull();
-
- // Open history file to read
- CAutoFile filein(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION);
- if (filein.IsNull())
- return error("ReadBlockFromDisk: OpenBlockFile failed for %s", pos.ToString());
-
- // Read block
- try {
- filein >> block;
- }
- catch (const std::exception& e) {
- return error("%s: Deserialize or I/O error - %s at %s", __func__, e.what(), pos.ToString());
- }
-
- // Check the header
- if (!CheckProofOfWork(block.GetHash(), block.nBits, consensusParams))
- return error("ReadBlockFromDisk: Errors in block header at %s", pos.ToString());
-
- // Signet only: check block solution
- if (consensusParams.signet_blocks && !CheckSignetBlockSolution(block, consensusParams)) {
- return error("ReadBlockFromDisk: Errors in block solution at %s", pos.ToString());
- }
-
- return true;
-}
-
-bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex, const Consensus::Params& consensusParams)
-{
- FlatFilePos blockPos;
- {
- LOCK(cs_main);
- blockPos = pindex->GetBlockPos();
- }
-
- if (!ReadBlockFromDisk(block, blockPos, consensusParams))
- return false;
- if (block.GetHash() != pindex->GetBlockHash())
- return error("ReadBlockFromDisk(CBlock&, CBlockIndex*): GetHash() doesn't match index for %s at %s",
- pindex->ToString(), pindex->GetBlockPos().ToString());
- return true;
-}
-
-bool ReadRawBlockFromDisk(std::vector<uint8_t>& block, const FlatFilePos& pos, const CMessageHeader::MessageStartChars& message_start)
-{
- FlatFilePos hpos = pos;
- hpos.nPos -= 8; // Seek back 8 bytes for meta header
- CAutoFile filein(OpenBlockFile(hpos, true), SER_DISK, CLIENT_VERSION);
- if (filein.IsNull()) {
- return error("%s: OpenBlockFile failed for %s", __func__, pos.ToString());
- }
-
- try {
- CMessageHeader::MessageStartChars blk_start;
- unsigned int blk_size;
-
- filein >> blk_start >> blk_size;
-
- if (memcmp(blk_start, message_start, CMessageHeader::MESSAGE_START_SIZE)) {
- return error("%s: Block magic mismatch for %s: %s versus expected %s", __func__, pos.ToString(),
- HexStr(blk_start),
- HexStr(message_start));
- }
-
- if (blk_size > MAX_SIZE) {
- return error("%s: Block data is larger than maximum deserialization size for %s: %s versus %s", __func__, pos.ToString(),
- blk_size, MAX_SIZE);
- }
-
- block.resize(blk_size); // Zeroing of memory is intentional here
- filein.read((char*)block.data(), blk_size);
- } catch(const std::exception& e) {
- return error("%s: Read from block file failed: %s for %s", __func__, e.what(), pos.ToString());
- }
-
- return true;
-}
-
-bool ReadRawBlockFromDisk(std::vector<uint8_t>& block, const CBlockIndex* pindex, const CMessageHeader::MessageStartChars& message_start)
-{
- FlatFilePos block_pos;
- {
- LOCK(cs_main);
- block_pos = pindex->GetBlockPos();
- }
-
- return ReadRawBlockFromDisk(block, block_pos, message_start);
-}
-
CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams)
{
int halvings = nHeight / consensusParams.nSubsidyHalvingInterval;
@@ -1636,19 +1520,6 @@ bool UndoReadFromDisk(CBlockUndo& blockundo, const CBlockIndex* pindex)
return true;
}
-/** Abort with a message */
-static bool AbortNode(const std::string& strMessage, bilingual_str user_message = bilingual_str())
-{
- SetMiscWarning(Untranslated(strMessage));
- LogPrintf("*** %s\n", strMessage);
- if (user_message.empty()) {
- user_message = _("A fatal internal error occurred, see debug.log for details");
- }
- AbortError(user_message);
- StartShutdown();
- return false;
-}
-
static bool AbortNode(BlockValidationState& state, const std::string& strMessage, const bilingual_str& userMessage = bilingual_str())
{
AbortNode(strMessage, userMessage);
@@ -3231,7 +3102,8 @@ void CChainState::ReceivedBlockTransactions(const CBlock& block, CBlockIndex* pi
}
}
-static bool FindBlockPos(FlatFilePos &pos, unsigned int nAddSize, unsigned int nHeight, CChain& active_chain, uint64_t nTime, bool fKnown = false)
+// TODO move to blockstorage
+bool FindBlockPos(FlatFilePos& pos, unsigned int nAddSize, unsigned int nHeight, CChain& active_chain, uint64_t nTime, bool fKnown = false)
{
LOCK(cs_LastBlockFile);
@@ -3709,25 +3581,6 @@ bool ChainstateManager::ProcessNewBlockHeaders(const std::vector<CBlockHeader>&
}
/** Store block on disk. If dbp is non-nullptr, the file is known to already reside on disk */
-static FlatFilePos SaveBlockToDisk(const CBlock& block, int nHeight, CChain& active_chain, const CChainParams& chainparams, const FlatFilePos* dbp) {
- unsigned int nBlockSize = ::GetSerializeSize(block, CLIENT_VERSION);
- FlatFilePos blockPos;
- if (dbp != nullptr)
- blockPos = *dbp;
- if (!FindBlockPos(blockPos, nBlockSize+8, nHeight, active_chain, block.GetBlockTime(), dbp != nullptr)) {
- error("%s: FindBlockPos failed", __func__);
- return FlatFilePos();
- }
- if (dbp == nullptr) {
- if (!WriteBlockToDisk(block, blockPos, chainparams.MessageStart())) {
- AbortNode("Failed to write block");
- return FlatFilePos();
- }
- }
- return blockPos;
-}
-
-/** Store block on disk. If dbp is non-nullptr, the file is known to already reside on disk */
bool CChainState::AcceptBlock(const std::shared_ptr<const CBlock>& pblock, BlockValidationState& state, const CChainParams& chainparams, CBlockIndex** ppindex, bool fRequested, const FlatFilePos* dbp, bool* fNewBlock)
{
const CBlock& block = *pblock;
@@ -5345,12 +5198,12 @@ bool ChainstateManager::PopulateAndValidateSnapshot(
while (coins_left > 0) {
try {
coins_file >> outpoint;
+ coins_file >> coin;
} catch (const std::ios_base::failure&) {
- LogPrintf("[snapshot] bad snapshot - no coins left after deserializing %d coins\n",
- coins_count - coins_left);
+ LogPrintf("[snapshot] bad snapshot format or truncated snapshot after deserializing %d coins\n",
+ coins_count - coins_left);
return false;
}
- coins_file >> coin;
coins_cache.EmplaceCoinInternalDANGER(std::move(outpoint), std::move(coin));
--coins_left;
@@ -5423,6 +5276,15 @@ bool ChainstateManager::PopulateAndValidateSnapshot(
assert(coins_cache.GetBestBlock() == base_blockhash);
+ CBlockIndex* snapshot_start_block = WITH_LOCK(::cs_main, return m_blockman.LookupBlockIndex(base_blockhash));
+
+ if (!snapshot_start_block) {
+ // Needed for GetUTXOStats to determine the height
+ LogPrintf("[snapshot] Did not find snapshot start blockheader %s\n",
+ base_blockhash.ToString());
+ return false;
+ }
+
CCoinsStats stats;
auto breakpoint_fnc = [] { /* TODO insert breakpoint here? */ };
@@ -5435,31 +5297,6 @@ bool ChainstateManager::PopulateAndValidateSnapshot(
return false;
}
- // Ensure that the base blockhash appears in the known chain of valid headers. We're willing to
- // wait a bit here because the snapshot may have been loaded on startup, before we've
- // received headers from the network.
-
- int max_secs_to_wait_for_headers = 60 * 10;
- CBlockIndex* snapshot_start_block = nullptr;
-
- while (max_secs_to_wait_for_headers > 0) {
- snapshot_start_block = WITH_LOCK(::cs_main,
- return m_blockman.LookupBlockIndex(base_blockhash));
- --max_secs_to_wait_for_headers;
-
- if (!snapshot_start_block) {
- std::this_thread::sleep_for(std::chrono::seconds(1));
- } else {
- break;
- }
- }
-
- if (snapshot_start_block == nullptr) {
- LogPrintf("[snapshot] timed out waiting for snapshot start blockheader %s\n",
- base_blockhash.ToString());
- return false;
- }
-
// Assert that the deserialized chainstate contents match the expected assumeutxo value.
int base_height = snapshot_start_block->nHeight;
diff --git a/src/validation.h b/src/validation.h
index 21e63947fa..de121ab46a 100644
--- a/src/validation.h
+++ b/src/validation.h
@@ -35,6 +35,7 @@
#include <set>
#include <stdint.h>
#include <string>
+#include <thread>
#include <utility>
#include <vector>
@@ -299,15 +300,6 @@ public:
/** Initializes the script-execution cache */
void InitScriptExecutionCache();
-
-/** Functions for disk access for blocks */
-bool ReadBlockFromDisk(CBlock& block, const FlatFilePos& pos, const Consensus::Params& consensusParams);
-bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex, const Consensus::Params& consensusParams);
-bool ReadRawBlockFromDisk(std::vector<uint8_t>& block, const FlatFilePos& pos, const CMessageHeader::MessageStartChars& message_start);
-bool ReadRawBlockFromDisk(std::vector<uint8_t>& block, const CBlockIndex* pindex, const CMessageHeader::MessageStartChars& message_start);
-
-bool UndoReadFromDisk(CBlockUndo& blockundo, const CBlockIndex* pindex);
-
/** Functions for validating blocks and updating the block tree */
/** Context-independent validity checks */
@@ -869,6 +861,7 @@ private:
friend CChain& ChainActive();
public:
+ std::thread m_load_block;
//! A single BlockManager instance is shared across each constructed
//! chainstate to avoid duplicating block metadata.
BlockManager m_blockman GUARDED_BY(::cs_main);
@@ -1029,7 +1022,7 @@ inline bool IsBlockPruned(const CBlockIndex* pblockindex)
/**
* Return the expected assumeutxo value for a given height, if one exists.
*
- * @param height[in] Get the assumeutxo value for this height.
+ * @param[in] height Get the assumeutxo value for this height.
*
* @returns empty if no assumeutxo configuration exists for the given height.
*/
diff --git a/src/versionbits.cpp b/src/versionbits.cpp
index af07c67ccf..df2ec4e056 100644
--- a/src/versionbits.cpp
+++ b/src/versionbits.cpp
@@ -9,6 +9,7 @@ ThresholdState AbstractThresholdConditionChecker::GetStateFor(const CBlockIndex*
{
int nPeriod = Period(params);
int nThreshold = Threshold(params);
+ int min_activation_height = MinActivationHeight(params);
int64_t nTimeStart = BeginTime(params);
int64_t nTimeTimeout = EndTime(params);
@@ -17,6 +18,11 @@ ThresholdState AbstractThresholdConditionChecker::GetStateFor(const CBlockIndex*
return ThresholdState::ACTIVE;
}
+ // Check if this deployment is never active.
+ if (nTimeStart == Consensus::BIP9Deployment::NEVER_ACTIVE) {
+ return ThresholdState::FAILED;
+ }
+
// A block's state is always the same as that of the first of its period, so it is computed based on a pindexPrev whose height equals a multiple of nPeriod - 1.
if (pindexPrev != nullptr) {
pindexPrev = pindexPrev->GetAncestor(pindexPrev->nHeight - ((pindexPrev->nHeight + 1) % nPeriod));
@@ -51,18 +57,12 @@ ThresholdState AbstractThresholdConditionChecker::GetStateFor(const CBlockIndex*
switch (state) {
case ThresholdState::DEFINED: {
- if (pindexPrev->GetMedianTimePast() >= nTimeTimeout) {
- stateNext = ThresholdState::FAILED;
- } else if (pindexPrev->GetMedianTimePast() >= nTimeStart) {
+ if (pindexPrev->GetMedianTimePast() >= nTimeStart) {
stateNext = ThresholdState::STARTED;
}
break;
}
case ThresholdState::STARTED: {
- if (pindexPrev->GetMedianTimePast() >= nTimeTimeout) {
- stateNext = ThresholdState::FAILED;
- break;
- }
// We need to count
const CBlockIndex* pindexCount = pindexPrev;
int count = 0;
@@ -74,12 +74,16 @@ ThresholdState AbstractThresholdConditionChecker::GetStateFor(const CBlockIndex*
}
if (count >= nThreshold) {
stateNext = ThresholdState::LOCKED_IN;
+ } else if (pindexPrev->GetMedianTimePast() >= nTimeTimeout) {
+ stateNext = ThresholdState::FAILED;
}
break;
}
case ThresholdState::LOCKED_IN: {
- // Always progresses into ACTIVE.
- stateNext = ThresholdState::ACTIVE;
+ // Progresses into ACTIVE provided activation height will have been reached.
+ if (pindexPrev->nHeight + 1 >= min_activation_height) {
+ stateNext = ThresholdState::ACTIVE;
+ }
break;
}
case ThresholdState::FAILED:
@@ -126,7 +130,7 @@ BIP9Stats AbstractThresholdConditionChecker::GetStateStatisticsFor(const CBlockI
int AbstractThresholdConditionChecker::GetStateSinceHeightFor(const CBlockIndex* pindexPrev, const Consensus::Params& params, ThresholdConditionCache& cache) const
{
int64_t start_time = BeginTime(params);
- if (start_time == Consensus::BIP9Deployment::ALWAYS_ACTIVE) {
+ if (start_time == Consensus::BIP9Deployment::ALWAYS_ACTIVE || start_time == Consensus::BIP9Deployment::NEVER_ACTIVE) {
return 0;
}
@@ -170,6 +174,7 @@ private:
protected:
int64_t BeginTime(const Consensus::Params& params) const override { return params.vDeployments[id].nStartTime; }
int64_t EndTime(const Consensus::Params& params) const override { return params.vDeployments[id].nTimeout; }
+ int MinActivationHeight(const Consensus::Params& params) const override { return params.vDeployments[id].min_activation_height; }
int Period(const Consensus::Params& params) const override { return params.nMinerConfirmationWindow; }
int Threshold(const Consensus::Params& params) const override { return params.nRuleChangeActivationThreshold; }
diff --git a/src/versionbits.h b/src/versionbits.h
index 6df1db8814..634a848ef5 100644
--- a/src/versionbits.h
+++ b/src/versionbits.h
@@ -25,7 +25,7 @@ static const int32_t VERSIONBITS_NUM_BITS = 29;
enum class ThresholdState {
DEFINED, // First state that each softfork starts out as. The genesis block is by definition in this state for each deployment.
STARTED, // For blocks past the starttime.
- LOCKED_IN, // For one retarget period after the first retarget period with STARTED blocks of which at least threshold have the associated bit set in nVersion.
+ LOCKED_IN, // For at least one retarget period after the first retarget period with STARTED blocks of which at least threshold have the associated bit set in nVersion, until min_activation_height is reached.
ACTIVE, // For all blocks after the LOCKED_IN retarget period (final state)
FAILED, // For all blocks once the first retarget period after the timeout time is hit, if LOCKED_IN wasn't already reached (final state)
};
@@ -57,6 +57,7 @@ protected:
virtual bool Condition(const CBlockIndex* pindex, const Consensus::Params& params) const =0;
virtual int64_t BeginTime(const Consensus::Params& params) const =0;
virtual int64_t EndTime(const Consensus::Params& params) const =0;
+ virtual int MinActivationHeight(const Consensus::Params& params) const { return 0; }
virtual int Period(const Consensus::Params& params) const =0;
virtual int Threshold(const Consensus::Params& params) const =0;
diff --git a/src/wallet/external_signer_scriptpubkeyman.cpp b/src/wallet/external_signer_scriptpubkeyman.cpp
index a2071e521a..fe2c810afa 100644
--- a/src/wallet/external_signer_scriptpubkeyman.cpp
+++ b/src/wallet/external_signer_scriptpubkeyman.cpp
@@ -3,9 +3,16 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <chainparams.h>
-#include <wallet/external_signer.h>
+#include <external_signer.h>
#include <wallet/external_signer_scriptpubkeyman.h>
+#include <iostream>
+#include <memory>
+#include <stdexcept>
+#include <string>
+#include <utility>
+#include <vector>
+
#ifdef ENABLE_EXTERNAL_SIGNER
bool ExternalSignerScriptPubKeyMan::SetupDescriptor(std::unique_ptr<Descriptor> desc)
diff --git a/src/wallet/external_signer_scriptpubkeyman.h b/src/wallet/external_signer_scriptpubkeyman.h
index e60d7b8004..1786958912 100644
--- a/src/wallet/external_signer_scriptpubkeyman.h
+++ b/src/wallet/external_signer_scriptpubkeyman.h
@@ -8,6 +8,8 @@
#ifdef ENABLE_EXTERNAL_SIGNER
#include <wallet/scriptpubkeyman.h>
+#include <memory>
+
class ExternalSignerScriptPubKeyMan : public DescriptorScriptPubKeyMan
{
public:
diff --git a/src/wallet/init.cpp b/src/wallet/init.cpp
index fdeead1fa5..0dc220b6fd 100644
--- a/src/wallet/init.cpp
+++ b/src/wallet/init.cpp
@@ -82,6 +82,12 @@ void WalletInit::AddWalletOptions(ArgsManager& argsman) const
argsman.AddHiddenArgs({"-dblogsize", "-flushwallet", "-privdb"});
#endif
+#ifdef USE_SQLITE
+ argsman.AddArg("-unsafesqlitesync", "Set SQLite synchronous=OFF to disable waiting for the database to sync to disk. This is unsafe and can cause data loss and corruption. This option is only used by tests to improve their performance (default: false)", ArgsManager::ALLOW_BOOL | ArgsManager::DEBUG_ONLY, OptionsCategory::WALLET_DEBUG_TEST);
+#else
+ argsman.AddHiddenArgs({"-unsafesqlitesync"});
+#endif
+
argsman.AddArg("-walletrejectlongchains", strprintf("Wallet will not create transactions that violate mempool chain limits (default: %u)", DEFAULT_WALLET_REJECT_LONG_CHAINS), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::WALLET_DEBUG_TEST);
argsman.AddHiddenArgs({"-zapwallettxes"});
diff --git a/src/wallet/interfaces.cpp b/src/wallet/interfaces.cpp
index da5b84ce83..64ce09d1d1 100644
--- a/src/wallet/interfaces.cpp
+++ b/src/wallet/interfaces.cpp
@@ -22,7 +22,6 @@
#include <wallet/fees.h>
#include <wallet/ismine.h>
#include <wallet/load.h>
-#include <wallet/rpcsigner.h>
#include <wallet/rpcwallet.h>
#include <wallet/wallet.h>
@@ -514,19 +513,12 @@ public:
{
for (const CRPCCommand& command : GetWalletRPCCommands()) {
m_rpc_commands.emplace_back(command.category, command.name, [this, &command](const JSONRPCRequest& request, UniValue& result, bool last_handler) {
- return command.actor({request, &m_context}, result, last_handler);
+ JSONRPCRequest wallet_request = request;
+ wallet_request.context = &m_context;
+ return command.actor(wallet_request, result, last_handler);
}, command.argNames, command.unique_id);
m_rpc_handlers.emplace_back(m_context.chain->handleRpc(m_rpc_commands.back()));
}
-
-#ifdef ENABLE_EXTERNAL_SIGNER
- for (const CRPCCommand& command : GetSignerRPCCommands()) {
- m_rpc_commands.emplace_back(command.category, command.name, [this, &command](const JSONRPCRequest& request, UniValue& result, bool last_handler) {
- return command.actor({request, m_context}, result, last_handler);
- }, command.argNames, command.unique_id);
- m_rpc_handlers.emplace_back(m_context.chain->handleRpc(m_rpc_commands.back()));
- }
-#endif
}
bool verify() override { return VerifyWallets(*m_context.chain); }
bool load() override { return LoadWallets(*m_context.chain); }
diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp
index 0737e68cf3..769987ccf2 100644
--- a/src/wallet/rpcdump.cpp
+++ b/src/wallet/rpcdump.cpp
@@ -1737,22 +1737,23 @@ RPCHelpMan listdescriptors()
"listdescriptors",
"\nList descriptors imported into a descriptor-enabled wallet.",
{},
- RPCResult{
- RPCResult::Type::ARR, "", "Response is an array of descriptor objects",
+ RPCResult{RPCResult::Type::OBJ, "", "", {
+ {RPCResult::Type::STR, "wallet_name", "Name of wallet this operation was performed on"},
+ {RPCResult::Type::ARR, "descriptors", "Array of descriptor objects",
{
{RPCResult::Type::OBJ, "", "", {
{RPCResult::Type::STR, "desc", "Descriptor string representation"},
{RPCResult::Type::NUM, "timestamp", "The creation time of the descriptor"},
{RPCResult::Type::BOOL, "active", "Activeness flag"},
- {RPCResult::Type::BOOL, "internal", true, "Whether this is internal or external descriptor; defined only for active descriptors"},
+ {RPCResult::Type::BOOL, "internal", true, "Whether this is an internal or external descriptor; defined only for active descriptors"},
{RPCResult::Type::ARR_FIXED, "range", true, "Defined only for ranged descriptors", {
{RPCResult::Type::NUM, "", "Range start inclusive"},
{RPCResult::Type::NUM, "", "Range end inclusive"},
}},
{RPCResult::Type::NUM, "next", true, "The next index to generate addresses from; defined only for ranged descriptors"},
}},
- }
- },
+ }}
+ }},
RPCExamples{
HelpExampleCli("listdescriptors", "") + HelpExampleRpc("listdescriptors", "")
},
@@ -1769,7 +1770,7 @@ RPCHelpMan listdescriptors()
LOCK(wallet->cs_wallet);
- UniValue response(UniValue::VARR);
+ UniValue descriptors(UniValue::VARR);
const auto active_spk_mans = wallet->GetActiveScriptPubKeyMans();
for (const auto& spk_man : wallet->GetAllScriptPubKeyMans()) {
const auto desc_spk_man = dynamic_cast<DescriptorScriptPubKeyMan*>(spk_man);
@@ -1798,9 +1799,13 @@ RPCHelpMan listdescriptors()
spk.pushKV("range", range);
spk.pushKV("next", wallet_descriptor.next_index);
}
- response.push_back(spk);
+ descriptors.push_back(spk);
}
+ UniValue response(UniValue::VOBJ);
+ response.pushKV("wallet_name", wallet->GetName());
+ response.pushKV("descriptors", descriptors);
+
return response;
},
};
diff --git a/src/wallet/rpcsigner.cpp b/src/wallet/rpcsigner.cpp
deleted file mode 100644
index 696c74d665..0000000000
--- a/src/wallet/rpcsigner.cpp
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright (c) 2018-2021 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 <chainparamsbase.h>
-#include <key_io.h>
-#include <rpc/server.h>
-#include <rpc/util.h>
-#include <util/strencodings.h>
-#include <wallet/rpcsigner.h>
-#include <wallet/rpcwallet.h>
-#include <wallet/wallet.h>
-
-#ifdef ENABLE_EXTERNAL_SIGNER
-
-static RPCHelpMan enumeratesigners()
-{
- return RPCHelpMan{
- "enumeratesigners",
- "Returns a list of external signers from -signer.",
- {},
- RPCResult{
- RPCResult::Type::OBJ, "", "",
- {
- {RPCResult::Type::ARR, "signers", /* optional */ false, "",
- {
- {RPCResult::Type::STR_HEX, "masterkeyfingerprint", "Master key fingerprint"},
- {RPCResult::Type::STR, "name", "Device name"},
- },
- }
- }
- },
- RPCExamples{""},
- [](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue {
- const std::string command = gArgs.GetArg("-signer", "");
- if (command == "") throw JSONRPCError(RPC_WALLET_ERROR, "Error: restart bitcoind with -signer=<cmd>");
- std::string chain = gArgs.GetChainName();
- UniValue signers_res = UniValue::VARR;
- try {
- std::vector<ExternalSigner> signers;
- ExternalSigner::Enumerate(command, signers, chain);
- for (ExternalSigner signer : signers) {
- UniValue signer_res = UniValue::VOBJ;
- signer_res.pushKV("fingerprint", signer.m_fingerprint);
- signer_res.pushKV("name", signer.m_name);
- signers_res.push_back(signer_res);
- }
- } catch (const ExternalSignerException& e) {
- throw JSONRPCError(RPC_WALLET_ERROR, e.what());
- }
- UniValue result(UniValue::VOBJ);
- result.pushKV("signers", signers_res);
- return result;
- }
- };
-}
-
-static RPCHelpMan signerdisplayaddress()
-{
- return RPCHelpMan{
- "signerdisplayaddress",
- "Display address on an external signer for verification.\n",
- {
- {"address", RPCArg::Type::STR, RPCArg::Optional::NO, /* default_val */ "", "bitcoin address to display"},
- },
- RPCResult{RPCResult::Type::NONE,"",""},
- RPCExamples{""},
- [](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue {
- std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
- if (!wallet) return NullUniValue;
- CWallet* const pwallet = wallet.get();
-
- LOCK(pwallet->cs_wallet);
-
- CTxDestination dest = DecodeDestination(request.params[0].get_str());
-
- // Make sure the destination is valid
- if (!IsValidDestination(dest)) {
- throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address");
- }
-
- if (!pwallet->DisplayAddress(dest)) {
- throw JSONRPCError(RPC_WALLET_ERROR, "Failed to display address");
- }
-
- UniValue result(UniValue::VOBJ);
- result.pushKV("address", request.params[0].get_str());
- return result;
- }
- };
-}
-
-Span<const CRPCCommand> GetSignerRPCCommands()
-{
-
-// clang-format off
-static const CRPCCommand commands[] =
-{ // category actor (function)
- // --------------------- ------------------------
- { "signer", &enumeratesigners, },
- { "signer", &signerdisplayaddress, },
-};
-// clang-format on
- return MakeSpan(commands);
-}
-
-
-#endif // ENABLE_EXTERNAL_SIGNER
diff --git a/src/wallet/rpcsigner.h b/src/wallet/rpcsigner.h
deleted file mode 100644
index f3ab83c428..0000000000
--- a/src/wallet/rpcsigner.h
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright (c) 2018-2021 The Bitcoin Core developers
-// Distributed under the MIT software license, see the accompanying
-// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-
-#ifndef BITCOIN_WALLET_RPCSIGNER_H
-#define BITCOIN_WALLET_RPCSIGNER_H
-
-#include <span.h>
-#include <util/system.h>
-#include <vector>
-
-#ifdef ENABLE_EXTERNAL_SIGNER
-
-class CRPCCommand;
-
-namespace interfaces {
-class Chain;
-class Handler;
-}
-
-Span<const CRPCCommand> GetSignerRPCCommands();
-
-#endif // ENABLE_EXTERNAL_SIGNER
-
-#endif //BITCOIN_WALLET_RPCSIGNER_H
diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp
index df26f039a0..76460f106b 100644
--- a/src/wallet/rpcwallet.cpp
+++ b/src/wallet/rpcwallet.cpp
@@ -1281,7 +1281,7 @@ static void MaybePushAddress(UniValue & entry, const CTxDestination &dest)
/**
* List transactions based on the given criteria.
*
- * @param pwallet The wallet.
+ * @param wallet The wallet.
* @param wtx The wallet transaction.
* @param nMinDepth The minimum confirmation depth.
* @param fLong Whether to include the JSON version of the transaction.
@@ -2711,6 +2711,8 @@ static RPCHelpMan createwallet()
RPCExamples{
HelpExampleCli("createwallet", "\"testwallet\"")
+ HelpExampleRpc("createwallet", "\"testwallet\"")
+ + HelpExampleCliNamed("createwallet", {{"wallet_name", "descriptors"}, {"avoid_reuse", true}, {"descriptors", true}, {"load_on_startup", true}})
+ + HelpExampleRpcNamed("createwallet", {{"wallet_name", "descriptors"}, {"avoid_reuse", true}, {"descriptors", true}, {"load_on_startup", true}})
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
@@ -2748,7 +2750,7 @@ static RPCHelpMan createwallet()
#ifdef ENABLE_EXTERNAL_SIGNER
flags |= WALLET_FLAG_EXTERNAL_SIGNER;
#else
- throw JSONRPCError(RPC_WALLET_ERROR, "Configure with --enable-external-signer to use this");
+ throw JSONRPCError(RPC_WALLET_ERROR, "Compiled without external signing support (required for external signing)");
#endif
}
@@ -4524,6 +4526,48 @@ static RPCHelpMan upgradewallet()
};
}
+#ifdef ENABLE_EXTERNAL_SIGNER
+static RPCHelpMan walletdisplayaddress()
+{
+ return RPCHelpMan{"walletdisplayaddress",
+ "Display address on an external signer for verification.",
+ {
+ {"address", RPCArg::Type::STR, RPCArg::Optional::NO, /* default_val */ "", "bitcoin address to display"},
+ },
+ RPCResult{
+ RPCResult::Type::OBJ,"","",
+ {
+ {RPCResult::Type::STR, "address", "The address as confirmed by the signer"},
+ }
+ },
+ RPCExamples{""},
+ [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
+ {
+ std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
+ if (!wallet) return NullUniValue;
+ CWallet* const pwallet = wallet.get();
+
+ LOCK(pwallet->cs_wallet);
+
+ CTxDestination dest = DecodeDestination(request.params[0].get_str());
+
+ // Make sure the destination is valid
+ if (!IsValidDestination(dest)) {
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address");
+ }
+
+ if (!pwallet->DisplayAddress(dest)) {
+ throw JSONRPCError(RPC_MISC_ERROR, "Failed to display address");
+ }
+
+ UniValue result(UniValue::VOBJ);
+ result.pushKV("address", request.params[0].get_str());
+ return result;
+ }
+ };
+}
+#endif // ENABLE_EXTERNAL_SIGNER
+
RPCHelpMan abortrescan();
RPCHelpMan dumpprivkey();
RPCHelpMan importprivkey();
@@ -4600,6 +4644,9 @@ static const CRPCCommand commands[] =
{ "wallet", &unloadwallet, },
{ "wallet", &upgradewallet, },
{ "wallet", &walletcreatefundedpsbt, },
+#ifdef ENABLE_EXTERNAL_SIGNER
+ { "wallet", &walletdisplayaddress, },
+#endif // ENABLE_EXTERNAL_SIGNER
{ "wallet", &walletlock, },
{ "wallet", &walletpassphrase, },
{ "wallet", &walletpassphrasechange, },
diff --git a/src/wallet/scriptpubkeyman.cpp b/src/wallet/scriptpubkeyman.cpp
index 54319ca662..149549410c 100644
--- a/src/wallet/scriptpubkeyman.cpp
+++ b/src/wallet/scriptpubkeyman.cpp
@@ -13,7 +13,7 @@
#include <util/system.h>
#include <util/time.h>
#include <util/translation.h>
-#include <wallet/external_signer.h>
+#include <external_signer.h>
#include <wallet/scriptpubkeyman.h>
#include <optional>
@@ -84,7 +84,7 @@ bool HaveKeys(const std::vector<valtype>& pubkeys, const LegacyScriptPubKeyMan&
//! Recursively solve script and return spendable/watchonly/invalid status.
//!
//! @param keystore legacy key and script store
-//! @param script script to solve
+//! @param scriptPubKey script to solve
//! @param sigversion script type (top-level / redeemscript / witnessscript)
//! @param recurse_scripthash whether to recurse into nested p2sh and p2wsh
//! scripts or simply treat any script that has been
diff --git a/src/wallet/sqlite.cpp b/src/wallet/sqlite.cpp
index 975974cb6a..e245a277e4 100644
--- a/src/wallet/sqlite.cpp
+++ b/src/wallet/sqlite.cpp
@@ -16,6 +16,9 @@
#include <sqlite3.h>
#include <stdint.h>
+#include <utility>
+#include <vector>
+
static constexpr int32_t WALLET_SCHEMA_VERSION = 0;
static Mutex g_sqlite_mutex;
@@ -69,30 +72,21 @@ SQLiteDatabase::SQLiteDatabase(const fs::path& dir_path, const fs::path& file_pa
void SQLiteBatch::SetupSQLStatements()
{
- int res;
- if (!m_read_stmt) {
- if ((res = sqlite3_prepare_v2(m_database.m_db, "SELECT value FROM main WHERE key = ?", -1, &m_read_stmt, nullptr)) != SQLITE_OK) {
- throw std::runtime_error(strprintf("SQLiteDatabase: Failed to setup SQL statements: %s\n", sqlite3_errstr(res)));
- }
- }
- if (!m_insert_stmt) {
- if ((res = sqlite3_prepare_v2(m_database.m_db, "INSERT INTO main VALUES(?, ?)", -1, &m_insert_stmt, nullptr)) != SQLITE_OK) {
- throw std::runtime_error(strprintf("SQLiteDatabase: Failed to setup SQL statements: %s\n", sqlite3_errstr(res)));
- }
- }
- if (!m_overwrite_stmt) {
- if ((res = sqlite3_prepare_v2(m_database.m_db, "INSERT or REPLACE into main values(?, ?)", -1, &m_overwrite_stmt, nullptr)) != SQLITE_OK) {
- throw std::runtime_error(strprintf("SQLiteDatabase: Failed to setup SQL statements: %s\n", sqlite3_errstr(res)));
- }
- }
- if (!m_delete_stmt) {
- if ((res = sqlite3_prepare_v2(m_database.m_db, "DELETE FROM main WHERE key = ?", -1, &m_delete_stmt, nullptr)) != SQLITE_OK) {
- throw std::runtime_error(strprintf("SQLiteDatabase: Failed to setup SQL statements: %s\n", sqlite3_errstr(res)));
- }
- }
- if (!m_cursor_stmt) {
- if ((res = sqlite3_prepare_v2(m_database.m_db, "SELECT key, value FROM main", -1, &m_cursor_stmt, nullptr)) != SQLITE_OK) {
- throw std::runtime_error(strprintf("SQLiteDatabase: Failed to setup SQL statements : %s\n", sqlite3_errstr(res)));
+ const std::vector<std::pair<sqlite3_stmt**, const char*>> statements{
+ {&m_read_stmt, "SELECT value FROM main WHERE key = ?"},
+ {&m_insert_stmt, "INSERT INTO main VALUES(?, ?)"},
+ {&m_overwrite_stmt, "INSERT or REPLACE into main values(?, ?)"},
+ {&m_delete_stmt, "DELETE FROM main WHERE key = ?"},
+ {&m_cursor_stmt, "SELECT key, value FROM main"},
+ };
+
+ for (const auto& [stmt_prepared, stmt_text] : statements) {
+ if (*stmt_prepared == nullptr) {
+ int res = sqlite3_prepare_v2(m_database.m_db, stmt_text, -1, stmt_prepared, nullptr);
+ if (res != SQLITE_OK) {
+ throw std::runtime_error(strprintf(
+ "SQLiteDatabase: Failed to setup SQL statements: %s\n", sqlite3_errstr(res)));
+ }
}
}
}
@@ -239,6 +233,15 @@ void SQLiteDatabase::Open()
throw std::runtime_error(strprintf("SQLiteDatabase: Failed to enable fullfsync: %s\n", sqlite3_errstr(ret)));
}
+ if (gArgs.GetBoolArg("-unsafesqlitesync", false)) {
+ // Use normal synchronous mode for the journal
+ LogPrintf("WARNING SQLite is configured to not wait for data to be flushed to disk. Data loss and corruption may occur.\n");
+ ret = sqlite3_exec(m_db, "PRAGMA synchronous = OFF", nullptr, nullptr, nullptr);
+ if (ret != SQLITE_OK) {
+ throw std::runtime_error(strprintf("SQLiteDatabase: Failed to set synchronous mode to OFF: %s\n", sqlite3_errstr(ret)));
+ }
+ }
+
// Make the table for our key-value pairs
// First check that the main table exists
sqlite3_stmt* check_main_stmt{nullptr};
@@ -353,31 +356,22 @@ void SQLiteBatch::Close()
}
// Free all of the prepared statements
- int ret = sqlite3_finalize(m_read_stmt);
- if (ret != SQLITE_OK) {
- LogPrintf("SQLiteBatch: Batch closed but could not finalize read statement: %s\n", sqlite3_errstr(ret));
- }
- ret = sqlite3_finalize(m_insert_stmt);
- if (ret != SQLITE_OK) {
- LogPrintf("SQLiteBatch: Batch closed but could not finalize insert statement: %s\n", sqlite3_errstr(ret));
- }
- ret = sqlite3_finalize(m_overwrite_stmt);
- if (ret != SQLITE_OK) {
- LogPrintf("SQLiteBatch: Batch closed but could not finalize overwrite statement: %s\n", sqlite3_errstr(ret));
- }
- ret = sqlite3_finalize(m_delete_stmt);
- if (ret != SQLITE_OK) {
- LogPrintf("SQLiteBatch: Batch closed but could not finalize delete statement: %s\n", sqlite3_errstr(ret));
- }
- ret = sqlite3_finalize(m_cursor_stmt);
- if (ret != SQLITE_OK) {
- LogPrintf("SQLiteBatch: Batch closed but could not finalize cursor statement: %s\n", sqlite3_errstr(ret));
+ const std::vector<std::pair<sqlite3_stmt**, const char*>> statements{
+ {&m_read_stmt, "read"},
+ {&m_insert_stmt, "insert"},
+ {&m_overwrite_stmt, "overwrite"},
+ {&m_delete_stmt, "delete"},
+ {&m_cursor_stmt, "cursor"},
+ };
+
+ for (const auto& [stmt_prepared, stmt_description] : statements) {
+ int res = sqlite3_finalize(*stmt_prepared);
+ if (res != SQLITE_OK) {
+ LogPrintf("SQLiteBatch: Batch closed but could not finalize %s statement: %s\n",
+ stmt_description, sqlite3_errstr(res));
+ }
+ *stmt_prepared = nullptr;
}
- m_read_stmt = nullptr;
- m_insert_stmt = nullptr;
- m_overwrite_stmt = nullptr;
- m_delete_stmt = nullptr;
- m_cursor_stmt = nullptr;
}
bool SQLiteBatch::ReadKey(CDataStream&& key, CDataStream& value)
diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp
index ba2e17d62a..011d59ecaf 100644
--- a/src/wallet/test/wallet_tests.cpp
+++ b/src/wallet/test/wallet_tests.cpp
@@ -213,8 +213,7 @@ BOOST_FIXTURE_TEST_CASE(importmulti_rescan, TestChain100Setup)
key.pushKV("timestamp", newTip->GetBlockTimeMax() + TIMESTAMP_WINDOW + 1);
key.pushKV("internal", UniValue(true));
keys.push_back(key);
- std::any context;
- JSONRPCRequest request(context);
+ JSONRPCRequest request;
request.params.setArray();
request.params.push_back(keys);
@@ -265,8 +264,7 @@ BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup)
AddWallet(wallet);
wallet->SetLastBlockProcessed(::ChainActive().Height(), ::ChainActive().Tip()->GetBlockHash());
}
- std::any context;
- JSONRPCRequest request(context);
+ JSONRPCRequest request;
request.params.setArray();
request.params.push_back(backup_file);
@@ -281,8 +279,7 @@ BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup)
LOCK(wallet->cs_wallet);
wallet->SetupLegacyScriptPubKeyMan();
- std::any context;
- JSONRPCRequest request(context);
+ JSONRPCRequest request;
request.params.setArray();
request.params.push_back(backup_file);
AddWallet(wallet);
@@ -298,8 +295,6 @@ BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup)
BOOST_CHECK_EQUAL(found, expected);
}
}
-
- SetMockTime(0);
}
// Check that GetImmatureCredit() returns a newly calculated value instead of
@@ -380,9 +375,6 @@ BOOST_AUTO_TEST_CASE(ComputeTimeSmart)
// If there are future entries, new transaction should use time of the
// newest entry that is no more than 300 seconds ahead of the clock time.
BOOST_CHECK_EQUAL(AddTx(*m_node.chainman, m_wallet, 5, 50, 600), 300);
-
- // Reset mock time for other tests.
- SetMockTime(0);
}
BOOST_AUTO_TEST_CASE(LoadReceiveRequests)
@@ -695,6 +687,7 @@ BOOST_FIXTURE_TEST_CASE(wallet_descriptor_test, BasicTestingSetup)
//! rescanning where new transactions in new blocks could be lost.
BOOST_FIXTURE_TEST_CASE(CreateWallet, TestChain100Setup)
{
+ gArgs.ForceSetArg("-unsafesqlitesync", "1");
// Create new wallet with known key and unload it.
auto wallet = TestLoadWallet(*m_node.chain);
CKey key;
@@ -790,6 +783,7 @@ BOOST_FIXTURE_TEST_CASE(CreateWallet, TestChain100Setup)
BOOST_FIXTURE_TEST_CASE(ZapSelectTx, TestChain100Setup)
{
+ gArgs.ForceSetArg("-unsafesqlitesync", "1");
auto wallet = TestLoadWallet(*m_node.chain);
CKey key;
key.MakeNewKey(true);
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index b00fa851fd..332e7b1397 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -3594,19 +3594,6 @@ void ReserveDestination::ReturnDestination()
address = CNoDestination();
}
-#ifdef ENABLE_EXTERNAL_SIGNER
-ExternalSigner CWallet::GetExternalSigner()
-{
- const std::string command = gArgs.GetArg("-signer", "");
- if (command == "") throw std::runtime_error(std::string(__func__) + ": restart bitcoind with -signer=<cmd>");
- std::vector<ExternalSigner> signers;
- ExternalSigner::Enumerate(command, signers, Params().NetworkIDString());
- if (signers.empty()) throw std::runtime_error(std::string(__func__) + ": No external signers found");
- // TODO: add fingerprint argument in case of multiple signers
- return signers[0];
-}
-#endif
-
bool CWallet::DisplayAddress(const CTxDestination& dest)
{
#ifdef ENABLE_EXTERNAL_SIGNER
@@ -3619,7 +3606,7 @@ bool CWallet::DisplayAddress(const CTxDestination& dest)
if (signer_spk_man == nullptr) {
return false;
}
- ExternalSigner signer = GetExternalSigner(); // TODO: move signer in spk_man
+ ExternalSigner signer = ExternalSignerScriptPubKeyMan::GetExternalSigner();
return signer_spk_man->DisplayAddress(scriptPubKey, signer);
#else
return false;
@@ -4516,7 +4503,7 @@ void CWallet::LoadDescriptorScriptPubKeyMan(uint256 id, WalletDescriptor& desc)
auto spk_manager = std::unique_ptr<ScriptPubKeyMan>(new ExternalSignerScriptPubKeyMan(*this, desc));
m_spk_managers[id] = std::move(spk_manager);
#else
- throw std::runtime_error(std::string(__func__) + ": Configure with --enable-external-signer to use external signer wallets");
+ throw std::runtime_error(std::string(__func__) + ": Compiled without external signing support (required for external signing)");
#endif
} else {
auto spk_manager = std::unique_ptr<ScriptPubKeyMan>(new DescriptorScriptPubKeyMan(*this, desc));
@@ -4585,8 +4572,8 @@ void CWallet::SetupDescriptorScriptPubKeyMans()
}
}
#else
- throw std::runtime_error(std::string(__func__) + ": Wallets with external signers require Boost::Process library.");
-#endif
+ throw std::runtime_error(std::string(__func__) + ": Compiled without external signing support (required for external signing)");
+#endif // ENABLE_EXTERNAL_SIGNER
}
}
diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h
index 6031d36b97..c4acef8705 100644
--- a/src/wallet/wallet.h
+++ b/src/wallet/wallet.h
@@ -22,7 +22,7 @@
#include <wallet/coinselection.h>
#include <wallet/crypter.h>
#include <wallet/scriptpubkeyman.h>
-#include <wallet/external_signer.h>
+#include <external_signer.h>
#include <wallet/walletdb.h>
#include <wallet/walletutil.h>
@@ -845,9 +845,6 @@ public:
std::vector<OutputGroup> GroupOutputs(const std::vector<COutput>& outputs, bool separate_coins, const CFeeRate& effective_feerate, const CFeeRate& long_term_feerate, const CoinEligibilityFilter& filter, bool positive_only) const;
-#ifdef ENABLE_EXTERNAL_SIGNER
- ExternalSigner GetExternalSigner() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
-#endif
/** Display address on an external signer. Returns false if external signer support is not compiled */
bool DisplayAddress(const CTxDestination& dest) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
@@ -1181,7 +1178,7 @@ public:
* Obviously holding cs_main/cs_wallet when going into this call may cause
* deadlock
*/
- void BlockUntilSyncedToCurrentChain() const EXCLUSIVE_LOCKS_REQUIRED(!::cs_main, !cs_wallet);
+ void BlockUntilSyncedToCurrentChain() const LOCKS_EXCLUDED(::cs_main) EXCLUSIVE_LOCKS_REQUIRED(!cs_wallet);
/** set a single wallet flag */
void SetWalletFlag(uint64_t flags);
diff --git a/src/zmq/zmqpublishnotifier.cpp b/src/zmq/zmqpublishnotifier.cpp
index 168ba841c8..25afa94d0f 100644
--- a/src/zmq/zmqpublishnotifier.cpp
+++ b/src/zmq/zmqpublishnotifier.cpp
@@ -6,10 +6,11 @@
#include <chain.h>
#include <chainparams.h>
+#include <node/blockstorage.h>
#include <rpc/server.h>
#include <streams.h>
#include <util/system.h>
-#include <validation.h>
+#include <validation.h> // For cs_main
#include <zmq/zmqutil.h>
#include <zmq.h>
diff --git a/test/functional/rpc_blockchain.py b/test/functional/rpc_blockchain.py
index e090030205..821409ccc1 100755
--- a/test/functional/rpc_blockchain.py
+++ b/test/functional/rpc_blockchain.py
@@ -149,6 +149,7 @@ class BlockchainTest(BitcoinTestFramework):
'count': 57,
'possible': True,
},
+ 'min_activation_height': 0,
},
'active': False
},
@@ -158,7 +159,8 @@ class BlockchainTest(BitcoinTestFramework):
'status': 'active',
'start_time': -1,
'timeout': 9223372036854775807,
- 'since': 0
+ 'since': 0,
+ 'min_activation_height': 0,
},
'height': 0,
'active': True
diff --git a/test/functional/rpc_net.py b/test/functional/rpc_net.py
index 9adb32c3c5..16d7958712 100755
--- a/test/functional/rpc_net.py
+++ b/test/functional/rpc_net.py
@@ -195,7 +195,7 @@ class NetTest(BitcoinTestFramework):
for i in range(10000):
first_octet = i >> 8
second_octet = i % 256
- a = "{}.{}.1.1".format(first_octet, second_octet)
+ a = "{}.{}.1.1".format(first_octet, second_octet) # IPV4
imported_addrs.append(a)
self.nodes[0].addpeeraddress(a, 8333)
@@ -212,6 +212,7 @@ class NetTest(BitcoinTestFramework):
assert_equal(a["services"], NODE_NETWORK | NODE_WITNESS)
assert a["address"] in imported_addrs
assert_equal(a["port"], 8333)
+ assert_equal(a["network"], "ipv4")
node_addresses = self.nodes[0].getnodeaddresses(1)
assert_equal(len(node_addresses), 1)
diff --git a/test/functional/rpc_signer.py b/test/functional/rpc_signer.py
new file mode 100755
index 0000000000..3188763f49
--- /dev/null
+++ b/test/functional/rpc_signer.py
@@ -0,0 +1,79 @@
+#!/usr/bin/env python3
+# Copyright (c) 2017-2018 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 external signer.
+
+Verify that a bitcoind node can use an external signer command.
+See also wallet_signer.py for tests that require wallet context.
+"""
+import os
+import platform
+
+from test_framework.test_framework import BitcoinTestFramework
+from test_framework.util import (
+ assert_equal,
+ assert_raises_rpc_error,
+)
+
+
+class RPCSignerTest(BitcoinTestFramework):
+ def mock_signer_path(self):
+ path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'mocks', 'signer.py')
+ if platform.system() == "Windows":
+ return "py " + path
+ else:
+ return path
+
+ def set_test_params(self):
+ self.num_nodes = 4
+
+ self.extra_args = [
+ [],
+ [f"-signer={self.mock_signer_path()}", '-keypool=10'],
+ [f"-signer={self.mock_signer_path()}", '-keypool=10'],
+ ["-signer=fake.py"],
+ ]
+
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_external_signer()
+
+ def set_mock_result(self, node, res):
+ with open(os.path.join(node.cwd, "mock_result"), "w", encoding="utf8") as f:
+ f.write(res)
+
+ def clear_mock_result(self, node):
+ os.remove(os.path.join(node.cwd, "mock_result"))
+
+ def run_test(self):
+ self.log.debug(f"-signer={self.mock_signer_path()}")
+
+ assert_raises_rpc_error(-1, 'Error: restart bitcoind with -signer=<cmd>',
+ self.nodes[0].enumeratesigners
+ )
+
+ # Handle script missing:
+ assert_raises_rpc_error(-1, 'execve failed: No such file or directory',
+ self.nodes[3].enumeratesigners
+ )
+
+ # Handle error thrown by script
+ self.set_mock_result(self.nodes[1], "2")
+ assert_raises_rpc_error(-1, 'RunCommandParseJSON error',
+ self.nodes[1].enumeratesigners
+ )
+ self.clear_mock_result(self.nodes[1])
+
+ self.set_mock_result(self.nodes[1], '0 [{"type": "trezor", "model": "trezor_t", "error": "fingerprint not found"}]')
+ assert_raises_rpc_error(-1, 'fingerprint not found',
+ self.nodes[1].enumeratesigners
+ )
+ self.clear_mock_result(self.nodes[1])
+
+ result = self.nodes[1].enumeratesigners()
+ assert_equal(len(result['signers']), 2)
+ assert_equal(result['signers'][0]["fingerprint"], "00000001")
+ assert_equal(result['signers'][0]["name"], "trezor_t")
+
+if __name__ == '__main__':
+ RPCSignerTest().main()
diff --git a/test/functional/rpc_signrawtransaction.py b/test/functional/rpc_signrawtransaction.py
index 2fbbdbbdf0..60b4d1c744 100755
--- a/test/functional/rpc_signrawtransaction.py
+++ b/test/functional/rpc_signrawtransaction.py
@@ -4,16 +4,17 @@
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Test transaction signing using the signrawtransaction* RPCs."""
-from test_framework.address import check_script, script_to_p2sh
+from test_framework.address import check_script, script_to_p2sh, script_to_p2wsh
from test_framework.key import ECKey
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import assert_equal, assert_raises_rpc_error, find_vout_for_address, hex_str_to_bytes
-from test_framework.messages import sha256
-from test_framework.script import CScript, OP_0, OP_CHECKSIG
+from test_framework.messages import sha256, CTransaction, CTxInWitness
+from test_framework.script import CScript, OP_0, OP_CHECKSIG, OP_CHECKSEQUENCEVERIFY, OP_CHECKLOCKTIMEVERIFY, OP_DROP, OP_TRUE
from test_framework.script_util import key_to_p2pkh_script, script_to_p2sh_p2wsh_script, script_to_p2wsh_script
from test_framework.wallet_util import bytes_to_wif
-from decimal import Decimal
+from decimal import Decimal, getcontext
+from io import BytesIO
class SignRawTransactionsTest(BitcoinTestFramework):
def set_test_params(self):
@@ -238,6 +239,78 @@ class SignRawTransactionsTest(BitcoinTestFramework):
txn = self.nodes[0].signrawtransactionwithwallet(hex_str, prev_txs)
assert txn["complete"]
+ def test_signing_with_csv(self):
+ self.log.info("Test signing a transaction containing a fully signed CSV input")
+ self.nodes[0].walletpassphrase("password", 9999)
+ getcontext().prec = 8
+
+ # Make sure CSV is active
+ self.nodes[0].generate(500)
+
+ # Create a P2WSH script with CSV
+ script = CScript([1, OP_CHECKSEQUENCEVERIFY, OP_DROP])
+ address = script_to_p2wsh(script)
+
+ # Fund that address and make the spend
+ txid = self.nodes[0].sendtoaddress(address, 1)
+ vout = find_vout_for_address(self.nodes[0], txid, address)
+ self.nodes[0].generate(1)
+ utxo = self.nodes[0].listunspent()[0]
+ amt = Decimal(1) + utxo["amount"] - Decimal(0.00001)
+ tx = self.nodes[0].createrawtransaction(
+ [{"txid": txid, "vout": vout, "sequence": 1},{"txid": utxo["txid"], "vout": utxo["vout"]}],
+ [{self.nodes[0].getnewaddress(): amt}],
+ self.nodes[0].getblockcount()
+ )
+
+ # Set the witness script
+ ctx = CTransaction()
+ ctx.deserialize(BytesIO(hex_str_to_bytes(tx)))
+ ctx.wit.vtxinwit.append(CTxInWitness())
+ ctx.wit.vtxinwit[0].scriptWitness.stack = [CScript([OP_TRUE]), script]
+ tx = ctx.serialize_with_witness().hex()
+
+ # Sign and send the transaction
+ signed = self.nodes[0].signrawtransactionwithwallet(tx)
+ assert_equal(signed["complete"], True)
+ self.nodes[0].sendrawtransaction(signed["hex"])
+
+ def test_signing_with_cltv(self):
+ self.log.info("Test signing a transaction containing a fully signed CLTV input")
+ self.nodes[0].walletpassphrase("password", 9999)
+ getcontext().prec = 8
+
+ # Make sure CSV is active
+ self.nodes[0].generate(1500)
+
+ # Create a P2WSH script with CLTV
+ script = CScript([1000, OP_CHECKLOCKTIMEVERIFY, OP_DROP])
+ address = script_to_p2wsh(script)
+
+ # Fund that address and make the spend
+ txid = self.nodes[0].sendtoaddress(address, 1)
+ vout = find_vout_for_address(self.nodes[0], txid, address)
+ self.nodes[0].generate(1)
+ utxo = self.nodes[0].listunspent()[0]
+ amt = Decimal(1) + utxo["amount"] - Decimal(0.00001)
+ tx = self.nodes[0].createrawtransaction(
+ [{"txid": txid, "vout": vout},{"txid": utxo["txid"], "vout": utxo["vout"]}],
+ [{self.nodes[0].getnewaddress(): amt}],
+ self.nodes[0].getblockcount()
+ )
+
+ # Set the witness script
+ ctx = CTransaction()
+ ctx.deserialize(BytesIO(hex_str_to_bytes(tx)))
+ ctx.wit.vtxinwit.append(CTxInWitness())
+ ctx.wit.vtxinwit[0].scriptWitness.stack = [CScript([OP_TRUE]), script]
+ tx = ctx.serialize_with_witness().hex()
+
+ # Sign and send the transaction
+ signed = self.nodes[0].signrawtransactionwithwallet(tx)
+ assert_equal(signed["complete"], True)
+ self.nodes[0].sendrawtransaction(signed["hex"])
+
def run_test(self):
self.successful_signing_test()
self.script_verification_error_test()
@@ -245,6 +318,8 @@ class SignRawTransactionsTest(BitcoinTestFramework):
self.OP_1NEGATE_test()
self.test_with_lock_outputs()
self.test_fully_signed_tx()
+ self.test_signing_with_csv()
+ self.test_signing_with_cltv()
if __name__ == '__main__':
diff --git a/test/functional/test_framework/util.py b/test/functional/test_framework/util.py
index 5c774934be..55166ba0ad 100644
--- a/test/functional/test_framework/util.py
+++ b/test/functional/test_framework/util.py
@@ -374,6 +374,8 @@ def write_config(config_path, *, n, chain, extra_config=""):
f.write("upnp=0\n")
f.write("natpmp=0\n")
f.write("shrinkdebugfile=0\n")
+ # To improve SQLite wallet performance so that the tests don't timeout, use -unsafesqlitesync
+ f.write("unsafesqlitesync=1\n")
f.write(extra_config)
diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py
index 001d161612..bd58f2cd51 100755
--- a/test/functional/test_runner.py
+++ b/test/functional/test_runner.py
@@ -111,6 +111,7 @@ BASE_SCRIPTS = [
'wallet_listtransactions.py --legacy-wallet',
'wallet_listtransactions.py --descriptors',
'feature_taproot.py',
+ 'rpc_signer.py',
'wallet_signer.py --descriptors',
# vv Tests less than 60s vv
'p2p_sendheaders.py',
diff --git a/test/functional/wallet_basic.py b/test/functional/wallet_basic.py
index dc6f8ed9c4..46eecae611 100755
--- a/test/functional/wallet_basic.py
+++ b/test/functional/wallet_basic.py
@@ -95,6 +95,8 @@ class WalletTest(BitcoinTestFramework):
# but invisible if you include mempool
txout = self.nodes[0].gettxout(confirmed_txid, confirmed_index, False)
assert_equal(txout['value'], 50)
+ txout = self.nodes[0].gettxout(confirmed_txid, confirmed_index) # by default include_mempool=True
+ assert txout is None
txout = self.nodes[0].gettxout(confirmed_txid, confirmed_index, True)
assert txout is None
# new utxo from mempool should be invisible if you exclude mempool
diff --git a/test/functional/wallet_listdescriptors.py b/test/functional/wallet_listdescriptors.py
index 8d02949ff4..c1444164ce 100755
--- a/test/functional/wallet_listdescriptors.py
+++ b/test/functional/wallet_listdescriptors.py
@@ -36,15 +36,16 @@ class ListDescriptorsTest(BitcoinTestFramework):
self.log.info('Test the command for empty descriptors wallet.')
node.createwallet(wallet_name='w2', blank=True, descriptors=True)
- assert_equal(0, len(node.get_wallet_rpc('w2').listdescriptors()))
+ assert_equal(0, len(node.get_wallet_rpc('w2').listdescriptors()['descriptors']))
self.log.info('Test the command for a default descriptors wallet.')
node.createwallet(wallet_name='w3', descriptors=True)
result = node.get_wallet_rpc('w3').listdescriptors()
- assert_equal(6, len(result))
- assert_equal(6, len([d for d in result if d['active']]))
- assert_equal(3, len([d for d in result if d['internal']]))
- for item in result:
+ assert_equal("w3", result['wallet_name'])
+ assert_equal(6, len(result['descriptors']))
+ assert_equal(6, len([d for d in result['descriptors'] if d['active']]))
+ assert_equal(3, len([d for d in result['descriptors'] if d['internal']]))
+ for item in result['descriptors']:
assert item['desc'] != ''
assert item['next'] == 0
assert item['range'] == [0, 0]
@@ -59,12 +60,17 @@ class ListDescriptorsTest(BitcoinTestFramework):
'desc': descsum_create('wpkh(' + xprv + hardened_path + '/0/*)'),
'timestamp': 1296688602,
}])
- expected = {'desc': descsum_create('wpkh([80002067' + hardened_path + ']' + xpub_acc + '/0/*)'),
- 'timestamp': 1296688602,
- 'active': False,
- 'range': [0, 0],
- 'next': 0}
- assert_equal([expected], wallet.listdescriptors())
+ expected = {
+ 'wallet_name': 'w2',
+ 'descriptors': [
+ {'desc': descsum_create('wpkh([80002067' + hardened_path + ']' + xpub_acc + '/0/*)'),
+ 'timestamp': 1296688602,
+ 'active': False,
+ 'range': [0, 0],
+ 'next': 0},
+ ],
+ }
+ assert_equal(expected, wallet.listdescriptors())
self.log.info('Test non-active non-range combo descriptor')
node.createwallet(wallet_name='w4', blank=True, descriptors=True)
@@ -73,9 +79,14 @@ class ListDescriptorsTest(BitcoinTestFramework):
'desc': descsum_create('combo(' + node.get_deterministic_priv_key().key + ')'),
'timestamp': 1296688602,
}])
- expected = [{'active': False,
- 'desc': 'combo(0227d85ba011276cf25b51df6a188b75e604b38770a462b2d0e9fb2fc839ef5d3f)#np574htj',
- 'timestamp': 1296688602}]
+ expected = {
+ 'wallet_name': 'w4',
+ 'descriptors': [
+ {'active': False,
+ 'desc': 'combo(0227d85ba011276cf25b51df6a188b75e604b38770a462b2d0e9fb2fc839ef5d3f)#np574htj',
+ 'timestamp': 1296688602},
+ ]
+ }
assert_equal(expected, wallet.listdescriptors())
diff --git a/test/functional/wallet_signer.py b/test/functional/wallet_signer.py
index 9dd080dca9..afd4fd3691 100755
--- a/test/functional/wallet_signer.py
+++ b/test/functional/wallet_signer.py
@@ -5,6 +5,7 @@
"""Test external signer.
Verify that a bitcoind node can use an external signer command
+See also rpc_signer.py for tests without wallet context.
"""
import os
import platform
@@ -16,7 +17,7 @@ from test_framework.util import (
)
-class SignerTest(BitcoinTestFramework):
+class WalletSignerTest(BitcoinTestFramework):
def mock_signer_path(self):
path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'mocks', 'signer.py')
if platform.system() == "Windows":
@@ -25,18 +26,16 @@ class SignerTest(BitcoinTestFramework):
return path
def set_test_params(self):
- self.num_nodes = 4
+ self.num_nodes = 2
self.extra_args = [
[],
[f"-signer={self.mock_signer_path()}", '-keypool=10'],
- [f"-signer={self.mock_signer_path()}", '-keypool=10'],
- ["-signer=fake.py"],
]
def skip_test_if_missing_module(self):
- self.skip_if_no_wallet()
self.skip_if_no_external_signer()
+ self.skip_if_no_wallet()
def set_mock_result(self, node, res):
with open(os.path.join(node.cwd, "mock_result"), "w", encoding="utf8") as f:
@@ -48,28 +47,6 @@ class SignerTest(BitcoinTestFramework):
def run_test(self):
self.log.debug(f"-signer={self.mock_signer_path()}")
- assert_raises_rpc_error(-4, 'Error: restart bitcoind with -signer=<cmd>',
- self.nodes[0].enumeratesigners
- )
-
- # Handle script missing:
- assert_raises_rpc_error(-1, 'execve failed: No such file or directory',
- self.nodes[3].enumeratesigners
- )
-
- # Handle error thrown by script
- self.set_mock_result(self.nodes[1], "2")
- assert_raises_rpc_error(-1, 'RunCommandParseJSON error',
- self.nodes[1].enumeratesigners
- )
- self.clear_mock_result(self.nodes[1])
-
- self.set_mock_result(self.nodes[1], '0 [{"type": "trezor", "model": "trezor_t", "error": "fingerprint not found"}]')
- assert_raises_rpc_error(-4, 'fingerprint not found',
- self.nodes[1].enumeratesigners
- )
- self.clear_mock_result(self.nodes[1])
-
# Create new wallets for an external signer.
# disable_private_keys and descriptors must be true:
assert_raises_rpc_error(-4, "Private keys must be disabled when using an external signer", self.nodes[1].createwallet, wallet_name='not_hww', disable_private_keys=False, descriptors=True, external_signer=True)
@@ -81,11 +58,6 @@ class SignerTest(BitcoinTestFramework):
self.nodes[1].createwallet(wallet_name='hww', disable_private_keys=True, descriptors=True, external_signer=True)
hww = self.nodes[1].get_wallet_rpc('hww')
- result = hww.enumeratesigners()
- assert_equal(len(result['signers']), 2)
- assert_equal(result['signers'][0]["fingerprint"], "00000001")
- assert_equal(result['signers'][0]["name"], "trezor_t")
-
# Flag can't be set afterwards (could be added later for non-blank descriptor based watch-only wallets)
self.nodes[1].createwallet(wallet_name='not_hww', disable_private_keys=True, descriptors=True, external_signer=False)
not_hww = self.nodes[1].get_wallet_rpc('not_hww')
@@ -123,14 +95,14 @@ class SignerTest(BitcoinTestFramework):
assert_equal(address_info['ismine'], True)
assert_equal(address_info['hdkeypath'], "m/44'/1'/0'/0/0")
- self.log.info('Test signerdisplayaddress')
- result = hww.signerdisplayaddress(address1)
+ self.log.info('Test walletdisplayaddress')
+ result = hww.walletdisplayaddress(address1)
assert_equal(result, {"address": address1})
# Handle error thrown by script
self.set_mock_result(self.nodes[1], "2")
assert_raises_rpc_error(-1, 'RunCommandParseJSON error',
- hww.signerdisplayaddress, address1
+ hww.walletdisplayaddress, address1
)
self.clear_mock_result(self.nodes[1])
@@ -214,4 +186,4 @@ class SignerTest(BitcoinTestFramework):
# self.clear_mock_result(self.nodes[4])
if __name__ == '__main__':
- SignerTest().main()
+ WalletSignerTest().main()
diff --git a/test/lint/lint-circular-dependencies.sh b/test/lint/lint-circular-dependencies.sh
index 0b15f99448..ad2333a808 100755
--- a/test/lint/lint-circular-dependencies.sh
+++ b/test/lint/lint-circular-dependencies.sh
@@ -11,7 +11,9 @@ export LC_ALL=C
EXPECTED_CIRCULAR_DEPENDENCIES=(
"chainparamsbase -> util/system -> chainparamsbase"
"index/txindex -> validation -> index/txindex"
- "index/blockfilterindex -> validation -> index/blockfilterindex"
+ "node/blockstorage -> validation -> node/blockstorage"
+ "index/blockfilterindex -> node/blockstorage -> validation -> index/blockfilterindex"
+ "index/base -> validation -> index/blockfilterindex -> index/base"
"policy/fees -> txmempool -> policy/fees"
"qt/addresstablemodel -> qt/walletmodel -> qt/addresstablemodel"
"qt/bitcoingui -> qt/walletframe -> qt/bitcoingui"
diff --git a/test/sanitizer_suppressions/tsan b/test/sanitizer_suppressions/tsan
index 3fc9fac25c..7db051ca37 100644
--- a/test/sanitizer_suppressions/tsan
+++ b/test/sanitizer_suppressions/tsan
@@ -3,32 +3,12 @@
#
# https://github.com/google/sanitizers/wiki/ThreadSanitizerSuppressions
-# double locks (TODO fix)
-mutex:g_genesis_wait_mutex
-mutex:Interrupt
-mutex:CThreadInterrupt
-mutex:CConnman::Interrupt
-mutex:CConnman::WakeMessageHandler
-mutex:CConnman::ThreadOpenConnections
-mutex:CConnman::ThreadOpenAddedConnections
-mutex:CConnman::SocketHandler
-mutex:UpdateTip
-mutex:PeerManagerImpl::UpdatedBlockTip
-mutex:g_best_block_mutex
-
# race (TODO fix)
-race:CConnman::WakeMessageHandler
-race:CConnman::ThreadMessageHandler
-race:fHaveGenesis
-race:ProcessNewBlock
-race:ThreadImport
race:LoadWallet
race:WalletBatch::WriteHDChain
race:BerkeleyBatch
race:BerkeleyDatabase
race:DatabaseBatch
-race:leveldb::DBImpl::DeleteObsoleteFiles
-race:validation_chainstatemanager_tests
race:zmq::*
race:bitcoin-qt
@@ -36,12 +16,16 @@ race:bitcoin-qt
deadlock:CChainState::ConnectTip
# Intentional deadlock in tests
-deadlock:TestPotentialDeadLockDetected
+deadlock:sync_tests::potential_deadlock_detected
# Wildcard for all gui tests, should be replaced with non-wildcard suppressions
race:src/qt/test/*
deadlock:src/qt/test/*
+# Race in src/test/main.cpp
+# Can be removed once upgraded to boost test 1.74 in depends
+race:validation_chainstatemanager_tests
+
# External libraries
deadlock:libdb
race:libzmq
diff --git a/test/sanitizer_suppressions/ubsan b/test/sanitizer_suppressions/ubsan
index 97f0f45e7f..27885b094e 100644
--- a/test/sanitizer_suppressions/ubsan
+++ b/test/sanitizer_suppressions/ubsan
@@ -1,6 +1,10 @@
# -fsanitize=undefined suppressions
# =================================
-# No suppressions at the moment. Hooray!
+# This would be `signed-integer-overflow:CTxMemPool::PrioritiseTransaction`,
+# however due to a bug in clang the symbolizer is disabled and thus no symbol
+# names can be used.
+# See https://github.com/google/sanitizers/issues/1364
+signed-integer-overflow:txmempool.cpp
# -fsanitize=integer suppressions
# ===============================