aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.cirrus.yml76
-rw-r--r--.python-version2
-rw-r--r--build_msvc/vcpkg.json7
-rw-r--r--ci/lint/Dockerfile2
-rwxr-xr-xci/test/00_setup_env_i686_centos.sh3
-rwxr-xr-xci/test/00_setup_env_native_asan.sh11
-rwxr-xr-xci/test/00_setup_env_native_fuzz.sh6
-rwxr-xr-xci/test/00_setup_env_native_fuzz_with_msan.sh4
-rwxr-xr-xci/test/00_setup_env_native_fuzz_with_valgrind.sh6
-rwxr-xr-xci/test/00_setup_env_native_msan.sh4
-rwxr-xr-xci/test/00_setup_env_native_nowallet_libbitcoinkernel.sh7
-rwxr-xr-xci/test/00_setup_env_native_qt5.sh10
-rwxr-xr-xci/test/00_setup_env_native_tidy.sh6
-rwxr-xr-xci/test/00_setup_env_native_tsan.sh6
-rwxr-xr-xci/test/00_setup_env_native_valgrind.sh6
-rwxr-xr-xci/test/01_base_install.sh71
-rwxr-xr-xci/test/04_install.sh30
-rwxr-xr-xci/test/05_before_script.sh1
-rwxr-xr-xci/test/06_script_b.sh5
-rw-r--r--configure.ac8
-rwxr-xr-xcontrib/devtools/symbol-check.py26
-rwxr-xr-xcontrib/guix/libexec/build.sh6
-rw-r--r--contrib/guix/manifest.scm80
-rw-r--r--contrib/seeds/README.md12
-rwxr-xr-xcontrib/seeds/generate-seeds.py2
-rwxr-xr-xcontrib/seeds/makeseeds.py16
-rw-r--r--contrib/seeds/nodes_main.txt1157
-rw-r--r--contrib/seeds/nodes_main_manual.txt71
-rw-r--r--contrib/valgrind.supp21
-rw-r--r--contrib/verify-binaries/README.md88
-rwxr-xr-xcontrib/verify-binaries/test.py59
-rwxr-xr-xcontrib/verify-binaries/verify.py713
-rwxr-xr-xcontrib/verify-commits/verify-commits.py15
-rw-r--r--contrib/verifybinaries/README.md30
-rwxr-xr-xcontrib/verifybinaries/verify.py183
-rw-r--r--depends/Makefile6
-rw-r--r--depends/README.md4
-rwxr-xr-xdepends/config.guess1234
-rw-r--r--depends/config.site.in4
-rwxr-xr-xdepends/config.sub109
-rw-r--r--depends/funcs.mk2
-rwxr-xr-xdepends/gen_id6
-rw-r--r--depends/hosts/darwin.mk8
-rw-r--r--depends/hosts/linux.mk2
-rw-r--r--depends/packages/bdb.mk2
-rw-r--r--depends/packages/fontconfig.mk1
-rw-r--r--depends/packages/libevent.mk5
-rw-r--r--depends/packages/libmultiprocess.mk4
-rw-r--r--depends/packages/qrencode.mk7
-rw-r--r--depends/packages/qt.mk12
-rw-r--r--doc/build-openbsd.md6
-rw-r--r--doc/dependencies.md6
-rw-r--r--doc/developer-notes.md4
-rw-r--r--doc/policy/packages.md37
-rw-r--r--doc/release-note-26194.md4
-rw-r--r--doc/release-notes-19762.md19
-rw-r--r--doc/release-notes-22087.md4
-rw-r--r--doc/release-notes-23395.md8
-rw-r--r--doc/release-notes-25158.md6
-rw-r--r--doc/release-notes-25375.md11
-rw-r--r--doc/release-notes-25412.md5
-rw-r--r--doc/release-notes-25574.md13
-rw-r--r--doc/release-notes-25730.md6
-rw-r--r--doc/release-notes-25934.md8
-rw-r--r--doc/release-notes-25943.md4
-rw-r--r--doc/release-notes-25957.md9
-rw-r--r--doc/release-notes-26094.md6
-rw-r--r--doc/release-notes-26213.md8
-rw-r--r--doc/release-notes-26265.md6
-rw-r--r--doc/release-notes-26471.md13
-rw-r--r--doc/release-notes-26618.md4
-rw-r--r--doc/release-notes-26628.md4
-rw-r--r--doc/release-notes-26646.md8
-rw-r--r--doc/release-notes-26896.md7
-rw-r--r--doc/release-notes-26899.md5
-rw-r--r--doc/release-notes-27037.md5
-rw-r--r--doc/release-notes-27068.md6
-rw-r--r--doc/release-process.md6
-rw-r--r--doc/tor.md8
-rw-r--r--src/.clang-tidy9
-rw-r--r--src/Makefile.am17
-rw-r--r--src/Makefile.bench.include1
-rw-r--r--src/Makefile.test.include3
-rw-r--r--src/Makefile.test_util.include1
-rw-r--r--src/addrdb.cpp5
-rw-r--r--src/addrdb.h2
-rw-r--r--src/addrman.cpp154
-rw-r--r--src/addrman.h7
-rw-r--r--src/addrman_impl.h12
-rw-r--r--src/banman.cpp1
-rw-r--r--src/banman.h2
-rw-r--r--src/bench/addrman.cpp52
-rw-r--r--src/bench/bench.cpp2
-rw-r--r--src/bench/bench.h2
-rw-r--r--src/bench/bench_bitcoin.cpp4
-rw-r--r--src/bench/checkblock.cpp2
-rw-r--r--src/bench/coin_selection.cpp3
-rw-r--r--src/bench/lockedpool.cpp4
-rw-r--r--src/bench/pool.cpp50
-rw-r--r--src/bench/wallet_create_tx.cpp5
-rw-r--r--src/bitcoin-chainstate.cpp2
-rw-r--r--src/bitcoin-cli.cpp5
-rw-r--r--src/bitcoin-tx.cpp3
-rw-r--r--src/bitcoin-util.cpp2
-rw-r--r--src/bitcoin-wallet.cpp3
-rw-r--r--src/bitcoind.cpp3
-rw-r--r--src/chainparams.cpp3
-rw-r--r--src/chainparamsbase.cpp2
-rw-r--r--src/chainparamsseeds.h1150
-rw-r--r--src/coins.cpp15
-rw-r--r--src/coins.h20
-rw-r--r--src/common/args.cpp823
-rw-r--r--src/common/args.h465
-rw-r--r--src/common/config.cpp220
-rw-r--r--src/common/init.cpp6
-rw-r--r--src/compat/assumptions.h1
-rw-r--r--src/compat/compat.h9
-rw-r--r--src/dbwrapper.cpp4
-rw-r--r--src/dbwrapper.h2
-rw-r--r--src/dummywallet.cpp3
-rw-r--r--src/flatfile.cpp2
-rw-r--r--src/flatfile.h2
-rw-r--r--src/headerssync.cpp2
-rw-r--r--src/headerssync.h13
-rw-r--r--src/httprpc.cpp3
-rw-r--r--src/httpserver.cpp6
-rw-r--r--src/i2p.cpp4
-rw-r--r--src/i2p.h2
-rw-r--r--src/index/base.cpp2
-rw-r--r--src/index/blockfilterindex.cpp3
-rw-r--r--src/index/coinstatsindex.cpp2
-rw-r--r--src/index/txindex.cpp2
-rw-r--r--src/init.cpp4
-rw-r--r--src/init/bitcoin-gui.cpp2
-rw-r--r--src/init/bitcoin-node.cpp2
-rw-r--r--src/init/bitcoin-qt.cpp2
-rw-r--r--src/init/bitcoind.cpp2
-rw-r--r--src/init/common.cpp5
-rw-r--r--src/interfaces/wallet.h15
-rw-r--r--src/ipc/interfaces.cpp2
-rw-r--r--src/ipc/process.cpp2
-rw-r--r--src/ipc/process.h2
-rw-r--r--src/kernel/chainparams.cpp42
-rw-r--r--src/kernel/mempool_persist.cpp4
-rw-r--r--src/kernel/mempool_persist.h2
-rw-r--r--src/logging.cpp4
-rw-r--r--src/logging.h2
-rw-r--r--src/memusage.h20
-rw-r--r--src/net.cpp70
-rw-r--r--src/net.h23
-rw-r--r--src/net_processing.cpp151
-rw-r--r--src/node/blockmanager_args.cpp2
-rw-r--r--src/node/blockstorage.cpp18
-rw-r--r--src/node/blockstorage.h2
-rw-r--r--src/node/caches.cpp2
-rw-r--r--src/node/chainstate.cpp1
-rw-r--r--src/node/chainstatemanager_args.cpp2
-rw-r--r--src/node/coins_view_args.cpp2
-rw-r--r--src/node/database_args.cpp2
-rw-r--r--src/node/interfaces.cpp3
-rw-r--r--src/node/mempool_args.cpp2
-rw-r--r--src/node/mempool_persist_args.cpp4
-rw-r--r--src/node/mempool_persist_args.h2
-rw-r--r--src/node/miner.cpp2
-rw-r--r--src/node/txreconciliation.cpp1
-rw-r--r--src/node/utxo_snapshot.cpp4
-rw-r--r--src/node/utxo_snapshot.h2
-rw-r--r--src/node/validation_cache_args.cpp2
-rw-r--r--src/outputtype.cpp2
-rw-r--r--src/policy/fees.cpp2
-rw-r--r--src/policy/fees.h2
-rw-r--r--src/policy/fees_args.cpp2
-rw-r--r--src/policy/fees_args.h2
-rw-r--r--src/protocol.cpp2
-rw-r--r--src/psbt.cpp32
-rw-r--r--src/psbt.h3
-rw-r--r--src/qt/addresstablemodel.cpp42
-rw-r--r--src/qt/addresstablemodel.h11
-rw-r--r--src/qt/bitcoin.cpp10
-rw-r--r--src/qt/bitcoingui.cpp8
-rw-r--r--src/qt/bitcoinstrings.cpp42
-rw-r--r--src/qt/clientmodel.cpp1
-rw-r--r--src/qt/coincontroldialog.cpp3
-rw-r--r--src/qt/editaddressdialog.cpp6
-rw-r--r--src/qt/forms/psbtoperationsdialog.ui2
-rw-r--r--src/qt/guiutil.cpp23
-rw-r--r--src/qt/guiutil.h2
-rw-r--r--src/qt/intro.cpp7
-rw-r--r--src/qt/locale/bitcoin_en.ts342
-rw-r--r--src/qt/locale/bitcoin_en.xlf3161
-rw-r--r--src/qt/optionsmodel.cpp6
-rw-r--r--src/qt/paymentserver.cpp2
-rw-r--r--src/qt/psbtoperationsdialog.cpp3
-rw-r--r--src/qt/receivecoinsdialog.cpp8
-rw-r--r--src/qt/rpcconsole.cpp9
-rw-r--r--src/qt/sendcoinsdialog.cpp43
-rw-r--r--src/qt/sendcoinsdialog.h3
-rw-r--r--src/qt/test/addressbooktests.cpp4
-rw-r--r--src/qt/test/optiontests.cpp2
-rw-r--r--src/qt/test/wallettests.cpp260
-rw-r--r--src/qt/trafficgraphwidget.cpp4
-rw-r--r--src/qt/transactiondesc.cpp6
-rw-r--r--src/qt/transactionrecord.cpp2
-rw-r--r--src/qt/utilitydialog.cpp2
-rw-r--r--src/qt/walletframe.cpp4
-rw-r--r--src/qt/walletmodel.cpp31
-rw-r--r--src/qt/walletmodel.h2
-rw-r--r--src/randomenv.cpp3
-rw-r--r--src/rest.cpp26
-rw-r--r--src/rpc/blockchain.cpp109
-rw-r--r--src/rpc/blockchain.h2
-rw-r--r--src/rpc/client.cpp2
-rw-r--r--src/rpc/external_signer.cpp4
-rw-r--r--src/rpc/mempool.cpp2
-rw-r--r--src/rpc/output_script.cpp2
-rw-r--r--src/rpc/rawtransaction.cpp145
-rw-r--r--src/rpc/request.cpp6
-rw-r--r--src/rpc/server.cpp4
-rw-r--r--src/rpc/server_util.cpp1
-rw-r--r--src/rpc/util.cpp30
-rw-r--r--src/rpc/util.h9
-rw-r--r--src/script/descriptor.cpp3
-rw-r--r--src/script/miniscript.h2
-rw-r--r--src/script/sigcache.cpp1
-rw-r--r--src/secp256k1/CHANGELOG.md20
-rw-r--r--src/secp256k1/CMakeLists.txt13
-rw-r--r--src/secp256k1/Makefile.am17
-rwxr-xr-xsrc/secp256k1/ci/cirrus.sh4
-rw-r--r--src/secp256k1/configure.ac28
-rw-r--r--src/secp256k1/doc/release-process.md15
-rw-r--r--src/secp256k1/include/secp256k1.h98
-rw-r--r--src/secp256k1/include/secp256k1_ecdh.h2
-rw-r--r--src/secp256k1/include/secp256k1_extrakeys.h30
-rw-r--r--src/secp256k1/include/secp256k1_preallocated.h14
-rw-r--r--src/secp256k1/include/secp256k1_recovery.h18
-rw-r--r--src/secp256k1/include/secp256k1_schnorrsig.h10
-rw-r--r--src/secp256k1/src/asm/field_10x26_arm.s2
-rw-r--r--src/secp256k1/src/ecmult_const.h21
-rw-r--r--src/secp256k1/src/ecmult_const_impl.h135
-rw-r--r--src/secp256k1/src/ecmult_impl.h17
-rw-r--r--src/secp256k1/src/field_10x26_impl.h10
-rw-r--r--src/secp256k1/src/field_5x52_impl.h6
-rw-r--r--src/secp256k1/src/int128_struct_impl.h2
-rw-r--r--src/secp256k1/src/modinv32_impl.h2
-rw-r--r--src/secp256k1/src/scalar_4x64_impl.h3
-rw-r--r--src/secp256k1/src/scalar_8x32_impl.h3
-rw-r--r--src/secp256k1/src/scalar_low_impl.h3
-rw-r--r--src/secp256k1/src/tests.c102
-rw-r--r--src/secp256k1/src/tests_exhaustive.c48
-rw-r--r--src/secp256k1/src/wycheproof/WYCHEPROOF_COPYING212
-rw-r--r--src/secp256k1/src/wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.h1564
-rw-r--r--src/secp256k1/src/wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.json6360
-rwxr-xr-xsrc/secp256k1/tools/tests_wycheproof_generate.py114
-rw-r--r--src/signet.cpp5
-rw-r--r--src/support/allocators/pool.h349
-rw-r--r--src/test/addrman_tests.cpp126
-rw-r--r--src/test/allocator_tests.cpp1
-rw-r--r--src/test/argsman_tests.cpp6
-rw-r--r--src/test/checkqueue_tests.cpp2
-rw-r--r--src/test/coins_tests.cpp39
-rw-r--r--src/test/denialofservice_tests.cpp2
-rw-r--r--src/test/flatfile_tests.cpp2
-rw-r--r--src/test/fs_tests.cpp4
-rw-r--r--src/test/fuzz/addrman.cpp2
-rw-r--r--src/test/fuzz/banman.cpp4
-rw-r--r--src/test/fuzz/coins_view.cpp3
-rw-r--r--src/test/fuzz/connman.cpp3
-rw-r--r--src/test/fuzz/deserialize.cpp2
-rw-r--r--src/test/fuzz/fuzz.cpp2
-rw-r--r--src/test/fuzz/headerssync.cpp117
-rw-r--r--src/test/fuzz/i2p.cpp2
-rw-r--r--src/test/fuzz/integer.cpp1
-rw-r--r--src/test/fuzz/miniscript.cpp2
-rw-r--r--src/test/fuzz/poolresource.cpp174
-rw-r--r--src/test/fuzz/rpc.cpp8
-rw-r--r--src/test/fuzz/string.cpp160
-rw-r--r--src/test/fuzz/system.cpp2
-rw-r--r--src/test/fuzz/tx_pool.cpp1
-rw-r--r--src/test/fuzz/utxo_snapshot.cpp2
-rw-r--r--src/test/fuzz/versionbits.cpp2
-rw-r--r--src/test/getarg_tests.cpp4
-rw-r--r--src/test/httpserver_tests.cpp4
-rw-r--r--src/test/i2p_tests.cpp2
-rw-r--r--src/test/miniscript_tests.cpp2
-rw-r--r--src/test/net_tests.cpp2
-rw-r--r--src/test/policyestimator_tests.cpp1
-rw-r--r--src/test/pool_tests.cpp190
-rw-r--r--src/test/random_tests.cpp1
-rw-r--r--src/test/scheduler_tests.cpp2
-rw-r--r--src/test/script_p2sh_tests.cpp4
-rw-r--r--src/test/script_tests.cpp2
-rw-r--r--src/test/settings_tests.cpp4
-rw-r--r--src/test/streams_tests.cpp2
-rw-r--r--src/test/txpackage_tests.cpp72
-rw-r--r--src/test/txrequest_tests.cpp1
-rw-r--r--src/test/util/chainstate.h2
-rw-r--r--src/test/util/net.cpp3
-rw-r--r--src/test/util/poolresourcetester.h129
-rw-r--r--src/test/util/setup_common.cpp28
-rw-r--r--src/test/util/setup_common.h16
-rw-r--r--src/test/util_tests.cpp11
-rw-r--r--src/test/util_threadnames_tests.cpp1
-rw-r--r--src/test/validation_block_tests.cpp1
-rw-r--r--src/test/validation_chainstatemanager_tests.cpp5
-rw-r--r--src/test/validation_flush_tests.cpp33
-rw-r--r--src/test/validation_tests.cpp2
-rw-r--r--src/test/validationinterface_tests.cpp2
-rw-r--r--src/timedata.cpp3
-rw-r--r--src/torcontrol.cpp3
-rw-r--r--src/torcontrol.h2
-rw-r--r--src/txdb.h2
-rw-r--r--src/txmempool.cpp1
-rw-r--r--src/util/asmap.cpp2
-rw-r--r--src/util/asmap.h2
-rw-r--r--src/util/bip32.cpp2
-rw-r--r--src/util/fs.cpp (renamed from src/fs.cpp)2
-rw-r--r--src/util/fs.h (renamed from src/fs.h)6
-rw-r--r--src/util/fs_helpers.cpp295
-rw-r--r--src/util/fs_helpers.h63
-rw-r--r--src/util/getuniquepath.cpp2
-rw-r--r--src/util/getuniquepath.h2
-rw-r--r--src/util/readwritefile.cpp2
-rw-r--r--src/util/readwritefile.h2
-rw-r--r--src/util/settings.cpp2
-rw-r--r--src/util/settings.h2
-rw-r--r--src/util/system.cpp1278
-rw-r--r--src/util/system.h492
-rw-r--r--src/validation.cpp41
-rw-r--r--src/validation.h4
-rw-r--r--src/wallet/bdb.cpp41
-rw-r--r--src/wallet/bdb.h8
-rw-r--r--src/wallet/coincontrol.cpp70
-rw-r--r--src/wallet/coincontrol.h124
-rw-r--r--src/wallet/coinselection.cpp82
-rw-r--r--src/wallet/coinselection.h15
-rw-r--r--src/wallet/db.cpp4
-rw-r--r--src/wallet/db.h4
-rw-r--r--src/wallet/dump.cpp4
-rw-r--r--src/wallet/dump.h2
-rw-r--r--src/wallet/external_signer_scriptpubkeyman.cpp2
-rw-r--r--src/wallet/feebumper.cpp37
-rw-r--r--src/wallet/init.cpp2
-rw-r--r--src/wallet/interfaces.cpp60
-rw-r--r--src/wallet/load.cpp4
-rw-r--r--src/wallet/receive.h2
-rw-r--r--src/wallet/rpc/addresses.cpp25
-rw-r--r--src/wallet/rpc/backup.cpp42
-rw-r--r--src/wallet/rpc/coins.cpp3
-rw-r--r--src/wallet/rpc/transactions.cpp16
-rw-r--r--src/wallet/rpc/util.cpp10
-rw-r--r--src/wallet/rpc/util.h10
-rw-r--r--src/wallet/rpc/wallet.cpp52
-rw-r--r--src/wallet/salvage.cpp2
-rw-r--r--src/wallet/salvage.h2
-rw-r--r--src/wallet/scriptpubkeyman.cpp10
-rw-r--r--src/wallet/scriptpubkeyman.h4
-rw-r--r--src/wallet/spend.cpp74
-rw-r--r--src/wallet/spend.h2
-rw-r--r--src/wallet/sqlite.cpp26
-rw-r--r--src/wallet/sqlite.h3
-rw-r--r--src/wallet/test/coinselector_tests.cpp234
-rw-r--r--src/wallet/test/db_tests.cpp2
-rw-r--r--src/wallet/test/fuzz/coinselection.cpp14
-rw-r--r--src/wallet/test/init_test_fixture.cpp4
-rw-r--r--src/wallet/test/init_tests.cpp2
-rw-r--r--src/wallet/test/ismine_tests.cpp2
-rw-r--r--src/wallet/test/wallet_tests.cpp71
-rw-r--r--src/wallet/transaction.h25
-rw-r--r--src/wallet/types.h (renamed from src/wallet/ismine.h)44
-rw-r--r--src/wallet/wallet.cpp197
-rw-r--r--src/wallet/wallet.h99
-rw-r--r--src/wallet/walletdb.cpp45
-rw-r--r--src/wallet/walletdb.h9
-rw-r--r--src/wallet/wallettool.cpp4
-rw-r--r--src/wallet/walletutil.cpp2
-rw-r--r--src/wallet/walletutil.h2
-rw-r--r--src/zmq/zmqnotificationinterface.cpp2
-rw-r--r--src/zmq/zmqpublishnotifier.cpp2
-rwxr-xr-xtest/functional/feature_anchors.py18
-rwxr-xr-xtest/functional/feature_dbcrash.py8
-rwxr-xr-xtest/functional/feature_fastprune.py29
-rwxr-xr-xtest/functional/feature_nulldummy.py3
-rwxr-xr-xtest/functional/feature_pruning.py7
-rwxr-xr-xtest/functional/feature_taproot.py5
-rwxr-xr-xtest/functional/interface_rest.py14
-rwxr-xr-xtest/functional/interface_zmq.py10
-rwxr-xr-xtest/functional/mempool_limit.py77
-rwxr-xr-xtest/functional/mempool_package_limits.py126
-rwxr-xr-xtest/functional/p2p_disconnect_ban.py12
-rwxr-xr-xtest/functional/p2p_sendheaders.py10
-rwxr-xr-xtest/functional/rpc_createmultisig.py3
-rwxr-xr-xtest/functional/rpc_packages.py40
-rwxr-xr-xtest/functional/rpc_psbt.py12
-rwxr-xr-xtest/functional/rpc_scanblocks.py4
-rwxr-xr-xtest/functional/rpc_scantxoutset.py5
-rwxr-xr-xtest/functional/rpc_setban.py8
-rwxr-xr-xtest/functional/rpc_signrawtransactionwithkey.py3
-rw-r--r--test/functional/test_framework/address.py21
-rw-r--r--test/functional/test_framework/authproxy.py29
-rw-r--r--test/functional/test_framework/blocktools.py3
-rw-r--r--test/functional/test_framework/key.py8
-rwxr-xr-xtest/functional/test_framework/messages.py22
-rw-r--r--test/functional/test_framework/muhash.py4
-rw-r--r--test/functional/test_framework/util.py33
-rw-r--r--test/functional/test_framework/wallet.py23
-rwxr-xr-xtest/functional/test_runner.py4
-rwxr-xr-xtest/functional/wallet_avoidreuse.py3
-rwxr-xr-xtest/functional/wallet_backwards_compatibility.py7
-rwxr-xr-xtest/functional/wallet_balance.py35
-rwxr-xr-xtest/functional/wallet_basic.py16
-rwxr-xr-xtest/functional/wallet_bumpfee.py103
-rwxr-xr-xtest/functional/wallet_create_tx.py1
-rwxr-xr-xtest/functional/wallet_createwallet.py31
-rwxr-xr-xtest/functional/wallet_fast_rescan.py3
-rwxr-xr-xtest/functional/wallet_labels.py4
-rwxr-xr-xtest/functional/wallet_orphanedreward.py5
-rwxr-xr-xtest/lint/lint-circular-dependencies.py2
-rwxr-xr-xtest/lint/lint-locale-dependence.py2
-rwxr-xr-xtest/lint/lint-python-utf8-encoding.py2
-rwxr-xr-xtest/lint/lint-python.py13
-rw-r--r--test/sanitizer_suppressions/lsan3
-rw-r--r--test/sanitizer_suppressions/tsan4
-rw-r--r--test/sanitizer_suppressions/ubsan6
423 files changed, 19683 insertions, 7604 deletions
diff --git a/.cirrus.yml b/.cirrus.yml
index 2ae49be7d2..2d3efee8cf 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -47,6 +47,7 @@ container_depends_template: &CONTAINER_DEPENDS_TEMPLATE
cpu: 2
greedy: true
memory: 8G # Set to 8GB to avoid OOM. https://cirrus-ci.org/guide/linux/#linux-containers
+ dockerfile: ci/test_imagefile # https://cirrus-ci.org/guide/docker-builder-vm/#dockerfile-as-a-ci-environment
depends_built_cache:
folder: "depends/built"
fingerprint_script: echo $CIRRUS_TASK_NAME $(git rev-parse HEAD:depends)
@@ -80,17 +81,18 @@ task:
<< : *CIRRUS_EPHEMERAL_WORKER_TEMPLATE_ENV
task:
- name: 'tidy [bookworm]'
+ name: 'tidy [lunar]'
<< : *GLOBAL_TASK_TEMPLATE
container:
- image: debian:bookworm
cpu: 2
memory: 5G
+ docker_arguments:
+ CI_IMAGE_NAME_TAG: ubuntu:lunar
+ FILE_ENV: "./ci/test/00_setup_env_native_tidy.sh"
# For faster CI feedback, immediately schedule the linters
<< : *CREDITS_TEMPLATE
env:
<< : *CIRRUS_EPHEMERAL_WORKER_TEMPLATE_ENV
- FILE_ENV: "./ci/test/00_setup_env_native_tidy.sh"
task:
name: "Win64 native [vs2022]"
@@ -192,37 +194,42 @@ task:
name: 'ARM [unit tests, no functional tests] [bullseye]'
<< : *GLOBAL_TASK_TEMPLATE
arm_container:
- image: debian:bullseye
cpu: 2
memory: 8G
+ dockerfile: ci/test_imagefile
+ docker_arguments:
+ CI_IMAGE_NAME_TAG: debian:bullseye
+ FILE_ENV: "./ci/test/00_setup_env_arm.sh"
env:
<< : *CIRRUS_EPHEMERAL_WORKER_TEMPLATE_ENV
- FILE_ENV: "./ci/test/00_setup_env_arm.sh"
QEMU_USER_CMD: "" # Disable qemu and run the test natively
task:
name: 'Win64 [unit tests, no gui tests, no boost::process, no functional tests] [jammy]'
<< : *GLOBAL_TASK_TEMPLATE
container:
- image: ubuntu:jammy
+ docker_arguments:
+ CI_IMAGE_NAME_TAG: ubuntu:jammy
+ FILE_ENV: "./ci/test/00_setup_env_win64.sh"
+ << : *CREDITS_TEMPLATE
env:
<< : *CIRRUS_EPHEMERAL_WORKER_TEMPLATE_ENV
- FILE_ENV: "./ci/test/00_setup_env_win64.sh"
task:
name: '32-bit + dash [gui] [CentOS 8]'
<< : *GLOBAL_TASK_TEMPLATE
container:
- image: quay.io/centos/centos:stream8
+ docker_arguments:
+ CI_IMAGE_NAME_TAG: quay.io/centos/centos:stream8
+ FILE_ENV: "./ci/test/00_setup_env_i686_centos.sh"
# For faster CI feedback, immediately schedule one task that runs all tests
<< : *CREDITS_TEMPLATE
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, DEBUG] [unsigned char] [buster]'
+ name: '[previous releases, qt5 dev package and depends packages, DEBUG] [focal]'
previous_releases_cache:
folder: "releases"
<< : *GLOBAL_TASK_TEMPLATE
@@ -232,24 +239,26 @@ task:
FILE_ENV: "./ci/test/00_setup_env_native_qt5.sh"
task:
- name: '[TSan, depends, gui] [jammy]'
+ name: '[TSan, depends, gui] [lunar]'
<< : *GLOBAL_TASK_TEMPLATE
container:
- image: ubuntu:jammy
cpu: 6 # Increase CPU and Memory to avoid timeout
memory: 24G
+ docker_arguments:
+ CI_IMAGE_NAME_TAG: ubuntu:lunar
+ FILE_ENV: "./ci/test/00_setup_env_native_tsan.sh"
env:
<< : *CIRRUS_EPHEMERAL_WORKER_TEMPLATE_ENV
- FILE_ENV: "./ci/test/00_setup_env_native_tsan.sh"
task:
- name: '[MSan, depends] [focal]'
+ name: '[MSan, depends] [lunar]'
<< : *GLOBAL_TASK_TEMPLATE
container:
- image: ubuntu:focal
+ docker_arguments:
+ CI_IMAGE_NAME_TAG: ubuntu:lunar
+ FILE_ENV: "./ci/test/00_setup_env_native_msan.sh"
env:
<< : *CIRRUS_EPHEMERAL_WORKER_TEMPLATE_ENV
- FILE_ENV: "./ci/test/00_setup_env_native_msan.sh"
MAKEJOBS: "-j4" # Avoid excessive memory use due to MSan
task:
@@ -261,8 +270,9 @@ task:
# Images can be found here: https://cloud.google.com/compute/docs/images/os-details
compute_engine_instance:
image_project: ubuntu-os-cloud
- image: family/ubuntu-2204-lts # when upgrading, check if we can drop "ADD_UNTRUSTED_BPFCC_PPA"
+ image: family/ubuntu-2304-amd64 # https://cirrus-ci.org/guide/custom-vms/#custom-compute-engine-vms
cpu: 4
+ disk: 100
memory: 12G
env:
<< : *CIRRUS_EPHEMERAL_WORKER_TEMPLATE_ENV
@@ -271,41 +281,48 @@ task:
MAKEJOBS: "-j4" # Avoid excessive memory use
task:
- name: '[fuzzer,address,undefined,integer, no depends] [jammy]'
+ name: '[fuzzer,address,undefined,integer, no depends] [lunar]'
<< : *GLOBAL_TASK_TEMPLATE
container:
- image: ubuntu:jammy
cpu: 4 # Increase CPU and memory to avoid timeout
memory: 16G
+ docker_arguments:
+ CI_IMAGE_NAME_TAG: ubuntu:lunar
+ FILE_ENV: "./ci/test/00_setup_env_native_fuzz.sh"
env:
<< : *CIRRUS_EPHEMERAL_WORKER_TEMPLATE_ENV
- FILE_ENV: "./ci/test/00_setup_env_native_fuzz.sh"
task:
name: '[multiprocess, i686, DEBUG] [focal]'
<< : *GLOBAL_TASK_TEMPLATE
container:
- image: ubuntu:focal
cpu: 4
memory: 16G # The default memory is sometimes just a bit too small, so double everything
+ docker_arguments:
+ CI_IMAGE_NAME_TAG: ubuntu:focal
+ FILE_ENV: "./ci/test/00_setup_env_i686_multiprocess.sh"
env:
<< : *CIRRUS_EPHEMERAL_WORKER_TEMPLATE_ENV
- FILE_ENV: "./ci/test/00_setup_env_i686_multiprocess.sh"
task:
- name: '[no wallet, libbitcoinkernel] [buster]'
+ name: '[no wallet, libbitcoinkernel] [focal]'
<< : *GLOBAL_TASK_TEMPLATE
container:
- image: debian:buster
+ docker_arguments:
+ CI_IMAGE_NAME_TAG: ubuntu:focal
+ FILE_ENV: "./ci/test/00_setup_env_native_nowallet_libbitcoinkernel.sh"
+ << : *CREDITS_TEMPLATE
env:
<< : *CIRRUS_EPHEMERAL_WORKER_TEMPLATE_ENV
- FILE_ENV: "./ci/test/00_setup_env_native_nowallet_libbitcoinkernel.sh"
task:
name: 'macOS 10.15 [gui, no tests] [focal]'
<< : *CONTAINER_DEPENDS_TEMPLATE
container:
- image: ubuntu:focal
+ docker_arguments:
+ CI_IMAGE_NAME_TAG: ubuntu:focal
+ FILE_ENV: "./ci/test/00_setup_env_mac.sh"
+ << : *CREDITS_TEMPLATE
macos_sdk_cache:
folder: "depends/SDKs/$MACOS_SDK"
fingerprint_key: "$MACOS_SDK"
@@ -313,7 +330,6 @@ task:
env:
MACOS_SDK: "Xcode-12.2-12B45b-extracted-SDK-with-libcxx-headers"
<< : *CIRRUS_EPHEMERAL_WORKER_TEMPLATE_ENV
- FILE_ENV: "./ci/test/00_setup_env_mac.sh"
task:
name: 'macOS 13 native arm64 [gui, sqlite only] [no depends]'
@@ -336,7 +352,10 @@ task:
name: 'ARM64 Android APK [jammy]'
<< : *CONTAINER_DEPENDS_TEMPLATE
container:
- image: ubuntu:jammy
+ docker_arguments:
+ CI_IMAGE_NAME_TAG: ubuntu:jammy
+ FILE_ENV: "./ci/test/00_setup_env_android.sh"
+ << : *CREDITS_TEMPLATE
android_sdk_cache:
folder: "depends/SDKs/android"
fingerprint_key: "ANDROID_API_LEVEL=28 ANDROID_BUILD_TOOLS_VERSION=28.0.3 ANDROID_NDK_VERSION=23.2.8568313"
@@ -346,4 +365,3 @@ task:
<< : *MAIN_TEMPLATE
env:
<< : *CIRRUS_EPHEMERAL_WORKER_TEMPLATE_ENV
- FILE_ENV: "./ci/test/00_setup_env_android.sh"
diff --git a/.python-version b/.python-version
index 36f601f10e..eee6392d5c 100644
--- a/.python-version
+++ b/.python-version
@@ -1 +1 @@
-3.7.16
+3.8.16
diff --git a/build_msvc/vcpkg.json b/build_msvc/vcpkg.json
index 86773d1fd3..3557269be0 100644
--- a/build_msvc/vcpkg.json
+++ b/build_msvc/vcpkg.json
@@ -13,5 +13,12 @@
"features": ["thread"]
},
"zeromq"
+ ],
+ "builtin-baseline": "f14984af3738e69f197bf0e647a8dca12de92996",
+ "overrides": [
+ {
+ "name": "libevent",
+ "version": "2.1.12#7"
+ }
]
}
diff --git a/ci/lint/Dockerfile b/ci/lint/Dockerfile
index 03c20c7286..a0a4516480 100644
--- a/ci/lint/Dockerfile
+++ b/ci/lint/Dockerfile
@@ -5,7 +5,7 @@
# entire repo as docker context during build; if it lived elsewhere, it wouldn't be
# able to make back-references to pull in the install scripts. So here it lives.
-FROM python:3.7-buster
+FROM python:3.8-buster
ENV DEBIAN_FRONTEND=noninteractive
ENV LC_ALL=C.UTF-8
diff --git a/ci/test/00_setup_env_i686_centos.sh b/ci/test/00_setup_env_i686_centos.sh
index 8a931d44e5..544d6150a6 100755
--- a/ci/test/00_setup_env_i686_centos.sh
+++ b/ci/test/00_setup_env_i686_centos.sh
@@ -8,7 +8,8 @@ export LC_ALL=C.UTF-8
export HOST=i686-pc-linux-gnu
export CONTAINER_NAME=ci_i686_centos
-export CI_IMAGE_NAME_TAG=quay.io/centos/centos:stream8
+export CI_IMAGE_NAME_TAG="quay.io/centos/centos:stream8"
+# Use minimum supported python3.8 and gcc-8, see doc/dependencies.md
export CI_BASE_PACKAGES="gcc-c++ glibc-devel.x86_64 libstdc++-devel.x86_64 glibc-devel.i686 libstdc++-devel.i686 ccache libtool make git python38 python38-pip which patch lbzip2 xz procps-ng dash rsync coreutils bison"
export PIP_PACKAGES="pyzmq"
export GOAL="install"
diff --git a/ci/test/00_setup_env_native_asan.sh b/ci/test/00_setup_env_native_asan.sh
index bb3f6997f3..8701d383dd 100755
--- a/ci/test/00_setup_env_native_asan.sh
+++ b/ci/test/00_setup_env_native_asan.sh
@@ -8,19 +8,14 @@ export LC_ALL=C.UTF-8
# Only install BCC tracing packages in Cirrus CI.
if [[ "${CIRRUS_CI}" == "true" ]]; then
- # We install an up-to-date 'bpfcc-tools' package from an untrusted PPA.
- # This can be dropped with the next Ubuntu or Debian release that includes up-to-date packages.
- # See the if-then in ci/test/04_install.sh too.
- export ADD_UNTRUSTED_BPFCC_PPA=true
export BPFCC_PACKAGE="bpfcc-tools"
else
- export ADD_UNTRUSTED_BPFCC_PPA=false
export BPFCC_PACKAGE=""
fi
export CONTAINER_NAME=ci_native_asan
-export PACKAGES="systemtap-sdt-dev clang llvm python3-zmq qtbase5-dev qttools5-dev-tools libevent-dev bsdmainutils libboost-dev libdb5.3++-dev libminiupnpc-dev libnatpmp-dev libzmq3-dev libqrencode-dev libsqlite3-dev ${BPFCC_PACKAGE}"
-export CI_IMAGE_NAME_TAG=ubuntu:22.04
+export PACKAGES="systemtap-sdt-dev clang-16 llvm-16 libclang-rt-16-dev python3-zmq qtbase5-dev qttools5-dev-tools libevent-dev bsdmainutils libboost-dev libdb5.3++-dev libminiupnpc-dev libnatpmp-dev libzmq3-dev libqrencode-dev libsqlite3-dev ${BPFCC_PACKAGE}"
+export CI_IMAGE_NAME_TAG=ubuntu:23.04 # Version 23.04 will reach EOL in Jan 2024, and can be replaced by "ubuntu:24.04" (or anything else that ships the wanted clang version).
export NO_DEPENDS=1
export GOAL="install"
-export BITCOIN_CONFIG="--enable-c++20 --enable-usdt --enable-zmq --with-incompatible-bdb --with-gui=qt5 CPPFLAGS='-DARENA_DEBUG -DDEBUG_LOCKORDER' --with-sanitizers=address,integer,undefined CC=clang CXX=clang++"
+export BITCOIN_CONFIG="--enable-c++20 --enable-usdt --enable-zmq --with-incompatible-bdb --with-gui=qt5 CPPFLAGS='-DARENA_DEBUG -DDEBUG_LOCKORDER' --with-sanitizers=address,integer,undefined CC=clang-16 CXX=clang++-16"
diff --git a/ci/test/00_setup_env_native_fuzz.sh b/ci/test/00_setup_env_native_fuzz.sh
index a2d393bb5a..05cb45c2d8 100755
--- a/ci/test/00_setup_env_native_fuzz.sh
+++ b/ci/test/00_setup_env_native_fuzz.sh
@@ -6,13 +6,13 @@
export LC_ALL=C.UTF-8
-export CI_IMAGE_NAME_TAG="ubuntu:22.04"
+export CI_IMAGE_NAME_TAG="ubuntu:23.04" # Version 23.04 will reach EOL in Jan 2024, and can be replaced by "ubuntu:24.04" (or anything else that ships the wanted clang version).
export CONTAINER_NAME=ci_native_fuzz
-export PACKAGES="clang llvm python3 libevent-dev bsdmainutils libboost-dev libsqlite3-dev"
+export PACKAGES="clang-16 llvm-16 libclang-rt-16-dev python3 libevent-dev bsdmainutils libboost-dev libsqlite3-dev"
export NO_DEPENDS=1
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 -ftrivial-auto-var-init=pattern' CXX='clang++ -ftrivial-auto-var-init=pattern'"
+export BITCOIN_CONFIG="--enable-fuzz --with-sanitizers=fuzzer,address,undefined,integer CC='clang-16 -ftrivial-auto-var-init=pattern' CXX='clang++-16 -ftrivial-auto-var-init=pattern'"
export CCACHE_SIZE=200M
diff --git a/ci/test/00_setup_env_native_fuzz_with_msan.sh b/ci/test/00_setup_env_native_fuzz_with_msan.sh
index 7886f6efc9..35a0de8034 100755
--- a/ci/test/00_setup_env_native_fuzz_with_msan.sh
+++ b/ci/test/00_setup_env_native_fuzz_with_msan.sh
@@ -6,14 +6,14 @@
export LC_ALL=C.UTF-8
-export CI_IMAGE_NAME_TAG="ubuntu:20.04"
+export CI_IMAGE_NAME_TAG="ubuntu:23.04" # Version 23.04 will reach EOL in Jan 2024, and can be replaced by "ubuntu:24.04" (or anything else that ships the wanted clang version).
LIBCXX_DIR="${BASE_SCRATCH_DIR}/msan/build/"
export MSAN_FLAGS="-fsanitize=memory -fsanitize-memory-track-origins=2 -fno-omit-frame-pointer -g -O1 -fno-optimize-sibling-calls"
LIBCXX_FLAGS="-nostdinc++ -stdlib=libc++ -L${LIBCXX_DIR}lib -lc++abi -I${LIBCXX_DIR}include -I${LIBCXX_DIR}include/c++/v1 -lpthread -Wl,-rpath,${LIBCXX_DIR}lib -Wno-unused-command-line-argument"
export MSAN_AND_LIBCXX_FLAGS="${MSAN_FLAGS} ${LIBCXX_FLAGS}"
export CONTAINER_NAME="ci_native_fuzz_msan"
-export PACKAGES="clang-12 llvm-12 cmake"
+export PACKAGES="clang-16 llvm-16 libclang-rt-16-dev cmake"
# BDB generates false-positives and will be removed in future
export DEP_OPTS="NO_BDB=1 NO_QT=1 CC='clang' CXX='clang++' CFLAGS='${MSAN_FLAGS}' CXXFLAGS='${MSAN_AND_LIBCXX_FLAGS}'"
export GOAL="install"
diff --git a/ci/test/00_setup_env_native_fuzz_with_valgrind.sh b/ci/test/00_setup_env_native_fuzz_with_valgrind.sh
index 75c10046b7..5fee10e37e 100755
--- a/ci/test/00_setup_env_native_fuzz_with_valgrind.sh
+++ b/ci/test/00_setup_env_native_fuzz_with_valgrind.sh
@@ -6,15 +6,15 @@
export LC_ALL=C.UTF-8
-export CI_IMAGE_NAME_TAG="ubuntu:22.04"
+export CI_IMAGE_NAME_TAG="debian:bookworm"
export CONTAINER_NAME=ci_native_fuzz_valgrind
-export PACKAGES="clang llvm python3 libevent-dev bsdmainutils libboost-dev libsqlite3-dev valgrind"
+export PACKAGES="clang llvm libclang-rt-dev python3 libevent-dev bsdmainutils libboost-dev libsqlite3-dev valgrind"
export NO_DEPENDS=1
export RUN_UNIT_TESTS=false
export RUN_FUNCTIONAL_TESTS=false
export RUN_FUZZ_TESTS=true
export FUZZ_TESTS_CONFIG="--valgrind"
export GOAL="install"
-# Temporarily pin dwarf 4, until valgrind can understand clang's dwarf 5
+# Temporarily pin dwarf 4, until using Valgrind 3.20 or later
export BITCOIN_CONFIG="--enable-fuzz --with-sanitizers=fuzzer CC=clang CXX=clang++ CFLAGS='-gdwarf-4' CXXFLAGS='-gdwarf-4'"
export CCACHE_SIZE=200M
diff --git a/ci/test/00_setup_env_native_msan.sh b/ci/test/00_setup_env_native_msan.sh
index 1f9209bafb..bdb9bd7b5d 100755
--- a/ci/test/00_setup_env_native_msan.sh
+++ b/ci/test/00_setup_env_native_msan.sh
@@ -6,14 +6,14 @@
export LC_ALL=C.UTF-8
-export CI_IMAGE_NAME_TAG="ubuntu:20.04"
+export CI_IMAGE_NAME_TAG="ubuntu:23.04" # Version 23.04 will reach EOL in Jan 2024, and can be replaced by "ubuntu:24.04" (or anything else that ships the wanted clang version).
LIBCXX_DIR="${BASE_SCRATCH_DIR}/msan/build/"
export MSAN_FLAGS="-fsanitize=memory -fsanitize-memory-track-origins=2 -fno-omit-frame-pointer -g -O1 -fno-optimize-sibling-calls"
LIBCXX_FLAGS="-nostdinc++ -stdlib=libc++ -L${LIBCXX_DIR}lib -lc++abi -I${LIBCXX_DIR}include -I${LIBCXX_DIR}include/c++/v1 -lpthread -Wl,-rpath,${LIBCXX_DIR}lib -Wno-unused-command-line-argument"
export MSAN_AND_LIBCXX_FLAGS="${MSAN_FLAGS} ${LIBCXX_FLAGS}"
export CONTAINER_NAME="ci_native_msan"
-export PACKAGES="clang-12 llvm-12 cmake"
+export PACKAGES="clang-16 llvm-16 libclang-rt-16-dev cmake"
# BDB generates false-positives and will be removed in future
export DEP_OPTS="NO_BDB=1 NO_QT=1 CC='clang' CXX='clang++' CFLAGS='${MSAN_FLAGS}' CXXFLAGS='${MSAN_AND_LIBCXX_FLAGS}'"
export GOAL="install"
diff --git a/ci/test/00_setup_env_native_nowallet_libbitcoinkernel.sh b/ci/test/00_setup_env_native_nowallet_libbitcoinkernel.sh
index 06bc2401c5..b86fa6f321 100755
--- a/ci/test/00_setup_env_native_nowallet_libbitcoinkernel.sh
+++ b/ci/test/00_setup_env_native_nowallet_libbitcoinkernel.sh
@@ -7,10 +7,9 @@
export LC_ALL=C.UTF-8
export CONTAINER_NAME=ci_native_nowallet_libbitcoinkernel
-export CI_IMAGE_NAME_TAG=debian:buster
-# Use minimum supported python3.7 and clang-8, see doc/dependencies.md
-export PACKAGES="-t buster-backports python3-zmq clang-8 llvm-8 libc++abi-8-dev libc++-8-dev"
-export APPEND_APT_SOURCES_LIST="deb http://deb.debian.org/debian buster-backports main"
+export CI_IMAGE_NAME_TAG="ubuntu:20.04"
+# Use minimum supported python3.8 and clang-8, see doc/dependencies.md
+export PACKAGES="python3-zmq clang-8 llvm-8 libc++abi-8-dev libc++-8-dev"
export DEP_OPTS="NO_WALLET=1 CC=clang-8 CXX='clang++-8 -stdlib=libc++'"
export GOAL="install"
export NO_WERROR=1
diff --git a/ci/test/00_setup_env_native_qt5.sh b/ci/test/00_setup_env_native_qt5.sh
index 5cc0addd33..59d8c7c871 100755
--- a/ci/test/00_setup_env_native_qt5.sh
+++ b/ci/test/00_setup_env_native_qt5.sh
@@ -7,10 +7,10 @@
export LC_ALL=C.UTF-8
export CONTAINER_NAME=ci_native_qt5
-export CI_IMAGE_NAME_TAG=debian:buster
-# Use minimum supported python3.7 and gcc-8, see doc/dependencies.md
-export PACKAGES="gcc-8 g++-8 python3-zmq qtbase5-dev qttools5-dev-tools libdbus-1-dev libharfbuzz-dev"
-export DEP_OPTS="NO_QT=1 NO_UPNP=1 NO_NATPMP=1 DEBUG=1 ALLOW_HOST_PACKAGES=1 CC=gcc-8 CXX=g++-8"
+export CI_IMAGE_NAME_TAG="ubuntu:20.04"
+# Use minimum supported python3.8 and gcc-8 (or best-effort gcc-9), see doc/dependencies.md
+export PACKAGES="gcc-9 g++-9 python3-zmq qtbase5-dev qttools5-dev-tools libdbus-1-dev libharfbuzz-dev"
+export DEP_OPTS="NO_QT=1 NO_UPNP=1 NO_NATPMP=1 DEBUG=1 ALLOW_HOST_PACKAGES=1 CC=gcc-9 CXX=g++-9"
export TEST_RUNNER_EXTRA="--previous-releases --coverage --extended --exclude feature_dbcrash" # Run extended tests so that coverage does not fail, but exclude the very slow dbcrash
export RUN_UNIT_TESTS_SEQUENTIAL="true"
export RUN_UNIT_TESTS="false"
@@ -18,4 +18,4 @@ export GOAL="install"
export NO_WERROR=1
export DOWNLOAD_PREVIOUS_RELEASES="true"
export BITCOIN_CONFIG="--enable-zmq --with-libs=no --with-gui=qt5 --enable-reduce-exports \
---enable-debug CFLAGS=\"-g0 -O2 -funsigned-char\" CXXFLAGS=\"-g0 -O2 -funsigned-char\" CC=gcc-8 CXX=g++-8"
+--enable-debug CFLAGS=\"-g0 -O2 -funsigned-char\" CXXFLAGS=\"-g0 -O2 -funsigned-char\""
diff --git a/ci/test/00_setup_env_native_tidy.sh b/ci/test/00_setup_env_native_tidy.sh
index 994275f3dd..2fa61b8465 100755
--- a/ci/test/00_setup_env_native_tidy.sh
+++ b/ci/test/00_setup_env_native_tidy.sh
@@ -6,14 +6,14 @@
export LC_ALL=C.UTF-8
-export CI_IMAGE_NAME_TAG="debian:bookworm"
+export CI_IMAGE_NAME_TAG="ubuntu:lunar" # Version 23.04 will reach EOL in Jan 2024, and can be replaced by "ubuntu:24.04" (or anything else that ships the wanted clang version).
export CONTAINER_NAME=ci_native_tidy
-export PACKAGES="clang-15 libclang-15-dev llvm-15-dev clang-tidy-15 bear cmake libevent-dev libboost-dev libminiupnpc-dev libnatpmp-dev libzmq3-dev systemtap-sdt-dev libqt5gui5 libqt5core5a libqt5dbus5 qttools5-dev qttools5-dev-tools libqrencode-dev libsqlite3-dev libdb++-dev"
+export PACKAGES="clang-16 libclang-16-dev llvm-16-dev libomp-16-dev clang-tidy-16 bear cmake libevent-dev libboost-dev libminiupnpc-dev libnatpmp-dev libzmq3-dev systemtap-sdt-dev libqt5gui5 libqt5core5a libqt5dbus5 qttools5-dev qttools5-dev-tools libqrencode-dev libsqlite3-dev libdb++-dev"
export NO_DEPENDS=1
export RUN_UNIT_TESTS=false
export RUN_FUNCTIONAL_TESTS=false
export RUN_FUZZ_TESTS=false
export RUN_TIDY=true
export GOAL="install"
-export BITCOIN_CONFIG="CC=clang-15 CXX=clang++-15 --with-incompatible-bdb --disable-hardening CFLAGS='-O0 -g0' CXXFLAGS='-O0 -g0'"
+export BITCOIN_CONFIG="CC=clang-16 CXX=clang++-16 --with-incompatible-bdb --disable-hardening CFLAGS='-O0 -g0' CXXFLAGS='-O0 -g0 -I/usr/lib/llvm-16/lib/clang/16/include'"
export CCACHE_SIZE=200M
diff --git a/ci/test/00_setup_env_native_tsan.sh b/ci/test/00_setup_env_native_tsan.sh
index 61bcd98f0a..e3fa7ab777 100755
--- 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 CI_IMAGE_NAME_TAG=ubuntu:22.04
-export PACKAGES="clang-13 llvm-13 libc++abi-13-dev libc++-13-dev python3-zmq"
-export DEP_OPTS="CC=clang-13 CXX='clang++-13 -stdlib=libc++'"
+export CI_IMAGE_NAME_TAG=ubuntu:23.04 # Version 23.04 will reach EOL in Jan 2024, and can be replaced by "ubuntu:24.04" (or anything else that ships the wanted clang version).
+export PACKAGES="clang-16 llvm-16 libclang-rt-16-dev libc++abi-16-dev libc++-16-dev python3-zmq"
+export DEP_OPTS="CC=clang-16 CXX='clang++-16 -stdlib=libc++'"
export GOAL="install"
export BITCOIN_CONFIG="--enable-zmq CPPFLAGS='-DARENA_DEBUG -DDEBUG_LOCKORDER -DDEBUG_LOCKCONTENTION' CXXFLAGS='-g' --with-sanitizers=thread"
diff --git a/ci/test/00_setup_env_native_valgrind.sh b/ci/test/00_setup_env_native_valgrind.sh
index 039a22b02e..97b85755ef 100755
--- a/ci/test/00_setup_env_native_valgrind.sh
+++ b/ci/test/00_setup_env_native_valgrind.sh
@@ -6,12 +6,12 @@
export LC_ALL=C.UTF-8
-export CI_IMAGE_NAME_TAG="ubuntu:22.04"
+export CI_IMAGE_NAME_TAG="debian:bookworm"
export CONTAINER_NAME=ci_native_valgrind
-export PACKAGES="valgrind clang llvm python3-zmq libevent-dev bsdmainutils libboost-dev libdb5.3++-dev libminiupnpc-dev libnatpmp-dev libzmq3-dev libsqlite3-dev"
+export PACKAGES="valgrind clang llvm libclang-rt-dev python3-zmq libevent-dev bsdmainutils libboost-dev libdb5.3++-dev libminiupnpc-dev libnatpmp-dev libzmq3-dev libsqlite3-dev"
export USE_VALGRIND=1
export NO_DEPENDS=1
export TEST_RUNNER_EXTRA="--nosandbox --exclude feature_init,rpc_bind,feature_bind_extra" # Excluded for now, see https://github.com/bitcoin/bitcoin/issues/17765#issuecomment-602068547
export GOAL="install"
-# Temporarily pin dwarf 4, until valgrind can understand clang's dwarf 5
+# Temporarily pin dwarf 4, until using Valgrind 3.20 or later
export BITCOIN_CONFIG="--enable-zmq --with-incompatible-bdb --with-gui=no CC=clang CXX=clang++ CFLAGS='-gdwarf-4' CXXFLAGS='-gdwarf-4'" # TODO enable GUI
diff --git a/ci/test/01_base_install.sh b/ci/test/01_base_install.sh
index a050067ae4..641ff964f3 100755
--- a/ci/test/01_base_install.sh
+++ b/ci/test/01_base_install.sh
@@ -6,35 +6,26 @@
export LC_ALL=C.UTF-8
-# This script is always run as root, and the functions can be removed and
-# replaced by a bash -c "command" directly, where needed.
-# For now, they are named aliases to aid review with --color-moved=dimmed-zebra.
-CI_EXEC_ROOT () { bash -c "$*"; }
-CI_EXEC() { bash -c "$*"; }
-export -f CI_EXEC_ROOT
-export -f CI_EXEC
+CFG_DONE="ci.base-install-done" # Use a global git setting to remember whether this script ran to avoid running it twice
+
+if [ "$(git config --global ${CFG_DONE})" == "true" ]; then
+ echo "Skip base install"
+ exit 0
+fi
if [ -n "$DPKG_ADD_ARCH" ]; then
- CI_EXEC_ROOT dpkg --add-architecture "$DPKG_ADD_ARCH"
+ dpkg --add-architecture "$DPKG_ADD_ARCH"
fi
if [[ $CI_IMAGE_NAME_TAG == *centos* ]]; then
- ${CI_RETRY_EXE} CI_EXEC_ROOT dnf -y install epel-release
- ${CI_RETRY_EXE} CI_EXEC_ROOT dnf -y --allowerasing install "$CI_BASE_PACKAGES" "$PACKAGES"
+ ${CI_RETRY_EXE} bash -c "dnf -y install epel-release"
+ ${CI_RETRY_EXE} bash -c "dnf -y --allowerasing install $CI_BASE_PACKAGES $PACKAGES"
elif [ "$CI_USE_APT_INSTALL" != "no" ]; then
- if [[ "${ADD_UNTRUSTED_BPFCC_PPA}" == "true" ]]; then
- # Ubuntu 22.04 LTS and Debian 11 both have an outdated bpfcc-tools packages.
- # The iovisor PPA is outdated as well. The next Ubuntu and Debian releases will contain updated
- # packages. Meanwhile, use an untrusted PPA to install an up-to-date version of the bpfcc-tools
- # package.
- # TODO: drop this once we can use newer images in GCE
- CI_EXEC_ROOT add-apt-repository ppa:hadret/bpfcc
- fi
if [[ -n "${APPEND_APT_SOURCES_LIST}" ]]; then
- CI_EXEC_ROOT echo "${APPEND_APT_SOURCES_LIST}" \>\> /etc/apt/sources.list
+ echo "${APPEND_APT_SOURCES_LIST}" >> /etc/apt/sources.list
fi
- ${CI_RETRY_EXE} CI_EXEC_ROOT apt-get update
- ${CI_RETRY_EXE} CI_EXEC_ROOT apt-get install --no-install-recommends --no-upgrade -y "$PACKAGES" "$CI_BASE_PACKAGES"
+ ${CI_RETRY_EXE} apt-get update
+ ${CI_RETRY_EXE} bash -c "apt-get install --no-install-recommends --no-upgrade -y $PACKAGES $CI_BASE_PACKAGES"
fi
if [ -n "$PIP_PACKAGES" ]; then
@@ -44,29 +35,25 @@ if [ -n "$PIP_PACKAGES" ]; then
IN_GETOPT_BIN="$(brew --prefix gnu-getopt)/bin/getopt" ${CI_RETRY_EXE} pip3 install --user $PIP_PACKAGES
else
# shellcheck disable=SC2086
- ${CI_RETRY_EXE} CI_EXEC pip3 install --user $PIP_PACKAGES
+ ${CI_RETRY_EXE} pip3 install --user $PIP_PACKAGES
fi
fi
if [[ ${USE_MEMORY_SANITIZER} == "true" ]]; then
- CI_EXEC_ROOT "update-alternatives --install /usr/bin/clang++ clang++ \$(which clang++-12) 100"
- CI_EXEC_ROOT "update-alternatives --install /usr/bin/clang clang \$(which clang-12) 100"
- CI_EXEC "mkdir -p ${BASE_SCRATCH_DIR}/msan/build/"
- CI_EXEC "git clone --depth=1 https://github.com/llvm/llvm-project -b llvmorg-12.0.0 ${BASE_SCRATCH_DIR}/msan/llvm-project"
- CI_EXEC "cd ${BASE_SCRATCH_DIR}/msan/build/ && cmake -DLLVM_ENABLE_PROJECTS='libcxx;libcxxabi' -DCMAKE_BUILD_TYPE=Release -DLLVM_USE_SANITIZER=MemoryWithOrigins -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DLLVM_TARGETS_TO_BUILD=X86 ../llvm-project/llvm/"
- CI_EXEC "cd ${BASE_SCRATCH_DIR}/msan/build/ && make $MAKEJOBS cxx"
+ update-alternatives --install /usr/bin/clang++ clang++ "$(which clang++-16)" 100
+ update-alternatives --install /usr/bin/clang clang "$(which clang-16)" 100
+ git clone --depth=1 https://github.com/llvm/llvm-project -b llvmorg-16.0.1 "${BASE_SCRATCH_DIR}"/msan/llvm-project
+ cmake -B "${BASE_SCRATCH_DIR}"/msan/build/ -DLLVM_ENABLE_RUNTIMES='libcxx;libcxxabi' -DCMAKE_BUILD_TYPE=Release -DLLVM_USE_SANITIZER=MemoryWithOrigins -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=OFF -DLIBCXX_ENABLE_DEBUG_MODE=ON -DLIBCXX_ENABLE_ASSERTIONS=ON -S "${BASE_SCRATCH_DIR}"/msan/llvm-project/runtimes
+ make -C "${BASE_SCRATCH_DIR}"/msan/build/ "$MAKEJOBS"
fi
if [[ "${RUN_TIDY}" == "true" ]]; then
- if [ ! -d "${DIR_IWYU}" ]; then
- CI_EXEC "mkdir -p ${DIR_IWYU}/build/"
- CI_EXEC "git clone --depth=1 https://github.com/include-what-you-use/include-what-you-use -b clang_15 ${DIR_IWYU}/include-what-you-use"
- CI_EXEC "cd ${DIR_IWYU}/build && cmake -G 'Unix Makefiles' -DCMAKE_PREFIX_PATH=/usr/lib/llvm-15 ../include-what-you-use"
- CI_EXEC_ROOT "cd ${DIR_IWYU}/build && make install $MAKEJOBS"
- fi
+ git clone --depth=1 https://github.com/include-what-you-use/include-what-you-use -b clang_16 "${DIR_IWYU}"/include-what-you-use
+ cmake -B "${DIR_IWYU}"/build/ -G 'Unix Makefiles' -DCMAKE_PREFIX_PATH=/usr/lib/llvm-16 -S "${DIR_IWYU}"/include-what-you-use
+ make -C "${DIR_IWYU}"/build/ install "$MAKEJOBS"
fi
-CI_EXEC mkdir -p "${DEPENDS_DIR}/SDKs" "${DEPENDS_DIR}/sdk-sources"
+mkdir -p "${DEPENDS_DIR}/SDKs" "${DEPENDS_DIR}/sdk-sources"
OSX_SDK_BASENAME="Xcode-${XCODE_VERSION}-${XCODE_BUILD_ID}-extracted-SDK-with-libcxx-headers"
@@ -74,17 +61,19 @@ if [ -n "$XCODE_VERSION" ] && [ ! -d "${DEPENDS_DIR}/SDKs/${OSX_SDK_BASENAME}" ]
OSX_SDK_FILENAME="${OSX_SDK_BASENAME}.tar.gz"
OSX_SDK_PATH="${DEPENDS_DIR}/sdk-sources/${OSX_SDK_FILENAME}"
if [ ! -f "$OSX_SDK_PATH" ]; then
- CI_EXEC curl --location --fail "${SDK_URL}/${OSX_SDK_FILENAME}" -o "$OSX_SDK_PATH"
+ curl --location --fail "${SDK_URL}/${OSX_SDK_FILENAME}" -o "$OSX_SDK_PATH"
fi
- CI_EXEC tar -C "${DEPENDS_DIR}/SDKs" -xf "$OSX_SDK_PATH"
+ tar -C "${DEPENDS_DIR}/SDKs" -xf "$OSX_SDK_PATH"
fi
if [ -n "$ANDROID_HOME" ] && [ ! -d "$ANDROID_HOME" ]; then
ANDROID_TOOLS_PATH=${DEPENDS_DIR}/sdk-sources/android-tools.zip
if [ ! -f "$ANDROID_TOOLS_PATH" ]; then
- CI_EXEC curl --location --fail "${ANDROID_TOOLS_URL}" -o "$ANDROID_TOOLS_PATH"
+ curl --location --fail "${ANDROID_TOOLS_URL}" -o "$ANDROID_TOOLS_PATH"
fi
- CI_EXEC mkdir -p "$ANDROID_HOME"
- CI_EXEC unzip -o "$ANDROID_TOOLS_PATH" -d "$ANDROID_HOME"
- CI_EXEC "yes | ${ANDROID_HOME}/cmdline-tools/bin/sdkmanager --sdk_root=\"${ANDROID_HOME}\" --install \"build-tools;${ANDROID_BUILD_TOOLS_VERSION}\" \"platform-tools\" \"platforms;android-${ANDROID_API_LEVEL}\" \"ndk;${ANDROID_NDK_VERSION}\""
+ mkdir -p "$ANDROID_HOME"
+ unzip -o "$ANDROID_TOOLS_PATH" -d "$ANDROID_HOME"
+ yes | "${ANDROID_HOME}"/cmdline-tools/bin/sdkmanager --sdk_root="${ANDROID_HOME}" --install "build-tools;${ANDROID_BUILD_TOOLS_VERSION}" "platform-tools" "platforms;android-${ANDROID_API_LEVEL}" "ndk;${ANDROID_NDK_VERSION}"
fi
+
+git config --global ${CFG_DONE} "true"
diff --git a/ci/test/04_install.sh b/ci/test/04_install.sh
index b4d507cdbb..1024222e96 100755
--- a/ci/test/04_install.sh
+++ b/ci/test/04_install.sh
@@ -28,11 +28,6 @@ export BINS_SCRATCH_DIR="${BASE_SCRATCH_DIR}/bins/"
if [ -z "$DANGER_RUN_CI_ON_HOST" ]; then
echo "Creating $CI_IMAGE_NAME_TAG container to run in"
- LOCAL_UID=$(id -u)
- LOCAL_GID=$(id -g)
-
- # the name isn't important, so long as we use the same UID
- LOCAL_USER=nonroot
DOCKER_BUILDKIT=1 ${CI_RETRY_EXE} docker build \
--file "${BASE_ROOT_DIR}/ci/test_imagefile" \
--build-arg "CI_IMAGE_NAME_TAG=${CI_IMAGE_NAME_TAG}" \
@@ -59,31 +54,22 @@ if [ -z "$DANGER_RUN_CI_ON_HOST" ]; then
--name $CONTAINER_NAME \
$CONTAINER_NAME)
export CI_CONTAINER_ID
- export CI_EXEC_CMD_PREFIX_ROOT="docker exec -u 0 $CI_CONTAINER_ID"
- export CI_EXEC_CMD_PREFIX="docker exec -u $LOCAL_UID $CI_CONTAINER_ID"
- $CI_EXEC_CMD_PREFIX_ROOT rsync --archive --stats --human-readable /ci_base_install/ "${BASE_ROOT_DIR}"
- $CI_EXEC_CMD_PREFIX_ROOT rsync --archive --stats --human-readable /ro_base/ "$BASE_ROOT_DIR"
-
- # Create a non-root user inside the container which matches the local user.
- #
- # This prevents the root user in the container modifying the local file system permissions
- # on the mounted directories
- docker exec "$CI_CONTAINER_ID" useradd -u "$LOCAL_UID" -o -m "$LOCAL_USER"
- docker exec "$CI_CONTAINER_ID" groupmod -o -g "$LOCAL_GID" "$LOCAL_USER"
- docker exec "$CI_CONTAINER_ID" chown -R "$LOCAL_USER":"$LOCAL_USER" "${BASE_ROOT_DIR}"
+ export CI_EXEC_CMD_PREFIX="docker exec ${CI_CONTAINER_ID}"
else
echo "Running on host system without docker wrapper"
- "${BASE_ROOT_DIR}/ci/test/01_base_install.sh"
fi
CI_EXEC () {
$CI_EXEC_CMD_PREFIX bash -c "export PATH=${BINS_SCRATCH_DIR}:\$PATH && cd \"$P_CI_DIR\" && $*"
}
-CI_EXEC_ROOT () {
- $CI_EXEC_CMD_PREFIX_ROOT bash -c "export PATH=${BINS_SCRATCH_DIR}:\$PATH && cd \"$P_CI_DIR\" && $*"
-}
export -f CI_EXEC
-export -f CI_EXEC_ROOT
+
+CI_EXEC rsync --archive --stats --human-readable /ci_base_install/ "${BASE_ROOT_DIR}" || echo "/ci_base_install/ missing"
+CI_EXEC "${BASE_ROOT_DIR}/ci/test/01_base_install.sh"
+CI_EXEC rsync --archive --stats --human-readable /ro_base/ "${BASE_ROOT_DIR}" || echo "Nothing to copy from ro_base"
+# Fixes permission issues when there is a container UID/GID mismatch with the owner
+# of the git source code directory.
+CI_EXEC git config --global --add safe.directory \"*\"
CI_EXEC mkdir -p "${BINS_SCRATCH_DIR}"
diff --git a/ci/test/05_before_script.sh b/ci/test/05_before_script.sh
index 8e3153a20b..199cdd64a7 100755
--- a/ci/test/05_before_script.sh
+++ b/ci/test/05_before_script.sh
@@ -11,7 +11,6 @@ if [ "$CI_OS_NAME" == "macos" ]; then
echo > "${HOME}/Library/Application Support/Bitcoin"
else
CI_EXEC echo \> \$HOME/.bitcoin
- CI_EXEC_ROOT echo \> \$HOME/.bitcoin
fi
if [ -z "$NO_DEPENDS" ]; then
diff --git a/ci/test/06_script_b.sh b/ci/test/06_script_b.sh
index e95a64186e..e0fae18b8e 100755
--- a/ci/test/06_script_b.sh
+++ b/ci/test/06_script_b.sh
@@ -39,9 +39,11 @@ fi
if [ "${RUN_TIDY}" = "true" ]; then
set -eo pipefail
export P_CI_DIR="${BASE_BUILD_DIR}/bitcoin-$HOST/src/"
- ( CI_EXEC run-clang-tidy-15 -quiet "${MAKEJOBS}" ) | grep -C5 "error"
+ ( CI_EXEC run-clang-tidy-16 -quiet "${MAKEJOBS}" ) | grep -C5 "error"
export P_CI_DIR="${BASE_BUILD_DIR}/bitcoin-$HOST/"
CI_EXEC "python3 ${DIR_IWYU}/include-what-you-use/iwyu_tool.py"\
+ " src/common/args.cpp"\
+ " src/common/config.cpp"\
" src/common/init.cpp"\
" src/common/url.cpp"\
" src/compat"\
@@ -61,6 +63,7 @@ if [ "${RUN_TIDY}" = "true" ]; then
" src/random.cpp"\
" src/rpc/fees.cpp"\
" src/rpc/signmessage.cpp"\
+ " src/test/fuzz/string.cpp"\
" src/test/fuzz/txorphan.cpp"\
" src/test/fuzz/util/"\
" src/test/util/coins.cpp"\
diff --git a/configure.ac b/configure.ac
index cbe3dbcf19..cbbf8d6172 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,5 +1,5 @@
AC_PREREQ([2.69])
-define(_CLIENT_VERSION_MAJOR, 24)
+define(_CLIENT_VERSION_MAJOR, 25)
define(_CLIENT_VERSION_MINOR, 99)
define(_CLIENT_VERSION_BUILD, 0)
define(_CLIENT_VERSION_RC, 0)
@@ -126,8 +126,8 @@ AC_PATH_TOOL([AR], [ar])
AC_PATH_TOOL([GCOV], [gcov])
AC_PATH_TOOL([LLVM_COV], [llvm-cov])
AC_PATH_PROG([LCOV], [lcov])
-dnl Python 3.7 is specified in .python-version and should be used if available, see doc/dependencies.md
-AC_PATH_PROGS([PYTHON], [python3.7 python3.8 python3.9 python3.10 python3.11 python3.12 python3 python])
+dnl Python 3.8 is specified in .python-version and should be used if available, see doc/dependencies.md
+AC_PATH_PROGS([PYTHON], [python3.8 python3.9 python3.10 python3.11 python3.12 python3 python])
AC_PATH_PROG([GENHTML], [genhtml])
AC_PATH_PROG([GIT], [git])
AC_PATH_PROG([CCACHE], [ccache])
@@ -1767,7 +1767,7 @@ else
use_upnp=yes
AC_DEFINE([USE_UPNP], [1], [Define to 1 if UPnP support should be compiled in.])
if test "$TARGET_OS" = "windows"; then
- MINIUPNPC_CPPFLAGS="$MINIUPNPC_CPPFLAGS -DSTATICLIB -DMINIUPNP_STATICLIB"
+ MINIUPNPC_CPPFLAGS="$MINIUPNPC_CPPFLAGS -DMINIUPNP_STATICLIB"
fi
else
AC_MSG_RESULT([no])
diff --git a/contrib/devtools/symbol-check.py b/contrib/devtools/symbol-check.py
index f26236dd59..3507f954f3 100755
--- a/contrib/devtools/symbol-check.py
+++ b/contrib/devtools/symbol-check.py
@@ -72,6 +72,25 @@ ELF_INTERPRETER_NAMES: Dict[lief.ELF.ARCH, Dict[lief.ENDIANNESS, str]] = {
},
}
+ELF_ABIS: Dict[lief.ELF.ARCH, Dict[lief.ENDIANNESS, List[int]]] = {
+ lief.ELF.ARCH.x86_64: {
+ lief.ENDIANNESS.LITTLE: [3,2,0],
+ },
+ lief.ELF.ARCH.ARM: {
+ lief.ENDIANNESS.LITTLE: [3,2,0],
+ },
+ lief.ELF.ARCH.AARCH64: {
+ lief.ENDIANNESS.LITTLE: [3,7,0],
+ },
+ lief.ELF.ARCH.PPC64: {
+ lief.ENDIANNESS.LITTLE: [3,10,0],
+ lief.ENDIANNESS.BIG: [3,2,0],
+ },
+ lief.ELF.ARCH.RISCV: {
+ lief.ENDIANNESS.LITTLE: [4,15,0],
+ },
+}
+
# Allowed NEEDED libraries
ELF_ALLOWED_LIBRARIES = {
# bitcoind and bitcoin-qt
@@ -242,12 +261,19 @@ def check_ELF_interpreter(binary) -> bool:
return binary.concrete.interpreter == expected_interpreter
+def check_ELF_ABI(binary) -> bool:
+ expected_abi = ELF_ABIS[binary.header.machine_type][binary.abstract.header.endianness]
+ note = binary.concrete.get(lief.ELF.NOTE_TYPES.ABI_TAG)
+ assert note.details.abi == lief.ELF.NOTE_ABIS.LINUX
+ return note.details.version == expected_abi
+
CHECKS = {
lief.EXE_FORMATS.ELF: [
('IMPORTED_SYMBOLS', check_imported_symbols),
('EXPORTED_SYMBOLS', check_exported_symbols),
('LIBRARY_DEPENDENCIES', check_ELF_libraries),
('INTERPRETER_NAME', check_ELF_interpreter),
+ ('ABI', check_ELF_ABI),
],
lief.EXE_FORMATS.MACHO: [
('DYNAMIC_LIBRARIES', check_MACHO_libraries),
diff --git a/contrib/guix/libexec/build.sh b/contrib/guix/libexec/build.sh
index 08a6c72a95..e0bd15493f 100755
--- a/contrib/guix/libexec/build.sh
+++ b/contrib/guix/libexec/build.sh
@@ -188,9 +188,9 @@ make -C depends --jobs="$JOBS" HOST="$HOST" \
${SDK_PATH+SDK_PATH="$SDK_PATH"} \
x86_64_linux_CC=x86_64-linux-gnu-gcc \
x86_64_linux_CXX=x86_64-linux-gnu-g++ \
- x86_64_linux_AR=x86_64-linux-gnu-ar \
- x86_64_linux_RANLIB=x86_64-linux-gnu-ranlib \
- x86_64_linux_NM=x86_64-linux-gnu-nm \
+ x86_64_linux_AR=x86_64-linux-gnu-gcc-ar \
+ x86_64_linux_RANLIB=x86_64-linux-gnu-gcc-ranlib \
+ x86_64_linux_NM=x86_64-linux-gnu-gcc-nm \
x86_64_linux_STRIP=x86_64-linux-gnu-strip \
FORCE_USE_SYSTEM_CLANG=1
diff --git a/contrib/guix/manifest.scm b/contrib/guix/manifest.scm
index 7c1550a8d1..d83ff08713 100644
--- a/contrib/guix/manifest.scm
+++ b/contrib/guix/manifest.scm
@@ -150,7 +150,7 @@ chain for " target " development."))
#:key
(base-gcc-for-libc base-gcc)
(base-kernel-headers base-linux-kernel-headers)
- (base-libc (hardened-glibc (make-glibc-without-werror glibc-2.27)))
+ (base-libc (hardened-glibc glibc-2.27))
(base-gcc (make-gcc-rpath-link (hardened-gcc base-gcc))))
"Convenience wrapper around MAKE-CROSS-TOOLCHAIN with default values
desirable for building Bitcoin Core release binaries."
@@ -208,35 +208,40 @@ chain for " target " development."))
(package-with-extra-patches lief
(search-our-patches "lief-fix-ppc64-nx-default.patch")))
-(define-public lief
+;; Our python-lief package can be removed once we are using
+;; guix 83bfdb409787cb2737e68b093a319b247b7858e6 or later.
+;; Note we currently use cmake-minimal.
+(define-public python-lief
(package
- (name "python-lief")
- (version "0.12.1")
- (source
- (origin
- (method git-fetch)
- (uri (git-reference
- (url "https://github.com/lief-project/LIEF.git")
- (commit version)))
- (file-name (git-file-name name version))
- (sha256
- (base32
- "1xzbh3bxy4rw1yamnx68da1v5s56ay4g081cyamv67256g0qy2i1"))))
- (build-system python-build-system)
- (arguments
- `(#:phases
- (modify-phases %standard-phases
- (add-after 'unpack 'parallel-jobs
- ;; build with multiple cores
- (lambda _
- (substitute* "setup.py" (("self.parallel if self.parallel else 1") (number->string (parallel-job-count)))))))))
- (native-inputs
- `(("cmake" ,cmake)))
- (home-page "https://github.com/lief-project/LIEF")
- (synopsis "Library to Instrument Executable Formats")
- (description "Python library to to provide a cross platform library which can
-parse, modify and abstract ELF, PE and MachO formats.")
- (license license:asl2.0)))
+ (name "python-lief")
+ (version "0.12.3")
+ (source (origin
+ (method git-fetch)
+ (uri (git-reference
+ (url "https://github.com/lief-project/LIEF")
+ (commit version)))
+ (file-name (git-file-name name version))
+ (sha256
+ (base32
+ "11i6hqmcjh56y554kqhl61698n9v66j2qk1c1g63mv2w07h2z661"))))
+ (build-system python-build-system)
+ (native-inputs (list cmake-minimal))
+ (arguments
+ (list
+ #:tests? #f ;needs network
+ #:phases #~(modify-phases %standard-phases
+ (replace 'build
+ (lambda _
+ (invoke
+ "python" "setup.py" "--sdk" "build"
+ (string-append
+ "-j" (number->string (parallel-job-count)))))))))
+ (home-page "https://github.com/lief-project/LIEF")
+ (synopsis "Library to instrument executable formats")
+ (description
+ "@code{python-lief} is a cross platform library which can parse, modify
+and abstract ELF, PE and MachO formats.")
+ (license license:asl2.0)))
(define osslsigncode
(package
@@ -530,15 +535,16 @@ and endian independent.")
inspecting signatures in Mach-O binaries.")
(license license:expat))))
-(define (make-glibc-without-werror glibc)
- (package-with-extra-configure-variable glibc "enable_werror" "no"))
-
;; https://www.gnu.org/software/libc/manual/html_node/Configuring-and-compiling.html
+;; We don't use --disable-werror directly, as that would be passed through to bash,
+;; and cause it's build to fail.
(define (hardened-glibc glibc)
(package-with-extra-configure-variable (
- package-with-extra-configure-variable glibc
- "--enable-stack-protector" "all")
- "--enable-bind-now" "yes"))
+ package-with-extra-configure-variable (
+ package-with-extra-configure-variable glibc
+ "enable_werror" "no")
+ "--enable-stack-protector" "all")
+ "--enable-bind-now" "yes"))
(define-public glibc-2.27
(package
@@ -592,11 +598,11 @@ inspecting signatures in Mach-O binaries.")
gcc-toolchain-10
(list gcc-toolchain-10 "static")
;; Scripting
- python-3
+ python-minimal ;; (3.9)
;; Git
git-minimal
;; Tests
- (fix-ppc64-nx-default lief))
+ (fix-ppc64-nx-default python-lief))
(let ((target (getenv "HOST")))
(cond ((string-suffix? "-mingw32" target)
;; Windows
diff --git a/contrib/seeds/README.md b/contrib/seeds/README.md
index b0bbe96493..6db77cbbea 100644
--- a/contrib/seeds/README.md
+++ b/contrib/seeds/README.md
@@ -11,8 +11,10 @@ to addrman with).
The seeds compiled into the release are created from sipa's DNS seed and AS map
data. Run the following commands from the `/contrib/seeds` directory:
- curl https://bitcoin.sipa.be/seeds.txt.gz | gzip -dc > seeds_main.txt
- curl https://bitcoin.sipa.be/asmap-filled.dat > asmap-filled.dat
- python3 makeseeds.py -a asmap-filled.dat -s seeds_main.txt > nodes_main.txt
- cat nodes_main_manual.txt >> nodes_main.txt
- python3 generate-seeds.py . > ../../src/chainparamsseeds.h
+```
+curl https://bitcoin.sipa.be/seeds.txt.gz | gzip -dc > seeds_main.txt
+curl https://bitcoin.sipa.be/asmap-filled.dat > asmap-filled.dat
+python3 makeseeds.py -a asmap-filled.dat -s seeds_main.txt > nodes_main.txt
+cat nodes_main_manual.txt >> nodes_main.txt
+python3 generate-seeds.py . > ../../src/chainparamsseeds.h
+```
diff --git a/contrib/seeds/generate-seeds.py b/contrib/seeds/generate-seeds.py
index a6f435af0d..e921757802 100755
--- a/contrib/seeds/generate-seeds.py
+++ b/contrib/seeds/generate-seeds.py
@@ -3,7 +3,7 @@
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
'''
-Script to generate list of seed nodes for chainparams.cpp.
+Script to generate list of seed nodes for kernel/chainparams.cpp.
This script expects two text files in the directory that is passed as an
argument:
diff --git a/contrib/seeds/makeseeds.py b/contrib/seeds/makeseeds.py
index 23d38ee48d..af408c2df5 100755
--- a/contrib/seeds/makeseeds.py
+++ b/contrib/seeds/makeseeds.py
@@ -37,19 +37,26 @@ PATTERN_AGENT = re.compile(
r"0.19.(0|1|2|99)|"
r"0.20.(0|1|2|99)|"
r"0.21.(0|1|2|99)|"
- r"22.(0|99)|"
- r"23.(0|99)|"
- r"24.99"
+ r"22.(0|1|99)|"
+ r"23.(0|1|99)|"
+ r"24.(0|1|99)|"
+ r"25.99"
r")")
def parseline(line: str) -> Union[dict, None]:
""" Parses a line from `seeds_main.txt` into a dictionary of details for that line.
or `None`, if the line could not be parsed.
"""
+ if line.startswith('#'):
+ # Ignore line that starts with comment
+ return None
sline = line.split()
if len(sline) < 11:
# line too short to be valid, skip it.
return None
+ # Skip bad results.
+ if int(sline[1]) == 0:
+ return None
m = PATTERN_IPV4.match(sline[0])
sortkey = None
ip = None
@@ -83,9 +90,6 @@ def parseline(line: str) -> Union[dict, None]:
sortkey = ip
ipstr = m.group(1)
port = int(m.group(6))
- # Skip bad results.
- if sline[1] == 0:
- return None
# Extract uptime %.
uptime30 = float(sline[7][:-1])
# Extract Unix timestamp of last success.
diff --git a/contrib/seeds/nodes_main.txt b/contrib/seeds/nodes_main.txt
index f8572b26c7..100fe09685 100644
--- a/contrib/seeds/nodes_main.txt
+++ b/contrib/seeds/nodes_main.txt
@@ -1,857 +1,896 @@
-2.3.25.181:8333 # AS3215
-2.152.78.124:8333 # AS12430
-5.39.74.166:8333 # AS16276
-5.45.79.81:18332 # AS50673
-5.53.16.128:8333 # AS50923
-5.95.186.78:8333 # AS30722
+1.65.195.98:8333 # AS4760
+2.59.236.56:8333 # AS24904
+2.83.114.20:8333 # AS8657
+2.248.194.16:8333 # AS3301
+5.2.154.6:8333 # AS8708
+5.101.140.30:8333 # AS42831
5.128.87.126:8333 # AS31200
-5.133.65.82:8333 # AS15440
-5.146.20.229:8333 # AS3209
-5.180.41.119:8333 # AS18978
+5.144.21.49:8333 # AS15600
+5.172.132.104:8333 # AS15600
5.188.62.18:8333 # AS34665
-5.199.173.66:8333 # AS16125
-5.255.97.25:8333 # AS60404
-5.255.103.180:8333 # AS60404
-8.209.70.77:8333 # AS45102
+5.200.2.180:8333 # AS49544
+8.129.184.255:8333 # AS37963
8.209.105.138:8333 # AS45102
-18.162.208.153:48332 # AS16509
-23.175.0.200:8333 # AS395502
+12.34.98.148:8333 # AS7018
+14.199.102.151:8333 # AS9269
+18.27.79.17:8333 # AS3
+18.27.124.231:8333 # AS3
+18.216.249.151:8333 # AS16509
+23.88.155.58:8333 # AS10242
+23.93.101.158:8333 # AS46375
+23.109.156.76:8333 # AS7979
+23.175.0.220:8333 # AS395502
23.175.0.222:8333 # AS395502
-23.233.107.21:8333 # AS5645
-23.236.25.169:8333 # AS30029
-24.35.68.229:8333 # AS11404
-24.84.164.50:8333 # AS6327
-24.116.153.115:8333 # AS11492
-24.184.0.146:8333 # AS6128
-27.33.160.196:8333 # AS7545
+24.232.36.225:8333 # AS7303
27.124.108.19:8333 # AS58511
27.148.206.140:8333 # AS4134
-31.17.64.192:8333 # AS204028
-31.18.114.135:8333 # AS204028
+31.7.70.195:8333 # AS49666
+31.25.98.16:8333 # AS48635
31.41.23.249:8333 # AS31287
-31.42.176.138:8333 # AS43641
+31.47.102.92:8333 # AS8251
31.47.202.112:8333 # AS34385
-34.65.45.157:8333 # AS15169
-34.80.134.68:8333 # AS15169
+31.165.78.146:8333 # AS6730
+31.165.228.138:8333 # AS6730
+34.64.101.4:8333 # AS139070
+34.105.19.97:8333 # AS15169
+34.126.107.179:8333 # AS396982
34.126.115.35:8333 # AS396982
-37.1.204.231:8333 # AS50673
+35.245.186.117:8333 # AS15169
+37.15.60.144:8333 # AS12479
+37.16.105.63:8333 # AS20904
37.120.155.34:8333 # AS9009
-37.143.118.174:8333 # AS48926
+37.120.179.29:8333 # AS47147
+37.139.102.73:8333 # AS35816
37.193.227.16:8333 # AS31200
37.220.135.151:8333 # AS41206
-37.235.146.236:8333 # AS41268
-38.124.126.42:8333 # AS11550
+38.53.129.67:8333 # AS40237
+38.54.14.89:8333 # AS138915
38.141.134.140:8333 # AS174
38.145.151.150:8333 # AS40545
-40.115.137.28:8333 # AS8075
41.72.154.66:8333 # AS37153
-41.79.70.146:8333 # AS37349
-42.193.55.135:8333 # AS45090
-43.225.62.107:8333 # AS63953
+43.143.203.198:8333 # AS45090
+45.15.124.117:8333 # AS35913
45.43.97.103:8333 # AS26827
-45.85.48.58:8333 # AS208016
-45.126.26.229:8333 # AS45763
+45.44.213.116:8333 # AS54198
+45.58.187.101:8333 # AS46844
+45.79.192.236:8333 # AS63949
+45.81.241.97:8333 # AS30823
+45.83.220.102:8333 # AS39351
+45.83.241.46:8333 # AS206238
+45.87.106.57:8333 # AS39238
+45.129.38.5:8333 # AS49666
+45.130.20.177:8333 # AS3214
45.134.142.40:8333 # AS60068
-45.154.252.162:8333 # AS13335
-46.13.216.169:8333 # AS6855
+45.135.4.143:8333 # AS25596
+45.135.92.127:8333 # AS12555
+45.145.188.112:8333 # AS206805
46.23.87.218:8333 # AS51088
-46.40.127.164:8333 # AS43205
-46.48.126.58:8333 # AS12668
-46.59.13.35:8333 # AS8473
-46.72.238.17:8333 # AS12714
-46.128.141.184:8333 # AS16097
-46.146.248.89:8333 # AS9049
-46.165.221.209:9333 # AS28753
+46.32.50.98:8333 # AS39642
+46.32.78.17:8333 # AS48416
+46.59.40.91:8333 # AS8473
+46.138.246.77:8333 # AS8359
46.166.142.2:8333 # AS43350
+46.166.162.59:8333 # AS16125
46.175.178.3:8333 # AS28725
-47.36.144.51:8333 # AS20115
-47.180.49.158:8333 # AS5650
-49.228.131.133:2210 # AS133481
+46.188.15.6:8333 # AS39153
+46.188.30.118:8333 # AS39153
+46.223.223.216:8333 # AS51185
+46.226.18.135:8333 # AS52176
+47.88.86.79:8333 # AS45102
+47.148.7.69:8333 # AS5650
+47.198.223.60:8333 # AS5650
50.2.13.164:8333 # AS62904
-50.35.71.51:8333 # AS20055
+50.4.135.84:8333 # AS12083
+50.53.39.237:8333 # AS20055
50.53.250.162:8333 # AS20055
-51.68.36.57:8333 # AS16276
-51.138.4.135:30001 # AS8075
+50.68.121.44:8333 # AS6327
+50.117.132.178:8333 # AS577
51.154.62.103:8333 # AS15796
51.158.150.155:8333 # AS12876
+51.250.46.215:8333 # AS200350
54.176.63.16:8333 # AS16509
58.158.0.86:8333 # AS2519
-59.138.115.137:8333 # AS2516
-59.167.191.60:8333 # AS4739
60.205.205.119:8333 # AS37963
-60.234.122.245:8333 # AS9790
-60.240.210.155:8333 # AS7545
-61.239.91.250:8333 # AS9269
-62.74.143.11:8333 # AS3329
-62.138.162.12:8333 # AS20773
-62.169.74.233:8333 # AS2860
+61.74.99.193:8333 # AS4766
+61.92.59.104:8333 # AS9269
+62.122.173.171:8333 # AS50245
62.171.129.32:8333 # AS51167
-62.209.198.65:8333 # AS6855
-63.247.147.166:8333 # AS30221
-64.98.76.62:8333 # AS32133
+62.178.27.239:8333 # AS8412
+62.209.210.3:8333 # AS6855
+62.215.127.73:8333 # AS21050
+62.238.148.104:8333 # AS15435
+62.245.153.8:8333 # AS8767
+64.146.136.45:8333 # AS16713
+65.21.134.184:8333 # AS24940
+66.18.13.146:8333 # AS13767
+66.23.233.43:8333 # AS19318
+66.27.98.216:8333 # AS20001
66.29.129.218:8333 # AS22612
-66.96.235.28:8333 # AS63859
-66.130.120.52:8333 # AS5769
-66.198.209.243:8333 # AS33152
+66.38.94.13:8333 # AS11979
+66.45.141.46:8333 # AS11232
+66.58.243.215:8333 # AS8047
+66.114.33.49:8333 # AS23175
+66.198.211.167:8333 # AS10835
66.208.64.128:8333 # AS10352
-66.225.231.148:8333 # AS23352
-67.55.3.200:8333 # AS33139
-67.58.232.107:8333 # AS14051
-67.211.92.2:8333 # AS11711
-67.223.119.122:8333 # AS22612
-68.48.131.251:8333 # AS7922
-68.181.4.12:8333 # AS47
-69.14.185.9:8333 # AS12083
-69.54.29.193:8333 # AS12282
+66.219.196.170:8333 # AS29933
+67.210.228.203:8333 # AS7819
+68.183.75.251:8333 # AS14061
+68.194.125.140:8333 # AS6128
+68.199.120.17:8333 # AS6128
+69.4.94.226:8333 # AS36352
+69.8.175.201:8333 # AS21766
69.59.18.22:8333 # AS397444
-69.131.101.176:8333 # AS4181
-69.165.205.142:8833 # AS5645
+69.196.152.33:8333 # AS5645
69.228.219.124:8333 # AS7018
-70.59.123.25:8333 # AS209
-70.62.13.150:8333 # AS7843
-70.66.248.170:8333 # AS6327
-70.112.153.229:8333 # AS7843
+70.64.27.12:8333 # AS6327
70.160.240.132:8333 # AS22773
-70.190.177.204:8333 # AS22773
-71.28.189.239:8333 # AS398465
-71.234.125.198:8333 # AS1351
-72.74.123.179:8333 # AS701
-72.253.236.217:8333 # AS36149
-73.219.254.120:8333 # AS1351
+71.79.109.128:8333 # AS7843
+71.184.193.75:8333 # AS701
+72.15.59.173:8333 # AS21949
+72.48.253.168:8333 # AS7459
+72.207.171.210:8333 # AS22773
+73.117.132.138:8333 # AS7922
+73.212.226.59:8333 # AS7922
+74.76.151.110:8333 # AS7843
74.91.115.229:8333 # AS14586
74.118.137.119:8333 # AS20326
-74.195.166.100:8333 # AS19108
+74.213.175.108:8333 # AS21949
+74.213.251.239:8333 # AS14978
74.220.255.190:8333 # AS23175
-76.67.211.110:8333 # AS577
-76.169.163.14:8333 # AS20001
-77.32.121.162:8333 # AS35612
-77.53.135.74:8333 # AS45011
+74.221.189.109:8333 # AS26827
+75.83.203.225:8333 # AS20001
+75.172.52.186:8333 # AS209
+76.24.143.22:8333 # AS1351
+76.69.202.247:8333 # AS577
+76.73.198.242:8333 # AS12083
+76.119.248.240:8333 # AS1351
+77.20.48.144:8333 # AS3209
+77.22.152.239:8333 # AS204028
+77.37.224.222:8333 # AS42610
+77.48.196.234:8333 # AS16019
77.70.16.245:8333 # AS8717
-77.85.204.149:8333 # AS8866
-77.107.38.239:8333 # AS62183
-77.120.26.102:8333 # AS25229
77.162.190.90:8333 # AS1136
78.20.227.249:8333 # AS6848
78.21.167.8:8333 # AS6848
-78.27.139.13:8333 # AS6723
-78.90.91.220:8333 # AS8717
+78.35.147.203:8333 # AS8422
78.108.108.25:8333 # AS8251
-78.108.108.38:8333 # AS8251
-79.77.182.183:8333 # AS13285
-79.98.159.7:11333 # AS44065
-79.189.211.201:8333 # AS5617
-80.55.225.158:8333 # AS5617
-80.83.186.35:8333 # AS33891
-80.88.172.227:64264 # AS31263
-80.209.87.103:9333 # AS31027
+78.154.237.60:8333 # AS9155
+79.11.31.76:8333 # AS3269
+79.87.88.235:8333 # AS15557
+79.101.1.25:8333 # AS8400
+79.124.7.241:8333 # AS203380
+79.124.7.253:8333 # AS203380
+79.150.68.42:8333 # AS3352
+79.249.10.53:8333 # AS3320
+80.82.21.77:8333 # AS42927
+80.82.76.59:8333 # AS202425
+80.88.172.227:8333 # AS31263
+80.93.213.246:8333 # AS42910
+80.111.142.213:8333 # AS6830
+80.208.227.134:8333 # AS62282
+80.208.228.9:8333 # AS62282
+80.209.64.86:8333 # AS31027
80.229.28.60:8333 # AS2856
81.7.16.182:8333 # AS35366
-81.7.17.202:8333 # AS35366
81.19.10.2:8333 # AS24641
-81.88.221.190:8333 # AS39709
+81.162.196.43:8333 # AS34955
81.171.22.143:8333 # AS60781
+81.172.221.4:8333 # AS12430
81.224.44.164:8333 # AS3301
-81.224.160.81:8333 # AS3301
+81.245.96.36:8333 # AS5432
82.1.68.54:8333 # AS5089
-82.21.164.47:8333 # AS5089
-82.64.116.5:8333 # AS12322
82.66.10.11:8333 # AS12322
+82.66.211.31:8333 # AS12322
+82.71.4.154:8333 # AS13037
82.96.96.40:8333 # AS29686
82.116.50.101:8333 # AS30936
-82.129.68.62:8333 # AS48945
-82.136.99.122:8333 # AS8821
-82.154.24.209:8333 # AS8657
-82.197.215.125:8333 # AS25596
-83.128.132.91:8333 # AS15435
+82.136.98.249:8333 # AS8821
+82.195.237.253:8333 # AS1836
83.137.41.10:8333 # AS31394
-83.208.6.211:8333 # AS5610
+83.171.175.5:8333 # AS8767
83.208.193.242:8333 # AS5610
-83.222.138.85:8333 # AS31736
-83.240.124.68:8333 # AS31246
-83.243.191.199:8333 # AS41164
-84.9.5.211:8333 # AS5378
-84.28.57.90:8333 # AS6830
+83.233.76.165:8333 # AS29518
+83.240.89.196:8333 # AS31246
84.38.3.249:8333 # AS196691
-84.112.60.16:8333 # AS8412
-84.215.56.119:8333 # AS41164
-84.226.243.175:8333 # AS6730
-84.245.14.73:8333 # AS25596
-84.252.157.90:18333 # AS200590
+84.54.23.48:8333 # AS35913
+84.126.216.77:8333 # AS12430
+84.211.187.211:8333 # AS41164
+84.246.200.122:8333 # AS42455
84.255.244.61:8333 # AS34779
-85.23.24.123:8333 # AS16086
-85.52.185.29:8666 # AS12479
-85.58.120.201:8333 # AS12479
-85.93.96.18:8333 # AS29208
-85.165.8.197:8333 # AS2119
-85.173.165.66:8333 # AS12389
-85.184.143.105:8333 # AS39642
-85.191.74.103:8333 # AS39642
+85.165.42.115:8333 # AS2119
85.194.238.134:8333 # AS47605
-85.195.54.110:8333 # AS35706
-85.195.196.142:8333 # AS13030
-85.208.69.11:8333 # AS25091
85.208.69.21:8333 # AS25091
85.208.71.36:8333 # AS42275
-85.208.71.39:8333 # AS42275
+85.209.240.91:8333 # AS205581
85.214.118.71:8333 # AS6724
85.214.161.252:8333 # AS6724
-85.216.32.73:8333 # AS51185
-85.254.98.221:8333 # AS13194
-86.58.11.152:8333 # AS3212
+85.236.190.252:8333 # AS35032
+85.243.115.136:8333 # AS8657
+86.22.20.13:8333 # AS5089
+86.49.34.92:8333 # AS16019
86.95.8.249:8333 # AS1136
-86.100.26.188:8333 # AS39007
-86.106.143.143:55373 # AS9009
-86.124.145.184:8333 # AS8708
-86.133.251.239:8901 # AS2856
+86.104.228.10:8333 # AS31638
+86.104.228.23:8333 # AS31638
87.79.94.221:8333 # AS8422
-87.120.8.5:20008 # AS34224
-87.125.157.220:8333 # AS12430
-88.9.76.133:8333 # AS3352
-88.90.184.68:8333 # AS2119
-88.151.101.14:5000 # AS41075
-88.151.101.253:5000 # AS41075
-88.198.92.47:8333 # AS24940
+88.10.89.23:8333 # AS3352
+88.84.223.30:8333 # AS21453
+88.86.125.50:8333 # AS39392
+88.90.77.100:8333 # AS2119
+88.97.40.50:8333 # AS13037
+88.137.109.62:8333 # AS15557
+88.147.244.250:8333 # AS12389
88.208.115.70:8333 # AS29208
-88.210.15.24:8333 # AS212702
-88.212.45.166:8333 # AS42841
-89.102.206.238:8333 # AS16019
-89.103.111.34:8333 # AS16019
-89.114.143.113:8333 # AS12353
-89.134.62.74:8333 # AS21334
-89.152.8.231:8333 # AS2860
-89.161.26.78:8333 # AS39375
-89.207.131.19:8333 # AS49544
-89.248.193.229:8333 # AS49505
-90.3.48.62:8333 # AS3215
-90.146.121.97:8333 # AS12605
+88.212.53.246:8333 # AS42841
+89.35.142.168:8333 # AS34977
+89.78.111.197:8333 # AS6830
+89.117.59.129:8333 # AS1239
+89.147.108.200:8333 # AS44735
+89.163.132.180:8333 # AS24961
+89.165.232.242:8333 # AS48161
+89.216.21.96:8333 # AS31042
+90.50.172.182:8333 # AS3215
90.146.130.214:8333 # AS12605
-90.196.169.58:8333 # AS5607
-90.250.9.1:8333 # AS5378
+90.146.208.162:8333 # AS12605
+90.156.26.148:8333 # AS12741
+90.163.172.139:8333 # AS12479
+90.177.163.77:8333 # AS5610
+91.67.145.110:8333 # AS3209
91.93.194.154:8333 # AS34984
-91.126.40.109:8333 # AS35699
-91.204.99.178:8333 # AS20485
+91.123.182.164:8333 # AS51648
+91.123.183.219:8333 # AS51792
+91.135.0.187:8333 # AS12496
+91.147.232.98:8333 # AS5483
+91.184.168.249:8333 # AS9063
+91.193.237.116:8333 # AS42916
+91.199.41.45:8333 # AS6866
91.204.149.5:8333 # AS42765
-91.206.17.195:8333 # AS13259
-91.209.51.131:8333 # AS48239
91.215.91.254:8333 # AS48078
-92.91.27.60:8333 # AS15557
+91.219.25.232:8333 # AS50448
+91.237.88.218:8333 # AS56813
+92.27.150.46:8333 # AS13285
+92.27.150.47:8333 # AS13285
92.221.20.232:8333 # AS29695
-92.255.85.31:8333 # AS9002
-93.4.101.37:8333 # AS15557
-93.46.81.5:8333 # AS12874
-93.57.81.162:8333 # AS12874
-93.73.39.196:8333 # AS25229
-93.90.82.226:8333 # AS47626
+92.221.126.65:8333 # AS29695
+93.33.192.204:8333 # AS12874
+93.41.237.78:8333 # AS12874
93.95.88.13:8333 # AS35434
+93.95.227.125:8333 # AS44735
+93.103.13.1:8333 # AS34779
+93.115.86.239:8333 # AS3223
93.123.180.164:8333 # AS35539
-93.189.145.169:8333 # AS12555
-94.17.185.107:8333 # AS12709
-94.75.198.120:8333 # AS60781
-94.114.196.169:8333 # AS3209
-94.142.213.250:55544 # AS5524
+93.186.201.173:8333 # AS24961
+93.190.117.26:8333 # AS196881
+94.19.7.55:8333 # AS35807
+94.23.21.80:8333 # AS16276
+94.23.205.110:8333 # AS16276
+94.131.0.73:8333 # AS29632
+94.142.237.4:8333 # AS48926
94.154.159.99:8333 # AS62240
-94.158.246.183:8333 # AS39798
-94.239.145.32:8333 # AS5410
-95.31.12.22:8333 # AS8402
-95.31.196.15:8333 # AS3216
-95.110.133.223:8333 # AS31034
+94.202.50.200:8333 # AS15802
+94.231.253.18:8333 # AS35224
+95.42.140.142:8333 # AS8866
+95.67.18.100:8333 # AS34867
+95.70.238.176:8333 # AS12735
+95.83.73.31:8333 # AS8359
+95.90.128.3:8333 # AS204028
95.110.234.93:8333 # AS31034
95.161.12.45:8333 # AS39598
+95.172.62.167:8333 # AS201826
+95.179.128.87:8333 # AS20473
95.191.130.100:8333 # AS12389
-95.208.158.161:8333 # AS51185
-95.213.145.218:8333 # AS49505
95.214.53.154:8333 # AS201814
-95.214.53.160:8333 # AS201814
-96.44.156.199:8333 # AS8100
+96.3.53.254:8333 # AS11232
97.75.145.12:8333 # AS22709
+97.81.198.180:8333 # AS20115
+97.87.216.110:8333 # AS20115
+99.229.210.111:8333 # AS812
+99.246.87.2:8333 # AS812
+101.43.124.195:8333 # AS45090
102.132.192.141:8333 # AS37680
-103.14.245.250:8333 # AS24482
-103.85.38.205:8333 # AS134090
-103.88.92.78:8332 # AS17547
+103.21.3.89:8333 # AS38195
+103.35.121.72:8333 # AS9498
103.99.168.100:8333 # AS6939
103.99.168.140:8333 # AS6939
103.99.170.210:8333 # AS54415
103.99.170.220:8333 # AS54415
-103.100.44.70:8333 # AS10143
-103.178.236.27:8333 # AS49981
-103.209.12.144:8333 # AS58511
-104.59.147.15:8333 # AS7018
-104.129.171.121:8333 # AS174
-104.200.65.234:8333 # AS23033
+103.105.202.50:8333 # AS137764
104.238.220.199:8333 # AS23470
+104.243.33.165:8333 # AS23470
104.244.73.6:8333 # AS53667
-106.71.119.230:8333 # AS4804
-107.173.166.43:8333 # AS23352
-108.161.22.78:8333 # AS54154
-108.174.63.234:8333 # AS36352
+108.26.125.214:8333 # AS701
+109.86.60.33:8333 # AS13188
109.99.63.159:8333 # AS9050
-109.105.40.247:8333 # AS12570
-109.107.185.130:8333 # AS48282
-109.110.239.4:8333 # AS35432
-109.173.41.43:8333 # AS42610
+109.120.194.136:8333 # AS34569
+109.123.233.138:8333 # AS15685
+109.123.240.53:8333 # AS15685
+109.153.94.35:8333 # AS2856
+109.173.126.157:8333 # AS42610
+109.193.76.200:8333 # AS51185
+109.221.229.197:8333 # AS3215
109.236.90.117:8333 # AS49981
109.248.206.13:8333 # AS203493
-109.255.106.206:8333 # AS6830
111.90.140.23:8333 # AS45839
111.90.140.46:8333 # AS45839
-111.90.159.246:8333 # AS34309
-112.118.188.50:8333 # AS4760
-115.47.141.250:8885 # AS4134
+111.90.145.37:8333 # AS18106
+114.173.159.209:8333 # AS4713
116.58.171.67:8333 # AS2514
-118.92.107.108:8333 # AS9500
+119.31.179.202:8333 # AS17408
119.42.55.203:8333 # AS133159
-120.79.71.72:8333 # AS37963
-121.99.240.87:8333 # AS9790
+122.222.160.190:8333 # AS2519
123.60.213.192:8333 # AS55990
-124.156.158.100:8333 # AS132203
-124.222.123.238:8333 # AS45090
-125.178.6.116:8333 # AS3786
+124.197.54.113:8333 # AS9790
+125.168.140.108:8333 # AS4826
128.0.190.26:8333 # AS30764
128.65.194.136:8333 # AS29222
129.13.189.212:8333 # AS34878
-129.126.172.115:8333 # AS17547
-129.146.52.174:8333 # AS31898
-130.44.168.202:8333 # AS6079
-131.161.80.166:8333 # AS263694
+129.13.189.215:8333 # AS34878
+129.226.216.148:8333 # AS132203
131.188.40.191:8333 # AS680
+134.65.9.63:8333 # AS19653
+134.122.200.160:8333 # AS64050
134.195.185.52:8333 # AS13536
-135.134.238.47:8333 # AS4181
-135.180.218.58:8333 # AS46375
-135.181.215.237:8333 # AS24940
-136.29.109.180:8333 # AS19165
+135.19.253.101:8333 # AS5769
+136.29.109.58:8333 # AS19165
136.32.238.6:8333 # AS16591
-136.56.170.96:8333 # AS16591
-137.25.38.108:8333 # AS20115
+136.49.201.24:8333 # AS16591
137.226.34.46:8333 # AS680
-138.207.211.106:8333 # AS11776
+138.207.211.189:8333 # AS11776
139.130.41.82:8333 # AS1221
-139.153.255.107:8333 # AS786
-140.190.12.129:8333 # AS14828
+140.238.220.99:8333 # AS31898
142.54.181.218:8333 # AS32097
+142.166.19.23:8333 # AS855
+142.254.87.115:8333 # AS46375
143.177.229.149:8333 # AS50266
-143.178.64.10:8333 # AS50266
-144.24.245.183:8333 # AS31898
-144.126.130.178:8333 # AS40021
-146.4.124.129:8333 # AS3303
+144.2.101.21:8333 # AS3303
+144.24.236.64:8333 # AS31898
+145.40.51.52:8333 # AS49808
146.71.69.103:8333 # AS7782
-146.83.56.69:8333 # AS23140
-147.194.177.165:8333 # AS15128
-149.90.214.78:8333 # AS12353
-149.102.157.156:8333 # AS13768
-151.248.156.55:8333 # AS8821
-151.252.193.245:8333 # AS29582
-153.92.93.114:8333 # AS41998
-154.211.6.2:8333 # AS140224
-156.17.103.2:8088 # AS8970
+146.120.241.173:8333 # AS208515
+147.50.238.53:8333 # AS45265
+148.103.101.132:8333 # AS28118
+149.75.48.92:8333 # AS6079
+152.44.137.83:8333 # AS11404
+154.0.3.194:8333 # AS37680
+154.26.137.105:8333 # AS174
+154.26.154.73:8333 # AS1299
+154.57.5.11:8333 # AS200736
+155.4.55.21:8333 # AS8473
+156.146.137.142:8333 # AS1448
156.146.177.221:8333 # AS1448
-157.131.143.173:8333 # AS46375
-158.58.188.37:8333 # AS57497
-158.248.39.239:8333 # AS29695
-159.89.230.128:8333 # AS14061
+157.22.72.175:8333 # AS397379
+157.97.0.118:8333 # AS43571
+158.140.141.69:8333 # AS132132
+158.181.132.84:8333 # AS41750
+159.2.215.98:8333 # AS855
159.196.3.239:8333 # AS4764
159.224.189.250:8333 # AS13188
-160.72.51.154:8333 # AS46887
-161.29.236.55:8333 # AS4826
-161.97.119.166:8333 # AS51167
+160.80.12.16:8333 # AS137
+161.230.38.160:8333 # AS12353
161.246.11.230:8333 # AS9486
+162.0.210.152:8333 # AS22612
162.62.18.226:8333 # AS132203
-162.250.123.179:8333 # AS19318
-162.250.191.222:8333 # AS26832
162.254.118.20:8333 # AS6130
-163.172.81.70:8333 # AS12876
-164.90.47.8:8333 # AS53449
+163.158.168.181:8333 # AS15435
+165.173.19.33:8333 # AS132132
165.228.174.117:8333 # AS1221
-166.70.145.151:8333 # AS6315
-168.91.238.8:8333 # AS11039
-170.253.11.25:8333 # AS15704
-171.103.170.115:8333 # AS7470
-172.93.166.135:8333 # AS22653
-172.103.217.236:8333 # AS25668
+165.255.241.184:8333 # AS327693
+167.88.11.203:8333 # AS20278
+167.179.147.155:8333 # AS4764
+170.17.151.235:8333 # AS3303
+170.64.174.230:8333 # AS15108
+172.92.102.115:8333 # AS11404
172.105.21.216:8333 # AS63949
-172.112.153.95:8333 # AS20001
-173.3.218.91:8333 # AS6128
-173.12.119.133:8333 # AS7922
-173.34.127.181:8333 # AS812
-173.76.123.173:8333 # AS701
-173.176.198.68:8333 # AS5769
-173.208.152.218:8333 # AS32097
-173.241.227.243:8333 # AS19009
-173.246.27.7:8333 # AS1403
-173.255.240.205:8333 # AS63949
-174.30.47.15:8333 # AS209
-174.114.250.86:8333 # AS812
-174.138.35.229:8333 # AS14061
-174.142.191.136:8333 # AS32613
-176.10.143.190:8333 # AS8473
+172.111.176.244:8333 # AS46562
+172.255.98.108:8333 # AS7979
+173.82.5.202:8333 # AS35916
+173.181.35.50:8333 # AS395570
+173.212.253.137:8333 # AS51167
+173.235.73.87:8333 # AS11272
+174.30.29.85:8333 # AS209
+174.141.209.40:8333 # AS6461
+176.9.17.121:8333 # AS24940
+176.12.16.135:8333 # AS8717
176.74.136.237:8333 # AS35613
-176.118.220.29:8333 # AS60042
-176.126.116.7:8333 # AS20473
+176.74.139.120:8333 # AS35613
+176.122.122.134:8333 # AS50581
176.126.167.10:8333 # AS8449
+176.151.244.130:8333 # AS5410
+176.186.19.106:8333 # AS5410
176.212.185.153:8333 # AS9049
-176.235.209.186:8333 # AS34984
-177.81.236.117:8333 # AS28573
-177.89.205.70:8333 # AS28220
-178.48.168.12:8333 # AS21334
+177.142.146.193:8333 # AS4230
+178.21.118.178:8333 # AS49544
+178.61.141.198:8333 # AS21050
178.124.162.209:8333 # AS6697
+178.143.25.194:8333 # AS15962
+178.154.233.197:8333 # AS200350
178.159.98.133:8333 # AS202390
-178.196.89.209:8333 # AS3303
+178.232.186.191:8333 # AS41164
178.236.137.63:8333 # AS44843
-178.252.123.24:8333 # AS42893
-179.43.170.186:8333 # AS51852
-180.150.46.187:8333 # AS4764
-181.117.128.140:8333 # AS19037
-184.19.19.16:8333 # AS5650
-185.21.217.48:8333 # AS200052
+179.60.149.4:8333 # AS395839
+184.160.110.104:8333 # AS5769
+184.174.37.139:8333 # AS1239
+185.8.104.179:8333 # AS16125
+185.14.30.25:8333 # AS21100
185.25.48.184:8333 # AS61272
-185.31.136.246:8333 # AS47605
185.52.93.45:8333 # AS39449
185.64.116.15:8333 # AS31736
-185.68.249.91:8333 # AS51184
+185.69.105.117:8333 # AS6855
185.98.54.20:8333 # AS39572
185.107.83.55:8333 # AS43350
+185.132.109.122:8333 # AS38919
+185.135.81.50:8333 # AS57494
185.140.253.169:8333 # AS200735
-185.148.145.74:8333 # AS44901
+185.148.3.227:8333 # AS47605
+185.154.2.3:8333 # AS29119
+185.162.92.36:8333 # AS41722
+185.163.44.36:8333 # AS39798
185.165.170.19:8333 # AS3223
185.167.113.59:8333 # AS207054
-185.185.26.141:8111 # AS201206
-185.197.163.136:8333 # AS60144
+185.185.59.12:8333 # AS48614
+185.203.41.148:8333 # AS9009
185.209.12.76:8333 # AS212323
185.209.70.17:8333 # AS204568
-185.227.156.226:8333 # AS209846
+185.210.125.33:8333 # AS205671
185.233.189.210:8333 # AS61303
+185.238.131.19:8333 # AS206238
+185.239.220.210:8333 # AS61282
185.239.221.5:8333 # AS61282
-185.244.100.106:8333 # AS2586
-185.254.97.164:8333 # AS44486
-186.33.167.11:8333 # AS1299
-186.176.98.37:8333 # AS262197
+185.250.90.246:8333 # AS61955
186.249.217.25:8333 # AS7195
186.250.95.132:8333 # AS262967
-188.32.14.31:8334 # AS42610
188.35.167.14:8333 # AS34123
-188.68.45.143:8333 # AS47147
-188.117.200.212:8333 # AS25447
-188.138.88.14:8333 # AS20773
-188.151.237.158:8333 # AS1257
-188.154.236.49:8333 # AS6730
-189.123.177.128:8333 # AS4230
+188.68.53.44:8333 # AS47147
+188.120.255.115:8333 # AS29182
+189.6.195.111:8333 # AS28573
+190.2.130.44:8333 # AS49981
+190.13.122.89:8333 # AS33576
190.123.27.11:8333 # AS52468
190.145.127.254:8333 # AS14080
-192.69.53.77:8333 # AS11142
+191.220.156.64:8333 # AS8167
+192.31.136.90:8333 # AS54098
+192.69.53.43:8333 # AS11142
192.146.137.44:8333 # AS25376
-192.222.24.54:8333 # AS22646
-192.222.147.141:8333 # AS1403
-193.32.127.162:60969 # AS39351
-193.111.198.187:8111 # AS24961
-193.196.37.62:8333 # AS34878
-194.13.80.185:15430 # AS47147
-194.147.113.201:8333 # AS21232
-194.165.30.20:8333 # AS35162
-194.191.239.98:8333 # AS1836
-195.56.63.4:8333 # AS5483
-195.56.63.10:8333 # AS5483
-195.123.239.185:8333 # AS64010
-195.140.226.154:8333 # AS35614
-198.1.231.6:8333 # AS30236
-198.148.112.27:8333 # AS35916
-199.126.234.237:8333 # AS395570
-199.193.174.173:8333 # AS7992
+192.174.121.33:8333 # AS11492
+192.222.147.175:8333 # AS1403
+193.198.34.24:8333 # AS2108
+193.222.130.14:8333 # AS29208
+194.35.185.167:8333 # AS9063
+194.54.83.234:8333 # AS41018
+194.233.84.100:8333 # AS141995
+195.2.73.88:8333 # AS48282
+195.48.12.8:8333 # AS1836
+195.154.200.157:8333 # AS12876
+197.211.133.15:8333 # AS51265
+198.84.146.8:8333 # AS5645
+198.98.55.86:8333 # AS53667
199.247.7.208:8333 # AS20473
-200.122.181.46:8333 # AS3790
+200.116.154.131:8333 # AS13489
201.191.6.103:8333 # AS11830
-201.212.36.209:8333 # AS7303
201.221.234.200:8333 # AS27928
+202.47.225.242:8333 # AS9931
+202.107.219.130:8333 # AS4134
202.108.211.135:8333 # AS4837
-202.169.17.178:8333 # AS137549
-202.177.24.140:8333 # AS7479
-203.130.48.117:8885 # AS54994
-203.132.94.196:8333 # AS38195
+202.138.13.122:8333 # AS4826
+203.86.195.32:8333 # AS23655
+203.184.52.247:8333 # AS9790
+204.111.163.114:8333 # AS4922
205.178.41.124:8333 # AS11039
-206.72.201.228:8333 # AS19318
206.192.203.0:8333 # AS7029
-206.223.153.52:8333 # AS19214
-207.134.216.145:8334 # AS395570
-207.188.154.50:8333 # AS15704
207.229.46.80:8333 # AS852
+207.244.248.81:8333 # AS40021
207.255.193.47:8333 # AS11776
-208.104.92.74:8333 # AS14615
+208.59.133.63:8333 # AS11039
209.58.145.157:8333 # AS394380
-209.58.158.232:8335 # AS394380
-209.141.43.243:8333 # AS53667
-209.226.142.62:8333 # AS577
-209.237.127.227:8333 # AS1299
+209.97.189.249:8333 # AS14061
+209.177.138.245:8333 # AS7832
209.237.133.54:8333 # AS53859
-211.248.90.50:8333 # AS4766
-212.21.18.78:8333 # AS20485
+210.54.37.190:8333 # AS4648
+210.54.39.238:8333 # AS4648
212.34.225.118:8333 # AS44395
-212.51.146.137:8333 # AS13030
-212.227.211.87:8333 # AS8560
-213.0.69.76:8333 # AS3352
-213.5.36.58:8333 # AS49974
+212.41.9.30:8333 # AS49505
+212.51.132.176:8333 # AS13030
+212.69.60.77:8333 # AS12496
+212.86.32.106:8333 # AS15366
213.47.64.105:8333 # AS8412
-213.89.135.151:8333 # AS1257
213.141.154.201:8333 # AS12714
-213.159.198.45:8333 # AS8359
+213.142.148.169:8333 # AS6762
213.184.244.24:8333 # AS60280
-213.214.66.182:8333 # AS43205
-213.226.123.76:8333 # AS49943
+213.227.147.244:8333 # AS60781
+213.250.21.112:8333 # AS5603
216.146.251.8:8333 # AS54579
-216.186.238.14:8333 # AS12083
-217.5.150.114:8333 # AS3320
+216.232.157.104:8333 # AS395570
217.15.178.11:8333 # AS25534
-217.24.239.109:8333 # AS9063
-217.64.47.138:8333 # AS39324
-217.73.80.104:8333 # AS44291
-217.79.181.38:8333 # AS24961
+217.26.32.10:8333 # AS197312
+217.64.47.200:8333 # AS39324
+217.76.51.25:8333 # AS39597
217.92.55.246:8333 # AS3320
-217.113.121.169:8333 # AS8416
-217.115.116.250:8333 # AS30900
-217.155.244.170:8333 # AS13037
217.170.124.170:8333 # AS35401
-220.132.135.54:8333 # AS3462
-220.233.178.199:8333 # AS38195
-222.154.111.46:8333 # AS4648
-[2001:1620:510::2]:8333 # AS13030
-[2001:19f0:6001:39aa:5400:3ff:fef0:916]:8333 # AS20473
-[2001:19f0:8001:f71:5400:4ff:fe10:6a63]:8333 # AS20473
+217.180.221.162:8333 # AS30600
+217.180.238.137:8333 # AS30600
+220.84.232.46:8333 # AS4766
+220.133.39.61:8333 # AS3462
+220.233.91.182:8333 # AS38195
+[2001:19f0:1000:1db3:5400:4ff:fe56:5a8d]:8333 # AS20473
+[2001:19f0:5:24da:3eec:efff:feb9:f36e]:8333 # AS20473
+[2001:19f0:5:24da::]:8333 # AS20473
+[2001:19f0:5:4535:3eec:efff:feb9:87e4]:8333 # AS20473
+[2001:19f0:5:4535::]:8333 # AS20473
[2001:1bc0:c1::2000]:8333 # AS29686
-[2001:1c02:11e:3500:df25:6321:8260:d9be]:8333 # AS6830
-[2001:41d0:1004:1b79::]:8339 # AS16276
+[2001:1c04:4008:6300:8a5f:2678:114b:a660]:8333 # AS6830
[2001:41d0:203:3739::]:8333 # AS16276
-[2001:41d0:203:aacc::]:8333 # AS16276
+[2001:41d0:203:8f49::]:8333 # AS16276
[2001:41d0:203:bb0a::]:8333 # AS16276
[2001:41d0:2:bf8f::]:8333 # AS16276
-[2001:41d0:303:6586::]:8333 # AS16276
-[2001:41d0:602:4493::]:8333 # AS16276
-[2001:41d0:8:b9d8::1]:8333 # AS16276
+[2001:41d0:303:de8b::]:8333 # AS16276
+[2001:41d0:403:3d61::]:8333 # AS16276
+[2001:41d0:405:9600::]:8333 # AS16276
+[2001:41d0:8:ed7f::1]:8333 # AS16276
[2001:41d0:a:69a2::1]:8333 # AS16276
[2001:41f0::62:6974:636f:696e]:8333 # AS6830
-[2001:44b8:256:5d11:216:3eff:fe39:d5d4]:8333 # AS4739
[2001:470:1b62::]:8333 # AS6939
-[2001:470:1f07:803:20c:29ff:fe2d:5879]:8333 # AS6939
+[2001:470:1f05:43b:2831:8530:7179:5864]:8333 # AS6939
+[2001:470:1f09:b14::11]:8333 # AS6939
[2001:470:1f15:106:e2d5:5eff:fe42:7ae5]:8333 # AS6939
-[2001:470:1f15:c43::11]:8333 # AS6939
-[2001:470:26:472::b7c]:8333 # AS6939
+[2001:470:1f1b:365:aa20:66ff:fe3f:1909]:8333 # AS6939
+[2001:470:1f1b:5a6:216:3eff:fe24:1162]:8333 # AS6939
+[2001:470:6a7c::]:8333 # AS6939
[2001:470:75e9:1::10]:8333 # AS6939
-[2001:470:de5a::ec]:9333 # AS6939
-[2001:4ba0:babe:584::1]:8333 # AS24961
+[2001:470:8ca0:2:4e72:b9ff:fe56:f8b8]:8333 # AS6939
+[2001:470:dbc7:0:1010::100]:8333 # AS6939
+[2001:4ba0:cafe:14cc::1]:8333 # AS24961
[2001:4ba0:ffff:24::1]:8333 # AS24961
[2001:4dd0:3564:0:30b7:1d7b:6fec:4c5c]:8333 # AS8422
[2001:4dd0:3564:0:88e:b4ff:2ad0:699b]:8333 # AS8422
[2001:4dd0:3564:0:9c1c:cc31:9fe8:5505]:8333 # AS8422
[2001:4dd0:3564:0:a0c4:d41f:4c4:1bb0]:8333 # AS8422
-[2001:4dd0:3564:0:fd76:c1d3:1854:5bd9]:8333 # AS8422
[2001:4dd0:3564:1::7676:8090]:8333 # AS8422
[2001:4dd0:3564:1:b977:bd71:4612:8e40]:8333 # AS8422
[2001:4dd0:af0e:3564::69:1]:8333 # AS8422
[2001:4dd0:af0e:3564::69:90]:8333 # AS8422
-[2001:4de8:b1b2:1:0:dead:beef:7]:8333 # AS29208
+[2001:560:441f:1::4]:8333 # AS18530
[2001:638:a000:4140::ffff:191]:8333 # AS680
-[2001:678:acc:42::]:8333 # AS60404
+[2001:67c:25dc:91::2]:8333 # AS41018
[2001:67c:26b4:ff00::44]:8333 # AS25376
[2001:67c:2db8:6::36]:8333 # AS39798
-[2001:7c0:2310:0:f816:3eff:fe0d:4ab6]:8333 # AS34878
[2001:7c0:2310:0:f816:3eff:fe6c:4f58]:8333 # AS34878
-[2001:861:3246:a10::40]:8333 # AS5410
-[2001:b07:2e6:38d7:ba27:ebff:fe60:3dc1]:8333 # AS12874
+[2001:861:3242:8420::40]:8333 # AS5410
+[2001:8b0:1301:1000::60]:8333 # AS20712
+[2001:b030:2422::208d]:8333 # AS3462
+[2001:b07:2ef:6e4a:3d:974e:784a:684b]:8333 # AS12874
+[2001:b07:5d32:b142:8f77:3c7d:a2fd:ed2e]:8333 # AS12874
[2001:b07:6461:7811:489:d2da:e07:1af7]:8333 # AS12874
-[2001:b07:ac9:442b:79d6:bbbe:b37c:a783]:8333 # AS12874
+[2001:b07:646b:8074:32e8:9243:a337:e60a]:8333 # AS12874
+[2001:b07:646b:8074:4cc6:79a5:3af7:7132]:8333 # AS12874
+[2001:b07:ad4:ca4b:7dd5:8471:50c3:5363]:8333 # AS12874
+[2001:bc8:1201:71a:2e59:e5ff:fe42:52f4]:8333 # AS12876
[2001:bc8:1600:0:208:a2ff:fe0c:8a2e]:8333 # AS12876
[2001:bc8:323c:ff:a634:384f:1849:f4bc]:8333 # AS12876
[2001:bc8:323c:ff:d217:c2ff:fe07:2cd9]:8333 # AS12876
-[2001:bc8:3bec:100::1]:8333 # AS12876
-[2002:2f5b:a5f9::2f5b:a5f9]:8885 # AS6939
-[2003:cb:8713:6102:aaa1:59ff:fe57:7779]:8333 # AS3320
-[2003:e0:370e:1400::5]:8333 # AS3320
-[2003:f6:3f10:6700:4c9f:7620:8324:d4a7]:8333 # AS3320
-[2400:2410:cea2:d00:41bc:c9ea:861b:51ee]:8333 # AS17676
-[2400:2411:a3e1:4900:2568:684b:e99:7120]:8333 # AS17676
-[2400:2411:a3e1:4900:2987:b88f:61e0:84fa]:8333 # AS17676
-[2400:3b00:20:c:bacb:29ff:feab:8886]:8333 # AS18229
+[2001:bc8:700:2b14::1]:8333 # AS12876
+[2001:bc8:700:8d16::1]:8333 # AS12876
+[2001:e68:5400:58d0:bd15:ea8c:5b20:7523]:8333 # AS4788
+[2400:2411:a3e1:4900:7298:f550:67e7:b99b]:8333 # AS17676
+[2400:8901::f03c:93ff:fe2b:5c0b]:8333 # AS63949
+[2400:8901::f03c:93ff:fe5a:685c]:8333 # AS63949
[2401:b140:1::100:210]:8333 # AS54415
[2401:b140:1::100:220]:8333 # AS54415
-[2401:b140::42:100]:8333 # AS6939
-[2401:b140::44:130]:8333 # AS6939
[2401:d002:3902:700:d72c:5e22:4e95:389d]:8333 # AS38195
-[2404:4408:6752:c000::1999]:8333 # AS9790
-[2404:7a85:4161:2b00:49a1:427a:fac:3409]:8333 # AS2518
-[2405:9800:b972:ab58:c05:e938:267e:271]:8333 # AS45430
+[2404:4408:63a4:a01::250]:8333 # AS9790
+[2406:3400:216:8b00:211:32ff:feca:336b]:8333 # AS10143
+[2406:8c00:0:3422:133:18:228:108]:8333 # AS24282
[2406:da11:169:b03:32b5:f901:9f7c:3e4b]:8333 # AS16509
-[2406:da14:335:b601:ceb7:b4fc:a855:f3a5]:8333 # AS16509
+[2406:da18:9f1:f301:7d2e:c256:c112:f2be]:8333 # AS16509
+[2406:da18:9f1:f303:c1c9:c569:b799:2057]:8333 # AS16509
+[2406:da1e:a4e:8a00:20db:dd8d:3670:28f0]:8333 # AS16509
[2406:da1e:a4e:8a03:2aad:496b:768d:e497]:8333 # AS16509
-[2407:8800:bc61:2202:a0c6:107:502b:4e3b]:8333 # AS7545
-[2409:10:ca20:1df0:224:e8ff:fe1f:60d9]:8333 # AS55391
-[2600:1700:22f1:641f:e8:39c8:eb1d:a1eb]:8333 # AS7018
-[2600:1700:9c5d:ed0::38]:8333 # AS7018
-[2600:1700:9c5d:ed0:d0d6:1d9:5cc2:ab47]:8333 # AS7018
-[2600:1702:1ce0:4010::40]:8333 # AS7018
-[2600:1f14:40e:e301:d155:aa3a:77be:960e]:8333 # AS16509
-[2600:1f16:a08:b901:1afa:ef4e:4ce7:2ba4]:8333 # AS16509
-[2600:1f1c:2d3:2403:5bac:3fc6:6513:7a63]:8333 # AS16509
+[2407:3640:2107:1278::1]:8333 # AS141995
+[2407:3640:3010:4012::1]:8333 # AS141995
+[2407:8800:bc61:2202:d63d:7eff:fe6c:dc36]:8333 # AS7545
+[2600:1700:5c5b:b0:aaa1:59ff:fe5f:615a]:8333 # AS7018
+[2600:1700:ec7b:5730::48]:8333 # AS7018
+[2600:1900:4000:4cc4:0:1::]:8333 # AS15169
+[2600:1900:4000:4cc4:0:2::]:8333 # AS15169
+[2600:1900:4000:4cc4:0:3::]:8333 # AS15169
+[2600:1900:4000:4cc4::]:8333 # AS15169
+[2600:1900:4030:a25e::]:8333 # AS15169
+[2600:1f14:40e:e301:afdd:ad00:e568:d220]:8333 # AS16509
+[2600:1f1c:2d3:2400:f15e:2f2a:760d:a33d]:8333 # AS16509
[2600:2104:1003:c5ab:dc5e:90ff:fe18:1d08]:8333 # AS11404
[2600:3c00::f03c:92ff:fe92:2745]:8333 # AS63949
[2600:3c00::f03c:92ff:fecf:61b6]:8333 # AS63949
-[2600:3c00::f03c:93ff:feb3:1b6]:8333 # AS63949
[2600:3c00:e002:2e32::1:14]:8333 # AS63949
+[2600:3c01::f03c:93ff:fe2a:5266]:8333 # AS63949
+[2600:3c01::f03c:93ff:fe74:5f59]:8333 # AS63949
+[2600:3c01::f03c:93ff:fee6:2146]:8333 # AS63949
[2600:3c02::f03c:92ff:fe5d:9fb]:8333 # AS63949
-[2600:4040:2854:5e00:c6e9:84ff:fe46:ee8]:8666 # AS13786
-[2600:6c54:7100:1ad1:bddf:550e:91be:f9e1]:8333 # AS20115
+[2600:4040:2004:3201:459f:8fe8:444d:baf1]:8333 # AS13786
+[2600:4040:4541:4900:4e1:b58a:8438:450e]:8333 # AS13786
+[2600:6c54:7100:1ad1:c92e:36d:651:bd18]:8333 # AS20115
+[2600:8801:2f80:477::141c]:8333 # AS22773
+[2600:8801:8d00:3eb0:20c:29ff:fec3:d799]:8333 # AS22773
[2600:8805:2400:14e:12dd:b1ff:fef2:3013]:8333 # AS22773
-[2601:184:300:bde:3c29:8e94:1ba8:fde3]:8333 # AS7922
-[2601:18c:8080:300f:219:d1ff:fe75:dc2f]:8333 # AS7922
-[2601:18d:4600:43f1:20e7:b3ff:fecf:a99]:8333 # AS7922
-[2601:18d:8701:c290::3330]:8333 # AS7922
-[2601:246:4d7f:9e28:f321:36ca:7a71:c687]:8333 # AS7922
-[2601:640:c201:960d:86eb:f27d:66a2:f2c1]:8333 # AS7922
-[2602:241:75d1:2b90::7840]:8333 # AS46375
-[2602:ffb8::208:72:57:200]:8333 # AS2914
+[2601:184:300:156c:ba4c:30:9da:6c06]:8333 # AS7922
+[2601:346:d7f:fff7:18c6:4856:ef75:744c]:8333 # AS7922
+[2601:405:4a00:876:c8d3:f081:2ce8:ba8e]:8333 # AS7922
+[2602:24c:b8f:cd90::7840]:8333 # AS46375
+[2602:fec3:0:1::69]:8333 # AS62563
+[2602:ff16:1:0:1:412:0:1]:8333 # AS29802
+[2603:3001:2618:c000:2ec1:df1f:a463:9119]:8333 # AS7922
+[2603:3003:11b:e100:20c:29ff:fe38:bbc0]:8333 # AS7922
[2603:3004:6a1:3800:851f:584d:7aba:affb]:8333 # AS7922
-[2603:3004:6a1:3800::4402]:8333 # AS7922
-[2603:3004:70d:1400:8532:2900:ce6f:acdf]:8333 # AS7922
-[2603:3004:745:900:f0d7:556a:a8c:ced5]:8333 # AS7922
-[2603:6080:c000:5d8a::104f]:8333 # AS7843
-[2603:8000:d100:8991:cc29:ccff:fe42:300c]:8333 # AS7843
+[2603:3004:6a1:3800::7bba]:8333 # AS7922
+[2603:3004:6a1:3800::f667]:8333 # AS7922
+[2603:3024:1606:1400::29ec]:8333 # AS7922
+[2603:3024:18ee:8000:20e:c4ff:fed1:ef15]:8333 # AS7922
+[2603:6000:a400:9300::2000]:8333 # AS7843
+[2603:6010:7001:4830::2:1]:8333 # AS7843
[2603:8080:1f07:6fdd:7de2:d969:78c9:b7ea]:8333 # AS7843
-[2603:8080:7300:531::13ea]:8333 # AS7843
-[2603:80a0:703:40f8::38]:8333 # AS7843
-[2604:180:f3::218]:8333 # AS3842
-[2604:3d08:0:5:d941:4b03:a093:131b]:8333 # AS6327
-[2604:7c00:120:4b::eb24]:8333 # AS174
-[2604:a00:21:3043:bf6a:535e:dfeb:5b7b]:8333 # AS19318
-[2604:a880:400:d0::1ce7:4001]:8333 # AS14061
-[2604:a880:400:d0::1d44:e001]:8333 # AS14061
+[2603:8080:d600:1800:7ce1:74a2:6a8a:4643]:8333 # AS7843
+[2603:8081:6c00:306e:215:5dff:fe02:150a]:8333 # AS7843
+[2604:3d09:7182:8700:bba9:cde6:5b37:a8df]:8333 # AS6327
+[2604:4080:1036:80b1::3be]:8333 # AS11404
+[2604:a00:3:1223:216:3eff:fe27:76e0]:8333 # AS19318
[2604:a880:400:d0::261f:6001]:8333 # AS14061
-[2604:a880:400:d1::7e2:e001]:8333 # AS14061
-[2604:a880:4:1d0::14:3000]:8333 # AS14061
+[2604:a880:4:1d0::13e:f000]:8333 # AS14061
+[2604:a880:4:1d0::17a:7000]:8333 # AS14061
+[2604:a880:4:1d0::c1:3000]:8333 # AS14061
[2604:a880:4:1d0::e5:b000]:8333 # AS14061
+[2605:4a80:a302:7940:7254:1ed4:90d7:4f39]:8333 # AS11232
+[2605:4a80:a302:7940::2]:8333 # AS11232
[2605:6400:30:f220::]:8333 # AS53667
-[2605:6f80:0:7:fc1b:ccff:fe8a:d822]:8333 # AS53340
-[2605:a140:2076:8253::1]:8333 # AS40021
-[2605:a140:3007:1287::1]:8333 # AS40021
+[2605:a140:3010:4014::1]:8333 # AS40021
[2605:ae00:203::203]:8333 # AS7819
+[2605:b40:14d0:5b00:7988:eb8:6bb6:66e2]:8333 # AS174
[2605:c000:2a0a:1::102]:8333 # AS7393
-[2607:1a00:1:d::11:7c4d]:8333 # AS22653
-[2607:5300:203:1214::]:8333 # AS16276
+[2607:5300:61:854::1]:8333 # AS16276
[2607:9280:b:73b:250:56ff:fe14:25b5]:8333 # AS395502
[2607:9280:b:73b:250:56ff:fe21:9c2f]:8333 # AS395502
[2607:9280:b:73b:250:56ff:fe21:bf32]:8333 # AS395502
[2607:9280:b:73b:250:56ff:fe33:4d1b]:8333 # AS395502
[2607:9280:b:73b:250:56ff:fe3d:401]:8333 # AS395502
-[2607:f2c0:e1c2:69:12c3:7bff:fe4d:9431]:8333 # AS5645
-[2607:f2c0:e1c2:69:ecb2:6e88:9f33:5057]:8333 # AS5645
-[2620:6:2003:105:2d8:61ff:fe0f:853]:8333 # AS25682
[2620:6e:a000:1:42:42:42:42]:8333 # AS397444
-[2620:a6:2000:1::3:d570]:8333 # AS27566
-[2620:a6:2000:1::5:162a]:8333 # AS27566
-[2620:a6:2000:1::5:1631]:8333 # AS27566
-[2620:a6:2000:1::c:e634]:8333 # AS27566
-[2800:40:33:8ab:a0e7:b215:fc83:5c31]:8333 # AS16814
-[2800:bf0:149:f4b:f8df:8d7d:801b:e25e]:8333 # AS27947
-[2804:14c:198:80d5:7603:41d1:d3fc:e797]:8333 # AS28573
-[2804:14d:ae81:827b:99a8:1e3f:6db2:29db]:8333 # AS4230
-[2804:d57:5537:4800:3e7c:3fff:fe7b:80aa]:8333 # AS8167
-[2a00:12e0:101:99:20c:29ff:fe29:d03f]:8333 # AS6798
-[2a00:1328:e101:c00::163]:8333 # AS31078
+[2620:a6:2000:1:1:0:5:1601]:8333 # AS27566
+[2620:a6:2000:1:2:0:9:900b]:8333 # AS27566
+[2620:a6:2000:1:2:0:b:300e]:8333 # AS27566
+[2800:150:11d:d2f:bdac:7807:2f5:4aa0]:8333 # AS22047
+[2803:9800:a007:82ba:650b:82b8:8377:d0]:8333 # AS19037
+[2804:14c:155:45e0:1e86:15a3:efd9:7287]:8333 # AS28573
+[2804:14c:657d:4030:28b4:eff:fe9b:8894]:8333 # AS28573
+[2804:14d:1087:9434::1002]:8333 # AS4230
+[2804:954:24:2:b390:d83b:358a:db53]:8333 # AS263073
+[2804:d57:554d:de00:3e7c:3fff:fe7b:80aa]:8333 # AS8167
+[2a00:1028:838c:563a:fd25:87b6:5a54:811]:8333 # AS5610
+[2a00:1298:8001::6542]:8333 # AS5578
[2a00:1398:4:2a03:215:5dff:fed6:1033]:8333 # AS34878
[2a00:1398:4:2a03::bc03]:8333 # AS34878
-[2a00:1630:10:1003:0:b19:b00b:babe]:8333 # AS49544
[2a00:1768:2001:27::ef6a]:8333 # AS43350
-[2a00:1828:a004:2::666]:8333 # AS34240
-[2a00:1c10:2:709::217]:22220 # AS50300
[2a00:1f40:5001:108:5d17:7703:b0f5:4133]:8333 # AS42864
[2a00:23c5:fe80:7301:d6ae:52ff:fed5:56a5]:8333 # AS2856
-[2a00:23c6:5c91:5808:c05a:4dff:fe65:9d69]:8333 # AS2856
-[2a00:6020:1bfa:d400:20c:29ff:fe61:4a4c]:8333 # AS60294
-[2a00:6020:b482:9200:491a:358c:d8f7:1da]:8333 # AS60294
+[2a00:6020:13dc:bc00:5559:258:27d:b52b]:8333 # AS60294
+[2a00:6020:4503:3700:20c:29ff:fe61:4a4c]:8333 # AS60294
+[2a00:6020:b434:eb00:dea6:32ff:fe0d:a5c0]:8333 # AS60294
[2a00:6020:b489:2000:5054:ff:fefc:5ed8]:8333 # AS60294
+[2a00:7c80:0:10c::2]:8333 # AS49981
[2a00:7c80:0:25::e37a]:8333 # AS49981
-[2a00:7c80:0:71::8]:8333 # AS49981
[2a00:8a60:e012:a00::21]:8333 # AS680
-[2a00:ae40:240e:3200::3]:8333 # AS50923
+[2a00:bbe0:cc:0:5a11:22ff:feb4:8f5c]:8333 # AS47605
[2a00:bbe0:cc:0:62a4:4cff:fe23:7510]:8333 # AS47605
-[2a00:ca8:a1f:3025:f949:e442:c940:13e8]:8333 # AS30764
-[2a00:d4e0:2:d002:4467:31e0:6fa5:b3ef]:8333 # AS15600
+[2a00:ca8:a15:9a5b:8b42:a886:7d48:7a21]:8333 # AS30764
+[2a00:ca8:a1f:f9b7:cb55:5766:524b:acaa]:8333 # AS30764
+[2a00:d4e0:ff:fc02:5e55:4a7c:b83b:e5a1]:8333 # AS15600
+[2a00:d520:9:9300:420b:544e:8019:6d3a]:8333 # AS15600
+[2a00:d880:5:c2::d329]:8333 # AS198203
[2a00:ee2:1200:1900:8d3:d2ff:feb1:bc58]:8333 # AS5603
-[2a01:238:420f:9200:fa5a:1a4b:1e6a:fadf]:8333 # AS6724
-[2a01:238:4389:c400:3b26:d94e:38d5:44ef]:8333 # AS6724
-[2a01:490:16:301::2]:8333 # AS8251
-[2a01:4b00:807c:3100:cda1:c6a:2bad:2418]:8333 # AS56478
-[2a01:4f8:141:2254::2]:8333 # AS24940
[2a01:4f8:173:230a::2]:8333 # AS24940
-[2a01:4f8:190:91c4::2]:8333 # AS24940
[2a01:4f8:200:7222::2]:8333 # AS24940
[2a01:4f8:202:3e6::2]:8333 # AS24940
[2a01:4f8:221:44d7::2]:8333 # AS24940
[2a01:4f8:231:915::2]:8333 # AS24940
-[2a01:4f9:2a:1ce0::2]:8333 # AS24940
+[2a01:4f8:261:2bcd::2]:8333 # AS24940
+[2a01:4f8:261:3cae::2]:8333 # AS24940
+[2a01:4f8:261:420c::2]:8333 # AS24940
[2a01:4f9:2b:29a::2]:8333 # AS24940
-[2a01:4f9:4a:31de::2]:8333 # AS24940
-[2a01:5200:6c:6162:7a61:746b:6f2e:736b]:8333 # AS6855
-[2a01:6380:fffe:73:10fb:d012:8581:b4d7]:8333 # AS25540
+[2a01:4f9:3a:2dd2::2]:8333 # AS24940
[2a01:7a7:2:2804:ae1f:6bff:fe9d:6c94]:8333 # AS20773
-[2a01:7c8:aaac:89:5054:ff:feb7:f5cb]:8333 # AS20857
+[2a01:7c8:aac2:180:5054:ff:fe56:8d10]:8333 # AS20857
[2a01:7c8:aac9:c9:5054:ff:fedf:ff95]:8333 # AS20857
-[2a01:7c8:d001:1c1:5054:ff:feee:3e1a]:8333 # AS20857
-[2a01:7c8:d009:2aa:5054:ff:fe1b:a196]:11520 # AS20857
-[2a01:7c8:fffa:50e:ddfe:c924:ca0a:cbab]:8333 # AS20857
-[2a01:7e00::f03c:93ff:fe59:66dc]:8333 # AS63949
-[2a01:7e01::f03c:93ff:fe3b:bb5b]:8333 # AS63949
+[2a01:7e01::f03c:93ff:fe49:2f5b]:8333 # AS63949
+[2a01:8740:1:753::e5cb]:8333 # AS57344
[2a01:8740:1:ffc5::8c6a]:8333 # AS57344
-[2a01:9f40:a000::100]:8333 # AS42908
-[2a01:cb00:d3d:7700:227:eff:fe28:c565]:8333 # AS3215
-[2a01:e0a:20:7350:919c:b1c3:8b83:adf9]:8333 # AS12322
+[2a01:cb00:b63:c000:227:eff:fe28:c565]:8333 # AS3215
+[2a01:cb19:688:e900:aa60:b6ff:fe29:bbae]:8333 # AS3215
+[2a01:e0a:163:c0b0:9da5:1690:a12b:bede]:8333 # AS12322
+[2a01:e0a:282:67b0:b4f4:aaff:fe7c:44a6]:8333 # AS12322
[2a01:e0a:301:7010:b87d:e14b:cea9:b998]:8333 # AS12322
-[2a01:e0a:48b:2d10:94f2:4d5c:ca5f:bf49]:8333 # AS12322
-[2a01:e0a:530:a0a0:f465:af5:be1b:9075]:8333 # AS12322
-[2a01:e0a:aa7:c8c0:9679:affa:b6e5:efc7]:8333 # AS12322
+[2a01:e0a:320:39a0:325a:3aff:fe02:3180]:8333 # AS12322
+[2a01:e0a:351:9fb0:6bf2:95d6:b7bd:b846]:8333 # AS12322
+[2a01:e0a:5fa:a0a0:ca1f:66ff:fece:b8a2]:8333 # AS12322
+[2a01:e0a:83d:dd30:3676:5d8e:8a6f:115a]:8333 # AS12322
+[2a01:e0a:9e9:c240:7b44:f32a:6ec0:a8af]:8333 # AS12322
+[2a01:e0a:b5:7f50:c257:a55b:4846:97e1]:8333 # AS12322
[2a01:e11:100c:70:cbc8:9e31:4b77:1626]:8333 # AS12322
-[2a01:e34:ee78:3060:230:48ff:fe81:f1c6]:8333 # AS12322
-[2a02:1210:14a9:6700:a00:27ff:fe4e:82b6]:8333 # AS3303
-[2a02:1210:4639:f00:10a7:e965:509a:7a4a]:8333 # AS3303
-[2a02:1210:7c92:5100:211:32ff:feae:152d]:8333 # AS3303
-[2a02:1210:86bf:f100:3178:d700:d44d:6bb1]:8333 # AS3303
-[2a02:1210:9487:a200:edc1:93a4:945:9a92]:8333 # AS3303
+[2a02:1210:2cdf:4600:2bc:e03e:43e8:4718]:8333 # AS3303
+[2a02:1210:86bf:f100:a9ac:d041:1f8e:6925]:8333 # AS3303
+[2a02:1210:94c3:3400:d8c3:743c:90f6:a48a]:8333 # AS3303
+[2a02:168:2000:96::12]:8333 # AS13030
[2a02:168:420b:a::20]:8333 # AS13030
-[2a02:168:6328:0:4a21:bff:fe26:38c3]:8333 # AS13030
[2a02:168:676e:0:e65f:1ff:fe09:3591]:8333 # AS13030
-[2a02:1748:f39f:5872:dead:beef:b1ac:c0fe]:8333 # AS51184
+[2a02:1748:f39f:5872:216:3eff:fe21:266]:8333 # AS51184
[2a02:180:1:1::517:10b6]:8333 # AS35366
-[2a02:2168:a379:d100:96de:80ff:fea3:fd00]:8333 # AS42610
[2a02:2780:9000:70::7]:8333 # AS35434
[2a02:2780:9000:70::f]:8333 # AS35434
[2a02:2780::e01a]:8333 # AS35434
-[2a02:2e02:3900:5400:a099:e1ff:feb6:d0e]:8333 # AS12479
-[2a02:2f05:660e:8b00::1]:8333 # AS48571
-[2a02:58:97:7d20::60]:8333 # AS25596
-[2a02:6d40:3073:c01:dea6:32ff:fe44:4b25]:8333 # AS42652
+[2a02:2f05:6008:ce00::1]:8333 # AS48571
+[2a02:390:9000:0:aaa1:59ff:fe43:b57b]:8333 # AS12496
+[2a02:578:85ce:1600:1e1b:dff:fee3:774b]:8333 # AS9031
+[2a02:768:f92b:db46:5e46:772b:71d:29b7]:8333 # AS44489
[2a02:7a01::91:228:45:130]:8333 # AS16019
+[2a02:7b40:50d0:e386::1]:8333 # AS62282
+[2a02:7b40:50d1:e35b::1]:8333 # AS62282
[2a02:7b40:5928:89::1]:8333 # AS62282
-[2a02:7b40:c3b5:f583::1]:8333 # AS62282
-[2a02:8308:8087:aa00:9ea8:1b2:ef98:56bf]:8333 # AS16019
+[2a02:7b40:b945:344d::1]:8333 # AS62282
+[2a02:7b40:d418:6d9a::1]:8333 # AS62282
+[2a02:8070:b84:6ae0:f9c6:fbb9:1c41:81aa]:8333 # AS51185
+[2a02:8070:f186:38e0::d5a6]:8333 # AS51185
+[2a02:8084:103:6810:1e69:7aff:fea2:1acc]:8333 # AS6830
+[2a02:8308:8081:f300:3b8:7ec0:2837:1b57]:8333 # AS16019
+[2a02:8388:e302:7980:6f85:a0b3:4b4d:8b0f]:8333 # AS8412
+[2a02:8388:e5c3:4a80:201:2eff:fe82:b3cc]:8333 # AS8412
[2a02:842a:1df:8a01:1e1b:dff:fe0b:236d]:8333 # AS15557
+[2a02:a210:28be:5f80::111]:8333 # AS6830
+[2a02:a44b:5cf9:1:b62e:99ff:fe49:d492]:8333 # AS1136
[2a02:a44d:14d6:1:2c0:8ff:fe8f:b3b2]:8333 # AS1136
[2a02:a45a:94cd:f00d::1]:8333 # AS1136
-[2a02:a45f:3b9d:30::3]:8333 # AS1136
-[2a02:a467:7833:1:7285:c2ff:fe2c:21e9]:8333 # AS1136
-[2a02:aa14:2380:b300:4040:be88:8b01:d38]:8333 # AS6830
+[2a02:a45f:3b9d:31::199]:8333 # AS1136
+[2a02:a464:3d6b::1:2]:8333 # AS1136
+[2a02:a46c:7f8e:1:35bf:3aeb:137c:1d35]:8333 # AS1136
+[2a02:a46d:36f:1:20d:b9ff:fe4e:6398]:8333 # AS1136
+[2a02:c205:2021:4216::1]:8333 # AS51167
[2a02:c206:2044:9826::1]:8333 # AS51167
-[2a02:c206:2082:1246::1]:8333 # AS51167
-[2a02:c206:3008:2368::1]:8333 # AS51167
-[2a02:c207:0:4971::1]:5332 # AS51167
+[2a02:c206:2075:3351::1]:8333 # AS51167
+[2a02:c207:0:3829::1]:8333 # AS51167
[2a02:c207:2014:4199::1]:8333 # AS51167
-[2a02:c207:2024:6115::1]:8333 # AS51167
+[2a02:c207:2014:8757::1]:8333 # AS51167
[2a02:c207:2026:6682::1]:8333 # AS51167
+[2a02:c207:2034:7358::1]:8333 # AS51167
[2a02:c207:3002:7468::1]:8333 # AS51167
+[2a02:c207:3008:4592::1]:8333 # AS51167
+[2a02:cb43:4000::178]:8333 # AS33891
+[2a02:e5e:1:10::27]:8333 # AS25057
[2a02:e98:20:1504::1]:8333 # AS24641
-[2a03:4000:6:416c::43]:8333 # AS47147
-[2a03:4000:6:f814:548b:17ff:fe31:b64a]:8333 # AS47147
+[2a03:4000:28:68:7411:53ff:fe4c:21d]:8333 # AS47147
+[2a03:4000:65:fdc:3462:66ff:fe05:ec5c]:8333 # AS47147
[2a03:6000:870:0:46:23:87:218]:8333 # AS51088
[2a03:94e0:ffff:185:243:218:0:19]:8333 # AS56655
[2a03:b0c0:1:e0::397:6001]:8333 # AS14061
-[2a03:b0c0:2:f0::163:3001]:8333 # AS14061
-[2a03:b0c0:2:f0::18a:d001]:8333 # AS14061
-[2a03:b0c0:3:d0::f3e:2001]:8333 # AS14061
-[2a03:e2c0:1347::2]:8333 # AS50113
-[2a03:ec0:0:928::701:701]:8333 # AS199669
-[2a04:52c0:103:c455::1]:8334 # AS60404
-[2a04:52c0:3007:200::2000]:8333 # AS60404
+[2a03:b0c0:1:e0::794:9001]:8333 # AS14061
+[2a03:b0c0:2:f0::288:c001]:8333 # AS14061
+[2a03:b0c0:2:f0::30c:1]:8333 # AS14061
+[2a03:b0c0:3:d0::e3b:5001]:8333 # AS14061
+[2a03:cfc0:8000:7::5fd6:3557]:8333 # AS201814
+[2a04:2180:dc05:2::3b]:8333 # AS61272
+[2a04:2180:ffff:fffe::d]:8333 # AS61272
+[2a04:52c0:103:c455::1]:8333 # AS60404
[2a04:bc40:1dc3:8d::2:1001]:8333 # AS35277
-[2a05:1500:702:0:1c00:40ff:fe00:c]:8333 # AS48635
-[2a05:3580:d101:3700::]:8333 # AS20764
-[2a05:3580:db0b:1600:c489:76ed:313d:b33]:8333 # AS20764
-[2a05:d014:a55:4001:8127:afa7:daf9:d91b]:8333 # AS16509
-[2a05:d014:a55:4001:f6ab:dd5e:4039:b46c]:8333 # AS16509
-[2a05:d014:a55:4003:6523:50a1:152:e88c]:8333 # AS16509
-[2a05:d01a:b7b:3c01:8bf7:ae14:afb3:33ae]:8333 # AS16509
+[2a05:3580:dc0b:1600:def4:5a62:de42:324a]:8333 # AS20764
+[2a05:d014:a55:4000:8dde:69f:4ac7:b26]:8333 # AS16509
+[2a05:d016:98f:5201:6be0:a4de:80c7:32d5]:8333 # AS16509
+[2a05:d018:a75:6c03:75b:2c73:8caa:414b]:8333 # AS16509
[2a05:f480:1800:697:5400:2ff:feb6:c36d]:8333 # AS20473
[2a06:e040:7603:2918:c6ef:464e:9fe5:73ec]:8333 # AS198507
-[2a07:abc4::1:946]:8333 # AS62000
+[2a07:abc4::89:234:180:194]:8333 # AS62000
+[2a07:d884::127e]:8333 # AS6762
+[2a09:2681:1010:10::5]:8333 # AS61282
[2a09:2681:102::210]:8333 # AS61282
-[2a0a:c801:1:7::183]:8333 # AS39798
-[2a0c:5a80:1210:a800:6af7:28ff:fee5:6b3a]:8333 # AS57269
-[2a0d:5600:24:a8e::a91e]:55373 # AS9009
-[2a0d:7c40:3000:b04::2]:8333 # AS54290
+[2a0b:f300:2:6::2]:8333 # AS62240
[2a0d:8340:24::2]:8333 # AS50113
-[2a0f:df00:0:2010::162]:8333 # AS41281
-[2a10:3781:16b9:1:fe3f:dbff:fe04:2d4c]:8333 # AS206238
-[2a10:3781:84b:1:b123:6306:943a:f09b]:8333 # AS206238
+[2a0e:8f02:21d1:144::101]:8333 # AS20473
+[2a0e:b780::55d1:f05b]:8333 # AS205581
+[2a10:3781:2c19::1]:8333 # AS206238
[2a10:d200:1:33:a6bf:1ff:fe6a:46a9]:8333 # AS212323
-[2c0f:f4c0:2202:20b0:261c:4ff:fe14:daa0]:8333 # AS327693
-[2c0f:f8f0:da51:0:70c3:eea9:9717:9579]:8333 # AS30844
+[2a12:8e40:5668:e40a::1]:8333 # AS34465
+[2a12:8e40:5668:e40b::1]:8333 # AS34465
+[2a12:8e40:5668:e40c::1]:8333 # AS34465
+[2a12:8e40:5668:e40d::1]:8333 # AS34465
+[2a12:8e40:5668:e40e::1]:8333 # AS34465
+[2a12:8e40:5668:e40f::1]:8333 # AS34465
+[2a12:8e40:5668:e410::1]:8333 # AS34465
+[2a12:8e40:5668:e411::1]:8333 # AS34465
+[2a12:8e40:5668:e412::1]:8333 # AS34465
+[2a12:8e40:5668:e417::1]:8333 # AS34465
+[2c0f:f8f0:da51:0:3a45:fc57:5e30:2593]:8333 # AS30844
-# manually updated 2022-08 for minimal torv3 bootstrap support
+# manually updated 2023-04 for minimal torv3 bootstrap support
+
+2bqghnldu6mcug4pikzprwhtjjnsyederctvci6klcwzepnjd46ikjyd.onion:8333
+4lr3w2iyyl5u5l6tosizclykf5v3smqroqdn2i4h3kq6pfbbjb2xytad.onion:8333
5g72ppm3krkorsfopcm2bi7wlv4ohhs4u4mlseymasn7g7zhdcyjpfid.onion:8333
+5sbmcl4m5api5tqafi4gcckrn3y52sz5mskxf3t6iw4bp7erwiptrgqd.onion:8333
+776aegl7tfhg6oiqqy76jnwrwbvcytsx2qegcgh2mjqujll4376ohlid.onion:8333
+77mdte42srl42shdh2mhtjr7nf7dmedqrw6bkcdekhdvmnld6ojyyiad.onion:8333
+azbpsh4arqlm6442wfimy7qr65bmha2zhgjg7wbaji6vvaug53hur2qd.onion:8333
b64xcbleqmwgq2u46bh4hegnlrzzvxntyzbmucn3zt7cssm7y4ubv3id.onion:8333
-fjdyxicpm4o42xmedlwl3uvk5gmqdfs5j37wir52327vncjzvtpfv7yd.onion:8333
+bsqbtcparrfihlwolt4xgjbf4cgqckvrvsfyvy6vhiqrnh4w6ghixoid.onion:8333
+bsqbtctulf2g4jtjsdfgl2ed7qs6zz5wqx27qnyiik7laockryvszqqd.onion:8333
+cwi3ekrwhig47dhhzfenr5hbvckj7fzaojygvazi2lucsenwbzwoyiqd.onion:8333
+devinbtcmwkuitvxl3tfi5of4zau46ymeannkjv6fpnylkgf3q5fa3id.onion:8333
+devinbtctu7uctl7hly2juu3thbgeivfnvw3ckj3phy6nyvpnx66yeyd.onion:8333
+devinbtcyk643iruzfpaxw3on2jket7rbjmwygm42dmdyub3ietrbmid.onion:8333
+dtql5vci4iaml4anmueftqr7bfgzqlauzfy4rc2tfgulldd3ekyijjyd.onion:8333
+emzybtc25oddoa2prol2znpz2axnrg6k77xwgirmhv7igoiucddsxiad.onion:8333
+emzybtc3ewh7zihpkdvuwlgxrhzcxy2p5fvjggp7ngjbxcytxvt4rjid.onion:8333
+emzybtc454ewbviqnmgtgx3rgublsgkk23r4onbhidcv36wremue4kqd.onion:8333
+emzybtc5bnpb2o6gh54oquiox54o4r7yn4a2wiiwzrjonlouaibm2zid.onion:8333
fpz6r5ppsakkwypjcglz6gcnwt7ytfhxskkfhzu62tnylcknh3eq6pad.onion:8333
-gxo5anvfnffnftfy5frkgvplq3rpga2ie3tcblo2vl754fvnhgorn5yd.onion:8333
-ifdu5qvbofrt4ekui2iyb3kbcyzcsglazhx2hn4wfskkrx2v24qxriid.onion:8333
-itz3oxsihs62muvknc237xabl5f6w6rfznfhbpayrslv2j2ubels47yd.onion:8333
+hanvo3hzqbhcqm5vahhi5a3czxxdwc7vt56p5gr7bifcvelaqurv6iid.onion:8333
+hz7oqntvj4adrwtqappcgaxfribg5u4rvfkpwlo3xup5fcuyvylkxlqd.onion:8333
+ityrxhidvjnjnf6imzyuqqnkkwridjnebkbokx25so3suq3fzezmksid.onion:8333
+jto2jfbsxhb6yvhcrrjddrgbakte6tgsy3c3z3prss64gndgvovvosyd.onion:8333
+k7nb3r7hxi5exvr4xmvnilhfw6hei7sw4rwz2t6onh4py6wbora6tuyd.onion:8333
kpgvmscirrdqpekbqjsvw5teanhatztpp2gl6eee4zkowvwfxwenqaid.onion:8333
+l7kw3vjs4cf5mnuejjgqcxrw6wwsjmabllq3h3amy4f5q33d6cgo2kyd.onion:8333
m7cbpjolo662uel7rpaid46as2otcj44vvwg3gccodnvaeuwbm3anbyd.onion:8333
+mowb2qwpjgs2a6q3yj3xa7nxklfssul4w7ynonyycw3uyopfu3x6ujad.onion:8333
mwmfluek4au6mxxpw6fy7sjhkm65bdfc7izc7lpz3trewfdghyrzsbid.onion:8333
-rp7k2go3s5lyj3fnj6zn62ktarlrsft2ohlsxkyd7v3e3idqyptvread.onion:8333
+rfqmn3qe36uaptkxhdvi74p4hyrzhir6vhmzb2hqryxodig4gue2zbyd.onion:8333
+rsgwtnousfc7zyg4qsm3gvczjx7cihh2njyjbjl3qvcj3xg7wmvhddqd.onion:8333
+s2d52bbttuwcl3pdrwzhxpmhtxn3jg23havjqg5eygwhtiw6lgyelpqd.onion:8333
+upvthy74hgvgbqi6w3zd2mlchoi5tvvw7b5hpmmhcddd5fnnwrixneid.onion:8333
+who3qs4eqlqzoxhqqgan4mg54ua5uz3mk4lj33ag53ei4orvnznrjbad.onion:8333
+wizbit5555bsslwv4ctronnsgk5vh2w2pdx7v7eyuivlyuoteejk7lid.onion:8333
+yrmedr35tt4wqfnwgilltxh5bnukeukxjpgg3jzmmsyld5lgsn5amvyd.onion:8333
-# manually updated 2022-08 for minimal i2p bootstrap support
+# manually updated 2023-04 for minimal i2p bootstrap support
255fhcp6ajvftnyo7bwz3an3t4a4brhopm3bamyh2iu5r3gnr2rq.b32.i2p:0
27yrtht5b5bzom2w5ajb27najuqvuydtzb7bavlak25wkufec5mq.b32.i2p:0
-2el6enckmfyiwbfcwsygkwksovtynzsigmyv3bzyk7j7qqahooua.b32.i2p:0
3gocb7wc4zvbmmebktet7gujccuux4ifk3kqilnxnj5wpdpqx2hq.b32.i2p:0
-3tns2oov4tnllntotazy6umzkq4fhkco3iu5rnkxtu3pbfzxda7q.b32.i2p:0
4fcc23wt3hyjk3csfzcdyjz5pcwg5dzhdqgma6bch2qyiakcbboa.b32.i2p:0
4osyqeknhx5qf3a73jeimexwclmt42cju6xdp7icja4ixxguu2hq.b32.i2p:0
4umsi4nlmgyp4rckosg4vegd2ysljvid47zu7pqsollkaszcbpqq.b32.i2p:0
-52v6uo6crlrlhzphslyiqblirux6olgsaa45ixih7sq5np4jujaa.b32.i2p:0
6j2ezegd3e2e2x3o3pox335f5vxfthrrigkdrbgfbdjchm5h4awa.b32.i2p:0
6n36ljyr55szci5ygidmxqer64qr24f4qmnymnbvgehz7qinxnla.b32.i2p:0
72yjs6mvlby3ky6mgpvvlemmwq5pfcznrzd34jkhclgrishqdxva.b32.i2p:0
-7r4ri53lby2i3xqbgpw3idvhzeku7ubhftlf72ldqkg5kde6dauq.b32.i2p:0
a5qsnv3maw77mlmmzlcglu6twje6ttctd3fhpbfwcbpmewx6fczq.b32.i2p:0
aovep2pco7v2k4rheofrgytbgk23eg22dczpsjqgqtxcqqvmxk6a.b32.i2p:0
-bddbsmkas3z6fakorbkfjhv77i4hv6rysyjsvrdjukxolfghc23q.b32.i2p:0
bitcoi656nll5hu6u7ddzrmzysdtwtnzcnrjd4rfdqbeey7dmn5a.b32.i2p:0
brifkruhlkgrj65hffybrjrjqcgdgqs2r7siizb5b2232nruik3a.b32.i2p:0
c4gfnttsuwqomiygupdqqqyy5y5emnk5c73hrfvatri67prd7vyq.b32.i2p:0
day3hgxyrtwjslt54sikevbhxxs4qzo7d6vi72ipmscqtq3qmijq.b32.i2p:0
-di2zq6fr3fegf2jdcd7hdwyql4umr462gonsns2nxz5qg5vz4bka.b32.i2p:0
+du5kydummi23bjfp6bd7owsvrijgt7zhvxmz5h5f5spcioeoetwq.b32.i2p:0
e55k6wu46rzp4pg5pk5npgbr3zz45bc3ihtzu2xcye5vwnzdy7pq.b32.i2p:0
eciohu5nq7vsvwjjc52epskuk75d24iccgzmhbzrwonw6lx4gdva.b32.i2p:0
ejlnngarmhqvune74ko7kk55xtgbz5i5ncs4vmnvjpy3l7y63xaa.b32.i2p:0
-g47cqoppu26pr4n2cfaioqx7lbdi7mea7yqhlrkdz3wjwxjxdh2a.b32.i2p:0
-h3r6bkn46qxftwja53pxiykntegfyfjqtnzbm6iv6r5mungmqgmq.b32.i2p:0
+fhzlp3xroabohnmjonu5iqazwhlbbwh5cpujvw2azcu3srqdceja.b32.i2p:0
+fx6np3oheacr3t7gluftrqo2qxldbbatgw4hepp7ulb4j5ry57ca.b32.i2p:0
+gehtac45oaghz54ypyopim64mql7oad2bqclla74l6tfeolzmodq.b32.i2p:0
hhfi4yqkg2twqiwezrfksftjjofbyx3ojkmlnfmcwntgnrjjhkya.b32.i2p:0
-hpiibrflqkbrcshfhmrtwfyeb7mds7a3obzwrgarejevddzamvsq.b32.i2p:0
-i4pyhsfdq4247dunel7paatdaq5gusi2hnybp2yf5wxwdnrgxaqq.b32.i2p:0
-iw6tgpmbdykffceku5da6nzf2bmz66fvp5fpcvemfu3df6aq6pga.b32.i2p:0
-jkfuajo4ayvo2rbv5qdj443q6adqmnormbhsf2f7rlp5t24xomda.b32.i2p:0
jz3s4eurm5vzjresf4mwo7oni4bk36daolwxh4iqtewakylgkxmq.b32.i2p:0
liu75cvktv4icbctg72w7nxbk4eibt7wamizfdii4omz7gcke5vq.b32.i2p:0
-ljsquuu3y4xje6l32p32inn6r2y6ull6oocgup6jtjrohrqxbz6a.b32.i2p:0
lrah7acdsgopybg43shadwwiv6igezaw64i6jb5muqdg7dmhj3la.b32.i2p:0
lzuu6mjtu7vd55d2biphicihufipoa7vyym6xfnkmmlra3tiziia.b32.i2p:0
m6bpynxkv2ktwxkg6p2gyudjfhdupb6kuzabeqdnckkdkf4kxjla.b32.i2p:0
m6v454xd6p3bt5swujgmveklsp7lzbkqlqqfc2p36cjlwv5dbucq.b32.i2p:0
mlgeizrroynuhpxbzeosajt5u4ddcvynxfmcbm6kwjpaufilxigq.b32.i2p:0
+o6t4fr5ayfadzieutstgwcllvwxeuzjlxmzsmpj3hpkvefhzfaea.b32.i2p:0
ofubxr2ir7u2guzjwyrvujicivzmvinwa36nuzlrg7tnsmebal7a.b32.i2p:0
-okfxeoh6itu4f5f43dhbzvkqwfrvm5c66lj6lvjj4q2b35i4pk4q.b32.i2p:0
oz2ia3flpm3du2tyusulrn7h7e2eo3juzkrmn34bvnrlcrugv7ia.b32.i2p:0
+pohfcrfc7prn4bvn4xstw6nt3e7hjmb7kuj4djtsfqsskwhmhnna.b32.i2p:0
qd6jlsevsexww3wefpqs7iglxb3f63y4e6ydulfzrvwflpicmdqa.b32.i2p:0
-qddg7myylinn4tw6kdjmmp6fsyetkosnrbp2gsjx77tmkqyqv6ua.b32.i2p:0
+rfjkzdzv4cwpxo6hzuncicvuyui76wxqx3a23lynq72ktwqs7aja.b32.i2p:0
rizfinyses2r3or4iubs5wx66gdy6mpf73w7uobfacm2l5cral3q.b32.i2p:0
-s5hhjtmlg53bko3nwwskas7xgsmeqzy6thtsj5aa64djyrljgqaq.b32.i2p:0
sedndhv5vpcgdmykyi5st4yqhdxl3hpdtglta4do435wupahhx6q.b32.i2p:0
-tsl4dlpu2id252b6crbdnblruct664se6f2iw35fuqwa3te7wcoq.b32.i2p:0
tugq6wa2ls2bv27pr2iy3da3k5ow3fzefbcvjcr22uc7w5vmevja.b32.i2p:0
usztavbib756k5vqggzgkyswoj6mttihjvp3c2pa642t2mb4pvsa.b32.i2p:0
vgu6llqbyjphml25umd5ztvyxrxuplz2g74fzbx75g3kkaetoyiq.b32.i2p:0
wjrul5jwwb4vqdmkkrjbmly7osj6amecdpsac5xvaoqrti4nb3ha.b32.i2p:0
-wvktcp7hy4l6immhi5cxyz2dlsbhhvtcmskjemrnqehacnoap23q.b32.i2p:0
wwbw7nqr3ahkqv62cuqfwgtneekvvpnuc4i4f6yo7tpoqjswvcwa.b32.i2p:0
-xlqndzjoe5nr2nsxo6xwibh44ghyz4jfqevu62xykvemextpmjbq.b32.i2p:0
+xfkarmvk43vfkfvhkehy7ioj2b6wtfdlezvmlakblz3q4r7mccfq.b32.i2p:0
yc4xwin5ujenvcr6ynwkz7lnmmq3nmzxvfguele6ovqqpxgjvonq.b32.i2p:0
zdoabsg7ugzothyawodjhq54nvlofa746rxfkxpnjzj6nukmha6a.b32.i2p:0
zsxwyo6qcn3chqzwxnseusqgsnuw3maqnztkiypyfxtya4snkoka.b32.i2p:0
zysrlpii5ftrzivfcyhdrwpeyyqddbrdefnfu5q6otk5gtugmh2a.b32.i2p:0
-# manually added 2022-01 for minimal cjdns bootstrap support
+# manually updated 2023-04 for minimal cjdns bootstrap support
[fc32:17ea:e415:c3bf:9808:149d:b5a2:c9aa]:8333
[fcc7:be49:ccd1:dc91:3125:f0da:457d:8ce]:8333
+[fcdc:73ae:b1a9:1bf8:d4c2:811:a4c7:c34e]:8333
diff --git a/contrib/seeds/nodes_main_manual.txt b/contrib/seeds/nodes_main_manual.txt
index 286448d95d..91a64c6e51 100644
--- a/contrib/seeds/nodes_main_manual.txt
+++ b/contrib/seeds/nodes_main_manual.txt
@@ -1,78 +1,95 @@
-# manually updated 2022-08 for minimal torv3 bootstrap support
+# manually updated 2023-04 for minimal torv3 bootstrap support
+
+2bqghnldu6mcug4pikzprwhtjjnsyederctvci6klcwzepnjd46ikjyd.onion:8333
+4lr3w2iyyl5u5l6tosizclykf5v3smqroqdn2i4h3kq6pfbbjb2xytad.onion:8333
5g72ppm3krkorsfopcm2bi7wlv4ohhs4u4mlseymasn7g7zhdcyjpfid.onion:8333
+5sbmcl4m5api5tqafi4gcckrn3y52sz5mskxf3t6iw4bp7erwiptrgqd.onion:8333
+776aegl7tfhg6oiqqy76jnwrwbvcytsx2qegcgh2mjqujll4376ohlid.onion:8333
+77mdte42srl42shdh2mhtjr7nf7dmedqrw6bkcdekhdvmnld6ojyyiad.onion:8333
+azbpsh4arqlm6442wfimy7qr65bmha2zhgjg7wbaji6vvaug53hur2qd.onion:8333
b64xcbleqmwgq2u46bh4hegnlrzzvxntyzbmucn3zt7cssm7y4ubv3id.onion:8333
-fjdyxicpm4o42xmedlwl3uvk5gmqdfs5j37wir52327vncjzvtpfv7yd.onion:8333
+bsqbtcparrfihlwolt4xgjbf4cgqckvrvsfyvy6vhiqrnh4w6ghixoid.onion:8333
+bsqbtctulf2g4jtjsdfgl2ed7qs6zz5wqx27qnyiik7laockryvszqqd.onion:8333
+cwi3ekrwhig47dhhzfenr5hbvckj7fzaojygvazi2lucsenwbzwoyiqd.onion:8333
+devinbtcmwkuitvxl3tfi5of4zau46ymeannkjv6fpnylkgf3q5fa3id.onion:8333
+devinbtctu7uctl7hly2juu3thbgeivfnvw3ckj3phy6nyvpnx66yeyd.onion:8333
+devinbtcyk643iruzfpaxw3on2jket7rbjmwygm42dmdyub3ietrbmid.onion:8333
+dtql5vci4iaml4anmueftqr7bfgzqlauzfy4rc2tfgulldd3ekyijjyd.onion:8333
+emzybtc25oddoa2prol2znpz2axnrg6k77xwgirmhv7igoiucddsxiad.onion:8333
+emzybtc3ewh7zihpkdvuwlgxrhzcxy2p5fvjggp7ngjbxcytxvt4rjid.onion:8333
+emzybtc454ewbviqnmgtgx3rgublsgkk23r4onbhidcv36wremue4kqd.onion:8333
+emzybtc5bnpb2o6gh54oquiox54o4r7yn4a2wiiwzrjonlouaibm2zid.onion:8333
fpz6r5ppsakkwypjcglz6gcnwt7ytfhxskkfhzu62tnylcknh3eq6pad.onion:8333
-gxo5anvfnffnftfy5frkgvplq3rpga2ie3tcblo2vl754fvnhgorn5yd.onion:8333
-ifdu5qvbofrt4ekui2iyb3kbcyzcsglazhx2hn4wfskkrx2v24qxriid.onion:8333
-itz3oxsihs62muvknc237xabl5f6w6rfznfhbpayrslv2j2ubels47yd.onion:8333
+hanvo3hzqbhcqm5vahhi5a3czxxdwc7vt56p5gr7bifcvelaqurv6iid.onion:8333
+hz7oqntvj4adrwtqappcgaxfribg5u4rvfkpwlo3xup5fcuyvylkxlqd.onion:8333
+ityrxhidvjnjnf6imzyuqqnkkwridjnebkbokx25so3suq3fzezmksid.onion:8333
+jto2jfbsxhb6yvhcrrjddrgbakte6tgsy3c3z3prss64gndgvovvosyd.onion:8333
+k7nb3r7hxi5exvr4xmvnilhfw6hei7sw4rwz2t6onh4py6wbora6tuyd.onion:8333
kpgvmscirrdqpekbqjsvw5teanhatztpp2gl6eee4zkowvwfxwenqaid.onion:8333
+l7kw3vjs4cf5mnuejjgqcxrw6wwsjmabllq3h3amy4f5q33d6cgo2kyd.onion:8333
m7cbpjolo662uel7rpaid46as2otcj44vvwg3gccodnvaeuwbm3anbyd.onion:8333
+mowb2qwpjgs2a6q3yj3xa7nxklfssul4w7ynonyycw3uyopfu3x6ujad.onion:8333
mwmfluek4au6mxxpw6fy7sjhkm65bdfc7izc7lpz3trewfdghyrzsbid.onion:8333
-rp7k2go3s5lyj3fnj6zn62ktarlrsft2ohlsxkyd7v3e3idqyptvread.onion:8333
+rfqmn3qe36uaptkxhdvi74p4hyrzhir6vhmzb2hqryxodig4gue2zbyd.onion:8333
+rsgwtnousfc7zyg4qsm3gvczjx7cihh2njyjbjl3qvcj3xg7wmvhddqd.onion:8333
+s2d52bbttuwcl3pdrwzhxpmhtxn3jg23havjqg5eygwhtiw6lgyelpqd.onion:8333
+upvthy74hgvgbqi6w3zd2mlchoi5tvvw7b5hpmmhcddd5fnnwrixneid.onion:8333
+who3qs4eqlqzoxhqqgan4mg54ua5uz3mk4lj33ag53ei4orvnznrjbad.onion:8333
+wizbit5555bsslwv4ctronnsgk5vh2w2pdx7v7eyuivlyuoteejk7lid.onion:8333
+yrmedr35tt4wqfnwgilltxh5bnukeukxjpgg3jzmmsyld5lgsn5amvyd.onion:8333
-# manually updated 2022-08 for minimal i2p bootstrap support
+# manually updated 2023-04 for minimal i2p bootstrap support
255fhcp6ajvftnyo7bwz3an3t4a4brhopm3bamyh2iu5r3gnr2rq.b32.i2p:0
27yrtht5b5bzom2w5ajb27najuqvuydtzb7bavlak25wkufec5mq.b32.i2p:0
-2el6enckmfyiwbfcwsygkwksovtynzsigmyv3bzyk7j7qqahooua.b32.i2p:0
3gocb7wc4zvbmmebktet7gujccuux4ifk3kqilnxnj5wpdpqx2hq.b32.i2p:0
-3tns2oov4tnllntotazy6umzkq4fhkco3iu5rnkxtu3pbfzxda7q.b32.i2p:0
4fcc23wt3hyjk3csfzcdyjz5pcwg5dzhdqgma6bch2qyiakcbboa.b32.i2p:0
4osyqeknhx5qf3a73jeimexwclmt42cju6xdp7icja4ixxguu2hq.b32.i2p:0
4umsi4nlmgyp4rckosg4vegd2ysljvid47zu7pqsollkaszcbpqq.b32.i2p:0
-52v6uo6crlrlhzphslyiqblirux6olgsaa45ixih7sq5np4jujaa.b32.i2p:0
6j2ezegd3e2e2x3o3pox335f5vxfthrrigkdrbgfbdjchm5h4awa.b32.i2p:0
6n36ljyr55szci5ygidmxqer64qr24f4qmnymnbvgehz7qinxnla.b32.i2p:0
72yjs6mvlby3ky6mgpvvlemmwq5pfcznrzd34jkhclgrishqdxva.b32.i2p:0
-7r4ri53lby2i3xqbgpw3idvhzeku7ubhftlf72ldqkg5kde6dauq.b32.i2p:0
a5qsnv3maw77mlmmzlcglu6twje6ttctd3fhpbfwcbpmewx6fczq.b32.i2p:0
aovep2pco7v2k4rheofrgytbgk23eg22dczpsjqgqtxcqqvmxk6a.b32.i2p:0
-bddbsmkas3z6fakorbkfjhv77i4hv6rysyjsvrdjukxolfghc23q.b32.i2p:0
bitcoi656nll5hu6u7ddzrmzysdtwtnzcnrjd4rfdqbeey7dmn5a.b32.i2p:0
brifkruhlkgrj65hffybrjrjqcgdgqs2r7siizb5b2232nruik3a.b32.i2p:0
c4gfnttsuwqomiygupdqqqyy5y5emnk5c73hrfvatri67prd7vyq.b32.i2p:0
day3hgxyrtwjslt54sikevbhxxs4qzo7d6vi72ipmscqtq3qmijq.b32.i2p:0
-di2zq6fr3fegf2jdcd7hdwyql4umr462gonsns2nxz5qg5vz4bka.b32.i2p:0
+du5kydummi23bjfp6bd7owsvrijgt7zhvxmz5h5f5spcioeoetwq.b32.i2p:0
e55k6wu46rzp4pg5pk5npgbr3zz45bc3ihtzu2xcye5vwnzdy7pq.b32.i2p:0
eciohu5nq7vsvwjjc52epskuk75d24iccgzmhbzrwonw6lx4gdva.b32.i2p:0
ejlnngarmhqvune74ko7kk55xtgbz5i5ncs4vmnvjpy3l7y63xaa.b32.i2p:0
-g47cqoppu26pr4n2cfaioqx7lbdi7mea7yqhlrkdz3wjwxjxdh2a.b32.i2p:0
-h3r6bkn46qxftwja53pxiykntegfyfjqtnzbm6iv6r5mungmqgmq.b32.i2p:0
+fhzlp3xroabohnmjonu5iqazwhlbbwh5cpujvw2azcu3srqdceja.b32.i2p:0
+fx6np3oheacr3t7gluftrqo2qxldbbatgw4hepp7ulb4j5ry57ca.b32.i2p:0
+gehtac45oaghz54ypyopim64mql7oad2bqclla74l6tfeolzmodq.b32.i2p:0
hhfi4yqkg2twqiwezrfksftjjofbyx3ojkmlnfmcwntgnrjjhkya.b32.i2p:0
-hpiibrflqkbrcshfhmrtwfyeb7mds7a3obzwrgarejevddzamvsq.b32.i2p:0
-i4pyhsfdq4247dunel7paatdaq5gusi2hnybp2yf5wxwdnrgxaqq.b32.i2p:0
-iw6tgpmbdykffceku5da6nzf2bmz66fvp5fpcvemfu3df6aq6pga.b32.i2p:0
-jkfuajo4ayvo2rbv5qdj443q6adqmnormbhsf2f7rlp5t24xomda.b32.i2p:0
jz3s4eurm5vzjresf4mwo7oni4bk36daolwxh4iqtewakylgkxmq.b32.i2p:0
liu75cvktv4icbctg72w7nxbk4eibt7wamizfdii4omz7gcke5vq.b32.i2p:0
-ljsquuu3y4xje6l32p32inn6r2y6ull6oocgup6jtjrohrqxbz6a.b32.i2p:0
lrah7acdsgopybg43shadwwiv6igezaw64i6jb5muqdg7dmhj3la.b32.i2p:0
lzuu6mjtu7vd55d2biphicihufipoa7vyym6xfnkmmlra3tiziia.b32.i2p:0
m6bpynxkv2ktwxkg6p2gyudjfhdupb6kuzabeqdnckkdkf4kxjla.b32.i2p:0
m6v454xd6p3bt5swujgmveklsp7lzbkqlqqfc2p36cjlwv5dbucq.b32.i2p:0
mlgeizrroynuhpxbzeosajt5u4ddcvynxfmcbm6kwjpaufilxigq.b32.i2p:0
+o6t4fr5ayfadzieutstgwcllvwxeuzjlxmzsmpj3hpkvefhzfaea.b32.i2p:0
ofubxr2ir7u2guzjwyrvujicivzmvinwa36nuzlrg7tnsmebal7a.b32.i2p:0
-okfxeoh6itu4f5f43dhbzvkqwfrvm5c66lj6lvjj4q2b35i4pk4q.b32.i2p:0
oz2ia3flpm3du2tyusulrn7h7e2eo3juzkrmn34bvnrlcrugv7ia.b32.i2p:0
+pohfcrfc7prn4bvn4xstw6nt3e7hjmb7kuj4djtsfqsskwhmhnna.b32.i2p:0
qd6jlsevsexww3wefpqs7iglxb3f63y4e6ydulfzrvwflpicmdqa.b32.i2p:0
-qddg7myylinn4tw6kdjmmp6fsyetkosnrbp2gsjx77tmkqyqv6ua.b32.i2p:0
+rfjkzdzv4cwpxo6hzuncicvuyui76wxqx3a23lynq72ktwqs7aja.b32.i2p:0
rizfinyses2r3or4iubs5wx66gdy6mpf73w7uobfacm2l5cral3q.b32.i2p:0
-s5hhjtmlg53bko3nwwskas7xgsmeqzy6thtsj5aa64djyrljgqaq.b32.i2p:0
sedndhv5vpcgdmykyi5st4yqhdxl3hpdtglta4do435wupahhx6q.b32.i2p:0
-tsl4dlpu2id252b6crbdnblruct664se6f2iw35fuqwa3te7wcoq.b32.i2p:0
tugq6wa2ls2bv27pr2iy3da3k5ow3fzefbcvjcr22uc7w5vmevja.b32.i2p:0
usztavbib756k5vqggzgkyswoj6mttihjvp3c2pa642t2mb4pvsa.b32.i2p:0
vgu6llqbyjphml25umd5ztvyxrxuplz2g74fzbx75g3kkaetoyiq.b32.i2p:0
wjrul5jwwb4vqdmkkrjbmly7osj6amecdpsac5xvaoqrti4nb3ha.b32.i2p:0
-wvktcp7hy4l6immhi5cxyz2dlsbhhvtcmskjemrnqehacnoap23q.b32.i2p:0
wwbw7nqr3ahkqv62cuqfwgtneekvvpnuc4i4f6yo7tpoqjswvcwa.b32.i2p:0
-xlqndzjoe5nr2nsxo6xwibh44ghyz4jfqevu62xykvemextpmjbq.b32.i2p:0
+xfkarmvk43vfkfvhkehy7ioj2b6wtfdlezvmlakblz3q4r7mccfq.b32.i2p:0
yc4xwin5ujenvcr6ynwkz7lnmmq3nmzxvfguele6ovqqpxgjvonq.b32.i2p:0
zdoabsg7ugzothyawodjhq54nvlofa746rxfkxpnjzj6nukmha6a.b32.i2p:0
zsxwyo6qcn3chqzwxnseusqgsnuw3maqnztkiypyfxtya4snkoka.b32.i2p:0
zysrlpii5ftrzivfcyhdrwpeyyqddbrdefnfu5q6otk5gtugmh2a.b32.i2p:0
-# manually added 2022-01 for minimal cjdns bootstrap support
+# manually updated 2023-04 for minimal cjdns bootstrap support
[fc32:17ea:e415:c3bf:9808:149d:b5a2:c9aa]:8333
[fcc7:be49:ccd1:dc91:3125:f0da:457d:8ce]:8333
+[fcdc:73ae:b1a9:1bf8:d4c2:811:a4c7:c34e]:8333
diff --git a/contrib/valgrind.supp b/contrib/valgrind.supp
index 9a8edba445..faba1f6ae6 100644
--- a/contrib/valgrind.supp
+++ b/contrib/valgrind.supp
@@ -13,19 +13,8 @@
#
# Note that suppressions may depend on OS and/or library versions.
# Tested on:
-# * aarch64 (Ubuntu 22.04 system libs, clang, without gui)
-# * x86_64 (Ubuntu 22.04 system libs, clang, without gui)
-{
- Suppress libstdc++ warning - https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65434
- Memcheck:Leak
- match-leak-kinds: reachable
- fun:malloc
- obj:*/libstdc++.*
- fun:call_init.part.0
- fun:call_init
- fun:_dl_init
- obj:*/ld-*.so
-}
+# * aarch64 (Debian Bookworm system libs, clang, without gui)
+# * x86_64 (Debian Bookworm system libs, clang, without gui)
{
Suppress libdb warning - https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=662917
Memcheck:Cond
@@ -71,12 +60,6 @@
fun:_Z8ShutdownR11NodeContext
}
{
- Ignore GUI warning
- Memcheck:Leak
- ...
- obj:/usr/lib64/libgdk-3.so.0.2404.7
-}
-{
Suppress leveldb leak
Memcheck:Leak
match-leak-kinds: reachable
diff --git a/contrib/verify-binaries/README.md b/contrib/verify-binaries/README.md
new file mode 100644
index 0000000000..c62d760e1a
--- /dev/null
+++ b/contrib/verify-binaries/README.md
@@ -0,0 +1,88 @@
+### Verify Binaries
+
+#### Preparation
+
+As of Bitcoin Core v22.0, releases are signed by a number of public keys on the basis
+of the [guix.sigs repository](https://github.com/bitcoin-core/guix.sigs/). When
+verifying binary downloads, you (the end user) decide which of these public keys you
+trust and then use that trust model to evaluate the signature on a file that contains
+hashes of the release binaries. The downloaded binaries are then hashed and compared to
+the signed checksum file.
+
+First, you have to figure out which public keys to recognize. Browse the [list of frequent
+builder-keys](https://github.com/bitcoin-core/guix.sigs/tree/main/builder-keys) and
+decide which of these keys you would like to trust. For each key you want to trust, you
+must obtain that key for your local GPG installation.
+
+You can obtain these keys by
+ - through a browser using a key server (e.g. keyserver.ubuntu.com),
+ - manually using the `gpg --keyserver <url> --recv-keys <key>` command, or
+ - you can run the packaged `verify.py ... --import-keys` script to
+ have it automatically retrieve unrecognized keys.
+
+#### Usage
+
+This script attempts to download the checksum file (`SHA256SUMS`) and corresponding
+signature file `SHA256SUMS.asc` from https://bitcoincore.org and https://bitcoin.org.
+
+It first checks if the checksum file is valid based upon a plurality of signatures, and
+then downloads the release files specified in the checksum file, and checks if the
+hashes of the release files are as expected.
+
+If we encounter pubkeys in the signature file that we do not recognize, the script
+can prompt the user as to whether they'd like to download the pubkeys. To enable
+this behavior, use the `--import-keys` flag.
+
+The script returns 0 if everything passes the checks. It returns 1 if either the
+signature check or the hash check doesn't pass. An exit code of >2 indicates an error.
+
+See the `Config` object for various options.
+
+#### Examples
+
+Validate releases with default settings:
+```sh
+./contrib/verify-binaries/verify.py pub 22.0
+./contrib/verify-binaries/verify.py pub 22.0-rc3
+```
+
+Get JSON output and don't prompt for user input (no auto key import):
+
+```sh
+./contrib/verify-binaries/verify.py --json pub 22.0-x86
+```
+
+Rely only on local GPG state and manually specified keys, while requiring a
+threshold of at least 10 trusted signatures:
+```sh
+./contrib/verify-binaries/verify.py \
+ --trusted-keys 74E2DEF5D77260B98BC19438099BAD163C70FBFA,9D3CC86A72F8494342EA5FD10A41BDC3F4FAFF1C \
+ --min-good-sigs 10 pub 22.0-x86
+```
+
+If you only want to download the binaries for a certain platform, add the corresponding suffix, e.g.:
+
+```sh
+./contrib/verify-binaries/verify.py pub 24.0.1-darwin
+./contrib/verify-binaries/verify.py pub 23.1-rc1-win64
+```
+
+If you do not want to keep the downloaded binaries, specify the cleanup option.
+
+```sh
+./contrib/verify-binaries/verify.py pub --cleanup 22.0
+```
+
+Use the bin subcommand to verify all files listed in a local checksum file
+
+```sh
+./contrib/verify-binaries/verify.py bin SHA256SUMS
+```
+
+Verify only a subset of the files listed in a local checksum file
+
+```sh
+./contrib/verify-binaries/verify.py bin ~/Downloads/SHA256SUMS \
+ ~/Downloads/bitcoin-24.0.1-x86_64-linux-gnu.tar.gz \
+ ~/Downloads/bitcoin-24.0.1-arm-linux-gnueabihf.tar.gz
+```
diff --git a/contrib/verify-binaries/test.py b/contrib/verify-binaries/test.py
new file mode 100755
index 0000000000..22d718ece3
--- /dev/null
+++ b/contrib/verify-binaries/test.py
@@ -0,0 +1,59 @@
+#!/usr/bin/env python3
+
+import json
+import sys
+import subprocess
+from pathlib import Path
+
+
+def main():
+ """Tests ordered roughly from faster to slower."""
+ expect_code(run_verify("", "pub", '0.32'), 4, "Nonexistent version should fail")
+ expect_code(run_verify("", "pub", '0.32.awefa.12f9h'), 11, "Malformed version should fail")
+ expect_code(run_verify('--min-good-sigs 20', "pub", "22.0"), 9, "--min-good-sigs 20 should fail")
+
+ print("- testing verification (22.0)", flush=True)
+ _220 = run_verify("--json", "pub", "22.0")
+ try:
+ result = json.loads(_220.stdout.decode())
+ except Exception:
+ print("failed on 22.0 --json:")
+ print_process_failure(_220)
+ raise
+
+ expect_code(_220, 0, "22.0 should succeed")
+ v = result['verified_binaries']
+ assert result['good_trusted_sigs']
+ assert v['bitcoin-22.0-aarch64-linux-gnu.tar.gz'] == 'ac718fed08570a81b3587587872ad85a25173afa5f9fbbd0c03ba4d1714cfa3e'
+ assert v['bitcoin-22.0-osx64.tar.gz'] == '2744d199c3343b2d94faffdfb2c94d75a630ba27301a70e47b0ad30a7e0155e9'
+ assert v['bitcoin-22.0-x86_64-linux-gnu.tar.gz'] == '59ebd25dd82a51638b7a6bb914586201e67db67b919b2a1ff08925a7936d1b16'
+
+
+def run_verify(global_args: str, command: str, command_args: str) -> subprocess.CompletedProcess:
+ maybe_here = Path.cwd() / 'verify.py'
+ path = maybe_here if maybe_here.exists() else Path.cwd() / 'contrib' / 'verify-binaries' / 'verify.py'
+
+ if command == "pub":
+ command += " --cleanup"
+
+ return subprocess.run(
+ f"{path} {global_args} {command} {command_args}",
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
+
+
+def expect_code(completed: subprocess.CompletedProcess, expected_code: int, msg: str):
+ if completed.returncode != expected_code:
+ print(f"{msg!r} failed: got code {completed.returncode}, expected {expected_code}")
+ print_process_failure(completed)
+ sys.exit(1)
+ else:
+ print(f"✓ {msg!r} passed")
+
+
+def print_process_failure(completed: subprocess.CompletedProcess):
+ print(f"stdout:\n{completed.stdout.decode()}")
+ print(f"stderr:\n{completed.stderr.decode()}")
+
+
+if __name__ == '__main__':
+ main()
diff --git a/contrib/verify-binaries/verify.py b/contrib/verify-binaries/verify.py
new file mode 100755
index 0000000000..d0749f503f
--- /dev/null
+++ b/contrib/verify-binaries/verify.py
@@ -0,0 +1,713 @@
+#!/usr/bin/env python3
+# Copyright (c) 2020-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.
+"""Script for verifying Bitcoin Core release binaries.
+
+This script attempts to download the sum file SHA256SUMS and corresponding
+signature file SHA256SUMS.asc from bitcoincore.org and bitcoin.org and
+compares them.
+
+The sum-signature file is signed by a number of builder keys. This script
+ensures that there is a minimum threshold of signatures from pubkeys that
+we trust. This trust is articulated on the basis of configuration options
+here, but by default is based upon local GPG trust settings.
+
+The builder keys are available in the guix.sigs repo:
+
+ https://github.com/bitcoin-core/guix.sigs/tree/main/builder-keys
+
+If a minimum good, trusted signature threshold is met on the sum file, we then
+download the files specified in SHA256SUMS, and check if the hashes of these
+files match those that are specified. The script returns 0 if everything passes
+the checks. It returns 1 if either the signature check or the hash check
+doesn't pass. If an error occurs the return value is >= 2.
+
+Logging output goes to stderr and final binary verification data goes to stdout.
+
+JSON output can by obtained by setting env BINVERIFY_JSON=1.
+"""
+import argparse
+import difflib
+import json
+import logging
+import os
+import subprocess
+import typing as t
+import re
+import sys
+import shutil
+import tempfile
+import textwrap
+import urllib.request
+import urllib.error
+import enum
+from hashlib import sha256
+from pathlib import PurePath, Path
+
+# The primary host; this will fail if we can't retrieve files from here.
+HOST1 = "https://bitcoincore.org"
+HOST2 = "https://bitcoin.org"
+VERSIONPREFIX = "bitcoin-core-"
+SUMS_FILENAME = 'SHA256SUMS'
+SIGNATUREFILENAME = f"{SUMS_FILENAME}.asc"
+
+
+class ReturnCode(enum.IntEnum):
+ SUCCESS = 0
+ INTEGRITY_FAILURE = 1
+ FILE_GET_FAILED = 4
+ FILE_MISSING_FROM_ONE_HOST = 5
+ FILES_NOT_EQUAL = 6
+ NO_BINARIES_MATCH = 7
+ NOT_ENOUGH_GOOD_SIGS = 9
+ BINARY_DOWNLOAD_FAILED = 10
+ BAD_VERSION = 11
+
+
+def set_up_logger(is_verbose: bool = True) -> logging.Logger:
+ """Set up a logger that writes to stderr."""
+ log = logging.getLogger(__name__)
+ log.setLevel(logging.INFO if is_verbose else logging.WARNING)
+ console = logging.StreamHandler(sys.stderr) # log to stderr
+ console.setLevel(logging.DEBUG)
+ formatter = logging.Formatter('[%(levelname)s] %(message)s')
+ console.setFormatter(formatter)
+ log.addHandler(console)
+ return log
+
+
+log = set_up_logger()
+
+
+def indent(output: str) -> str:
+ return textwrap.indent(output, ' ')
+
+
+def bool_from_env(key, default=False) -> bool:
+ if key not in os.environ:
+ return default
+ raw = os.environ[key]
+
+ if raw.lower() in ('1', 'true'):
+ return True
+ elif raw.lower() in ('0', 'false'):
+ return False
+ raise ValueError(f"Unrecognized environment value {key}={raw!r}")
+
+
+VERSION_FORMAT = "<major>.<minor>[.<patch>][-rc[0-9]][-platform]"
+VERSION_EXAMPLE = "22.0-x86_64 or 23.1-rc1-darwin"
+
+def parse_version_string(version_str):
+ parts = version_str.split('-')
+ version_base = parts[0]
+ version_rc = ""
+ version_os = ""
+ if len(parts) == 2: # "<version>-rcN" or "version-platform"
+ if "rc" in parts[1]:
+ version_rc = parts[1]
+ else:
+ version_os = parts[1]
+ elif len(parts) == 3: # "<version>-rcN-platform"
+ version_rc = parts[1]
+ version_os = parts[2]
+
+ return version_base, version_rc, version_os
+
+
+def download_with_wget(remote_file, local_file):
+ result = subprocess.run(['wget', '-O', local_file, remote_file],
+ stderr=subprocess.STDOUT, stdout=subprocess.PIPE)
+ return result.returncode == 0, result.stdout.decode().rstrip()
+
+
+def download_lines_with_urllib(url) -> t.Tuple[bool, t.List[str]]:
+ """Get (success, text lines of a file) over HTTP."""
+ try:
+ return (True, [
+ line.strip().decode() for line in urllib.request.urlopen(url).readlines()])
+ except urllib.error.HTTPError as e:
+ log.warning(f"HTTP request to {url} failed (HTTPError): {e}")
+ except Exception as e:
+ log.warning(f"HTTP request to {url} failed ({e})")
+ return (False, [])
+
+
+def verify_with_gpg(
+ filename,
+ signature_filename,
+ output_filename: t.Optional[str] = None
+) -> t.Tuple[int, str]:
+ with tempfile.NamedTemporaryFile() as status_file:
+ args = [
+ 'gpg', '--yes', '--verify', '--verify-options', 'show-primary-uid-only', "--status-file", status_file.name,
+ '--output', output_filename if output_filename else '', signature_filename, filename]
+
+ env = dict(os.environ, LANGUAGE='en')
+ result = subprocess.run(args, stderr=subprocess.STDOUT, stdout=subprocess.PIPE, env=env)
+
+ gpg_data = status_file.read().decode().rstrip()
+
+ log.debug(f'Result from GPG ({result.returncode}): {result.stdout.decode()}')
+ log.debug(f"{gpg_data}")
+ return result.returncode, gpg_data
+
+
+def remove_files(filenames):
+ for filename in filenames:
+ os.remove(filename)
+
+
+class SigData:
+ """GPG signature data as parsed from GPG stdout."""
+ def __init__(self):
+ self.key = None
+ self.name = ""
+ self.trusted = False
+ self.status = ""
+
+ def __bool__(self):
+ return self.key is not None
+
+ def __repr__(self):
+ return (
+ "SigData(%r, %r, trusted=%s, status=%r)" %
+ (self.key, self.name, self.trusted, self.status))
+
+
+def parse_gpg_result(
+ output: t.List[str]
+) -> t.Tuple[t.List[SigData], t.List[SigData], t.List[SigData]]:
+ """Returns good, unknown, and bad signatures from GPG stdout."""
+ good_sigs: t.List[SigData] = []
+ unknown_sigs: t.List[SigData] = []
+ bad_sigs: t.List[SigData] = []
+ total_resolved_sigs = 0
+
+ # Ensure that all lines we match on include a prefix that prevents malicious input
+ # from fooling the parser.
+ def line_begins_with(patt: str, line: str) -> t.Optional[re.Match]:
+ return re.match(r'^(\[GNUPG:\])\s+' + patt, line)
+
+ curr_sigs = unknown_sigs
+ curr_sigdata = SigData()
+
+ for line in output:
+ if line_begins_with(r"NEWSIG(?:\s|$)", line):
+ total_resolved_sigs += 1
+ if curr_sigdata:
+ curr_sigs.append(curr_sigdata)
+ curr_sigdata = SigData()
+ newsig_split = line.split()
+ if len(newsig_split) == 3:
+ curr_sigdata.name = newsig_split[2]
+
+ elif line_begins_with(r"GOODSIG(?:\s|$)", line):
+ curr_sigdata.key, curr_sigdata.name = line.split(maxsplit=3)[2:4]
+ curr_sigs = good_sigs
+
+ elif line_begins_with(r"EXPKEYSIG(?:\s|$)", line):
+ curr_sigdata.key, curr_sigdata.name = line.split(maxsplit=3)[2:4]
+ curr_sigs = good_sigs
+ curr_sigdata.status = "expired"
+
+ elif line_begins_with(r"REVKEYSIG(?:\s|$)", line):
+ curr_sigdata.key, curr_sigdata.name = line.split(maxsplit=3)[2:4]
+ curr_sigs = good_sigs
+ curr_sigdata.status = "revoked"
+
+ elif line_begins_with(r"BADSIG(?:\s|$)", line):
+ curr_sigdata.key, curr_sigdata.name = line.split(maxsplit=3)[2:4]
+ curr_sigs = bad_sigs
+
+ elif line_begins_with(r"ERRSIG(?:\s|$)", line):
+ curr_sigdata.key, _, _, _, _, _ = line.split()[2:8]
+ curr_sigs = unknown_sigs
+
+ elif line_begins_with(r"TRUST_(UNDEFINED|NEVER)(?:\s|$)", line):
+ curr_sigdata.trusted = False
+
+ elif line_begins_with(r"TRUST_(MARGINAL|FULLY|ULTIMATE)(?:\s|$)", line):
+ curr_sigdata.trusted = True
+
+ # The last one won't have been added, so add it now
+ assert curr_sigdata
+ curr_sigs.append(curr_sigdata)
+
+ all_found = len(good_sigs + bad_sigs + unknown_sigs)
+ if all_found != total_resolved_sigs:
+ raise RuntimeError(
+ f"failed to evaluate all signatures: found {all_found} "
+ f"but expected {total_resolved_sigs}")
+
+ return (good_sigs, unknown_sigs, bad_sigs)
+
+
+def files_are_equal(filename1, filename2):
+ with open(filename1, 'rb') as file1:
+ contents1 = file1.read()
+ with open(filename2, 'rb') as file2:
+ contents2 = file2.read()
+ eq = contents1 == contents2
+
+ if not eq:
+ with open(filename1, 'r', encoding='utf-8') as f1, \
+ open(filename2, 'r', encoding='utf-8') as f2:
+ f1lines = f1.readlines()
+ f2lines = f2.readlines()
+
+ diff = indent(
+ ''.join(difflib.unified_diff(f1lines, f2lines)))
+ log.warning(f"found diff in files ({filename1}, {filename2}):\n{diff}\n")
+
+ return eq
+
+
+def get_files_from_hosts_and_compare(
+ hosts: t.List[str], path: str, filename: str, require_all: bool = False
+) -> ReturnCode:
+ """
+ Retrieve the same file from a number of hosts and ensure they have the same contents.
+ The first host given will be treated as the "primary" host, and is required to succeed.
+
+ Args:
+ filename: for writing the file locally.
+ """
+ assert len(hosts) > 1
+ primary_host = hosts[0]
+ other_hosts = hosts[1:]
+ got_files = []
+
+ def join_url(host: str) -> str:
+ return host.rstrip('/') + '/' + path.lstrip('/')
+
+ url = join_url(primary_host)
+ success, output = download_with_wget(url, filename)
+ if not success:
+ log.error(
+ f"couldn't fetch file ({url}). "
+ "Have you specified the version number in the following format?\n"
+ f"{VERSION_FORMAT} "
+ f"(example: {VERSION_EXAMPLE})\n"
+ f"wget output:\n{indent(output)}")
+ return ReturnCode.FILE_GET_FAILED
+ else:
+ log.info(f"got file {url} as {filename}")
+ got_files.append(filename)
+
+ for i, host in enumerate(other_hosts):
+ url = join_url(host)
+ fname = filename + f'.{i + 2}'
+ success, output = download_with_wget(url, fname)
+
+ if require_all and not success:
+ log.error(
+ f"{host} failed to provide file ({url}), but {primary_host} did?\n"
+ f"wget output:\n{indent(output)}")
+ return ReturnCode.FILE_MISSING_FROM_ONE_HOST
+ elif not success:
+ log.warning(
+ f"{host} failed to provide file ({url}). "
+ f"Continuing based solely upon {primary_host}.")
+ else:
+ log.info(f"got file {url} as {fname}")
+ got_files.append(fname)
+
+ for i, got_file in enumerate(got_files):
+ if got_file == got_files[-1]:
+ break # break on last file, nothing after it to compare to
+
+ compare_to = got_files[i + 1]
+ if not files_are_equal(got_file, compare_to):
+ log.error(f"files not equal: {got_file} and {compare_to}")
+ return ReturnCode.FILES_NOT_EQUAL
+
+ return ReturnCode.SUCCESS
+
+
+def check_multisig(sums_file: str, sigfilename: str, args: argparse.Namespace) -> t.Tuple[int, str, t.List[SigData], t.List[SigData], t.List[SigData]]:
+ # check signature
+ #
+ # We don't write output to a file because this command will almost certainly
+ # fail with GPG exit code '2' (and so not writing to --output) because of the
+ # likely presence of multiple untrusted signatures.
+ retval, output = verify_with_gpg(sums_file, sigfilename)
+
+ if args.verbose:
+ log.info(f"gpg output:\n{indent(output)}")
+
+ good, unknown, bad = parse_gpg_result(output.splitlines())
+
+ if unknown and args.import_keys:
+ # Retrieve unknown keys and then try GPG again.
+ for unsig in unknown:
+ if prompt_yn(f" ? Retrieve key {unsig.key} ({unsig.name})? (y/N) "):
+ ran = subprocess.run(
+ ["gpg", "--keyserver", args.keyserver, "--recv-keys", unsig.key])
+
+ if ran.returncode != 0:
+ log.warning(f"failed to retrieve key {unsig.key}")
+
+ # Reparse the GPG output now that we have more keys
+ retval, output = verify_with_gpg(sums_file, sigfilename)
+ good, unknown, bad = parse_gpg_result(output.splitlines())
+
+ return retval, output, good, unknown, bad
+
+
+def prompt_yn(prompt) -> bool:
+ """Return true if the user inputs 'y'."""
+ got = ''
+ while got not in ['y', 'n']:
+ got = input(prompt).lower()
+ return got == 'y'
+
+def verify_shasums_signature(
+ signature_file_path: str, sums_file_path: str, args: argparse.Namespace
+) -> t.Tuple[
+ ReturnCode, t.List[SigData], t.List[SigData], t.List[SigData], t.List[SigData]
+]:
+ min_good_sigs = args.min_good_sigs
+ gpg_allowed_codes = [0, 2] # 2 is returned when untrusted signatures are present.
+
+ gpg_retval, gpg_output, good, unknown, bad = check_multisig(sums_file_path, signature_file_path, args)
+
+ if gpg_retval not in gpg_allowed_codes:
+ if gpg_retval == 1:
+ log.critical(f"Bad signature (code: {gpg_retval}).")
+ else:
+ log.critical(f"unexpected GPG exit code ({gpg_retval})")
+
+ log.error(f"gpg output:\n{indent(gpg_output)}")
+ return (ReturnCode.INTEGRITY_FAILURE, [], [], [], [])
+
+ # Decide which keys we trust, though not "trust" in the GPG sense, but rather
+ # which pubkeys convince us that this sums file is legitimate. In other words,
+ # which pubkeys within the Bitcoin community do we trust for the purposes of
+ # binary verification?
+ trusted_keys = set()
+ if args.trusted_keys:
+ trusted_keys |= set(args.trusted_keys.split(','))
+
+ # Tally signatures and make sure we have enough goods to fulfill
+ # our threshold.
+ good_trusted = [sig for sig in good if sig.trusted or sig.key in trusted_keys]
+ good_untrusted = [sig for sig in good if sig not in good_trusted]
+ num_trusted = len(good_trusted) + len(good_untrusted)
+ log.info(f"got {num_trusted} good signatures")
+
+ if num_trusted < min_good_sigs:
+ log.info("Maybe you need to import "
+ f"(`gpg --keyserver {args.keyserver} --recv-keys <key-id>`) "
+ "some of the following keys: ")
+ log.info('')
+ for sig in unknown:
+ log.info(f" {sig.key} ({sig.name})")
+ log.info('')
+ log.error(
+ "not enough trusted sigs to meet threshold "
+ f"({num_trusted} vs. {min_good_sigs})")
+
+ return (ReturnCode.NOT_ENOUGH_GOOD_SIGS, [], [], [], [])
+
+ for sig in good_trusted:
+ log.info(f"GOOD SIGNATURE: {sig}")
+
+ for sig in good_untrusted:
+ log.info(f"GOOD SIGNATURE (untrusted): {sig}")
+
+ for sig in [sig for sig in good if sig.status == 'expired']:
+ log.warning(f"key {sig.key} for {sig.name} is expired")
+
+ for sig in bad:
+ log.warning(f"BAD SIGNATURE: {sig}")
+
+ for sig in unknown:
+ log.warning(f"UNKNOWN SIGNATURE: {sig}")
+
+ return (ReturnCode.SUCCESS, good_trusted, good_untrusted, unknown, bad)
+
+
+def parse_sums_file(sums_file_path: str, filename_filter: t.List[str]) -> t.List[t.List[str]]:
+ # extract hashes/filenames of binaries to verify from hash file;
+ # each line has the following format: "<hash> <binary_filename>"
+ with open(sums_file_path, 'r', encoding='utf8') as hash_file:
+ return [line.split()[:2] for line in hash_file if len(filename_filter) == 0 or any(f in line for f in filename_filter)]
+
+
+def verify_binary_hashes(hashes_to_verify: t.List[t.List[str]]) -> t.Tuple[ReturnCode, t.Dict[str, str]]:
+ offending_files = []
+ files_to_hashes = {}
+
+ for hash_expected, binary_filename in hashes_to_verify:
+ with open(binary_filename, 'rb') as binary_file:
+ hash_calculated = sha256(binary_file.read()).hexdigest()
+ if hash_calculated != hash_expected:
+ offending_files.append(binary_filename)
+ else:
+ files_to_hashes[binary_filename] = hash_calculated
+
+ if offending_files:
+ joined_files = '\n'.join(offending_files)
+ log.critical(
+ "Hashes don't match.\n"
+ f"Offending files:\n{joined_files}")
+ return (ReturnCode.INTEGRITY_FAILURE, files_to_hashes)
+
+ return (ReturnCode.SUCCESS, files_to_hashes)
+
+
+def verify_published_handler(args: argparse.Namespace) -> ReturnCode:
+ WORKINGDIR = Path(tempfile.gettempdir()) / f"bitcoin_verify_binaries.{args.version}"
+
+ def cleanup():
+ log.info("cleaning up files")
+ os.chdir(Path.home())
+ shutil.rmtree(WORKINGDIR)
+
+ # determine remote dir dependent on provided version string
+ try:
+ version_base, version_rc, os_filter = parse_version_string(args.version)
+ version_tuple = [int(i) for i in version_base.split('.')]
+ except Exception as e:
+ log.debug(e)
+ log.error(f"unable to parse version; expected format is {VERSION_FORMAT}")
+ log.error(f" e.g. {VERSION_EXAMPLE}")
+ return ReturnCode.BAD_VERSION
+
+ remote_dir = f"/bin/{VERSIONPREFIX}{version_base}/"
+ if version_rc:
+ remote_dir += f"test.{version_rc}/"
+ remote_sigs_path = remote_dir + SIGNATUREFILENAME
+ remote_sums_path = remote_dir + SUMS_FILENAME
+
+ # create working directory
+ os.makedirs(WORKINGDIR, exist_ok=True)
+ os.chdir(WORKINGDIR)
+
+ hosts = [HOST1, HOST2]
+
+ got_sig_status = get_files_from_hosts_and_compare(
+ hosts, remote_sigs_path, SIGNATUREFILENAME, args.require_all_hosts)
+ if got_sig_status != ReturnCode.SUCCESS:
+ return got_sig_status
+
+ # Multi-sig verification is available after 22.0.
+ if version_tuple[0] < 22:
+ log.error("Version too old - single sig not supported. Use a previous "
+ "version of this script from the repo.")
+ return ReturnCode.BAD_VERSION
+
+ got_sums_status = get_files_from_hosts_and_compare(
+ hosts, remote_sums_path, SUMS_FILENAME, args.require_all_hosts)
+ if got_sums_status != ReturnCode.SUCCESS:
+ return got_sums_status
+
+ # Verify the signature on the SHA256SUMS file
+ sigs_status, good_trusted, good_untrusted, unknown, bad = verify_shasums_signature(SIGNATUREFILENAME, SUMS_FILENAME, args)
+ if sigs_status != ReturnCode.SUCCESS:
+ if sigs_status == ReturnCode.INTEGRITY_FAILURE:
+ cleanup()
+ return sigs_status
+
+ # Extract hashes and filenames
+ hashes_to_verify = parse_sums_file(SUMS_FILENAME, [os_filter])
+ if not hashes_to_verify:
+ log.error("no files matched the platform specified")
+ return ReturnCode.NO_BINARIES_MATCH
+
+ # remove binaries that are known not to be hosted by bitcoincore.org
+ fragments_to_remove = ['-unsigned', '-debug', '-codesignatures']
+ for fragment in fragments_to_remove:
+ nobinaries = [i for i in hashes_to_verify if fragment in i[1]]
+ if nobinaries:
+ remove_str = ', '.join(i[1] for i in nobinaries)
+ log.info(
+ f"removing *{fragment} binaries ({remove_str}) from verification "
+ f"since {HOST1} does not host *{fragment} binaries")
+ hashes_to_verify = [i for i in hashes_to_verify if fragment not in i[1]]
+
+ # download binaries
+ for _, binary_filename in hashes_to_verify:
+ log.info(f"downloading {binary_filename} to {WORKINGDIR}")
+ success, output = download_with_wget(
+ HOST1 + remote_dir + binary_filename, binary_filename)
+
+ if not success:
+ log.error(
+ f"failed to download {binary_filename}\n"
+ f"wget output:\n{indent(output)}")
+ return ReturnCode.BINARY_DOWNLOAD_FAILED
+
+ # verify hashes
+ hashes_status, files_to_hashes = verify_binary_hashes(hashes_to_verify)
+ if hashes_status != ReturnCode.SUCCESS:
+ return hashes_status
+
+
+ if args.cleanup:
+ cleanup()
+ else:
+ log.info(f"did not clean up {WORKINGDIR}")
+
+ if args.json:
+ output = {
+ 'good_trusted_sigs': [str(s) for s in good_trusted],
+ 'good_untrusted_sigs': [str(s) for s in good_untrusted],
+ 'unknown_sigs': [str(s) for s in unknown],
+ 'bad_sigs': [str(s) for s in bad],
+ 'verified_binaries': files_to_hashes,
+ }
+ print(json.dumps(output, indent=2))
+ else:
+ for filename in files_to_hashes:
+ print(f"VERIFIED: {filename}")
+
+ return ReturnCode.SUCCESS
+
+
+def verify_binaries_handler(args: argparse.Namespace) -> ReturnCode:
+ binary_to_basename = {}
+ for file in args.binary:
+ binary_to_basename[PurePath(file).name] = file
+
+ sums_sig_path = None
+ if args.sums_sig_file:
+ sums_sig_path = Path(args.sums_sig_file)
+ else:
+ log.info(f"No signature file specified, assuming it is {args.sums_file}.asc")
+ sums_sig_path = Path(args.sums_file).with_suffix(".asc")
+
+ # Verify the signature on the SHA256SUMS file
+ sigs_status, good_trusted, good_untrusted, unknown, bad = verify_shasums_signature(str(sums_sig_path), args.sums_file, args)
+ if sigs_status != ReturnCode.SUCCESS:
+ return sigs_status
+
+ # Extract hashes and filenames
+ hashes_to_verify = parse_sums_file(args.sums_file, [k for k, n in binary_to_basename.items()])
+ if not hashes_to_verify:
+ log.error(f"No files in {args.sums_file} match the specified binaries")
+ return ReturnCode.NO_BINARIES_MATCH
+
+ # Make sure all files are accounted for
+ sums_file_path = Path(args.sums_file)
+ missing_files = []
+ files_to_hash = []
+ if len(binary_to_basename) > 0:
+ for file_hash, file in hashes_to_verify:
+ files_to_hash.append([file_hash, binary_to_basename[file]])
+ del binary_to_basename[file]
+ if len(binary_to_basename) > 0:
+ log.error(f"Not all specified binaries are in {args.sums_file}")
+ return ReturnCode.NO_BINARIES_MATCH
+ else:
+ log.info(f"No binaries specified, assuming all files specified in {args.sums_file} are located relatively")
+ for file_hash, file in hashes_to_verify:
+ file_path = Path(sums_file_path.parent.joinpath(file))
+ if file_path.exists():
+ files_to_hash.append([file_hash, str(file_path)])
+ else:
+ missing_files.append(file)
+
+ # verify hashes
+ hashes_status, files_to_hashes = verify_binary_hashes(files_to_hash)
+ if hashes_status != ReturnCode.SUCCESS:
+ return hashes_status
+
+ if args.json:
+ output = {
+ 'good_trusted_sigs': [str(s) for s in good_trusted],
+ 'good_untrusted_sigs': [str(s) for s in good_untrusted],
+ 'unknown_sigs': [str(s) for s in unknown],
+ 'bad_sigs': [str(s) for s in bad],
+ 'verified_binaries': files_to_hashes,
+ "missing_binaries": missing_files,
+ }
+ print(json.dumps(output, indent=2))
+ else:
+ for filename in files_to_hashes:
+ print(f"VERIFIED: {filename}")
+ for filename in missing_files:
+ print(f"MISSING: {filename}")
+
+ return ReturnCode.SUCCESS
+
+
+def main():
+ parser = argparse.ArgumentParser(description=__doc__)
+ parser.add_argument(
+ '-v', '--verbose', action='store_true',
+ default=bool_from_env('BINVERIFY_VERBOSE'),
+ )
+ parser.add_argument(
+ '-q', '--quiet', action='store_true',
+ default=bool_from_env('BINVERIFY_QUIET'),
+ )
+ parser.add_argument(
+ '--import-keys', action='store_true',
+ default=bool_from_env('BINVERIFY_IMPORTKEYS'),
+ help='if specified, ask to import each unknown builder key'
+ )
+ parser.add_argument(
+ '--min-good-sigs', type=int, action='store', nargs='?',
+ default=int(os.environ.get('BINVERIFY_MIN_GOOD_SIGS', 3)),
+ help=(
+ 'The minimum number of good signatures to require successful termination.'),
+ )
+ parser.add_argument(
+ '--keyserver', action='store', nargs='?',
+ default=os.environ.get('BINVERIFY_KEYSERVER', 'hkps://keys.openpgp.org'),
+ help='which keyserver to use',
+ )
+ parser.add_argument(
+ '--trusted-keys', action='store', nargs='?',
+ default=os.environ.get('BINVERIFY_TRUSTED_KEYS', ''),
+ help='A list of trusted signer GPG keys, separated by commas. Not "trusted keys" in the GPG sense.',
+ )
+ parser.add_argument(
+ '--json', action='store_true',
+ default=bool_from_env('BINVERIFY_JSON'),
+ help='If set, output the result as JSON',
+ )
+
+ subparsers = parser.add_subparsers(title="Commands", required=True, dest="command")
+
+ pub_parser = subparsers.add_parser("pub", help="Verify a published release.")
+ pub_parser.set_defaults(func=verify_published_handler)
+ pub_parser.add_argument(
+ 'version', type=str, help=(
+ f'version of the bitcoin release to download; of the format '
+ f'{VERSION_FORMAT}. Example: {VERSION_EXAMPLE}')
+ )
+ pub_parser.add_argument(
+ '--cleanup', action='store_true',
+ default=bool_from_env('BINVERIFY_CLEANUP'),
+ help='if specified, clean up files afterwards'
+ )
+ pub_parser.add_argument(
+ '--require-all-hosts', action='store_true',
+ default=bool_from_env('BINVERIFY_REQUIRE_ALL_HOSTS'),
+ help=(
+ f'If set, require all hosts ({HOST1}, {HOST2}) to provide signatures. '
+ '(Sometimes bitcoin.org lags behind bitcoincore.org.)')
+ )
+
+ bin_parser = subparsers.add_parser("bin", help="Verify local binaries.")
+ bin_parser.set_defaults(func=verify_binaries_handler)
+ bin_parser.add_argument("--sums-sig-file", "-s", help="Path to the SHA256SUMS.asc file to verify")
+ bin_parser.add_argument("sums_file", help="Path to the SHA256SUMS file to verify")
+ bin_parser.add_argument(
+ "binary", nargs="*",
+ help="Path to a binary distribution file to verify. Can be specified multiple times for multiple files to verify."
+ )
+
+ args = parser.parse_args()
+ if args.quiet:
+ log.setLevel(logging.WARNING)
+
+ return args.func(args)
+
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/contrib/verify-commits/verify-commits.py b/contrib/verify-commits/verify-commits.py
index f301964280..a1fe78a643 100755
--- a/contrib/verify-commits/verify-commits.py
+++ b/contrib/verify-commits/verify-commits.py
@@ -178,7 +178,20 @@ def main():
allow_unclean = current_commit in unclean_merge_allowed
if len(parents) == 2 and check_merge and not allow_unclean:
current_tree = subprocess.check_output([GIT, 'show', '--format=%T', current_commit]).decode('utf8').splitlines()[0]
- recreated_tree = subprocess.check_output([GIT, "merge-tree", parents[0], parents[1]]).decode('utf8').splitlines()[0]
+
+ # This merge-tree functionality requires git >= 2.38. The
+ # --write-tree option was added in order to opt-in to the new
+ # behavior. Older versions of git will not recognize the option and
+ # will instead exit with code 128.
+ try:
+ recreated_tree = subprocess.check_output([GIT, "merge-tree", "--write-tree", parents[0], parents[1]]).decode('utf8').splitlines()[0]
+ except subprocess.CalledProcessError as e:
+ if e.returncode == 128:
+ print("git v2.38+ is required for this functionality.", file=sys.stderr)
+ sys.exit(1)
+ else:
+ raise e
+
if current_tree != recreated_tree:
print("Merge commit {} is not clean".format(current_commit), file=sys.stderr)
subprocess.call([GIT, 'diff', recreated_tree, current_tree])
diff --git a/contrib/verifybinaries/README.md b/contrib/verifybinaries/README.md
deleted file mode 100644
index ab831eea28..0000000000
--- a/contrib/verifybinaries/README.md
+++ /dev/null
@@ -1,30 +0,0 @@
-### Verify Binaries
-
-#### Usage:
-
-This script attempts to download the signature file `SHA256SUMS.asc` from https://bitcoin.org.
-
-It first checks if the signature passes, and then downloads the files specified in the file, and checks if the hashes of these files match those that are specified in the signature file.
-
-The script returns 0 if everything passes the checks. It returns 1 if either the signature check or the hash check doesn't pass. If an error occurs the return value is 2.
-
-
-```sh
-./verify.py bitcoin-core-0.11.2
-./verify.py bitcoin-core-0.12.0
-./verify.py bitcoin-core-0.13.0-rc3
-```
-
-If you only want to download the binaries of certain platform, add the corresponding suffix, e.g.:
-
-```sh
-./verify.py bitcoin-core-0.11.2-osx
-./verify.py 0.12.0-linux
-./verify.py bitcoin-core-0.13.0-rc3-win64
-```
-
-If you do not want to keep the downloaded binaries, specify anything as the second parameter.
-
-```sh
-./verify.py bitcoin-core-0.13.0 delete
-```
diff --git a/contrib/verifybinaries/verify.py b/contrib/verifybinaries/verify.py
deleted file mode 100755
index b5e4f1318b..0000000000
--- a/contrib/verifybinaries/verify.py
+++ /dev/null
@@ -1,183 +0,0 @@
-#!/usr/bin/env python3
-# Copyright (c) 2020-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.
-"""Script for verifying Bitcoin Core release binaries
-
-This script attempts to download the signature file SHA256SUMS.asc from
-bitcoincore.org and bitcoin.org and compares them.
-It first checks if the signature passes, and then downloads the files
-specified in the file, and checks if the hashes of these files match those
-that are specified in the signature file.
-The script returns 0 if everything passes the checks. It returns 1 if either
-the signature check or the hash check doesn't pass. If an error occurs the
-return value is >= 2.
-"""
-from hashlib import sha256
-import os
-import subprocess
-import sys
-from textwrap import indent
-
-WORKINGDIR = "/tmp/bitcoin_verify_binaries"
-HASHFILE = "hashes.tmp"
-HOST1 = "https://bitcoincore.org"
-HOST2 = "https://bitcoin.org"
-VERSIONPREFIX = "bitcoin-core-"
-SIGNATUREFILENAME = "SHA256SUMS.asc"
-
-
-def parse_version_string(version_str):
- if version_str.startswith(VERSIONPREFIX): # remove version prefix
- version_str = version_str[len(VERSIONPREFIX):]
-
- parts = version_str.split('-')
- version_base = parts[0]
- version_rc = ""
- version_os = ""
- if len(parts) == 2: # "<version>-rcN" or "version-platform"
- if "rc" in parts[1]:
- version_rc = parts[1]
- else:
- version_os = parts[1]
- elif len(parts) == 3: # "<version>-rcN-platform"
- version_rc = parts[1]
- version_os = parts[2]
-
- return version_base, version_rc, version_os
-
-
-def download_with_wget(remote_file, local_file=None):
- if local_file:
- wget_args = ['wget', '-O', local_file, remote_file]
- else:
- # use timestamping mechanism if local filename is not explicitly set
- wget_args = ['wget', '-N', remote_file]
-
- result = subprocess.run(wget_args,
- stderr=subprocess.STDOUT, stdout=subprocess.PIPE)
- return result.returncode == 0, result.stdout.decode().rstrip()
-
-
-def files_are_equal(filename1, filename2):
- with open(filename1, 'rb') as file1:
- contents1 = file1.read()
- with open(filename2, 'rb') as file2:
- contents2 = file2.read()
- return contents1 == contents2
-
-
-def verify_with_gpg(signature_filename, output_filename):
- result = subprocess.run(['gpg', '--yes', '--decrypt', '--output',
- output_filename, signature_filename],
- stderr=subprocess.STDOUT, stdout=subprocess.PIPE)
- return result.returncode, result.stdout.decode().rstrip()
-
-
-def remove_files(filenames):
- for filename in filenames:
- os.remove(filename)
-
-
-def main(args):
- # sanity check
- if len(args) < 1:
- print("Error: need to specify a version on the command line")
- return 3
-
- # determine remote dir dependent on provided version string
- version_base, version_rc, os_filter = parse_version_string(args[0])
- remote_dir = f"/bin/{VERSIONPREFIX}{version_base}/"
- if version_rc:
- remote_dir += f"test.{version_rc}/"
- remote_sigfile = remote_dir + SIGNATUREFILENAME
-
- # create working directory
- os.makedirs(WORKINGDIR, exist_ok=True)
- os.chdir(WORKINGDIR)
-
- # fetch first signature file
- sigfile1 = SIGNATUREFILENAME
- success, output = download_with_wget(HOST1 + remote_sigfile, sigfile1)
- if not success:
- print("Error: couldn't fetch signature file. "
- "Have you specified the version number in the following format?")
- print(f"[{VERSIONPREFIX}]<version>[-rc[0-9]][-platform] "
- f"(example: {VERSIONPREFIX}0.21.0-rc3-osx)")
- print("wget output:")
- print(indent(output, '\t'))
- return 4
-
- # fetch second signature file
- sigfile2 = SIGNATUREFILENAME + ".2"
- success, output = download_with_wget(HOST2 + remote_sigfile, sigfile2)
- if not success:
- print("bitcoin.org failed to provide signature file, "
- "but bitcoincore.org did?")
- print("wget output:")
- print(indent(output, '\t'))
- remove_files([sigfile1])
- return 5
-
- # ensure that both signature files are equal
- if not files_are_equal(sigfile1, sigfile2):
- print("bitcoin.org and bitcoincore.org signature files were not equal?")
- print(f"See files {WORKINGDIR}/{sigfile1} and {WORKINGDIR}/{sigfile2}")
- return 6
-
- # check signature and extract data into file
- retval, output = verify_with_gpg(sigfile1, HASHFILE)
- if retval != 0:
- if retval == 1:
- print("Bad signature.")
- elif retval == 2:
- print("gpg error. Do you have the Bitcoin Core binary release "
- "signing key installed?")
- print("gpg output:")
- print(indent(output, '\t'))
- remove_files([sigfile1, sigfile2, HASHFILE])
- return 1
-
- # extract hashes/filenames of binaries to verify from hash file;
- # each line has the following format: "<hash> <binary_filename>"
- with open(HASHFILE, 'r', encoding='utf8') as hash_file:
- hashes_to_verify = [
- line.split()[:2] for line in hash_file if os_filter in line]
- remove_files([HASHFILE])
- if not hashes_to_verify:
- print("error: no files matched the platform specified")
- return 7
-
- # download binaries
- for _, binary_filename in hashes_to_verify:
- print(f"Downloading {binary_filename}")
- download_with_wget(HOST1 + remote_dir + binary_filename)
-
- # verify hashes
- offending_files = []
- for hash_expected, binary_filename in hashes_to_verify:
- with open(binary_filename, 'rb') as binary_file:
- hash_calculated = sha256(binary_file.read()).hexdigest()
- if hash_calculated != hash_expected:
- offending_files.append(binary_filename)
- if offending_files:
- print("Hashes don't match.")
- print("Offending files:")
- print('\n'.join(offending_files))
- return 1
- verified_binaries = [entry[1] for entry in hashes_to_verify]
-
- # clean up files if desired
- if len(args) >= 2:
- print("Clean up the binaries")
- remove_files([sigfile1, sigfile2] + verified_binaries)
- else:
- print(f"Keep the binaries in {WORKINGDIR}")
-
- print("Verified hashes of")
- print('\n'.join(verified_binaries))
- return 0
-
-
-if __name__ == '__main__':
- sys.exit(main(sys.argv[1:]))
diff --git a/depends/Makefile b/depends/Makefile
index 27bf804c6b..3169117633 100644
--- a/depends/Makefile
+++ b/depends/Makefile
@@ -45,6 +45,7 @@ NO_USDT ?=
NO_NATPMP ?=
MULTIPROCESS ?=
LTO ?=
+NO_HARDEN ?=
FALLBACK_DOWNLOAD_PATH ?= https://bitcoincore.org/depends-sources
C_STANDARD ?= c11
@@ -146,8 +147,8 @@ include packages/packages.mk
# 2. Before including packages/*.mk (excluding packages/packages.mk), since
# they rely on the build_id variables
#
-build_id:=$(shell env CC='$(build_CC)' C_STANDARD='$(C_STANDARD)' CXX='$(build_CXX)' CXX_STANDARD='$(CXX_STANDARD)' AR='$(build_AR)' RANLIB='$(build_RANLIB)' STRIP='$(build_STRIP)' SHA256SUM='$(build_SHA256SUM)' DEBUG='$(DEBUG)' LTO='$(LTO)' ./gen_id '$(BUILD_ID_SALT)' 'GUIX_ENVIRONMENT=$(realpath $(GUIX_ENVIRONMENT))')
-$(host_arch)_$(host_os)_id:=$(shell env CC='$(host_CC)' C_STANDARD='$(C_STANDARD)' CXX='$(host_CXX)' CXX_STANDARD='$(CXX_STANDARD)' AR='$(host_AR)' RANLIB='$(host_RANLIB)' STRIP='$(host_STRIP)' SHA256SUM='$(build_SHA256SUM)' DEBUG='$(DEBUG)' LTO='$(LTO)' ./gen_id '$(HOST_ID_SALT)' 'GUIX_ENVIRONMENT=$(realpath $(GUIX_ENVIRONMENT))')
+build_id:=$(shell env CC='$(build_CC)' C_STANDARD='$(C_STANDARD)' CXX='$(build_CXX)' CXX_STANDARD='$(CXX_STANDARD)' AR='$(build_AR)' RANLIB='$(build_RANLIB)' STRIP='$(build_STRIP)' SHA256SUM='$(build_SHA256SUM)' DEBUG='$(DEBUG)' LTO='$(LTO)' NO_HARDEN='$(NO_HARDEN)' ./gen_id '$(BUILD_ID_SALT)' 'GUIX_ENVIRONMENT=$(realpath $(GUIX_ENVIRONMENT))')
+$(host_arch)_$(host_os)_id:=$(shell env CC='$(host_CC)' C_STANDARD='$(C_STANDARD)' CXX='$(host_CXX)' CXX_STANDARD='$(CXX_STANDARD)' AR='$(host_AR)' RANLIB='$(host_RANLIB)' STRIP='$(host_STRIP)' SHA256SUM='$(build_SHA256SUM)' DEBUG='$(DEBUG)' LTO='$(LTO)' NO_HARDEN='$(NO_HARDEN)' ./gen_id '$(HOST_ID_SALT)' 'GUIX_ENVIRONMENT=$(realpath $(GUIX_ENVIRONMENT))')
boost_packages_$(NO_BOOST) = $(boost_packages)
@@ -253,6 +254,7 @@ $(host_prefix)/share/config.site : config.site.in $(host_prefix)/.stamp_$(final_
-e 's|@no_natpmp@|$(NO_NATPMP)|' \
-e 's|@multiprocess@|$(MULTIPROCESS)|' \
-e 's|@lto@|$(LTO)|' \
+ -e 's|@no_harden@|$(NO_HARDEN)|' \
-e 's|@debug@|$(DEBUG)|' \
$< > $@
touch $@
diff --git a/depends/README.md b/depends/README.md
index 11abbbd90d..1064b7d18a 100644
--- a/depends/README.md
+++ b/depends/README.md
@@ -107,7 +107,8 @@ The following can be set when running make: `make FOO=bar`
- `NO_BDB`: Don't download/build/cache BerkeleyDB
- `NO_SQLITE`: Don't download/build/cache SQLite
- `NO_UPNP`: Don't download/build/cache packages needed for enabling UPnP
-- `NO_NATPMP`: Don't download/build/cache packages needed for enabling NAT-PMP</dd>
+- `NO_NATPMP`: Don't download/build/cache packages needed for enabling NAT-PMP
+- `NO_USDT`: Don't download/build/cache packages needed for enabling USDT tracepoints
- `ALLOW_HOST_PACKAGES`: Packages that are missed in dependencies (due to `NO_*` option or
build script logic) are searched for among the host system packages using
`pkg-config`. It allows building with packages of other (newer) versions
@@ -122,6 +123,7 @@ The following can be set when running make: `make FOO=bar`
resides in the `depends` directory, and the log file is printed out automatically in case
of build error. After successful build log files are moved along with package archives
- `LTO`: Use LTO when building packages.
+- `NO_HARDEN=1`: Don't use hardening options when building packages
If some packages are not built, for example `make NO_WALLET=1`, the appropriate
options will be passed to bitcoin's configure. In this case, `--disable-wallet`.
diff --git a/depends/config.guess b/depends/config.guess
index dc0a6b2997..69188da73d 100755
--- a/depends/config.guess
+++ b/depends/config.guess
@@ -1,12 +1,14 @@
#! /bin/sh
# Attempt to guess a canonical system name.
-# Copyright 1992-2021 Free Software Foundation, Inc.
+# Copyright 1992-2023 Free Software Foundation, Inc.
-timestamp='2021-05-24'
+# shellcheck disable=SC2006,SC2268 # see below for rationale
+
+timestamp='2023-01-01'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
+# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
@@ -32,7 +34,15 @@ timestamp='2021-05-24'
# Please send patches to <config-patches@gnu.org>.
-me=$(echo "$0" | sed -e 's,.*/,,')
+# The "shellcheck disable" line above the timestamp inhibits complaints
+# about features and limitations of the classic Bourne shell that were
+# superseded or lifted in POSIX. However, this script identifies a wide
+# variety of pre-POSIX systems that do not have POSIX shells at all, and
+# even some reasonably current systems (Solaris 10 as case-in-point) still
+# have a pre-POSIX /bin/sh.
+
+
+me=`echo "$0" | sed -e 's,.*/,,'`
usage="\
Usage: $0 [OPTION]
@@ -50,7 +60,7 @@ version="\
GNU config.guess ($timestamp)
Originally written by Per Bothner.
-Copyright 1992-2021 Free Software Foundation, Inc.
+Copyright 1992-2023 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -84,6 +94,9 @@ if test $# != 0; then
exit 1
fi
+# Just in case it came from the environment.
+GUESS=
+
# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
# compiler to aid in system detection is discouraged as it requires
# temporary files to be created and, as you can see below, it is a
@@ -102,8 +115,8 @@ set_cc_for_build() {
# prevent multiple calls if $tmp is already set
test "$tmp" && return 0
: "${TMPDIR=/tmp}"
- # shellcheck disable=SC2039
- { tmp=$( (umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null) && test -n "$tmp" && test -d "$tmp" ; } ||
+ # shellcheck disable=SC2039,SC3028
+ { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
{ test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } ||
{ tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } ||
{ echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; }
@@ -112,7 +125,7 @@ set_cc_for_build() {
,,) echo "int x;" > "$dummy.c"
for driver in cc gcc c89 c99 ; do
if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then
- CC_FOR_BUILD="$driver"
+ CC_FOR_BUILD=$driver
break
fi
done
@@ -131,10 +144,10 @@ if test -f /.attbin/uname ; then
PATH=$PATH:/.attbin ; export PATH
fi
-UNAME_MACHINE=$( (uname -m) 2>/dev/null) || UNAME_MACHINE=unknown
-UNAME_RELEASE=$( (uname -r) 2>/dev/null) || UNAME_RELEASE=unknown
-UNAME_SYSTEM=$( (uname -s) 2>/dev/null) || UNAME_SYSTEM=unknown
-UNAME_VERSION=$( (uname -v) 2>/dev/null) || UNAME_VERSION=unknown
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
case $UNAME_SYSTEM in
Linux|GNU|GNU/*)
@@ -157,7 +170,8 @@ Linux|GNU|GNU/*)
#endif
#endif
EOF
- eval "$($CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g')"
+ cc_set_libc=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
+ eval "$cc_set_libc"
# Second heuristic to detect musl libc.
if [ "$LIBC" = unknown ] &&
@@ -188,10 +202,10 @@ case $UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION in
#
# Note: NetBSD doesn't particularly care about the vendor
# portion of the name. We always set it to "unknown".
- UNAME_MACHINE_ARCH=$( (uname -p 2>/dev/null || \
+ UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \
/sbin/sysctl -n hw.machine_arch 2>/dev/null || \
/usr/sbin/sysctl -n hw.machine_arch 2>/dev/null || \
- echo unknown))
+ echo unknown)`
case $UNAME_MACHINE_ARCH in
aarch64eb) machine=aarch64_be-unknown ;;
armeb) machine=armeb-unknown ;;
@@ -200,11 +214,11 @@ case $UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION in
sh3eb) machine=sh-unknown ;;
sh5el) machine=sh5le-unknown ;;
earmv*)
- arch=$(echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,')
- endian=$(echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p')
- machine="${arch}${endian}"-unknown
+ arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'`
+ endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'`
+ machine=${arch}${endian}-unknown
;;
- *) machine="$UNAME_MACHINE_ARCH"-unknown ;;
+ *) machine=$UNAME_MACHINE_ARCH-unknown ;;
esac
# The Operating System including object format, if it has switched
# to ELF recently (or will in the future) and ABI.
@@ -232,7 +246,7 @@ case $UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION in
case $UNAME_MACHINE_ARCH in
earm*)
expr='s/^earmv[0-9]/-eabi/;s/eb$//'
- abi=$(echo "$UNAME_MACHINE_ARCH" | sed -e "$expr")
+ abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"`
;;
esac
# The OS release
@@ -245,76 +259,76 @@ case $UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION in
release='-gnu'
;;
*)
- release=$(echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2)
+ release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2`
;;
esac
# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
# contains redundant information, the shorter form:
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
- echo "$machine-${os}${release}${abi-}"
- exit ;;
+ GUESS=$machine-${os}${release}${abi-}
+ ;;
*:Bitrig:*:*)
- UNAME_MACHINE_ARCH=$(arch | sed 's/Bitrig.//')
- echo "$UNAME_MACHINE_ARCH"-unknown-bitrig"$UNAME_RELEASE"
- exit ;;
+ UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
+ GUESS=$UNAME_MACHINE_ARCH-unknown-bitrig$UNAME_RELEASE
+ ;;
*:OpenBSD:*:*)
- UNAME_MACHINE_ARCH=$(arch | sed 's/OpenBSD.//')
- echo "$UNAME_MACHINE_ARCH"-unknown-openbsd"$UNAME_RELEASE"
- exit ;;
+ UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+ GUESS=$UNAME_MACHINE_ARCH-unknown-openbsd$UNAME_RELEASE
+ ;;
*:SecBSD:*:*)
- UNAME_MACHINE_ARCH=$(arch | sed 's/SecBSD.//')
- echo "$UNAME_MACHINE_ARCH"-unknown-secbsd"$UNAME_RELEASE"
- exit ;;
+ UNAME_MACHINE_ARCH=`arch | sed 's/SecBSD.//'`
+ GUESS=$UNAME_MACHINE_ARCH-unknown-secbsd$UNAME_RELEASE
+ ;;
*:LibertyBSD:*:*)
- UNAME_MACHINE_ARCH=$(arch | sed 's/^.*BSD\.//')
- echo "$UNAME_MACHINE_ARCH"-unknown-libertybsd"$UNAME_RELEASE"
- exit ;;
+ UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'`
+ GUESS=$UNAME_MACHINE_ARCH-unknown-libertybsd$UNAME_RELEASE
+ ;;
*:MidnightBSD:*:*)
- echo "$UNAME_MACHINE"-unknown-midnightbsd"$UNAME_RELEASE"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-midnightbsd$UNAME_RELEASE
+ ;;
*:ekkoBSD:*:*)
- echo "$UNAME_MACHINE"-unknown-ekkobsd"$UNAME_RELEASE"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-ekkobsd$UNAME_RELEASE
+ ;;
*:SolidBSD:*:*)
- echo "$UNAME_MACHINE"-unknown-solidbsd"$UNAME_RELEASE"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-solidbsd$UNAME_RELEASE
+ ;;
*:OS108:*:*)
- echo "$UNAME_MACHINE"-unknown-os108_"$UNAME_RELEASE"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-os108_$UNAME_RELEASE
+ ;;
macppc:MirBSD:*:*)
- echo powerpc-unknown-mirbsd"$UNAME_RELEASE"
- exit ;;
+ GUESS=powerpc-unknown-mirbsd$UNAME_RELEASE
+ ;;
*:MirBSD:*:*)
- echo "$UNAME_MACHINE"-unknown-mirbsd"$UNAME_RELEASE"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-mirbsd$UNAME_RELEASE
+ ;;
*:Sortix:*:*)
- echo "$UNAME_MACHINE"-unknown-sortix
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-sortix
+ ;;
*:Twizzler:*:*)
- echo "$UNAME_MACHINE"-unknown-twizzler
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-twizzler
+ ;;
*:Redox:*:*)
- echo "$UNAME_MACHINE"-unknown-redox
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-redox
+ ;;
mips:OSF1:*.*)
- echo mips-dec-osf1
- exit ;;
+ GUESS=mips-dec-osf1
+ ;;
alpha:OSF1:*:*)
# Reset EXIT trap before exiting to avoid spurious non-zero exit code.
trap '' 0
case $UNAME_RELEASE in
*4.0)
- UNAME_RELEASE=$(/usr/sbin/sizer -v | awk '{print $3}')
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
;;
*5.*)
- UNAME_RELEASE=$(/usr/sbin/sizer -v | awk '{print $4}')
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
;;
esac
# According to Compaq, /usr/sbin/psrinfo has been available on
# OSF/1 and Tru64 systems produced since 1995. I hope that
# covers most systems running today. This code pipes the CPU
# types through head -n 1, so we only detect the type of CPU 0.
- ALPHA_CPU_TYPE=$(/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1)
+ ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
case $ALPHA_CPU_TYPE in
"EV4 (21064)")
UNAME_MACHINE=alpha ;;
@@ -352,65 +366,69 @@ case $UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION in
# A Tn.n version is a released field test version.
# A Xn.n version is an unreleased experimental baselevel.
# 1.2 uses "1.2" for uname -r.
- echo "$UNAME_MACHINE"-dec-osf"$(echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz)"
- exit ;;
+ OSF_REL=`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
+ GUESS=$UNAME_MACHINE-dec-osf$OSF_REL
+ ;;
Amiga*:UNIX_System_V:4.0:*)
- echo m68k-unknown-sysv4
- exit ;;
+ GUESS=m68k-unknown-sysv4
+ ;;
*:[Aa]miga[Oo][Ss]:*:*)
- echo "$UNAME_MACHINE"-unknown-amigaos
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-amigaos
+ ;;
*:[Mm]orph[Oo][Ss]:*:*)
- echo "$UNAME_MACHINE"-unknown-morphos
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-morphos
+ ;;
*:OS/390:*:*)
- echo i370-ibm-openedition
- exit ;;
+ GUESS=i370-ibm-openedition
+ ;;
*:z/VM:*:*)
- echo s390-ibm-zvmoe
- exit ;;
+ GUESS=s390-ibm-zvmoe
+ ;;
*:OS400:*:*)
- echo powerpc-ibm-os400
- exit ;;
+ GUESS=powerpc-ibm-os400
+ ;;
arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
- echo arm-acorn-riscix"$UNAME_RELEASE"
- exit ;;
+ GUESS=arm-acorn-riscix$UNAME_RELEASE
+ ;;
arm*:riscos:*:*|arm*:RISCOS:*:*)
- echo arm-unknown-riscos
- exit ;;
+ GUESS=arm-unknown-riscos
+ ;;
SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
- echo hppa1.1-hitachi-hiuxmpp
- exit ;;
+ GUESS=hppa1.1-hitachi-hiuxmpp
+ ;;
Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
- if test "$( (/bin/universe) 2>/dev/null)" = att ; then
- echo pyramid-pyramid-sysv3
- else
- echo pyramid-pyramid-bsd
- fi
- exit ;;
+ case `(/bin/universe) 2>/dev/null` in
+ att) GUESS=pyramid-pyramid-sysv3 ;;
+ *) GUESS=pyramid-pyramid-bsd ;;
+ esac
+ ;;
NILE*:*:*:dcosx)
- echo pyramid-pyramid-svr4
- exit ;;
+ GUESS=pyramid-pyramid-svr4
+ ;;
DRS?6000:unix:4.0:6*)
- echo sparc-icl-nx6
- exit ;;
+ GUESS=sparc-icl-nx6
+ ;;
DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
- case $(/usr/bin/uname -p) in
- sparc) echo sparc-icl-nx7; exit ;;
- esac ;;
+ case `/usr/bin/uname -p` in
+ sparc) GUESS=sparc-icl-nx7 ;;
+ esac
+ ;;
s390x:SunOS:*:*)
- echo "$UNAME_MACHINE"-ibm-solaris2"$(echo "$UNAME_RELEASE" | sed -e 's/[^.]*//')"
- exit ;;
+ SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
+ GUESS=$UNAME_MACHINE-ibm-solaris2$SUN_REL
+ ;;
sun4H:SunOS:5.*:*)
- echo sparc-hal-solaris2"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')"
- exit ;;
+ SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
+ GUESS=sparc-hal-solaris2$SUN_REL
+ ;;
sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
- echo sparc-sun-solaris2"$(echo "$UNAME_RELEASE" | sed -e 's/[^.]*//')"
- exit ;;
+ SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
+ GUESS=sparc-sun-solaris2$SUN_REL
+ ;;
i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
- echo i386-pc-auroraux"$UNAME_RELEASE"
- exit ;;
+ GUESS=i386-pc-auroraux$UNAME_RELEASE
+ ;;
i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
set_cc_for_build
SUN_ARCH=i386
@@ -419,47 +437,50 @@ case $UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION in
# This test works for both compilers.
if test "$CC_FOR_BUILD" != no_compiler_found; then
if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
- (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
+ (CCOPTS="" $CC_FOR_BUILD -m64 -E - 2>/dev/null) | \
grep IS_64BIT_ARCH >/dev/null
then
SUN_ARCH=x86_64
fi
fi
- echo "$SUN_ARCH"-pc-solaris2"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')"
- exit ;;
+ SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
+ GUESS=$SUN_ARCH-pc-solaris2$SUN_REL
+ ;;
sun4*:SunOS:6*:*)
# According to config.sub, this is the proper way to canonicalize
# SunOS6. Hard to guess exactly what SunOS6 will be like, but
# it's likely to be more like Solaris than SunOS4.
- echo sparc-sun-solaris3"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')"
- exit ;;
+ SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
+ GUESS=sparc-sun-solaris3$SUN_REL
+ ;;
sun4*:SunOS:*:*)
- case $(/usr/bin/arch -k) in
+ case `/usr/bin/arch -k` in
Series*|S4*)
- UNAME_RELEASE=$(uname -v)
+ UNAME_RELEASE=`uname -v`
;;
esac
# Japanese Language versions have a version number like `4.1.3-JL'.
- echo sparc-sun-sunos"$(echo "$UNAME_RELEASE"|sed -e 's/-/_/')"
- exit ;;
+ SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/'`
+ GUESS=sparc-sun-sunos$SUN_REL
+ ;;
sun3*:SunOS:*:*)
- echo m68k-sun-sunos"$UNAME_RELEASE"
- exit ;;
+ GUESS=m68k-sun-sunos$UNAME_RELEASE
+ ;;
sun*:*:4.2BSD:*)
- UNAME_RELEASE=$( (sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null)
+ UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3
- case $(/bin/arch) in
+ case `/bin/arch` in
sun3)
- echo m68k-sun-sunos"$UNAME_RELEASE"
+ GUESS=m68k-sun-sunos$UNAME_RELEASE
;;
sun4)
- echo sparc-sun-sunos"$UNAME_RELEASE"
+ GUESS=sparc-sun-sunos$UNAME_RELEASE
;;
esac
- exit ;;
+ ;;
aushp:SunOS:*:*)
- echo sparc-auspex-sunos"$UNAME_RELEASE"
- exit ;;
+ GUESS=sparc-auspex-sunos$UNAME_RELEASE
+ ;;
# The situation for MiNT is a little confusing. The machine name
# can be virtually everything (everything which is not
# "atarist" or "atariste" at least should have a processor
@@ -469,41 +490,41 @@ case $UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION in
# MiNT. But MiNT is downward compatible to TOS, so this should
# be no problem.
atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
- echo m68k-atari-mint"$UNAME_RELEASE"
- exit ;;
+ GUESS=m68k-atari-mint$UNAME_RELEASE
+ ;;
atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
- echo m68k-atari-mint"$UNAME_RELEASE"
- exit ;;
+ GUESS=m68k-atari-mint$UNAME_RELEASE
+ ;;
*falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
- echo m68k-atari-mint"$UNAME_RELEASE"
- exit ;;
+ GUESS=m68k-atari-mint$UNAME_RELEASE
+ ;;
milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
- echo m68k-milan-mint"$UNAME_RELEASE"
- exit ;;
+ GUESS=m68k-milan-mint$UNAME_RELEASE
+ ;;
hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
- echo m68k-hades-mint"$UNAME_RELEASE"
- exit ;;
+ GUESS=m68k-hades-mint$UNAME_RELEASE
+ ;;
*:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
- echo m68k-unknown-mint"$UNAME_RELEASE"
- exit ;;
+ GUESS=m68k-unknown-mint$UNAME_RELEASE
+ ;;
m68k:machten:*:*)
- echo m68k-apple-machten"$UNAME_RELEASE"
- exit ;;
+ GUESS=m68k-apple-machten$UNAME_RELEASE
+ ;;
powerpc:machten:*:*)
- echo powerpc-apple-machten"$UNAME_RELEASE"
- exit ;;
+ GUESS=powerpc-apple-machten$UNAME_RELEASE
+ ;;
RISC*:Mach:*:*)
- echo mips-dec-mach_bsd4.3
- exit ;;
+ GUESS=mips-dec-mach_bsd4.3
+ ;;
RISC*:ULTRIX:*:*)
- echo mips-dec-ultrix"$UNAME_RELEASE"
- exit ;;
+ GUESS=mips-dec-ultrix$UNAME_RELEASE
+ ;;
VAX*:ULTRIX*:*:*)
- echo vax-dec-ultrix"$UNAME_RELEASE"
- exit ;;
+ GUESS=vax-dec-ultrix$UNAME_RELEASE
+ ;;
2020:CLIX:*:* | 2430:CLIX:*:*)
- echo clipper-intergraph-clix"$UNAME_RELEASE"
- exit ;;
+ GUESS=clipper-intergraph-clix$UNAME_RELEASE
+ ;;
mips:*:*:UMIPS | mips:*:*:RISCos)
set_cc_for_build
sed 's/^ //' << EOF > "$dummy.c"
@@ -528,78 +549,79 @@ case $UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION in
}
EOF
$CC_FOR_BUILD -o "$dummy" "$dummy.c" &&
- dummyarg=$(echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p') &&
- SYSTEM_NAME=$("$dummy" "$dummyarg") &&
+ dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+ SYSTEM_NAME=`"$dummy" "$dummyarg"` &&
{ echo "$SYSTEM_NAME"; exit; }
- echo mips-mips-riscos"$UNAME_RELEASE"
- exit ;;
+ GUESS=mips-mips-riscos$UNAME_RELEASE
+ ;;
Motorola:PowerMAX_OS:*:*)
- echo powerpc-motorola-powermax
- exit ;;
+ GUESS=powerpc-motorola-powermax
+ ;;
Motorola:*:4.3:PL8-*)
- echo powerpc-harris-powermax
- exit ;;
+ GUESS=powerpc-harris-powermax
+ ;;
Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
- echo powerpc-harris-powermax
- exit ;;
+ GUESS=powerpc-harris-powermax
+ ;;
Night_Hawk:Power_UNIX:*:*)
- echo powerpc-harris-powerunix
- exit ;;
+ GUESS=powerpc-harris-powerunix
+ ;;
m88k:CX/UX:7*:*)
- echo m88k-harris-cxux7
- exit ;;
+ GUESS=m88k-harris-cxux7
+ ;;
m88k:*:4*:R4*)
- echo m88k-motorola-sysv4
- exit ;;
+ GUESS=m88k-motorola-sysv4
+ ;;
m88k:*:3*:R3*)
- echo m88k-motorola-sysv3
- exit ;;
+ GUESS=m88k-motorola-sysv3
+ ;;
AViiON:dgux:*:*)
# DG/UX returns AViiON for all architectures
- UNAME_PROCESSOR=$(/usr/bin/uname -p)
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
if test "$UNAME_PROCESSOR" = mc88100 || test "$UNAME_PROCESSOR" = mc88110
then
if test "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx || \
test "$TARGET_BINARY_INTERFACE"x = x
then
- echo m88k-dg-dgux"$UNAME_RELEASE"
+ GUESS=m88k-dg-dgux$UNAME_RELEASE
else
- echo m88k-dg-dguxbcs"$UNAME_RELEASE"
+ GUESS=m88k-dg-dguxbcs$UNAME_RELEASE
fi
else
- echo i586-dg-dgux"$UNAME_RELEASE"
+ GUESS=i586-dg-dgux$UNAME_RELEASE
fi
- exit ;;
+ ;;
M88*:DolphinOS:*:*) # DolphinOS (SVR3)
- echo m88k-dolphin-sysv3
- exit ;;
+ GUESS=m88k-dolphin-sysv3
+ ;;
M88*:*:R3*:*)
# Delta 88k system running SVR3
- echo m88k-motorola-sysv3
- exit ;;
+ GUESS=m88k-motorola-sysv3
+ ;;
XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
- echo m88k-tektronix-sysv3
- exit ;;
+ GUESS=m88k-tektronix-sysv3
+ ;;
Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
- echo m68k-tektronix-bsd
- exit ;;
+ GUESS=m68k-tektronix-bsd
+ ;;
*:IRIX*:*:*)
- echo mips-sgi-irix"$(echo "$UNAME_RELEASE"|sed -e 's/-/_/g')"
- exit ;;
+ IRIX_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/g'`
+ GUESS=mips-sgi-irix$IRIX_REL
+ ;;
????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
- echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
- exit ;; # Note that: echo "'$(uname -s)'" gives 'AIX '
+ GUESS=romp-ibm-aix # uname -m gives an 8 hex-code CPU id
+ ;; # Note that: echo "'`uname -s`'" gives 'AIX '
i*86:AIX:*:*)
- echo i386-ibm-aix
- exit ;;
+ GUESS=i386-ibm-aix
+ ;;
ia64:AIX:*:*)
if test -x /usr/bin/oslevel ; then
- IBM_REV=$(/usr/bin/oslevel)
+ IBM_REV=`/usr/bin/oslevel`
else
- IBM_REV="$UNAME_VERSION.$UNAME_RELEASE"
+ IBM_REV=$UNAME_VERSION.$UNAME_RELEASE
fi
- echo "$UNAME_MACHINE"-ibm-aix"$IBM_REV"
- exit ;;
+ GUESS=$UNAME_MACHINE-ibm-aix$IBM_REV
+ ;;
*:AIX:2:3)
if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
set_cc_for_build
@@ -614,63 +636,63 @@ EOF
exit(0);
}
EOF
- if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=$("$dummy")
+ if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"`
then
- echo "$SYSTEM_NAME"
+ GUESS=$SYSTEM_NAME
else
- echo rs6000-ibm-aix3.2.5
+ GUESS=rs6000-ibm-aix3.2.5
fi
elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
- echo rs6000-ibm-aix3.2.4
+ GUESS=rs6000-ibm-aix3.2.4
else
- echo rs6000-ibm-aix3.2
+ GUESS=rs6000-ibm-aix3.2
fi
- exit ;;
+ ;;
*:AIX:*:[4567])
- IBM_CPU_ID=$(/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }')
+ IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then
IBM_ARCH=rs6000
else
IBM_ARCH=powerpc
fi
if test -x /usr/bin/lslpp ; then
- IBM_REV=$(/usr/bin/lslpp -Lqc bos.rte.libc |
- awk -F: '{ print $3 }' | sed s/[0-9]*$/0/)
+ IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | \
+ awk -F: '{ print $3 }' | sed s/[0-9]*$/0/`
else
- IBM_REV="$UNAME_VERSION.$UNAME_RELEASE"
+ IBM_REV=$UNAME_VERSION.$UNAME_RELEASE
fi
- echo "$IBM_ARCH"-ibm-aix"$IBM_REV"
- exit ;;
+ GUESS=$IBM_ARCH-ibm-aix$IBM_REV
+ ;;
*:AIX:*:*)
- echo rs6000-ibm-aix
- exit ;;
+ GUESS=rs6000-ibm-aix
+ ;;
ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*)
- echo romp-ibm-bsd4.4
- exit ;;
+ GUESS=romp-ibm-bsd4.4
+ ;;
ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
- echo romp-ibm-bsd"$UNAME_RELEASE" # 4.3 with uname added to
- exit ;; # report: romp-ibm BSD 4.3
+ GUESS=romp-ibm-bsd$UNAME_RELEASE # 4.3 with uname added to
+ ;; # report: romp-ibm BSD 4.3
*:BOSX:*:*)
- echo rs6000-bull-bosx
- exit ;;
+ GUESS=rs6000-bull-bosx
+ ;;
DPX/2?00:B.O.S.:*:*)
- echo m68k-bull-sysv3
- exit ;;
+ GUESS=m68k-bull-sysv3
+ ;;
9000/[34]??:4.3bsd:1.*:*)
- echo m68k-hp-bsd
- exit ;;
+ GUESS=m68k-hp-bsd
+ ;;
hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
- echo m68k-hp-bsd4.4
- exit ;;
+ GUESS=m68k-hp-bsd4.4
+ ;;
9000/[34678]??:HP-UX:*:*)
- HPUX_REV=$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//')
+ HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'`
case $UNAME_MACHINE in
9000/31?) HP_ARCH=m68000 ;;
9000/[34]??) HP_ARCH=m68k ;;
9000/[678][0-9][0-9])
if test -x /usr/bin/getconf; then
- sc_cpu_version=$(/usr/bin/getconf SC_CPU_VERSION 2>/dev/null)
- sc_kernel_bits=$(/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null)
+ sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+ sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
case $sc_cpu_version in
523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0
528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1
@@ -717,7 +739,7 @@ EOF
exit (0);
}
EOF
- (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=$("$dummy")
+ (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"`
test -z "$HP_ARCH" && HP_ARCH=hppa
fi ;;
esac
@@ -742,12 +764,12 @@ EOF
HP_ARCH=hppa64
fi
fi
- echo "$HP_ARCH"-hp-hpux"$HPUX_REV"
- exit ;;
+ GUESS=$HP_ARCH-hp-hpux$HPUX_REV
+ ;;
ia64:HP-UX:*:*)
- HPUX_REV=$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//')
- echo ia64-hp-hpux"$HPUX_REV"
- exit ;;
+ HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'`
+ GUESS=ia64-hp-hpux$HPUX_REV
+ ;;
3050*:HI-UX:*:*)
set_cc_for_build
sed 's/^ //' << EOF > "$dummy.c"
@@ -775,38 +797,38 @@ EOF
exit (0);
}
EOF
- $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=$("$dummy") &&
+ $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` &&
{ echo "$SYSTEM_NAME"; exit; }
- echo unknown-hitachi-hiuxwe2
- exit ;;
+ GUESS=unknown-hitachi-hiuxwe2
+ ;;
9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*)
- echo hppa1.1-hp-bsd
- exit ;;
+ GUESS=hppa1.1-hp-bsd
+ ;;
9000/8??:4.3bsd:*:*)
- echo hppa1.0-hp-bsd
- exit ;;
+ GUESS=hppa1.0-hp-bsd
+ ;;
*9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
- echo hppa1.0-hp-mpeix
- exit ;;
+ GUESS=hppa1.0-hp-mpeix
+ ;;
hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*)
- echo hppa1.1-hp-osf
- exit ;;
+ GUESS=hppa1.1-hp-osf
+ ;;
hp8??:OSF1:*:*)
- echo hppa1.0-hp-osf
- exit ;;
+ GUESS=hppa1.0-hp-osf
+ ;;
i*86:OSF1:*:*)
if test -x /usr/sbin/sysversion ; then
- echo "$UNAME_MACHINE"-unknown-osf1mk
+ GUESS=$UNAME_MACHINE-unknown-osf1mk
else
- echo "$UNAME_MACHINE"-unknown-osf1
+ GUESS=$UNAME_MACHINE-unknown-osf1
fi
- exit ;;
+ ;;
parisc*:Lites*:*:*)
- echo hppa1.1-hp-lites
- exit ;;
+ GUESS=hppa1.1-hp-lites
+ ;;
C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
- echo c1-convex-bsd
- exit ;;
+ GUESS=c1-convex-bsd
+ ;;
C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
if getsysinfo -f scalar_acc
then echo c32-convex-bsd
@@ -814,17 +836,18 @@ EOF
fi
exit ;;
C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
- echo c34-convex-bsd
- exit ;;
+ GUESS=c34-convex-bsd
+ ;;
C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
- echo c38-convex-bsd
- exit ;;
+ GUESS=c38-convex-bsd
+ ;;
C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
- echo c4-convex-bsd
- exit ;;
+ GUESS=c4-convex-bsd
+ ;;
CRAY*Y-MP:*:*:*)
- echo ymp-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
- exit ;;
+ CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`
+ GUESS=ymp-cray-unicos$CRAY_REL
+ ;;
CRAY*[A-Z]90:*:*:*)
echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \
| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
@@ -832,114 +855,135 @@ EOF
-e 's/\.[^.]*$/.X/'
exit ;;
CRAY*TS:*:*:*)
- echo t90-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
- exit ;;
+ CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`
+ GUESS=t90-cray-unicos$CRAY_REL
+ ;;
CRAY*T3E:*:*:*)
- echo alphaev5-cray-unicosmk"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
- exit ;;
+ CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`
+ GUESS=alphaev5-cray-unicosmk$CRAY_REL
+ ;;
CRAY*SV1:*:*:*)
- echo sv1-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
- exit ;;
+ CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`
+ GUESS=sv1-cray-unicos$CRAY_REL
+ ;;
*:UNICOS/mp:*:*)
- echo craynv-cray-unicosmp"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
- exit ;;
+ CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`
+ GUESS=craynv-cray-unicosmp$CRAY_REL
+ ;;
F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
- FUJITSU_PROC=$(uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz)
- FUJITSU_SYS=$(uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///')
- FUJITSU_REL=$(echo "$UNAME_RELEASE" | sed -e 's/ /_/')
- echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
- exit ;;
+ FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
+ FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
+ FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'`
+ GUESS=${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}
+ ;;
5000:UNIX_System_V:4.*:*)
- FUJITSU_SYS=$(uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///')
- FUJITSU_REL=$(echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/')
- echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
- exit ;;
+ FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
+ FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'`
+ GUESS=sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}
+ ;;
i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
- echo "$UNAME_MACHINE"-pc-bsdi"$UNAME_RELEASE"
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-bsdi$UNAME_RELEASE
+ ;;
sparc*:BSD/OS:*:*)
- echo sparc-unknown-bsdi"$UNAME_RELEASE"
- exit ;;
+ GUESS=sparc-unknown-bsdi$UNAME_RELEASE
+ ;;
*:BSD/OS:*:*)
- echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-bsdi$UNAME_RELEASE
+ ;;
arm:FreeBSD:*:*)
- UNAME_PROCESSOR=$(uname -p)
+ UNAME_PROCESSOR=`uname -p`
set_cc_for_build
if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ARM_PCS_VFP
then
- echo "${UNAME_PROCESSOR}"-unknown-freebsd"$(echo ${UNAME_RELEASE}|sed -e 's/[-(].*//')"-gnueabi
+ FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
+ GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabi
else
- echo "${UNAME_PROCESSOR}"-unknown-freebsd"$(echo ${UNAME_RELEASE}|sed -e 's/[-(].*//')"-gnueabihf
+ FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
+ GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabihf
fi
- exit ;;
+ ;;
*:FreeBSD:*:*)
- UNAME_PROCESSOR=$(/usr/bin/uname -p)
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
case $UNAME_PROCESSOR in
amd64)
UNAME_PROCESSOR=x86_64 ;;
i386)
UNAME_PROCESSOR=i586 ;;
esac
- echo "$UNAME_PROCESSOR"-unknown-freebsd"$(echo "$UNAME_RELEASE"|sed -e 's/[-(].*//')"
- exit ;;
+ FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
+ GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL
+ ;;
i*:CYGWIN*:*)
- echo "$UNAME_MACHINE"-pc-cygwin
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-cygwin
+ ;;
*:MINGW64*:*)
- echo "$UNAME_MACHINE"-pc-mingw64
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-mingw64
+ ;;
*:MINGW*:*)
- echo "$UNAME_MACHINE"-pc-mingw32
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-mingw32
+ ;;
*:MSYS*:*)
- echo "$UNAME_MACHINE"-pc-msys
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-msys
+ ;;
i*:PW*:*)
- echo "$UNAME_MACHINE"-pc-pw32
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-pw32
+ ;;
+ *:SerenityOS:*:*)
+ GUESS=$UNAME_MACHINE-pc-serenity
+ ;;
*:Interix*:*)
case $UNAME_MACHINE in
x86)
- echo i586-pc-interix"$UNAME_RELEASE"
- exit ;;
+ GUESS=i586-pc-interix$UNAME_RELEASE
+ ;;
authenticamd | genuineintel | EM64T)
- echo x86_64-unknown-interix"$UNAME_RELEASE"
- exit ;;
+ GUESS=x86_64-unknown-interix$UNAME_RELEASE
+ ;;
IA64)
- echo ia64-unknown-interix"$UNAME_RELEASE"
- exit ;;
+ GUESS=ia64-unknown-interix$UNAME_RELEASE
+ ;;
esac ;;
i*:UWIN*:*)
- echo "$UNAME_MACHINE"-pc-uwin
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-uwin
+ ;;
amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
- echo x86_64-pc-cygwin
- exit ;;
+ GUESS=x86_64-pc-cygwin
+ ;;
prep*:SunOS:5.*:*)
- echo powerpcle-unknown-solaris2"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')"
- exit ;;
+ SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
+ GUESS=powerpcle-unknown-solaris2$SUN_REL
+ ;;
*:GNU:*:*)
# the GNU system
- echo "$(echo "$UNAME_MACHINE"|sed -e 's,[-/].*$,,')-unknown-$LIBC$(echo "$UNAME_RELEASE"|sed -e 's,/.*$,,')"
- exit ;;
+ GNU_ARCH=`echo "$UNAME_MACHINE" | sed -e 's,[-/].*$,,'`
+ GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's,/.*$,,'`
+ GUESS=$GNU_ARCH-unknown-$LIBC$GNU_REL
+ ;;
*:GNU/*:*:*)
# other systems with GNU libc and userland
- echo "$UNAME_MACHINE-unknown-$(echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]")$(echo "$UNAME_RELEASE"|sed -e 's/[-(].*//')-$LIBC"
- exit ;;
+ GNU_SYS=`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"`
+ GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
+ GUESS=$UNAME_MACHINE-unknown-$GNU_SYS$GNU_REL-$LIBC
+ ;;
+ x86_64:[Mm]anagarm:*:*|i?86:[Mm]anagarm:*:*)
+ GUESS="$UNAME_MACHINE-pc-managarm-mlibc"
+ ;;
+ *:[Mm]anagarm:*:*)
+ GUESS="$UNAME_MACHINE-unknown-managarm-mlibc"
+ ;;
*:Minix:*:*)
- echo "$UNAME_MACHINE"-unknown-minix
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-minix
+ ;;
aarch64:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
aarch64_be:Linux:*:*)
UNAME_MACHINE=aarch64_be
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
alpha:Linux:*:*)
- case $(sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null) in
+ case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null` in
EV5) UNAME_MACHINE=alphaev5 ;;
EV56) UNAME_MACHINE=alphaev56 ;;
PCA56) UNAME_MACHINE=alphapca56 ;;
@@ -950,63 +994,63 @@ EOF
esac
objdump --private-headers /bin/sh | grep -q ld.so.1
if test "$?" = 0 ; then LIBC=gnulibc1 ; fi
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
- arc:Linux:*:* | arceb:Linux:*:* | arc64:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
+ arc:Linux:*:* | arceb:Linux:*:* | arc32:Linux:*:* | arc64:Linux:*:*)
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
arm*:Linux:*:*)
set_cc_for_build
if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ARM_EABI__
then
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
else
if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ARM_PCS_VFP
then
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabi
+ GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabi
else
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabihf
+ GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabihf
fi
fi
- exit ;;
+ ;;
avr32*:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
cris:Linux:*:*)
- echo "$UNAME_MACHINE"-axis-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-axis-linux-$LIBC
+ ;;
crisv32:Linux:*:*)
- echo "$UNAME_MACHINE"-axis-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-axis-linux-$LIBC
+ ;;
e2k:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
frv:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
hexagon:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
i*86:Linux:*:*)
- echo "$UNAME_MACHINE"-pc-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-linux-$LIBC
+ ;;
ia64:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
k1om:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
- loongarch32:Linux:*:* | loongarch64:Linux:*:* | loongarchx32:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
+ loongarch32:Linux:*:* | loongarch64:Linux:*:*)
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
m32r*:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
m68*:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
mips:Linux:*:* | mips64:Linux:*:*)
set_cc_for_build
IS_GLIBC=0
@@ -1051,138 +1095,150 @@ EOF
#endif
#endif
EOF
- eval "$($CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI')"
+ cc_set_vars=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI'`
+ eval "$cc_set_vars"
test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; }
;;
mips64el:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
openrisc*:Linux:*:*)
- echo or1k-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=or1k-unknown-linux-$LIBC
+ ;;
or32:Linux:*:* | or1k*:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
padre:Linux:*:*)
- echo sparc-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=sparc-unknown-linux-$LIBC
+ ;;
parisc64:Linux:*:* | hppa64:Linux:*:*)
- echo hppa64-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=hppa64-unknown-linux-$LIBC
+ ;;
parisc:Linux:*:* | hppa:Linux:*:*)
# Look for CPU level
- case $(grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2) in
- PA7*) echo hppa1.1-unknown-linux-"$LIBC" ;;
- PA8*) echo hppa2.0-unknown-linux-"$LIBC" ;;
- *) echo hppa-unknown-linux-"$LIBC" ;;
+ case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+ PA7*) GUESS=hppa1.1-unknown-linux-$LIBC ;;
+ PA8*) GUESS=hppa2.0-unknown-linux-$LIBC ;;
+ *) GUESS=hppa-unknown-linux-$LIBC ;;
esac
- exit ;;
+ ;;
ppc64:Linux:*:*)
- echo powerpc64-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=powerpc64-unknown-linux-$LIBC
+ ;;
ppc:Linux:*:*)
- echo powerpc-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=powerpc-unknown-linux-$LIBC
+ ;;
ppc64le:Linux:*:*)
- echo powerpc64le-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=powerpc64le-unknown-linux-$LIBC
+ ;;
ppcle:Linux:*:*)
- echo powerpcle-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=powerpcle-unknown-linux-$LIBC
+ ;;
riscv32:Linux:*:* | riscv32be:Linux:*:* | riscv64:Linux:*:* | riscv64be:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
s390:Linux:*:* | s390x:Linux:*:*)
- echo "$UNAME_MACHINE"-ibm-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-ibm-linux-$LIBC
+ ;;
sh64*:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
sh*:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
sparc:Linux:*:* | sparc64:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
tile*:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
vax:Linux:*:*)
- echo "$UNAME_MACHINE"-dec-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-dec-linux-$LIBC
+ ;;
x86_64:Linux:*:*)
set_cc_for_build
+ CPU=$UNAME_MACHINE
LIBCABI=$LIBC
if test "$CC_FOR_BUILD" != no_compiler_found; then
- if (echo '#ifdef __ILP32__'; echo IS_X32; echo '#endif') | \
- (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
- grep IS_X32 >/dev/null
- then
- LIBCABI="$LIBC"x32
- fi
+ ABI=64
+ sed 's/^ //' << EOF > "$dummy.c"
+ #ifdef __i386__
+ ABI=x86
+ #else
+ #ifdef __ILP32__
+ ABI=x32
+ #endif
+ #endif
+EOF
+ cc_set_abi=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^ABI' | sed 's, ,,g'`
+ eval "$cc_set_abi"
+ case $ABI in
+ x86) CPU=i686 ;;
+ x32) LIBCABI=${LIBC}x32 ;;
+ esac
fi
- echo "$UNAME_MACHINE"-pc-linux-"$LIBCABI"
- exit ;;
+ GUESS=$CPU-pc-linux-$LIBCABI
+ ;;
xtensa*:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
i*86:DYNIX/ptx:4*:*)
# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
# earlier versions are messed up and put the nodename in both
# sysname and nodename.
- echo i386-sequent-sysv4
- exit ;;
+ GUESS=i386-sequent-sysv4
+ ;;
i*86:UNIX_SV:4.2MP:2.*)
# Unixware is an offshoot of SVR4, but it has its own version
# number series starting with 2...
# I am not positive that other SVR4 systems won't match this,
# I just have to hope. -- rms.
# Use sysv4.2uw... so that sysv4* matches it.
- echo "$UNAME_MACHINE"-pc-sysv4.2uw"$UNAME_VERSION"
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-sysv4.2uw$UNAME_VERSION
+ ;;
i*86:OS/2:*:*)
# If we were able to find `uname', then EMX Unix compatibility
# is probably installed.
- echo "$UNAME_MACHINE"-pc-os2-emx
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-os2-emx
+ ;;
i*86:XTS-300:*:STOP)
- echo "$UNAME_MACHINE"-unknown-stop
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-stop
+ ;;
i*86:atheos:*:*)
- echo "$UNAME_MACHINE"-unknown-atheos
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-atheos
+ ;;
i*86:syllable:*:*)
- echo "$UNAME_MACHINE"-pc-syllable
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-syllable
+ ;;
i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
- echo i386-unknown-lynxos"$UNAME_RELEASE"
- exit ;;
+ GUESS=i386-unknown-lynxos$UNAME_RELEASE
+ ;;
i*86:*DOS:*:*)
- echo "$UNAME_MACHINE"-pc-msdosdjgpp
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-msdosdjgpp
+ ;;
i*86:*:4.*:*)
- UNAME_REL=$(echo "$UNAME_RELEASE" | sed 's/\/MP$//')
+ UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'`
if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
- echo "$UNAME_MACHINE"-univel-sysv"$UNAME_REL"
+ GUESS=$UNAME_MACHINE-univel-sysv$UNAME_REL
else
- echo "$UNAME_MACHINE"-pc-sysv"$UNAME_REL"
+ GUESS=$UNAME_MACHINE-pc-sysv$UNAME_REL
fi
- exit ;;
+ ;;
i*86:*:5:[678]*)
# UnixWare 7.x, OpenUNIX and OpenServer 6.
- case $(/bin/uname -X | grep "^Machine") in
+ case `/bin/uname -X | grep "^Machine"` in
*486*) UNAME_MACHINE=i486 ;;
*Pentium) UNAME_MACHINE=i586 ;;
*Pent*|*Celeron) UNAME_MACHINE=i686 ;;
esac
- echo "$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+ ;;
i*86:*:3.2:*)
if test -f /usr/options/cb.name; then
- UNAME_REL=$(sed -n 's/.*Version //p' </usr/options/cb.name)
- echo "$UNAME_MACHINE"-pc-isc"$UNAME_REL"
+ UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+ GUESS=$UNAME_MACHINE-pc-isc$UNAME_REL
elif /bin/uname -X 2>/dev/null >/dev/null ; then
- UNAME_REL=$( (/bin/uname -X|grep Release|sed -e 's/.*= //'))
+ UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
&& UNAME_MACHINE=i586
@@ -1190,11 +1246,11 @@ EOF
&& UNAME_MACHINE=i686
(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
&& UNAME_MACHINE=i686
- echo "$UNAME_MACHINE"-pc-sco"$UNAME_REL"
+ GUESS=$UNAME_MACHINE-pc-sco$UNAME_REL
else
- echo "$UNAME_MACHINE"-pc-sysv32
+ GUESS=$UNAME_MACHINE-pc-sysv32
fi
- exit ;;
+ ;;
pc:*:*:*)
# Left here for compatibility:
# uname -m prints for DJGPP always 'pc', but it prints nothing about
@@ -1202,37 +1258,37 @@ EOF
# Note: whatever this is, it MUST be the same as what config.sub
# prints for the "djgpp" host, or else GDB configure will decide that
# this is a cross-build.
- echo i586-pc-msdosdjgpp
- exit ;;
+ GUESS=i586-pc-msdosdjgpp
+ ;;
Intel:Mach:3*:*)
- echo i386-pc-mach3
- exit ;;
+ GUESS=i386-pc-mach3
+ ;;
paragon:*:*:*)
- echo i860-intel-osf1
- exit ;;
+ GUESS=i860-intel-osf1
+ ;;
i860:*:4.*:*) # i860-SVR4
if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
- echo i860-stardent-sysv"$UNAME_RELEASE" # Stardent Vistra i860-SVR4
+ GUESS=i860-stardent-sysv$UNAME_RELEASE # Stardent Vistra i860-SVR4
else # Add other i860-SVR4 vendors below as they are discovered.
- echo i860-unknown-sysv"$UNAME_RELEASE" # Unknown i860-SVR4
+ GUESS=i860-unknown-sysv$UNAME_RELEASE # Unknown i860-SVR4
fi
- exit ;;
+ ;;
mini*:CTIX:SYS*5:*)
# "miniframe"
- echo m68010-convergent-sysv
- exit ;;
+ GUESS=m68010-convergent-sysv
+ ;;
mc68k:UNIX:SYSTEM5:3.51m)
- echo m68k-convergent-sysv
- exit ;;
+ GUESS=m68k-convergent-sysv
+ ;;
M680?0:D-NIX:5.3:*)
- echo m68k-diab-dnix
- exit ;;
+ GUESS=m68k-diab-dnix
+ ;;
M68*:*:R3V[5678]*:*)
test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
OS_REL=''
test -r /etc/.relid \
- && OS_REL=.$(sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid)
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& { echo i486-ncr-sysv4.3"$OS_REL"; exit; }
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
@@ -1243,7 +1299,7 @@ EOF
NCR*:*:4.2:* | MPRAS*:*:4.2:*)
OS_REL='.3'
test -r /etc/.relid \
- && OS_REL=.$(sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid)
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& { echo i486-ncr-sysv4.3"$OS_REL"; exit; }
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
@@ -1251,118 +1307,121 @@ EOF
/bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
&& { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;;
m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
- echo m68k-unknown-lynxos"$UNAME_RELEASE"
- exit ;;
+ GUESS=m68k-unknown-lynxos$UNAME_RELEASE
+ ;;
mc68030:UNIX_System_V:4.*:*)
- echo m68k-atari-sysv4
- exit ;;
+ GUESS=m68k-atari-sysv4
+ ;;
TSUNAMI:LynxOS:2.*:*)
- echo sparc-unknown-lynxos"$UNAME_RELEASE"
- exit ;;
+ GUESS=sparc-unknown-lynxos$UNAME_RELEASE
+ ;;
rs6000:LynxOS:2.*:*)
- echo rs6000-unknown-lynxos"$UNAME_RELEASE"
- exit ;;
+ GUESS=rs6000-unknown-lynxos$UNAME_RELEASE
+ ;;
PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
- echo powerpc-unknown-lynxos"$UNAME_RELEASE"
- exit ;;
+ GUESS=powerpc-unknown-lynxos$UNAME_RELEASE
+ ;;
SM[BE]S:UNIX_SV:*:*)
- echo mips-dde-sysv"$UNAME_RELEASE"
- exit ;;
+ GUESS=mips-dde-sysv$UNAME_RELEASE
+ ;;
RM*:ReliantUNIX-*:*:*)
- echo mips-sni-sysv4
- exit ;;
+ GUESS=mips-sni-sysv4
+ ;;
RM*:SINIX-*:*:*)
- echo mips-sni-sysv4
- exit ;;
+ GUESS=mips-sni-sysv4
+ ;;
*:SINIX-*:*:*)
if uname -p 2>/dev/null >/dev/null ; then
- UNAME_MACHINE=$( (uname -p) 2>/dev/null)
- echo "$UNAME_MACHINE"-sni-sysv4
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ GUESS=$UNAME_MACHINE-sni-sysv4
else
- echo ns32k-sni-sysv
+ GUESS=ns32k-sni-sysv
fi
- exit ;;
+ ;;
PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
# says <Richard.M.Bartel@ccMail.Census.GOV>
- echo i586-unisys-sysv4
- exit ;;
+ GUESS=i586-unisys-sysv4
+ ;;
*:UNIX_System_V:4*:FTX*)
# From Gerald Hewes <hewes@openmarket.com>.
# How about differentiating between stratus architectures? -djm
- echo hppa1.1-stratus-sysv4
- exit ;;
+ GUESS=hppa1.1-stratus-sysv4
+ ;;
*:*:*:FTX*)
# From seanf@swdc.stratus.com.
- echo i860-stratus-sysv4
- exit ;;
+ GUESS=i860-stratus-sysv4
+ ;;
i*86:VOS:*:*)
# From Paul.Green@stratus.com.
- echo "$UNAME_MACHINE"-stratus-vos
- exit ;;
+ GUESS=$UNAME_MACHINE-stratus-vos
+ ;;
*:VOS:*:*)
# From Paul.Green@stratus.com.
- echo hppa1.1-stratus-vos
- exit ;;
+ GUESS=hppa1.1-stratus-vos
+ ;;
mc68*:A/UX:*:*)
- echo m68k-apple-aux"$UNAME_RELEASE"
- exit ;;
+ GUESS=m68k-apple-aux$UNAME_RELEASE
+ ;;
news*:NEWS-OS:6*:*)
- echo mips-sony-newsos6
- exit ;;
+ GUESS=mips-sony-newsos6
+ ;;
R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
if test -d /usr/nec; then
- echo mips-nec-sysv"$UNAME_RELEASE"
+ GUESS=mips-nec-sysv$UNAME_RELEASE
else
- echo mips-unknown-sysv"$UNAME_RELEASE"
+ GUESS=mips-unknown-sysv$UNAME_RELEASE
fi
- exit ;;
+ ;;
BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
- echo powerpc-be-beos
- exit ;;
+ GUESS=powerpc-be-beos
+ ;;
BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
- echo powerpc-apple-beos
- exit ;;
+ GUESS=powerpc-apple-beos
+ ;;
BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
- echo i586-pc-beos
- exit ;;
+ GUESS=i586-pc-beos
+ ;;
BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
- echo i586-pc-haiku
- exit ;;
- x86_64:Haiku:*:*)
- echo x86_64-unknown-haiku
- exit ;;
+ GUESS=i586-pc-haiku
+ ;;
+ ppc:Haiku:*:*) # Haiku running on Apple PowerPC
+ GUESS=powerpc-apple-haiku
+ ;;
+ *:Haiku:*:*) # Haiku modern gcc (not bound by BeOS compat)
+ GUESS=$UNAME_MACHINE-unknown-haiku
+ ;;
SX-4:SUPER-UX:*:*)
- echo sx4-nec-superux"$UNAME_RELEASE"
- exit ;;
+ GUESS=sx4-nec-superux$UNAME_RELEASE
+ ;;
SX-5:SUPER-UX:*:*)
- echo sx5-nec-superux"$UNAME_RELEASE"
- exit ;;
+ GUESS=sx5-nec-superux$UNAME_RELEASE
+ ;;
SX-6:SUPER-UX:*:*)
- echo sx6-nec-superux"$UNAME_RELEASE"
- exit ;;
+ GUESS=sx6-nec-superux$UNAME_RELEASE
+ ;;
SX-7:SUPER-UX:*:*)
- echo sx7-nec-superux"$UNAME_RELEASE"
- exit ;;
+ GUESS=sx7-nec-superux$UNAME_RELEASE
+ ;;
SX-8:SUPER-UX:*:*)
- echo sx8-nec-superux"$UNAME_RELEASE"
- exit ;;
+ GUESS=sx8-nec-superux$UNAME_RELEASE
+ ;;
SX-8R:SUPER-UX:*:*)
- echo sx8r-nec-superux"$UNAME_RELEASE"
- exit ;;
+ GUESS=sx8r-nec-superux$UNAME_RELEASE
+ ;;
SX-ACE:SUPER-UX:*:*)
- echo sxace-nec-superux"$UNAME_RELEASE"
- exit ;;
+ GUESS=sxace-nec-superux$UNAME_RELEASE
+ ;;
Power*:Rhapsody:*:*)
- echo powerpc-apple-rhapsody"$UNAME_RELEASE"
- exit ;;
+ GUESS=powerpc-apple-rhapsody$UNAME_RELEASE
+ ;;
*:Rhapsody:*:*)
- echo "$UNAME_MACHINE"-apple-rhapsody"$UNAME_RELEASE"
- exit ;;
+ GUESS=$UNAME_MACHINE-apple-rhapsody$UNAME_RELEASE
+ ;;
arm64:Darwin:*:*)
- echo aarch64-apple-darwin"$UNAME_RELEASE"
- exit ;;
+ GUESS=aarch64-apple-darwin$UNAME_RELEASE
+ ;;
*:Darwin:*:*)
- UNAME_PROCESSOR=$(uname -p)
+ UNAME_PROCESSOR=`uname -p`
case $UNAME_PROCESSOR in
unknown) UNAME_PROCESSOR=powerpc ;;
esac
@@ -1396,43 +1455,43 @@ EOF
# uname -m returns i386 or x86_64
UNAME_PROCESSOR=$UNAME_MACHINE
fi
- echo "$UNAME_PROCESSOR"-apple-darwin"$UNAME_RELEASE"
- exit ;;
+ GUESS=$UNAME_PROCESSOR-apple-darwin$UNAME_RELEASE
+ ;;
*:procnto*:*:* | *:QNX:[0123456789]*:*)
- UNAME_PROCESSOR=$(uname -p)
+ UNAME_PROCESSOR=`uname -p`
if test "$UNAME_PROCESSOR" = x86; then
UNAME_PROCESSOR=i386
UNAME_MACHINE=pc
fi
- echo "$UNAME_PROCESSOR"-"$UNAME_MACHINE"-nto-qnx"$UNAME_RELEASE"
- exit ;;
+ GUESS=$UNAME_PROCESSOR-$UNAME_MACHINE-nto-qnx$UNAME_RELEASE
+ ;;
*:QNX:*:4*)
- echo i386-pc-qnx
- exit ;;
+ GUESS=i386-pc-qnx
+ ;;
NEO-*:NONSTOP_KERNEL:*:*)
- echo neo-tandem-nsk"$UNAME_RELEASE"
- exit ;;
+ GUESS=neo-tandem-nsk$UNAME_RELEASE
+ ;;
NSE-*:NONSTOP_KERNEL:*:*)
- echo nse-tandem-nsk"$UNAME_RELEASE"
- exit ;;
+ GUESS=nse-tandem-nsk$UNAME_RELEASE
+ ;;
NSR-*:NONSTOP_KERNEL:*:*)
- echo nsr-tandem-nsk"$UNAME_RELEASE"
- exit ;;
+ GUESS=nsr-tandem-nsk$UNAME_RELEASE
+ ;;
NSV-*:NONSTOP_KERNEL:*:*)
- echo nsv-tandem-nsk"$UNAME_RELEASE"
- exit ;;
+ GUESS=nsv-tandem-nsk$UNAME_RELEASE
+ ;;
NSX-*:NONSTOP_KERNEL:*:*)
- echo nsx-tandem-nsk"$UNAME_RELEASE"
- exit ;;
+ GUESS=nsx-tandem-nsk$UNAME_RELEASE
+ ;;
*:NonStop-UX:*:*)
- echo mips-compaq-nonstopux
- exit ;;
+ GUESS=mips-compaq-nonstopux
+ ;;
BS2000:POSIX*:*:*)
- echo bs2000-siemens-sysv
- exit ;;
+ GUESS=bs2000-siemens-sysv
+ ;;
DS/*:UNIX_System_V:*:*)
- echo "$UNAME_MACHINE"-"$UNAME_SYSTEM"-"$UNAME_RELEASE"
- exit ;;
+ GUESS=$UNAME_MACHINE-$UNAME_SYSTEM-$UNAME_RELEASE
+ ;;
*:Plan9:*:*)
# "uname -m" is not consistent, so use $cputype instead. 386
# is converted to i386 for consistency with other x86
@@ -1440,64 +1499,75 @@ EOF
if test "${cputype-}" = 386; then
UNAME_MACHINE=i386
elif test "x${cputype-}" != x; then
- UNAME_MACHINE="$cputype"
+ UNAME_MACHINE=$cputype
fi
- echo "$UNAME_MACHINE"-unknown-plan9
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-plan9
+ ;;
*:TOPS-10:*:*)
- echo pdp10-unknown-tops10
- exit ;;
+ GUESS=pdp10-unknown-tops10
+ ;;
*:TENEX:*:*)
- echo pdp10-unknown-tenex
- exit ;;
+ GUESS=pdp10-unknown-tenex
+ ;;
KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
- echo pdp10-dec-tops20
- exit ;;
+ GUESS=pdp10-dec-tops20
+ ;;
XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
- echo pdp10-xkl-tops20
- exit ;;
+ GUESS=pdp10-xkl-tops20
+ ;;
*:TOPS-20:*:*)
- echo pdp10-unknown-tops20
- exit ;;
+ GUESS=pdp10-unknown-tops20
+ ;;
*:ITS:*:*)
- echo pdp10-unknown-its
- exit ;;
+ GUESS=pdp10-unknown-its
+ ;;
SEI:*:*:SEIUX)
- echo mips-sei-seiux"$UNAME_RELEASE"
- exit ;;
+ GUESS=mips-sei-seiux$UNAME_RELEASE
+ ;;
*:DragonFly:*:*)
- echo "$UNAME_MACHINE"-unknown-dragonfly"$(echo "$UNAME_RELEASE"|sed -e 's/[-(].*//')"
- exit ;;
+ DRAGONFLY_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
+ GUESS=$UNAME_MACHINE-unknown-dragonfly$DRAGONFLY_REL
+ ;;
*:*VMS:*:*)
- UNAME_MACHINE=$( (uname -p) 2>/dev/null)
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
case $UNAME_MACHINE in
- A*) echo alpha-dec-vms ; exit ;;
- I*) echo ia64-dec-vms ; exit ;;
- V*) echo vax-dec-vms ; exit ;;
+ A*) GUESS=alpha-dec-vms ;;
+ I*) GUESS=ia64-dec-vms ;;
+ V*) GUESS=vax-dec-vms ;;
esac ;;
*:XENIX:*:SysV)
- echo i386-pc-xenix
- exit ;;
+ GUESS=i386-pc-xenix
+ ;;
i*86:skyos:*:*)
- echo "$UNAME_MACHINE"-pc-skyos"$(echo "$UNAME_RELEASE" | sed -e 's/ .*$//')"
- exit ;;
+ SKYOS_REL=`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'`
+ GUESS=$UNAME_MACHINE-pc-skyos$SKYOS_REL
+ ;;
i*86:rdos:*:*)
- echo "$UNAME_MACHINE"-pc-rdos
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-rdos
+ ;;
+ i*86:Fiwix:*:*)
+ GUESS=$UNAME_MACHINE-pc-fiwix
+ ;;
*:AROS:*:*)
- echo "$UNAME_MACHINE"-unknown-aros
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-aros
+ ;;
x86_64:VMkernel:*:*)
- echo "$UNAME_MACHINE"-unknown-esx
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-esx
+ ;;
amd64:Isilon\ OneFS:*:*)
- echo x86_64-unknown-onefs
- exit ;;
+ GUESS=x86_64-unknown-onefs
+ ;;
*:Unleashed:*:*)
- echo "$UNAME_MACHINE"-unknown-unleashed"$UNAME_RELEASE"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-unleashed$UNAME_RELEASE
+ ;;
esac
+# Do we have a guess based on uname results?
+if test "x$GUESS" != x; then
+ echo "$GUESS"
+ exit
+fi
+
# No uname command or uname output not recognized.
set_cc_for_build
cat > "$dummy.c" <<EOF
@@ -1537,7 +1607,7 @@ main ()
#define __ARCHITECTURE__ "m68k"
#endif
int version;
- version=$( (hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null);
+ version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
if (version < 4)
printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
else
@@ -1629,7 +1699,7 @@ main ()
}
EOF
-$CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=$($dummy) &&
+$CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=`"$dummy"` &&
{ echo "$SYSTEM_NAME"; exit; }
# Apollos put the system type in the environment.
@@ -1659,9 +1729,11 @@ and
https://git.savannah.gnu.org/cgit/config.git/plain/config.sub
EOF
-year=$(echo $timestamp | sed 's,-.*,,')
+our_year=`echo $timestamp | sed 's,-.*,,'`
+thisyear=`date +%Y`
# shellcheck disable=SC2003
-if test "$(expr "$(date +%Y)" - "$year")" -lt 3 ; then
+script_age=`expr "$thisyear" - "$our_year"`
+if test "$script_age" -lt 3 ; then
cat >&2 <<EOF
If $0 has already been updated, send the following data and any
@@ -1670,20 +1742,20 @@ provide the necessary information to handle your system.
config.guess timestamp = $timestamp
-uname -m = $( (uname -m) 2>/dev/null || echo unknown)
-uname -r = $( (uname -r) 2>/dev/null || echo unknown)
-uname -s = $( (uname -s) 2>/dev/null || echo unknown)
-uname -v = $( (uname -v) 2>/dev/null || echo unknown)
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
-/usr/bin/uname -p = $( (/usr/bin/uname -p) 2>/dev/null)
-/bin/uname -X = $( (/bin/uname -X) 2>/dev/null)
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null`
-hostinfo = $( (hostinfo) 2>/dev/null)
-/bin/universe = $( (/bin/universe) 2>/dev/null)
-/usr/bin/arch -k = $( (/usr/bin/arch -k) 2>/dev/null)
-/bin/arch = $( (/bin/arch) 2>/dev/null)
-/usr/bin/oslevel = $( (/usr/bin/oslevel) 2>/dev/null)
-/usr/convex/getsysinfo = $( (/usr/convex/getsysinfo) 2>/dev/null)
+hostinfo = `(hostinfo) 2>/dev/null`
+/bin/universe = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
UNAME_MACHINE = "$UNAME_MACHINE"
UNAME_RELEASE = "$UNAME_RELEASE"
diff --git a/depends/config.site.in b/depends/config.site.in
index 8f6849214d..05c2ccbac1 100644
--- a/depends/config.site.in
+++ b/depends/config.site.in
@@ -82,6 +82,10 @@ if test -z "$enable_lto" && test -n "@lto@"; then
enable_lto=yes
fi
+if test -z "$enable_hardening" && test -n "@no_harden@"; then
+ enable_hardening=no
+fi
+
PKG_CONFIG="$(which pkg-config) --static"
PKG_CONFIG_PATH="${depends_prefix}/share/pkgconfig:${depends_prefix}/lib/pkgconfig"
diff --git a/depends/config.sub b/depends/config.sub
index 7384e9198b..de4259e404 100755
--- a/depends/config.sub
+++ b/depends/config.sub
@@ -1,12 +1,14 @@
#! /bin/sh
# Configuration validation subroutine script.
-# Copyright 1992-2021 Free Software Foundation, Inc.
+# Copyright 1992-2023 Free Software Foundation, Inc.
-timestamp='2021-04-30'
+# shellcheck disable=SC2006,SC2268 # see below for rationale
+
+timestamp='2023-01-21'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
+# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
@@ -50,7 +52,14 @@ timestamp='2021-04-30'
# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
# It is wrong to echo any other type of specification.
-me=$(echo "$0" | sed -e 's,.*/,,')
+# The "shellcheck disable" line above the timestamp inhibits complaints
+# about features and limitations of the classic Bourne shell that were
+# superseded or lifted in POSIX. However, this script identifies a wide
+# variety of pre-POSIX systems that do not have POSIX shells at all, and
+# even some reasonably current systems (Solaris 10 as case-in-point) still
+# have a pre-POSIX /bin/sh.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
usage="\
Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS
@@ -67,7 +76,7 @@ Report bugs and patches to <config-patches@gnu.org>."
version="\
GNU config.sub ($timestamp)
-Copyright 1992-2021 Free Software Foundation, Inc.
+Copyright 1992-2023 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -112,9 +121,11 @@ esac
# Split fields of configuration type
# shellcheck disable=SC2162
+saved_IFS=$IFS
IFS="-" read field1 field2 field3 field4 <<EOF
$1
EOF
+IFS=$saved_IFS
# Separate into logical components for further validation
case $1 in
@@ -134,7 +145,7 @@ case $1 in
nto-qnx* | linux-* | uclinux-uclibc* \
| uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \
| netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \
- | storm-chaos* | os2-emx* | rtmk-nova*)
+ | storm-chaos* | os2-emx* | rtmk-nova* | managarm-*)
basic_machine=$field1
basic_os=$maybe_os
;;
@@ -163,6 +174,10 @@ case $1 in
basic_machine=$field1
basic_os=$field2
;;
+ zephyr*)
+ basic_machine=$field1-unknown
+ basic_os=$field2
+ ;;
# Manufacturers
dec* | mips* | sequent* | encore* | pc533* | sgi* | sony* \
| att* | 7300* | 3300* | delta* | motorola* | sun[234]* \
@@ -769,22 +784,22 @@ case $basic_machine in
vendor=hp
;;
i*86v32)
- cpu=$(echo "$1" | sed -e 's/86.*/86/')
+ cpu=`echo "$1" | sed -e 's/86.*/86/'`
vendor=pc
basic_os=sysv32
;;
i*86v4*)
- cpu=$(echo "$1" | sed -e 's/86.*/86/')
+ cpu=`echo "$1" | sed -e 's/86.*/86/'`
vendor=pc
basic_os=sysv4
;;
i*86v)
- cpu=$(echo "$1" | sed -e 's/86.*/86/')
+ cpu=`echo "$1" | sed -e 's/86.*/86/'`
vendor=pc
basic_os=sysv
;;
i*86sol2)
- cpu=$(echo "$1" | sed -e 's/86.*/86/')
+ cpu=`echo "$1" | sed -e 's/86.*/86/'`
vendor=pc
basic_os=solaris2
;;
@@ -917,14 +932,16 @@ case $basic_machine in
;;
leon-*|leon[3-9]-*)
cpu=sparc
- vendor=$(echo "$basic_machine" | sed 's/-.*//')
+ vendor=`echo "$basic_machine" | sed 's/-.*//'`
;;
*-*)
# shellcheck disable=SC2162
+ saved_IFS=$IFS
IFS="-" read cpu vendor <<EOF
$basic_machine
EOF
+ IFS=$saved_IFS
;;
# We use `pc' rather than `unknown'
# because (1) that's what they normally are, and
@@ -1003,6 +1020,11 @@ case $cpu-$vendor in
;;
# Here we normalize CPU types with a missing or matching vendor
+ armh-unknown | armh-alt)
+ cpu=armv7l
+ vendor=alt
+ basic_os=${basic_os:-linux-gnueabihf}
+ ;;
dpx20-unknown | dpx20-bull)
cpu=rs6000
vendor=bull
@@ -1053,7 +1075,7 @@ case $cpu-$vendor in
pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
cpu=i586
;;
- pentiumpro-* | p6-* | 6x86-* | athlon-* | athalon_*-*)
+ pentiumpro-* | p6-* | 6x86-* | athlon-* | athlon_*-*)
cpu=i686
;;
pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
@@ -1084,7 +1106,7 @@ case $cpu-$vendor in
cpu=mipsisa64sb1el
;;
sh5e[lb]-*)
- cpu=$(echo "$cpu" | sed 's/^\(sh.\)e\(.\)$/\1\2e/')
+ cpu=`echo "$cpu" | sed 's/^\(sh.\)e\(.\)$/\1\2e/'`
;;
spur-*)
cpu=spur
@@ -1102,9 +1124,9 @@ case $cpu-$vendor in
cpu=x86_64
;;
xscale-* | xscalee[bl]-*)
- cpu=$(echo "$cpu" | sed 's/^xscale/arm/')
+ cpu=`echo "$cpu" | sed 's/^xscale/arm/'`
;;
- arm64-*)
+ arm64-* | aarch64le-*)
cpu=aarch64
;;
@@ -1165,7 +1187,7 @@ case $cpu-$vendor in
| alphapca5[67] | alpha64pca5[67] \
| am33_2.0 \
| amdgcn \
- | arc | arceb | arc64 \
+ | arc | arceb | arc32 | arc64 \
| arm | arm[lb]e | arme[lb] | armv* \
| avr | avr32 \
| asmjs \
@@ -1185,7 +1207,7 @@ case $cpu-$vendor in
| k1om \
| le32 | le64 \
| lm32 \
- | loongarch32 | loongarch64 | loongarchx32 \
+ | loongarch32 | loongarch64 \
| m32c | m32r | m32rle \
| m5200 | m68000 | m680[012346]0 | m68360 | m683?2 | m68k \
| m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x \
@@ -1287,35 +1309,41 @@ esac
if test x$basic_os != x
then
-# First recognize some ad-hoc caes, or perhaps split kernel-os, or else just
+# First recognize some ad-hoc cases, or perhaps split kernel-os, or else just
# set os.
case $basic_os in
gnu/linux*)
kernel=linux
- os=$(echo $basic_os | sed -e 's|gnu/linux|gnu|')
+ os=`echo "$basic_os" | sed -e 's|gnu/linux|gnu|'`
;;
os2-emx)
kernel=os2
- os=$(echo $basic_os | sed -e 's|os2-emx|emx|')
+ os=`echo "$basic_os" | sed -e 's|os2-emx|emx|'`
;;
nto-qnx*)
kernel=nto
- os=$(echo $basic_os | sed -e 's|nto-qnx|qnx|')
+ os=`echo "$basic_os" | sed -e 's|nto-qnx|qnx|'`
;;
*-*)
# shellcheck disable=SC2162
+ saved_IFS=$IFS
IFS="-" read kernel os <<EOF
$basic_os
EOF
+ IFS=$saved_IFS
;;
# Default OS when just kernel was specified
nto*)
kernel=nto
- os=$(echo $basic_os | sed -e 's|nto|qnx|')
+ os=`echo "$basic_os" | sed -e 's|nto|qnx|'`
;;
linux*)
kernel=linux
- os=$(echo $basic_os | sed -e 's|linux|gnu|')
+ os=`echo "$basic_os" | sed -e 's|linux|gnu|'`
+ ;;
+ managarm*)
+ kernel=managarm
+ os=`echo "$basic_os" | sed -e 's|managarm|mlibc|'`
;;
*)
kernel=
@@ -1336,7 +1364,7 @@ case $os in
os=cnk
;;
solaris1 | solaris1.*)
- os=$(echo $os | sed -e 's|solaris1|sunos4|')
+ os=`echo "$os" | sed -e 's|solaris1|sunos4|'`
;;
solaris)
os=solaris2
@@ -1365,7 +1393,7 @@ case $os in
os=sco3.2v4
;;
sco3.2.[4-9]*)
- os=$(echo $os | sed -e 's/sco3.2./sco3.2v/')
+ os=`echo "$os" | sed -e 's/sco3.2./sco3.2v/'`
;;
sco*v* | scout)
# Don't match below
@@ -1395,7 +1423,7 @@ case $os in
os=lynxos
;;
mac[0-9]*)
- os=$(echo "$os" | sed -e 's|mac|macos|')
+ os=`echo "$os" | sed -e 's|mac|macos|'`
;;
opened*)
os=openedition
@@ -1404,10 +1432,10 @@ case $os in
os=os400
;;
sunos5*)
- os=$(echo "$os" | sed -e 's|sunos5|solaris2|')
+ os=`echo "$os" | sed -e 's|sunos5|solaris2|'`
;;
sunos6*)
- os=$(echo "$os" | sed -e 's|sunos6|solaris3|')
+ os=`echo "$os" | sed -e 's|sunos6|solaris3|'`
;;
wince*)
os=wince
@@ -1441,7 +1469,7 @@ case $os in
;;
# Preserve the version number of sinix5.
sinix5.*)
- os=$(echo $os | sed -e 's|sinix|sysv|')
+ os=`echo "$os" | sed -e 's|sinix|sysv|'`
;;
sinix*)
os=sysv4
@@ -1688,7 +1716,7 @@ fi
# Now, validate our (potentially fixed-up) OS.
case $os in
# Sometimes we do "kernel-libc", so those need to count as OSes.
- musl* | newlib* | uclibc*)
+ musl* | newlib* | relibc* | uclibc*)
;;
# Likewise for "kernel-abi"
eabi* | gnueabi*)
@@ -1729,7 +1757,8 @@ case $os in
| skyos* | haiku* | rdos* | toppers* | drops* | es* \
| onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \
| midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \
- | nsk* | powerunix* | genode* | zvmoe* | qnx* | emx*)
+ | nsk* | powerunix* | genode* | zvmoe* | qnx* | emx* | zephyr* \
+ | fiwix* | mlibc* )
;;
# This one is extra strict with allowed versions
sco3.2v2 | sco3.2v[4-9]* | sco5v6*)
@@ -1737,6 +1766,9 @@ case $os in
;;
none)
;;
+ kernel* )
+ # Restricted further below
+ ;;
*)
echo Invalid configuration \`"$1"\': OS \`"$os"\' not recognized 1>&2
exit 1
@@ -1746,16 +1778,27 @@ esac
# As a final step for OS-related things, validate the OS-kernel combination
# (given a valid OS), if there is a kernel.
case $kernel-$os in
- linux-gnu* | linux-dietlibc* | linux-android* | linux-newlib* | linux-musl* | linux-uclibc* )
+ linux-gnu* | linux-dietlibc* | linux-android* | linux-newlib* \
+ | linux-musl* | linux-relibc* | linux-uclibc* | linux-mlibc* )
;;
uclinux-uclibc* )
;;
- -dietlibc* | -newlib* | -musl* | -uclibc* )
+ managarm-mlibc* | managarm-kernel* )
+ ;;
+ -dietlibc* | -newlib* | -musl* | -relibc* | -uclibc* | -mlibc* )
# These are just libc implementations, not actual OSes, and thus
# require a kernel.
echo "Invalid configuration \`$1': libc \`$os' needs explicit kernel." 1>&2
exit 1
;;
+ -kernel* )
+ echo "Invalid configuration \`$1': \`$os' needs explicit kernel." 1>&2
+ exit 1
+ ;;
+ *-kernel* )
+ echo "Invalid configuration \`$1': \`$kernel' does not support \`$os'." 1>&2
+ exit 1
+ ;;
kfreebsd*-gnu* | kopensolaris*-gnu*)
;;
vxworks-simlinux | vxworks-simwindows | vxworks-spe)
diff --git a/depends/funcs.mk b/depends/funcs.mk
index f0bbf4a168..987be4e611 100644
--- a/depends/funcs.mk
+++ b/depends/funcs.mk
@@ -176,7 +176,7 @@ $(1)_cmake=env CC="$$($(1)_cc)" \
CXX="$$($(1)_cxx)" \
CXXFLAGS="$$($(1)_cppflags) $$($(1)_cxxflags)" \
LDFLAGS="$$($(1)_ldflags)" \
- cmake -DCMAKE_INSTALL_PREFIX:PATH="$$($($(1)_type)_prefix)" $$($(1)_cmake_opts)
+ cmake -DCMAKE_INSTALL_PREFIX:PATH="$$($($(1)_type)_prefix)" $$($(1)_config_opts)
ifeq ($($(1)_type),build)
$(1)_cmake += -DCMAKE_INSTALL_RPATH:PATH="$$($($(1)_type)_prefix)/lib"
else
diff --git a/depends/gen_id b/depends/gen_id
index 7caf8d764d..3341310e46 100755
--- a/depends/gen_id
+++ b/depends/gen_id
@@ -2,7 +2,7 @@
# Usage: env [ CC=... ] [ C_STANDARD=...] [ CXX=... ] [CXX_STANDARD=...] \
# [ AR=... ] [ RANLIB=... ] [ STRIP=... ] [ DEBUG=... ] \
-# [ LTO=... ] ./build-id [ID_SALT]...
+# [ LTO=... ] [ NO_HARDEN=... ] ./build-id [ID_SALT]...
#
# Prints to stdout a SHA256 hash representing the current toolset, used by
# depends/Makefile as a build id for caching purposes (detecting when the
@@ -70,6 +70,10 @@
echo "LTO=${LTO}"
echo "END LTO"
+ echo "BEGIN NO_HARDEN"
+ echo "NO_HARDEN=${NO_HARDEN}"
+ echo "END NO_HARDEN"
+
echo "END ALL"
) | if [ -n "$DEBUG" ] && command -v tee > /dev/null 2>&1; then
# When debugging and `tee` is available, output the preimage to stderr
diff --git a/depends/hosts/darwin.mk b/depends/hosts/darwin.mk
index 8fcea35d98..522a6b17ef 100644
--- a/depends/hosts/darwin.mk
+++ b/depends/hosts/darwin.mk
@@ -99,8 +99,8 @@ darwin_CC=env -u C_INCLUDE_PATH -u CPLUS_INCLUDE_PATH \
$(clang_prog) --target=$(host) -mmacosx-version-min=$(OSX_MIN_VERSION) \
-B$(build_prefix)/bin -mlinker-version=$(LD64_VERSION) \
-isysroot$(OSX_SDK) \
- -Xclang -internal-externc-isystem$(clang_resource_dir)/include \
- -Xclang -internal-externc-isystem$(OSX_SDK)/usr/include
+ -Xclang -internal-externc-isystem -Xclang $(clang_resource_dir)/include \
+ -Xclang -internal-externc-isystem -Xclang $(OSX_SDK)/usr/include
darwin_CXX=env -u C_INCLUDE_PATH -u CPLUS_INCLUDE_PATH \
-u OBJC_INCLUDE_PATH -u OBJCPLUS_INCLUDE_PATH -u CPATH \
-u LIBRARY_PATH \
@@ -109,8 +109,8 @@ darwin_CXX=env -u C_INCLUDE_PATH -u CPLUS_INCLUDE_PATH \
-isysroot$(OSX_SDK) \
-stdlib=libc++ \
-stdlib++-isystem$(OSX_SDK)/usr/include/c++/v1 \
- -Xclang -internal-externc-isystem$(clang_resource_dir)/include \
- -Xclang -internal-externc-isystem$(OSX_SDK)/usr/include
+ -Xclang -internal-externc-isystem -Xclang $(clang_resource_dir)/include \
+ -Xclang -internal-externc-isystem -Xclang $(OSX_SDK)/usr/include
darwin_CFLAGS=-pipe -std=$(C_STANDARD)
darwin_CXXFLAGS=-pipe -std=$(CXX_STANDARD)
diff --git a/depends/hosts/linux.mk b/depends/hosts/linux.mk
index 635d3d16da..0e2496174e 100644
--- a/depends/hosts/linux.mk
+++ b/depends/hosts/linux.mk
@@ -17,7 +17,7 @@ linux_release_CXXFLAGS=$(linux_release_CFLAGS)
linux_debug_CFLAGS=-O1
linux_debug_CXXFLAGS=$(linux_debug_CFLAGS)
-linux_debug_CPPFLAGS=-D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC -D_LIBCPP_DEBUG=1
+linux_debug_CPPFLAGS=-D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC -D_LIBCPP_ENABLE_ASSERTIONS=1
ifeq (86,$(findstring 86,$(build_arch)))
i686_linux_CC=gcc -m32
diff --git a/depends/packages/bdb.mk b/depends/packages/bdb.mk
index d607336059..9f5a925015 100644
--- a/depends/packages/bdb.mk
+++ b/depends/packages/bdb.mk
@@ -14,7 +14,7 @@ $(package)_config_opts_freebsd=--with-pic
$(package)_config_opts_netbsd=--with-pic
$(package)_config_opts_openbsd=--with-pic
$(package)_config_opts_android=--with-pic
-$(package)_cflags+=-Wno-error=implicit-function-declaration -Wno-error=format-security
+$(package)_cflags+=-Wno-error=implicit-function-declaration -Wno-error=format-security -Wno-error=implicit-int
$(package)_cppflags_freebsd=-D_XOPEN_SOURCE=600 -D__BSD_VISIBLE=1
$(package)_cppflags_netbsd=-D_XOPEN_SOURCE=600
$(package)_cppflags_openbsd=-D_XOPEN_SOURCE=600
diff --git a/depends/packages/fontconfig.mk b/depends/packages/fontconfig.mk
index c8b2fc33d5..444acfe36d 100644
--- a/depends/packages/fontconfig.mk
+++ b/depends/packages/fontconfig.mk
@@ -9,6 +9,7 @@ $(package)_patches=gperf_header_regen.patch
define $(package)_set_vars
$(package)_config_opts=--disable-docs --disable-static --disable-libxml2 --disable-iconv
$(package)_config_opts += --disable-dependency-tracking --enable-option-checking
+ $(package)_cflags += -Wno-implicit-function-declaration
endef
define $(package)_preprocess_cmds
diff --git a/depends/packages/libevent.mk b/depends/packages/libevent.mk
index 8374f2a103..9650f77db9 100644
--- a/depends/packages/libevent.mk
+++ b/depends/packages/libevent.mk
@@ -16,8 +16,11 @@ define $(package)_set_vars
$(package)_config_opts_netbsd=--with-pic
$(package)_config_opts_openbsd=--with-pic
$(package)_config_opts_android=--with-pic
- $(package)_cppflags+=-D_FORTIFY_SOURCE=3
$(package)_cppflags_mingw32=-D_WIN32_WINNT=0x0601
+
+ ifeq ($(NO_HARDEN),)
+ $(package)_cppflags+=-D_FORTIFY_SOURCE=3
+ endif
endef
define $(package)_preprocess_cmds
diff --git a/depends/packages/libmultiprocess.mk b/depends/packages/libmultiprocess.mk
index 6da5693b3f..765d649377 100644
--- a/depends/packages/libmultiprocess.mk
+++ b/depends/packages/libmultiprocess.mk
@@ -10,8 +10,8 @@ endif
define $(package)_set_vars :=
ifneq ($(host),$(build))
-$(package)_cmake_opts := -DCAPNP_EXECUTABLE="$$(native_capnp_prefixbin)/capnp"
-$(package)_cmake_opts += -DCAPNPC_CXX_EXECUTABLE="$$(native_capnp_prefixbin)/capnpc-c++"
+$(package)_config_opts := -DCAPNP_EXECUTABLE="$$(native_capnp_prefixbin)/capnp"
+$(package)_config_opts += -DCAPNPC_CXX_EXECUTABLE="$$(native_capnp_prefixbin)/capnpc-c++"
endif
endef
diff --git a/depends/packages/qrencode.mk b/depends/packages/qrencode.mk
index d1687883bc..2afd95d7c4 100644
--- a/depends/packages/qrencode.mk
+++ b/depends/packages/qrencode.mk
@@ -1,15 +1,16 @@
package=qrencode
-$(package)_version=3.4.4
+$(package)_version=4.1.1
$(package)_download_path=https://fukuchi.org/works/qrencode/
$(package)_file_name=$(package)-$($(package)_version).tar.bz2
-$(package)_sha256_hash=efe5188b1ddbcbf98763b819b146be6a90481aac30cfc8d858ab78a19cde1fa5
+$(package)_sha256_hash=e455d9732f8041cf5b9c388e345a641fd15707860f928e94507b1961256a6923
define $(package)_set_vars
-$(package)_config_opts=--disable-shared --without-tools --without-tests --disable-sdltest
+$(package)_config_opts=--disable-shared --without-tools --without-tests --without-png
$(package)_config_opts += --disable-gprof --disable-gcov --disable-mudflap
$(package)_config_opts += --disable-dependency-tracking --enable-option-checking
$(package)_config_opts_linux=--with-pic
$(package)_config_opts_android=--with-pic
+$(package)_cflags += -Wno-int-conversion -Wno-implicit-function-declaration
endef
define $(package)_preprocess_cmds
diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk
index 2f7ddf6a5f..136ce32579 100644
--- a/depends/packages/qt.mk
+++ b/depends/packages/qt.mk
@@ -161,9 +161,15 @@ $(package)_config_opts_linux += -dbus-runtime
ifneq ($(LTO),)
$(package)_config_opts_linux += -ltcg
endif
-$(package)_config_opts_linux += -platform linux-g++ -xplatform bitcoin-linux-g++
-ifneq (,$(findstring -stdlib=libc++,$($(1)_cxx)))
-$(package)_config_opts_x86_64_linux = -xplatform linux-clang-libc++
+
+ifneq (,$(findstring clang,$($(package)_cxx)))
+ ifneq (,$(findstring -stdlib=libc++,$($(package)_cxx)))
+ $(package)_config_opts_linux += -platform linux-clang-libc++ -xplatform linux-clang-libc++
+ else
+ $(package)_config_opts_linux += -platform linux-clang -xplatform linux-clang
+ endif
+else
+ $(package)_config_opts_linux += -platform linux-g++ -xplatform bitcoin-linux-g++
endif
$(package)_config_opts_mingw32 = -no-opengl
diff --git a/doc/build-openbsd.md b/doc/build-openbsd.md
index 255995a517..96ee714341 100644
--- a/doc/build-openbsd.md
+++ b/doc/build-openbsd.md
@@ -1,6 +1,6 @@
# OpenBSD Build Guide
-**Updated for OpenBSD [7.1](https://www.openbsd.org/71.html)**
+**Updated for OpenBSD [7.3](https://www.openbsd.org/73.html)**
This guide describes how to build bitcoind, command-line utilities, and GUI on OpenBSD.
@@ -80,10 +80,6 @@ export AUTOMAKE_VERSION=1.16
### 1. Configuration
-Note that external signer support is currently not available on OpenBSD, since
-the used header-only library Boost.Process fails to compile (certain system
-calls and preprocessor defines like `waitid()` and `WEXITED` are missing).
-
There are many ways to configure Bitcoin Core, here are a few common examples:
##### Descriptor Wallet and GUI:
diff --git a/doc/dependencies.md b/doc/dependencies.md
index a9ca5b3e7a..c8417f49e6 100644
--- a/doc/dependencies.md
+++ b/doc/dependencies.md
@@ -10,7 +10,7 @@ You can find installation instructions in the `build-*.md` file for your platfor
| [Automake](https://www.gnu.org/software/automake/) | [1.13](https://github.com/bitcoin/bitcoin/pull/18290) |
| [Clang](https://clang.llvm.org) | [8.0](https://github.com/bitcoin/bitcoin/pull/24164) |
| [GCC](https://gcc.gnu.org) | [8.1](https://github.com/bitcoin/bitcoin/pull/23060) |
-| [Python](https://www.python.org) (tests) | [3.7](https://github.com/bitcoin/bitcoin/pull/26226) |
+| [Python](https://www.python.org) (scripts, tests) | [3.8](https://github.com/bitcoin/bitcoin/pull/27483) |
| [systemtap](https://sourceware.org/systemtap/) ([tracing](tracing.md))| N/A |
## Required
@@ -29,7 +29,7 @@ You can find installation instructions in the `build-*.md` file for your platfor
| --- | --- | --- | --- | --- |
| [Fontconfig](../depends/packages/fontconfig.mk) | [link](https://www.freedesktop.org/wiki/Software/fontconfig/) | [2.12.6](https://github.com/bitcoin/bitcoin/pull/23495) | 2.6 | Yes |
| [FreeType](../depends/packages/freetype.mk) | [link](https://freetype.org) | [2.11.0](https://github.com/bitcoin/bitcoin/commit/01544dd78ccc0b0474571da854e27adef97137fb) | 2.3.0 | Yes |
-| [qrencode](../depends/packages/qrencode.mk) | [link](https://fukuchi.org/works/qrencode/) | [3.4.4](https://github.com/bitcoin/bitcoin/pull/6373) | | No |
+| [qrencode](../depends/packages/qrencode.mk) | [link](https://fukuchi.org/works/qrencode/) | [4.1.1](https://github.com/bitcoin/bitcoin/pull/27312) | | No |
| [Qt](../depends/packages/qt.mk) | [link](https://download.qt.io/official_releases/qt/) | [5.15.5](https://github.com/bitcoin/bitcoin/pull/25719) | [5.11.3](https://github.com/bitcoin/bitcoin/pull/24132) | No |
### Networking
@@ -47,4 +47,4 @@ You can find installation instructions in the `build-*.md` file for your platfor
| Dependency | Releases | Version used | Minimum required | Runtime |
| --- | --- | --- | --- | --- |
| [Berkeley DB](../depends/packages/bdb.mk) (legacy wallet) | [link](https://www.oracle.com/technetwork/database/database-technologies/berkeleydb/downloads/index.html) | 4.8.30 | 4.8.x | No |
-| [SQLite](../depends/packages/sqlite.mk) | [link](https://sqlite.org) | [3.32.1](https://github.com/bitcoin/bitcoin/pull/19077) | [3.7.17](https://github.com/bitcoin/bitcoin/pull/19077) | No |
+| [SQLite](../depends/packages/sqlite.mk) | [link](https://sqlite.org) | [3.38.5](https://github.com/bitcoin/bitcoin/pull/25378) | [3.7.17](https://github.com/bitcoin/bitcoin/pull/19077) | No |
diff --git a/doc/developer-notes.md b/doc/developer-notes.md
index ceaba8cb99..08dde2aa61 100644
--- a/doc/developer-notes.md
+++ b/doc/developer-notes.md
@@ -111,8 +111,8 @@ code.
- `static_assert` is preferred over `assert` where possible. Generally; compile-time checking is preferred over run-time checking.
- Use a named cast or functional cast, not a C-Style cast. When casting
between integer types, use functional casts such as `int(x)` or `int{x}`
- instead of `(int) x`. When casting between more complex types, use static_cast.
- Use reinterpret_cast and const_cast as appropriate.
+ instead of `(int) x`. When casting between more complex types, use `static_cast`.
+ Use `reinterpret_cast` and `const_cast` as appropriate.
For function calls a namespace should be specified explicitly, unless such functions have been declared within it.
Otherwise, [argument-dependent lookup](https://en.cppreference.com/w/cpp/language/adl), also known as ADL, could be
diff --git a/doc/policy/packages.md b/doc/policy/packages.md
index 274854ddf9..2a5758318a 100644
--- a/doc/policy/packages.md
+++ b/doc/policy/packages.md
@@ -80,24 +80,37 @@ test accepts):
If any transactions in the package are already in the mempool, they are not submitted again
("deduplicated") and are thus excluded from this calculation.
-To meet the two feerate requirements of a mempool, i.e., the pre-configured minimum relay feerate
-(`-minrelaytxfee`) and the dynamic mempool minimum feerate, the total package feerate is used instead
-of the individual feerate. The individual transactions are allowed to be below the feerate
-requirements if the package meets the feerate requirements. For example, the parent(s) in the
-package can pay no fees but be paid for by the child.
-
-*Rationale*: This can be thought of as "CPFP within a package," solving the issue of a parent not
-meeting minimum fees on its own. This would allow contracting applications to adjust their fees at
-broadcast time instead of overshooting or risking becoming stuck or pinned.
-
-*Rationale*: It would be incorrect to use the fees of transactions that are already in the mempool, as
-we do not want a transaction's fees to be double-counted.
+To meet the dynamic mempool minimum feerate, i.e., the feerate determined by the transactions
+evicted when the mempool reaches capacity (not the static minimum relay feerate), the total package
+feerate instead of individual feerate can be used. For example, if the mempool minimum feerate is
+5sat/vB and a 1sat/vB parent transaction has a high-feerate child, it may be accepted if
+submitted as a package.
+
+*Rationale*: This can be thought of as "CPFP within a package," solving the issue of a presigned
+transaction (i.e. in which a replacement transaction with a higher fee cannot be signed) being
+rejected from the mempool when transaction volume is high and the mempool minimum feerate rises.
+
+Note: Package feerate cannot be used to meet the minimum relay feerate (`-minrelaytxfee`)
+requirement. For example, if the mempool minimum feerate is 5sat/vB and the minimum relay feerate is
+set to 5satvB, a 1sat/vB parent transaction with a high-feerate child will not be accepted, even if
+submitted as a package.
+
+*Rationale*: Avoid situations in which the mempool contains non-bumped transactions below min relay
+feerate (which we consider to have pay 0 fees and thus receiving free relay). While package
+submission would ensure these transactions are bumped at the time of entry, it is not guaranteed
+that the transaction will always be bumped. For example, a later transaction could replace the
+fee-bumping child without still bumping the parent. These no-longer-bumped transactions should be
+removed during a replacement, but we do not have a DoS-resistant way of removing them or enforcing a
+limit on their quantity. Instead, prevent their entry into the mempool.
Implementation Note: Transactions within a package are always validated individually first, and
package validation is used for the transactions that failed. Since package feerate is only
calculated using transactions that are not in the mempool, this implementation detail affects the
outcome of package validation.
+*Rationale*: It would be incorrect to use the fees of transactions that are already in the mempool, as
+we do not want a transaction's fees to be double-counted.
+
*Rationale*: Packages are intended for incentive-compatible fee-bumping: transaction B is a
"legitimate" fee-bump for transaction A only if B is a descendant of A and has a *higher* feerate
than A. We want to prevent "parents pay for children" behavior; fees of parents should not help
diff --git a/doc/release-note-26194.md b/doc/release-note-26194.md
deleted file mode 100644
index b72dbf9a23..0000000000
--- a/doc/release-note-26194.md
+++ /dev/null
@@ -1,4 +0,0 @@
-Add `next_index` in `listdescriptors` RPC
------------------
-
-- Added a new `next_index` field in the response in `listdescriptors` to have the same format as `importdescriptors`
diff --git a/doc/release-notes-19762.md b/doc/release-notes-19762.md
deleted file mode 100644
index 4dc45fb2c8..0000000000
--- a/doc/release-notes-19762.md
+++ /dev/null
@@ -1,19 +0,0 @@
-JSON-RPC
----
-
-All JSON-RPC methods accept a new [named
-parameter](JSON-RPC-interface.md#parameter-passing) called `args` that can
-contain positional parameter values. This is a convenience to allow some
-parameter values to be passed by name without having to name every value. The
-python test framework and `bitcoin-cli` tool both take advantage of this, so
-for example:
-
-```sh
-bitcoin-cli -named createwallet wallet_name=mywallet load_on_startup=1
-```
-
-Can now be shortened to:
-
-```sh
-bitcoin-cli -named createwallet mywallet load_on_startup=1
-```
diff --git a/doc/release-notes-22087.md b/doc/release-notes-22087.md
deleted file mode 100644
index 8d7fd242b2..0000000000
--- a/doc/release-notes-22087.md
+++ /dev/null
@@ -1,4 +0,0 @@
-Updated settings
-----------------
-
-- Ports specified in `-port` and `-rpcport` options are now validated at startup. Values that previously worked and were considered valid can now result in errors. (#22087)
diff --git a/doc/release-notes-23395.md b/doc/release-notes-23395.md
deleted file mode 100644
index b9d7d9409c..0000000000
--- a/doc/release-notes-23395.md
+++ /dev/null
@@ -1,8 +0,0 @@
-Notable changes
-===============
-
-New settings
-------------
-
-- The `shutdownnotify` option is used to specify a command to execute synchronously
-before Bitcoin Core has begun its shutdown sequence. (#23395)
diff --git a/doc/release-notes-25158.md b/doc/release-notes-25158.md
new file mode 100644
index 0000000000..ce8ab53ddd
--- /dev/null
+++ b/doc/release-notes-25158.md
@@ -0,0 +1,6 @@
+RPC Wallet
+----------
+
+- The `gettransaction`, `listtransactions`, `listsinceblock` RPCs now return
+ the `abandoned` field for all transactions. Previously, the "abandoned" field
+ was only returned for sent transactions. (#25158) \ No newline at end of file
diff --git a/doc/release-notes-25375.md b/doc/release-notes-25375.md
deleted file mode 100644
index 504a2644f4..0000000000
--- a/doc/release-notes-25375.md
+++ /dev/null
@@ -1,11 +0,0 @@
-Updated RPCs
---------
-
-The `minconf` option, which allows a user to specify the minimum number
-of confirmations a UTXO being spent has, and the `maxconf` option,
-which allows specifying the maximum number of confirmations, have been
-added to the following RPCs:
-- `fundrawtransaction`
-- `send`
-- `walletcreatefundedpsbt`
-- `sendall`
diff --git a/doc/release-notes-25412.md b/doc/release-notes-25412.md
deleted file mode 100644
index b11fe73d45..0000000000
--- a/doc/release-notes-25412.md
+++ /dev/null
@@ -1,5 +0,0 @@
-New REST endpoint
------------------
-
-- A new `/rest/deploymentinfo` endpoint has been added for fetching various
- state info regarding deployments of consensus changes. (#25412)
diff --git a/doc/release-notes-25574.md b/doc/release-notes-25574.md
deleted file mode 100644
index 312a99d95b..0000000000
--- a/doc/release-notes-25574.md
+++ /dev/null
@@ -1,13 +0,0 @@
-Updated settings
-----------------
-
-If the `-checkblocks` or `-checklevel` options are explicitly provided by the
-user, but the verification checks cannot be completed due to an insufficient
-dbcache, Bitcoin Core will now return an error at startup. (#25574)
-
-RPC
----
-The `-verifychain` RPC will now return `false` if the checks didn't fail,
-but couldn't be completed at the desired depth and level. This could be due
-to missing data while pruning, due to an insufficient dbcache or due to
-the node being shutdown before the call could finish. (#25574)
diff --git a/doc/release-notes-25730.md b/doc/release-notes-25730.md
deleted file mode 100644
index 33393cf314..0000000000
--- a/doc/release-notes-25730.md
+++ /dev/null
@@ -1,6 +0,0 @@
-RPC Wallet
-----------
-
-- RPC `listunspent` now has a new argument `include_immature_coinbase`
- to include coinbase UTXOs that don't meet the minimum spendability
- depth requirement (which before were silently skipped). (#25730) \ No newline at end of file
diff --git a/doc/release-notes-25934.md b/doc/release-notes-25934.md
deleted file mode 100644
index b4f1ae0d3c..0000000000
--- a/doc/release-notes-25934.md
+++ /dev/null
@@ -1,8 +0,0 @@
-Low-level changes
-=================
-
-RPC
----
-
-- RPC `listsinceblock` now accepts an optional `label` argument
- to fetch incoming transactions having the specified label. (#25934) \ No newline at end of file
diff --git a/doc/release-notes-25943.md b/doc/release-notes-25943.md
deleted file mode 100644
index 81b0a48b5d..0000000000
--- a/doc/release-notes-25943.md
+++ /dev/null
@@ -1,4 +0,0 @@
-New RPC Argument
---------
-- `sendrawtransaction` has a new, optional argument, `maxburnamount` with a default value of `0`. Any transaction containing an unspendable output with a value greater than `maxburnamount` will not be submitted. At present, the outputs deemed unspendable are those with scripts that begin with an `OP_RETURN` code (known as 'datacarriers'), scripts that exceed the maximum script size, and scripts that contain invalid opcodes.
-
diff --git a/doc/release-notes-25957.md b/doc/release-notes-25957.md
deleted file mode 100644
index c71afa2c2e..0000000000
--- a/doc/release-notes-25957.md
+++ /dev/null
@@ -1,9 +0,0 @@
-Wallet
-------
-
-- Rescans for descriptor wallets are now significantly faster if compact
- block filters (BIP158) are available. Since those are not constructed
- by default, the configuration option "-blockfilterindex=1" has to be
- provided to take advantage of the optimization. This improves the
- performance of the RPC calls `rescanblockchain`, `importdescriptors`
- and `restorewallet`. (#25957)
diff --git a/doc/release-notes-26094.md b/doc/release-notes-26094.md
new file mode 100644
index 0000000000..ba73f2707e
--- /dev/null
+++ b/doc/release-notes-26094.md
@@ -0,0 +1,6 @@
+- The `getbalances` RPC now returns a `lastprocessedblock` JSON object which contains the wallet's last processed block
+ hash and height at the time the balances were calculated. This result shouldn't be cached because importing new keys could invalidate it.
+- The `gettransaction` RPC now returns a `lastprocessedblock` JSON object which contains the wallet's last processed block
+ hash and height at the time the transaction information was generated.
+- The `getwalletinfo` RPC now returns a `lastprocessedblock` JSON object which contains the wallet's last processed block
+ hash and height at the time the wallet information was generated. \ No newline at end of file
diff --git a/doc/release-notes-26213.md b/doc/release-notes-26213.md
deleted file mode 100644
index e78d718ca9..0000000000
--- a/doc/release-notes-26213.md
+++ /dev/null
@@ -1,8 +0,0 @@
-Low-level changes
-=================
-
-- Previously `setban`, `addpeeraddress`, `walletcreatefundedpsbt`, methods
- allowed non-boolean and non-null values to be passed as boolean parameters.
- Any string, number, array, or object value that was passed would be treated
- as false. After this change, passing any value except `true`, `false`, or
- `null` now triggers a JSON value is not of expected type error. (#26213)
diff --git a/doc/release-notes-26265.md b/doc/release-notes-26265.md
deleted file mode 100644
index ca2313d956..0000000000
--- a/doc/release-notes-26265.md
+++ /dev/null
@@ -1,6 +0,0 @@
-P2P and network changes
----------
-
-- Transactions of non-witness size 65 and above are now allowed by mempool
- and relay policy. This is to better reflect the actual afforded protections
- against CVE-2017-12842 and open up additional use-cases of smaller transaction sizes. (#26265)
diff --git a/doc/release-notes-26471.md b/doc/release-notes-26471.md
deleted file mode 100644
index 2cb74804ca..0000000000
--- a/doc/release-notes-26471.md
+++ /dev/null
@@ -1,13 +0,0 @@
-Updated settings
-----------------
-
-- Setting `-blocksonly` will now reduce the maximum mempool memory
- to 5MB (users may still use `-maxmempool` to override). Previously,
- the default 300MB would be used, leading to unexpected memory usage
- for users running with `-blocksonly` expecting it to eliminate
- mempool memory usage.
-
- As unused mempool memory is shared with dbcache, this also reduces
- the dbcache size for users running with `-blocksonly`, potentially
- impacting performance.
-
diff --git a/doc/release-notes-26618.md b/doc/release-notes-26618.md
deleted file mode 100644
index 9d1ef3bd2e..0000000000
--- a/doc/release-notes-26618.md
+++ /dev/null
@@ -1,4 +0,0 @@
-RPC Wallet
-----------
-
-- RPC `unloadwallet` now fails if a rescan is in progress. (#26618)
diff --git a/doc/release-notes-26628.md b/doc/release-notes-26628.md
deleted file mode 100644
index 48a07c1e81..0000000000
--- a/doc/release-notes-26628.md
+++ /dev/null
@@ -1,4 +0,0 @@
-JSON-RPC
----
-
-The JSON-RPC server now rejects requests where a parameter is specified multiple times with the same name, instead of silently overwriting earlier parameter values with later ones. (#26628)
diff --git a/doc/release-notes-26646.md b/doc/release-notes-26646.md
deleted file mode 100644
index 7f94505a01..0000000000
--- a/doc/release-notes-26646.md
+++ /dev/null
@@ -1,8 +0,0 @@
-JSON-RPC
---------
-
-The `testmempoolaccept` RPC now returns 2 additional results within the "fees" result:
-"effective-feerate" is the feerate including fees and sizes of transactions validated together if
-package validation was used, and also includes any modified fees from prioritisetransaction. The
-"effective-includes" result lists the wtxids of transactions whose modified fees and sizes were used
-in the effective-feerate (#26646).
diff --git a/doc/release-notes-26896.md b/doc/release-notes-26896.md
deleted file mode 100644
index ff4ab44e27..0000000000
--- a/doc/release-notes-26896.md
+++ /dev/null
@@ -1,7 +0,0 @@
-Build System
-------------
-
-The --enable-upnp-default and --enable-natpmp-default options
-have been removed. If you want to use port mapping, you can
-configure it using a .conf file, or by passing the relevant
-options at runtime. \ No newline at end of file
diff --git a/doc/release-notes-26899.md b/doc/release-notes-26899.md
deleted file mode 100644
index ceb9ec2f7a..0000000000
--- a/doc/release-notes-26899.md
+++ /dev/null
@@ -1,5 +0,0 @@
-Updated settings
-----------------
-
-- Setting `-maxconnections=0` will now disable `-dnsseed`
- and `-listen` (users may still set them to override). \ No newline at end of file
diff --git a/doc/release-notes-27037.md b/doc/release-notes-27037.md
deleted file mode 100644
index ee30e64010..0000000000
--- a/doc/release-notes-27037.md
+++ /dev/null
@@ -1,5 +0,0 @@
-RPC
----
-
-- `decodescript` may now infer a Miniscript descriptor under P2WSH context if it is not lacking
- information.
diff --git a/doc/release-notes-27068.md b/doc/release-notes-27068.md
deleted file mode 100644
index 3f5c5dba37..0000000000
--- a/doc/release-notes-27068.md
+++ /dev/null
@@ -1,6 +0,0 @@
-Wallet
-------
-
-- Wallet passphrases may now contain null characters.
- Prior to this change, only characters up to the first
- null character were recognized and accepted. (#27068) \ No newline at end of file
diff --git a/doc/release-process.md b/doc/release-process.md
index f1fd72f8ac..9c2e03d402 100644
--- a/doc/release-process.md
+++ b/doc/release-process.md
@@ -29,7 +29,7 @@ Release Process
#### Before branch-off
* Update hardcoded [seeds](/contrib/seeds/README.md), see [this pull request](https://github.com/bitcoin/bitcoin/pull/7415) for an example.
-* Update the following variables in [`src/chainparams.cpp`](/src/chainparams.cpp) for mainnet, testnet, and signet:
+* Update the following variables in [`src/kernel/chainparams.cpp`](/src/kernel/chainparams.cpp) for mainnet, testnet, and signet:
- `m_assumed_blockchain_size` and `m_assumed_chain_state_size` with the current size plus some overhead (see
[this](#how-to-calculate-assumed-blockchain-and-chain-state-size) for information on how to calculate them).
- The following updates should be reviewed with `reindex-chainstate` and `assumevalid=0` to catch any defect
@@ -98,7 +98,7 @@ Generate the change log. As this is a huge amount of work to do manually, there
Generate list of authors:
- git log --format='- %aN' v(current version, e.g. 0.20.0)..v(new version, e.g. 0.20.1) | sort -fiu
+ git log --format='- %aN' v(current version, e.g. 24.0)..v(new version, e.g. 24.1) | sort -fiu
### Setup and perform Guix builds
@@ -107,7 +107,7 @@ Checkout the Bitcoin Core version you'd like to build:
```sh
pushd ./bitcoin
SIGNER='(your builder key, ie bluematt, sipa, etc)'
-VERSION='(new version without v-prefix, e.g. 0.20.0)'
+VERSION='(new version without v-prefix, e.g. 24.0)'
git fetch origin "v${VERSION}"
git checkout "v${VERSION}"
popd
diff --git a/doc/tor.md b/doc/tor.md
index 08d031d084..581d124f7a 100644
--- a/doc/tor.md
+++ b/doc/tor.md
@@ -92,19 +92,13 @@ out by default (if not, add them):
ControlPort 9051
CookieAuthentication 1
CookieAuthFileGroupReadable 1
+DataDirectoryGroupReadable 1
```
Add or uncomment those, save, and restart Tor (usually `systemctl restart tor`
or `sudo systemctl restart tor` on most systemd-based systems, including recent
Debian and Ubuntu, or just restart the computer).
-On some systems (such as Arch Linux), you may also need to add the following
-line:
-
-```
-DataDirectoryGroupReadable 1
-```
-
### Authentication
Connecting to Tor's control socket API requires one of two authentication
diff --git a/src/.clang-tidy b/src/.clang-tidy
index b2c1b49588..39566c0cb7 100644
--- a/src/.clang-tidy
+++ b/src/.clang-tidy
@@ -5,10 +5,11 @@ bugprone-use-after-move,
misc-unused-using-decls,
modernize-use-default-member-init,
modernize-use-nullptr,
-performance-for-range-copy,
-performance-move-const-arg,
-performance-no-automatic-move,
-performance-unnecessary-copy-initialization,
+performance-*,
+-performance-inefficient-string-concatenation,
+-performance-no-int-to-ptr,
+-performance-noexcept-move-constructor,
+-performance-unnecessary-value-param,
readability-const-return-type,
readability-redundant-declaration,
readability-redundant-string-init,
diff --git a/src/Makefile.am b/src/Makefile.am
index 53c809c901..d12edca64e 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -133,6 +133,7 @@ BITCOIN_CORE_H = \
checkqueue.h \
clientversion.h \
coins.h \
+ common/args.h \
common/bloom.h \
common/init.h \
common/run_command.h \
@@ -154,7 +155,6 @@ BITCOIN_CORE_H = \
deploymentstatus.h \
external_signer.h \
flatfile.h \
- fs.h \
headerssync.h \
httprpc.h \
httpserver.h \
@@ -261,6 +261,7 @@ BITCOIN_CORE_H = \
shutdown.h \
signet.h \
streams.h \
+ support/allocators/pool.h \
support/allocators/secure.h \
support/allocators/zeroafterfree.h \
support/cleanse.h \
@@ -285,6 +286,8 @@ BITCOIN_CORE_H = \
util/exception.h \
util/fastrange.h \
util/fees.h \
+ util/fs.h \
+ util/fs_helpers.h \
util/getuniquepath.h \
util/golombrice.h \
util/hash_type.h \
@@ -328,7 +331,6 @@ BITCOIN_CORE_H = \
wallet/external_signer_scriptpubkeyman.h \
wallet/feebumper.h \
wallet/fees.h \
- wallet/ismine.h \
wallet/load.h \
wallet/receive.h \
wallet/rpc/util.h \
@@ -338,6 +340,7 @@ BITCOIN_CORE_H = \
wallet/spend.h \
wallet/sqlite.h \
wallet/transaction.h \
+ wallet/types.h \
wallet/wallet.h \
wallet/walletdb.h \
wallet/wallettool.h \
@@ -645,7 +648,9 @@ libbitcoin_common_a_SOURCES = \
bech32.cpp \
chainparams.cpp \
coins.cpp \
+ common/args.cpp \
common/bloom.cpp \
+ common/config.cpp \
common/init.cpp \
common/interfaces.cpp \
common/run_command.cpp \
@@ -694,7 +699,6 @@ libbitcoin_util_a_SOURCES = \
support/lockedpool.cpp \
chainparamsbase.cpp \
clientversion.cpp \
- fs.cpp \
logging.cpp \
random.cpp \
randomenv.cpp \
@@ -707,6 +711,8 @@ libbitcoin_util_a_SOURCES = \
util/error.cpp \
util/exception.cpp \
util/fees.cpp \
+ util/fs.cpp \
+ util/fs_helpers.cpp \
util/getuniquepath.cpp \
util/hasher.cpp \
util/sock.cpp \
@@ -899,6 +905,8 @@ libbitcoinkernel_la_SOURCES = \
chainparams.cpp \
clientversion.cpp \
coins.cpp \
+ common/args.cpp \
+ common/config.cpp \
compressor.cpp \
consensus/merkle.cpp \
consensus/tx_check.cpp \
@@ -908,7 +916,6 @@ libbitcoinkernel_la_SOURCES = \
deploymentinfo.cpp \
deploymentstatus.cpp \
flatfile.cpp \
- fs.cpp \
hash.cpp \
kernel/chain.cpp \
kernel/checks.cpp \
@@ -951,6 +958,8 @@ libbitcoinkernel_la_SOURCES = \
uint256.cpp \
util/check.cpp \
util/exception.cpp \
+ util/fs.cpp \
+ util/fs_helpers.cpp \
util/getuniquepath.cpp \
util/hasher.cpp \
util/moneystr.cpp \
diff --git a/src/Makefile.bench.include b/src/Makefile.bench.include
index f1e4e706a1..c230728a1c 100644
--- a/src/Makefile.bench.include
+++ b/src/Makefile.bench.include
@@ -42,6 +42,7 @@ bench_bench_bitcoin_SOURCES = \
bench/nanobench.h \
bench/peer_eviction.cpp \
bench/poly1305.cpp \
+ bench/pool.cpp \
bench/prevector.cpp \
bench/rollingbloom.cpp \
bench/rpc_blockchain.cpp \
diff --git a/src/Makefile.test.include b/src/Makefile.test.include
index a39b0abd9d..69965ed1b8 100644
--- a/src/Makefile.test.include
+++ b/src/Makefile.test.include
@@ -116,6 +116,7 @@ BITCOIN_TESTS =\
test/pmt_tests.cpp \
test/policy_fee_tests.cpp \
test/policyestimator_tests.cpp \
+ test/pool_tests.cpp \
test/pow_tests.cpp \
test/prevector_tests.cpp \
test/raii_event_tests.cpp \
@@ -272,6 +273,7 @@ test_fuzz_fuzz_SOURCES = \
test/fuzz/flatfile.cpp \
test/fuzz/float.cpp \
test/fuzz/golomb_rice.cpp \
+ test/fuzz/headerssync.cpp \
test/fuzz/hex.cpp \
test/fuzz/http_request.cpp \
test/fuzz/i2p.cpp \
@@ -300,6 +302,7 @@ test_fuzz_fuzz_SOURCES = \
test/fuzz/partially_downloaded_block.cpp \
test/fuzz/policy_estimator.cpp \
test/fuzz/policy_estimator_io.cpp \
+ test/fuzz/poolresource.cpp \
test/fuzz/pow.cpp \
test/fuzz/prevector.cpp \
test/fuzz/primitives_transaction.cpp \
diff --git a/src/Makefile.test_util.include b/src/Makefile.test_util.include
index aefefe789a..11b93ad13e 100644
--- a/src/Makefile.test_util.include
+++ b/src/Makefile.test_util.include
@@ -15,6 +15,7 @@ TEST_UTIL_H = \
test/util/logging.h \
test/util/mining.h \
test/util/net.h \
+ test/util/poolresourcetester.h \
test/util/random.h \
test/util/script.h \
test/util/setup_common.h \
diff --git a/src/addrdb.cpp b/src/addrdb.cpp
index 9ae8244d1c..b679ad0602 100644
--- a/src/addrdb.cpp
+++ b/src/addrdb.cpp
@@ -8,8 +8,8 @@
#include <addrman.h>
#include <chainparams.h>
#include <clientversion.h>
+#include <common/args.h>
#include <cstdint>
-#include <fs.h>
#include <hash.h>
#include <logging.h>
#include <logging/timer.h>
@@ -19,8 +19,9 @@
#include <streams.h>
#include <tinyformat.h>
#include <univalue.h>
+#include <util/fs.h>
+#include <util/fs_helpers.h>
#include <util/settings.h>
-#include <util/system.h>
#include <util/translation.h>
namespace {
diff --git a/src/addrdb.h b/src/addrdb.h
index 627ef3ac3c..08d86d0f01 100644
--- a/src/addrdb.h
+++ b/src/addrdb.h
@@ -6,9 +6,9 @@
#ifndef BITCOIN_ADDRDB_H
#define BITCOIN_ADDRDB_H
-#include <fs.h>
#include <net_types.h> // For banmap_t
#include <univalue.h>
+#include <util/fs.h>
#include <optional>
#include <vector>
diff --git a/src/addrman.cpp b/src/addrman.cpp
index f5ca9a5c34..cdfd079fcd 100644
--- a/src/addrman.cpp
+++ b/src/addrman.cpp
@@ -58,9 +58,9 @@ int AddrInfo::GetNewBucket(const uint256& nKey, const CNetAddr& src, const NetGr
return hash2 % ADDRMAN_NEW_BUCKET_COUNT;
}
-int AddrInfo::GetBucketPosition(const uint256& nKey, bool fNew, int nBucket) const
+int AddrInfo::GetBucketPosition(const uint256& nKey, bool fNew, int bucket) const
{
- uint64_t hash1 = (CHashWriter(SER_GETHASH, 0) << nKey << (fNew ? uint8_t{'N'} : uint8_t{'K'}) << nBucket << GetKey()).GetCheapHash();
+ uint64_t hash1 = (CHashWriter(SER_GETHASH, 0) << nKey << (fNew ? uint8_t{'N'} : uint8_t{'K'}) << bucket << GetKey()).GetCheapHash();
return hash1 % ADDRMAN_BUCKET_SIZE;
}
@@ -714,72 +714,98 @@ void AddrManImpl::Attempt_(const CService& addr, bool fCountFailure, NodeSeconds
}
}
-std::pair<CAddress, NodeSeconds> AddrManImpl::Select_(bool newOnly) const
+std::pair<CAddress, NodeSeconds> AddrManImpl::Select_(bool new_only, std::optional<Network> network) const
{
AssertLockHeld(cs);
if (vRandom.empty()) return {};
- if (newOnly && nNew == 0) return {};
-
- // Use a 50% chance for choosing between tried and new table entries.
- if (!newOnly &&
- (nTried > 0 && (nNew == 0 || insecure_rand.randbool() == 0))) {
- // use a tried node
- double fChanceFactor = 1.0;
- while (1) {
- // Pick a tried bucket, and an initial position in that bucket.
- int nKBucket = insecure_rand.randrange(ADDRMAN_TRIED_BUCKET_COUNT);
- int nKBucketPos = insecure_rand.randrange(ADDRMAN_BUCKET_SIZE);
- // Iterate over the positions of that bucket, starting at the initial one,
- // and looping around.
- int i;
- for (i = 0; i < ADDRMAN_BUCKET_SIZE; ++i) {
- if (vvTried[nKBucket][(nKBucketPos + i) % ADDRMAN_BUCKET_SIZE] != -1) break;
- }
- // If the bucket is entirely empty, start over with a (likely) different one.
- if (i == ADDRMAN_BUCKET_SIZE) continue;
- // Find the entry to return.
- int nId = vvTried[nKBucket][(nKBucketPos + i) % ADDRMAN_BUCKET_SIZE];
- const auto it_found{mapInfo.find(nId)};
- assert(it_found != mapInfo.end());
- const AddrInfo& info{it_found->second};
- // With probability GetChance() * fChanceFactor, return the entry.
- if (insecure_rand.randbits(30) < fChanceFactor * info.GetChance() * (1 << 30)) {
- LogPrint(BCLog::ADDRMAN, "Selected %s from tried\n", info.ToStringAddrPort());
- return {info, info.m_last_try};
- }
- // Otherwise start over with a (likely) different bucket, and increased chance factor.
- fChanceFactor *= 1.2;
- }
+ size_t new_count = nNew;
+ size_t tried_count = nTried;
+
+ if (network.has_value()) {
+ auto it = m_network_counts.find(*network);
+ if (it == m_network_counts.end()) return {};
+
+ auto counts = it->second;
+ new_count = counts.n_new;
+ tried_count = counts.n_tried;
+ }
+
+ if (new_only && new_count == 0) return {};
+ if (new_count + tried_count == 0) return {};
+
+ // Decide if we are going to search the new or tried table
+ // If either option is viable, use a 50% chance to choose
+ bool search_tried;
+ if (new_only || tried_count == 0) {
+ search_tried = false;
+ } else if (new_count == 0) {
+ search_tried = true;
} else {
- // use a new node
- double fChanceFactor = 1.0;
- while (1) {
- // Pick a new bucket, and an initial position in that bucket.
- int nUBucket = insecure_rand.randrange(ADDRMAN_NEW_BUCKET_COUNT);
- int nUBucketPos = insecure_rand.randrange(ADDRMAN_BUCKET_SIZE);
- // Iterate over the positions of that bucket, starting at the initial one,
- // and looping around.
- int i;
- for (i = 0; i < ADDRMAN_BUCKET_SIZE; ++i) {
- if (vvNew[nUBucket][(nUBucketPos + i) % ADDRMAN_BUCKET_SIZE] != -1) break;
- }
- // If the bucket is entirely empty, start over with a (likely) different one.
- if (i == ADDRMAN_BUCKET_SIZE) continue;
- // Find the entry to return.
- int nId = vvNew[nUBucket][(nUBucketPos + i) % ADDRMAN_BUCKET_SIZE];
- const auto it_found{mapInfo.find(nId)};
- assert(it_found != mapInfo.end());
- const AddrInfo& info{it_found->second};
- // With probability GetChance() * fChanceFactor, return the entry.
- if (insecure_rand.randbits(30) < fChanceFactor * info.GetChance() * (1 << 30)) {
- LogPrint(BCLog::ADDRMAN, "Selected %s from new\n", info.ToStringAddrPort());
- return {info, info.m_last_try};
+ search_tried = insecure_rand.randbool();
+ }
+
+ const int bucket_count{search_tried ? ADDRMAN_TRIED_BUCKET_COUNT : ADDRMAN_NEW_BUCKET_COUNT};
+
+ // Loop through the addrman table until we find an appropriate entry
+ double chance_factor = 1.0;
+ while (1) {
+ // Pick a bucket, and an initial position in that bucket.
+ int bucket = insecure_rand.randrange(bucket_count);
+ int initial_position = insecure_rand.randrange(ADDRMAN_BUCKET_SIZE);
+
+ // Iterate over the positions of that bucket, starting at the initial one,
+ // and looping around.
+ int i;
+ for (i = 0; i < ADDRMAN_BUCKET_SIZE; ++i) {
+ int position = (initial_position + i) % ADDRMAN_BUCKET_SIZE;
+ int node_id = GetEntry(search_tried, bucket, position);
+ if (node_id != -1) {
+ if (network.has_value()) {
+ const auto it{mapInfo.find(node_id)};
+ assert(it != mapInfo.end());
+ const auto info{it->second};
+ if (info.GetNetwork() == *network) break;
+ } else {
+ break;
+ }
}
- // Otherwise start over with a (likely) different bucket, and increased chance factor.
- fChanceFactor *= 1.2;
}
+
+ // If the bucket is entirely empty, start over with a (likely) different one.
+ if (i == ADDRMAN_BUCKET_SIZE) continue;
+
+ // Find the entry to return.
+ int position = (initial_position + i) % ADDRMAN_BUCKET_SIZE;
+ int nId = GetEntry(search_tried, bucket, position);
+ const auto it_found{mapInfo.find(nId)};
+ assert(it_found != mapInfo.end());
+ const AddrInfo& info{it_found->second};
+
+ // With probability GetChance() * chance_factor, return the entry.
+ if (insecure_rand.randbits(30) < chance_factor * info.GetChance() * (1 << 30)) {
+ LogPrint(BCLog::ADDRMAN, "Selected %s from %s\n", info.ToStringAddrPort(), search_tried ? "tried" : "new");
+ return {info, info.m_last_try};
+ }
+
+ // Otherwise start over with a (likely) different bucket, and increased chance factor.
+ chance_factor *= 1.2;
+ }
+}
+
+int AddrManImpl::GetEntry(bool use_tried, size_t bucket, size_t position) const
+{
+ AssertLockHeld(cs);
+
+ assert(position < ADDRMAN_BUCKET_SIZE);
+
+ if (use_tried) {
+ assert(bucket < ADDRMAN_TRIED_BUCKET_COUNT);
+ return vvTried[bucket][position];
+ } else {
+ assert(bucket < ADDRMAN_NEW_BUCKET_COUNT);
+ return vvNew[bucket][position];
}
}
@@ -1164,11 +1190,11 @@ std::pair<CAddress, NodeSeconds> AddrManImpl::SelectTriedCollision()
return ret;
}
-std::pair<CAddress, NodeSeconds> AddrManImpl::Select(bool newOnly) const
+std::pair<CAddress, NodeSeconds> AddrManImpl::Select(bool new_only, std::optional<Network> network) const
{
LOCK(cs);
Check();
- auto addrRet = Select_(newOnly);
+ auto addrRet = Select_(new_only, network);
Check();
return addrRet;
}
@@ -1262,9 +1288,9 @@ std::pair<CAddress, NodeSeconds> AddrMan::SelectTriedCollision()
return m_impl->SelectTriedCollision();
}
-std::pair<CAddress, NodeSeconds> AddrMan::Select(bool newOnly) const
+std::pair<CAddress, NodeSeconds> AddrMan::Select(bool new_only, std::optional<Network> network) const
{
- return m_impl->Select(newOnly);
+ return m_impl->Select(new_only, network);
}
std::vector<CAddress> AddrMan::GetAddr(size_t max_addresses, size_t max_pct, std::optional<Network> network) const
diff --git a/src/addrman.h b/src/addrman.h
index 4985fc764c..6284b80a52 100644
--- a/src/addrman.h
+++ b/src/addrman.h
@@ -146,11 +146,14 @@ public:
/**
* Choose an address to connect to.
*
- * @param[in] newOnly Whether to only select addresses from the new table.
+ * @param[in] new_only Whether to only select addresses from the new table. Passing `true` returns
+ * an address from the new table or an empty pair. Passing `false` will return an
+ * address from either the new or tried table (it does not guarantee a tried entry).
+ * @param[in] network Select only addresses of this network (nullopt = all)
* @return CAddress The record for the selected peer.
* seconds The last time we attempted to connect to that peer.
*/
- std::pair<CAddress, NodeSeconds> Select(bool newOnly = false) const;
+ std::pair<CAddress, NodeSeconds> Select(bool new_only = false, std::optional<Network> network = std::nullopt) const;
/**
* Return all or many randomly selected addresses, optionally by network.
diff --git a/src/addrman_impl.h b/src/addrman_impl.h
index 94fe81aca9..7aead2812b 100644
--- a/src/addrman_impl.h
+++ b/src/addrman_impl.h
@@ -90,7 +90,7 @@ public:
}
//! Calculate in which position of a bucket to store this entry.
- int GetBucketPosition(const uint256 &nKey, bool fNew, int nBucket) const;
+ int GetBucketPosition(const uint256 &nKey, bool fNew, int bucket) const;
//! Determine whether the statistics about this entry are bad enough so that it can just be deleted
bool IsTerrible(NodeSeconds now = Now<NodeSeconds>()) const;
@@ -127,7 +127,7 @@ public:
std::pair<CAddress, NodeSeconds> SelectTriedCollision() EXCLUSIVE_LOCKS_REQUIRED(!cs);
- std::pair<CAddress, NodeSeconds> Select(bool newOnly) const
+ std::pair<CAddress, NodeSeconds> Select(bool new_only, std::optional<Network> network) const
EXCLUSIVE_LOCKS_REQUIRED(!cs);
std::vector<CAddress> GetAddr(size_t max_addresses, size_t max_pct, std::optional<Network> network) const
@@ -251,7 +251,13 @@ private:
void Attempt_(const CService& addr, bool fCountFailure, NodeSeconds time) EXCLUSIVE_LOCKS_REQUIRED(cs);
- std::pair<CAddress, NodeSeconds> Select_(bool newOnly) const EXCLUSIVE_LOCKS_REQUIRED(cs);
+ std::pair<CAddress, NodeSeconds> Select_(bool new_only, std::optional<Network> network) const EXCLUSIVE_LOCKS_REQUIRED(cs);
+
+ /** Helper to generalize looking up an addrman entry from either table.
+ *
+ * @return int The nid of the entry or -1 if the addrman position is empty.
+ * */
+ int GetEntry(bool use_tried, size_t bucket, size_t position) const EXCLUSIVE_LOCKS_REQUIRED(cs);
std::vector<CAddress> GetAddr_(size_t max_addresses, size_t max_pct, std::optional<Network> network) const EXCLUSIVE_LOCKS_REQUIRED(cs);
diff --git a/src/banman.cpp b/src/banman.cpp
index ece949d997..5b2049d654 100644
--- a/src/banman.cpp
+++ b/src/banman.cpp
@@ -5,6 +5,7 @@
#include <banman.h>
+#include <logging.h>
#include <netaddress.h>
#include <node/interface_ui.h>
#include <sync.h>
diff --git a/src/banman.h b/src/banman.h
index 241f01dd2e..5a5f5677b0 100644
--- a/src/banman.h
+++ b/src/banman.h
@@ -7,9 +7,9 @@
#include <addrdb.h>
#include <common/bloom.h>
-#include <fs.h>
#include <net_types.h> // For banmap_t
#include <sync.h>
+#include <util/fs.h>
#include <chrono>
#include <cstdint>
diff --git a/src/bench/addrman.cpp b/src/bench/addrman.cpp
index d6b52eb587..8a5cab443f 100644
--- a/src/bench/addrman.cpp
+++ b/src/bench/addrman.cpp
@@ -4,6 +4,7 @@
#include <addrman.h>
#include <bench/bench.h>
+#include <netbase.h>
#include <netgroup.h>
#include <random.h>
#include <util/check.h>
@@ -71,6 +72,20 @@ static void FillAddrMan(AddrMan& addrman)
AddAddressesToAddrMan(addrman);
}
+static CNetAddr ResolveIP(const std::string& ip)
+{
+ CNetAddr addr;
+ LookupHost(ip, addr, false);
+ return addr;
+}
+
+static CService ResolveService(const std::string& ip, uint16_t port = 0)
+{
+ CService serv;
+ Lookup(ip, serv, port, false);
+ return serv;
+}
+
/* Benchmarks */
static void AddrManAdd(benchmark::Bench& bench)
@@ -95,6 +110,41 @@ static void AddrManSelect(benchmark::Bench& bench)
});
}
+// The worst case performance of the Select() function is when there is only
+// one address on the table, because it linearly searches every position of
+// several buckets before identifying the correct bucket
+static void AddrManSelectFromAlmostEmpty(benchmark::Bench& bench)
+{
+ AddrMan addrman{EMPTY_NETGROUPMAN, /*deterministic=*/false, ADDRMAN_CONSISTENCY_CHECK_RATIO};
+
+ // Add one address to the new table
+ CService addr = ResolveService("250.3.1.1", 8333);
+ addrman.Add({CAddress(addr, NODE_NONE)}, ResolveService("250.3.1.1", 8333));
+
+ bench.run([&] {
+ (void)addrman.Select();
+ });
+}
+
+static void AddrManSelectByNetwork(benchmark::Bench& bench)
+{
+ AddrMan addrman{EMPTY_NETGROUPMAN, /*deterministic=*/false, ADDRMAN_CONSISTENCY_CHECK_RATIO};
+
+ // add single I2P address to new table
+ CService i2p_service;
+ i2p_service.SetSpecial("udhdrtrcetjm5sxzskjyr5ztpeszydbh4dpl3pl4utgqqw2v4jna.b32.i2p");
+ CAddress i2p_address(i2p_service, NODE_NONE);
+ i2p_address.nTime = Now<NodeSeconds>();
+ CNetAddr source = ResolveIP("252.2.2.2");
+ addrman.Add({i2p_address}, source);
+
+ FillAddrMan(addrman);
+
+ bench.run([&] {
+ (void)addrman.Select(/*new_only=*/false, NET_I2P);
+ });
+}
+
static void AddrManGetAddr(benchmark::Bench& bench)
{
AddrMan addrman{EMPTY_NETGROUPMAN, /*deterministic=*/false, ADDRMAN_CONSISTENCY_CHECK_RATIO};
@@ -135,5 +185,7 @@ static void AddrManAddThenGood(benchmark::Bench& bench)
BENCHMARK(AddrManAdd, benchmark::PriorityLevel::HIGH);
BENCHMARK(AddrManSelect, benchmark::PriorityLevel::HIGH);
+BENCHMARK(AddrManSelectFromAlmostEmpty, benchmark::PriorityLevel::HIGH);
+BENCHMARK(AddrManSelectByNetwork, benchmark::PriorityLevel::HIGH);
BENCHMARK(AddrManGetAddr, benchmark::PriorityLevel::HIGH);
BENCHMARK(AddrManAddThenGood, benchmark::PriorityLevel::HIGH);
diff --git a/src/bench/bench.cpp b/src/bench/bench.cpp
index 4374a63250..84b66bc4b2 100644
--- a/src/bench/bench.cpp
+++ b/src/bench/bench.cpp
@@ -4,8 +4,8 @@
#include <bench/bench.h>
-#include <fs.h>
#include <test/util/setup_common.h>
+#include <util/fs.h>
#include <util/string.h>
#include <chrono>
diff --git a/src/bench/bench.h b/src/bench/bench.h
index 22c63a797b..78196134e7 100644
--- a/src/bench/bench.h
+++ b/src/bench/bench.h
@@ -5,7 +5,7 @@
#ifndef BITCOIN_BENCH_BENCH_H
#define BITCOIN_BENCH_BENCH_H
-#include <fs.h>
+#include <util/fs.h>
#include <util/macros.h>
#include <chrono>
diff --git a/src/bench/bench_bitcoin.cpp b/src/bench/bench_bitcoin.cpp
index 06e32f684f..8c421c3fec 100644
--- a/src/bench/bench_bitcoin.cpp
+++ b/src/bench/bench_bitcoin.cpp
@@ -5,10 +5,10 @@
#include <bench/bench.h>
#include <clientversion.h>
+#include <common/args.h>
#include <crypto/sha256.h>
-#include <fs.h>
+#include <util/fs.h>
#include <util/strencodings.h>
-#include <util/system.h>
#include <chrono>
#include <cstdint>
diff --git a/src/bench/checkblock.cpp b/src/bench/checkblock.cpp
index ee76f7b767..260c8991ce 100644
--- a/src/bench/checkblock.cpp
+++ b/src/bench/checkblock.cpp
@@ -6,9 +6,9 @@
#include <bench/data.h>
#include <chainparams.h>
+#include <common/args.h>
#include <consensus/validation.h>
#include <streams.h>
-#include <util/system.h>
#include <validation.h>
// These are the two major time-sinks which happen after we have fully received
diff --git a/src/bench/coin_selection.cpp b/src/bench/coin_selection.cpp
index 265d4bf655..11ce14728d 100644
--- a/src/bench/coin_selection.cpp
+++ b/src/bench/coin_selection.cpp
@@ -5,6 +5,7 @@
#include <bench/bench.h>
#include <interfaces/chain.h>
#include <node/context.h>
+#include <policy/policy.h>
#include <wallet/coinselection.h>
#include <wallet/spend.h>
#include <wallet/wallet.h>
@@ -115,7 +116,7 @@ static void BnBExhaustion(benchmark::Bench& bench)
bench.run([&] {
// Benchmark
CAmount target = make_hard_case(17, utxo_pool);
- SelectCoinsBnB(utxo_pool, target, 0); // Should exhaust
+ SelectCoinsBnB(utxo_pool, target, 0, MAX_STANDARD_TX_WEIGHT); // Should exhaust
// Cleanup
utxo_pool.clear();
diff --git a/src/bench/lockedpool.cpp b/src/bench/lockedpool.cpp
index 161f9af621..6851ed0bd8 100644
--- a/src/bench/lockedpool.cpp
+++ b/src/bench/lockedpool.cpp
@@ -17,9 +17,7 @@ static void BenchLockedPool(benchmark::Bench& bench)
const size_t synth_size = 1024*1024;
Arena b(synth_base, synth_size, 16);
- std::vector<void*> addr;
- for (int x=0; x<ASIZE; ++x)
- addr.push_back(nullptr);
+ std::vector<void*> addr{ASIZE, nullptr};
uint32_t s = 0x12345678;
bench.run([&] {
int idx = s & (addr.size() - 1);
diff --git a/src/bench/pool.cpp b/src/bench/pool.cpp
new file mode 100644
index 0000000000..b3e54d85a2
--- /dev/null
+++ b/src/bench/pool.cpp
@@ -0,0 +1,50 @@
+// Copyright (c) 2022 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 <bench/bench.h>
+#include <support/allocators/pool.h>
+
+#include <unordered_map>
+
+template <typename Map>
+void BenchFillClearMap(benchmark::Bench& bench, Map& map)
+{
+ size_t batch_size = 5000;
+
+ // make sure each iteration of the benchmark contains exactly 5000 inserts and one clear.
+ // do this at least 10 times so we get reasonable accurate results
+
+ bench.batch(batch_size).minEpochIterations(10).run([&] {
+ auto rng = ankerl::nanobench::Rng(1234);
+ for (size_t i = 0; i < batch_size; ++i) {
+ map[rng()];
+ }
+ map.clear();
+ });
+}
+
+static void PoolAllocator_StdUnorderedMap(benchmark::Bench& bench)
+{
+ auto map = std::unordered_map<uint64_t, uint64_t>();
+ BenchFillClearMap(bench, map);
+}
+
+static void PoolAllocator_StdUnorderedMapWithPoolResource(benchmark::Bench& bench)
+{
+ using Map = std::unordered_map<uint64_t,
+ uint64_t,
+ std::hash<uint64_t>,
+ std::equal_to<uint64_t>,
+ PoolAllocator<std::pair<const uint64_t, uint64_t>,
+ sizeof(std::pair<const uint64_t, uint64_t>) + 4 * sizeof(void*),
+ alignof(void*)>>;
+
+ // make sure the resource supports large enough pools to hold the node. We do this by adding the size of a few pointers to it.
+ auto pool_resource = Map::allocator_type::ResourceType();
+ auto map = Map{0, std::hash<uint64_t>{}, std::equal_to<uint64_t>{}, &pool_resource};
+ BenchFillClearMap(bench, map);
+}
+
+BENCHMARK(PoolAllocator_StdUnorderedMap, benchmark::PriorityLevel::HIGH);
+BENCHMARK(PoolAllocator_StdUnorderedMapWithPoolResource, benchmark::PriorityLevel::HIGH);
diff --git a/src/bench/wallet_create_tx.cpp b/src/bench/wallet_create_tx.cpp
index bd32a5abdc..cb31421598 100644
--- a/src/bench/wallet_create_tx.cpp
+++ b/src/bench/wallet_create_tx.cpp
@@ -102,7 +102,7 @@ static void WalletCreateTx(benchmark::Bench& bench, const OutputType output_type
}
// Check available balance
- auto bal = wallet::GetAvailableBalance(wallet); // Cache
+ auto bal = WITH_LOCK(wallet.cs_wallet, return wallet::AvailableCoins(wallet).GetTotalAmount()); // Cache
assert(bal == 50 * COIN * (chain_size - COINBASE_MATURITY));
wallet::CCoinControl coin_control;
@@ -146,6 +146,7 @@ static void AvailableCoins(benchmark::Bench& bench, const std::vector<OutputType
// Generate destinations
std::vector<CScript> dest_wallet;
+ dest_wallet.reserve(output_type.size());
for (auto type : output_type) {
dest_wallet.emplace_back(GetScriptForDestination(getNewDestination(wallet, type)));
}
@@ -160,7 +161,7 @@ static void AvailableCoins(benchmark::Bench& bench, const std::vector<OutputType
}
// Check available balance
- auto bal = wallet::GetAvailableBalance(wallet); // Cache
+ auto bal = WITH_LOCK(wallet.cs_wallet, return wallet::AvailableCoins(wallet).GetTotalAmount()); // Cache
assert(bal == 50 * COIN * (chain_size - COINBASE_MATURITY));
bench.epochIterations(2).run([&] {
diff --git a/src/bitcoin-chainstate.cpp b/src/bitcoin-chainstate.cpp
index abe3af70c3..04f6aae4f7 100644
--- a/src/bitcoin-chainstate.cpp
+++ b/src/bitcoin-chainstate.cpp
@@ -17,6 +17,7 @@
#include <kernel/validation_cache_sizes.h>
#include <chainparams.h>
+#include <common/args.h>
#include <consensus/validation.h>
#include <core_io.h>
#include <node/blockstorage.h>
@@ -24,7 +25,6 @@
#include <node/chainstate.h>
#include <scheduler.h>
#include <script/sigcache.h>
-#include <util/system.h>
#include <util/thread.h>
#include <validation.h>
#include <validationinterface.h>
diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp
index eb52b30ae4..63ba6a935d 100644
--- a/src/bitcoin-cli.cpp
+++ b/src/bitcoin-cli.cpp
@@ -9,6 +9,7 @@
#include <chainparamsbase.h>
#include <clientversion.h>
+#include <common/args.h>
#include <common/url.h>
#include <compat/compat.h>
#include <compat/stdin.h>
@@ -22,6 +23,7 @@
#include <util/exception.h>
#include <util/strencodings.h>
#include <util/system.h>
+#include <util/time.h>
#include <util/translation.h>
#include <algorithm>
@@ -1032,6 +1034,7 @@ static void ParseGetInfoResult(UniValue& result)
}
std::vector<std::string> formatted_proxies;
+ formatted_proxies.reserve(ordered_proxies.size());
for (const std::string& proxy : ordered_proxies) {
formatted_proxies.emplace_back(strprintf("%s (%s)", proxy, Join(proxy_networks.find(proxy)->second, ", ")));
}
@@ -1227,7 +1230,7 @@ static int CommandLineRPC(int argc, char *argv[])
MAIN_FUNCTION
{
#ifdef WIN32
- util::WinCmdLineArgs winArgs;
+ common::WinCmdLineArgs winArgs;
std::tie(argc, argv) = winArgs.get();
#endif
SetupEnvironment();
diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp
index f36b6054bb..c35a111313 100644
--- a/src/bitcoin-tx.cpp
+++ b/src/bitcoin-tx.cpp
@@ -8,11 +8,11 @@
#include <clientversion.h>
#include <coins.h>
+#include <common/args.h>
#include <compat/compat.h>
#include <consensus/amount.h>
#include <consensus/consensus.h>
#include <core_io.h>
-#include <fs.h>
#include <key_io.h>
#include <policy/policy.h>
#include <primitives/transaction.h>
@@ -21,6 +21,7 @@
#include <script/signingprovider.h>
#include <univalue.h>
#include <util/exception.h>
+#include <util/fs.h>
#include <util/moneystr.h>
#include <util/rbf.h>
#include <util/strencodings.h>
diff --git a/src/bitcoin-util.cpp b/src/bitcoin-util.cpp
index cf59ca9bff..e3f70e1b76 100644
--- a/src/bitcoin-util.cpp
+++ b/src/bitcoin-util.cpp
@@ -11,6 +11,7 @@
#include <chainparams.h>
#include <chainparamsbase.h>
#include <clientversion.h>
+#include <common/args.h>
#include <compat/compat.h>
#include <core_io.h>
#include <streams.h>
@@ -127,6 +128,7 @@ static int Grind(const std::vector<std::string>& args, std::string& strPrint)
std::vector<std::thread> threads;
int n_tasks = std::max(1u, std::thread::hardware_concurrency());
+ threads.reserve(n_tasks);
for (int i = 0; i < n_tasks; ++i) {
threads.emplace_back(grind_task, nBits, header, i, n_tasks, std::ref(found), std::ref(proposed_nonce));
}
diff --git a/src/bitcoin-wallet.cpp b/src/bitcoin-wallet.cpp
index 1ebe98b920..5dbf8a8616 100644
--- a/src/bitcoin-wallet.cpp
+++ b/src/bitcoin-wallet.cpp
@@ -9,6 +9,7 @@
#include <chainparams.h>
#include <chainparamsbase.h>
#include <clientversion.h>
+#include <common/args.h>
#include <common/url.h>
#include <compat/compat.h>
#include <interfaces/init.h>
@@ -99,7 +100,7 @@ MAIN_FUNCTION
{
ArgsManager& args = gArgs;
#ifdef WIN32
- util::WinCmdLineArgs winArgs;
+ common::WinCmdLineArgs winArgs;
std::tie(argc, argv) = winArgs.get();
#endif
diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp
index 2ff34125e1..e476b06017 100644
--- a/src/bitcoind.cpp
+++ b/src/bitcoind.cpp
@@ -9,6 +9,7 @@
#include <chainparams.h>
#include <clientversion.h>
+#include <common/args.h>
#include <common/init.h>
#include <common/url.h>
#include <compat/compat.h>
@@ -247,7 +248,7 @@ static bool AppInit(NodeContext& node, int argc, char* argv[])
MAIN_FUNCTION
{
#ifdef WIN32
- util::WinCmdLineArgs winArgs;
+ common::WinCmdLineArgs winArgs;
std::tie(argc, argv) = winArgs.get();
#endif
diff --git a/src/chainparams.cpp b/src/chainparams.cpp
index 6f48ee41b3..d3d358a3f0 100644
--- a/src/chainparams.cpp
+++ b/src/chainparams.cpp
@@ -6,12 +6,13 @@
#include <chainparams.h>
#include <chainparamsseeds.h>
+#include <common/args.h>
#include <consensus/merkle.h>
#include <deploymentinfo.h>
#include <hash.h> // for signet block challenge hash
+#include <logging.h>
#include <script/interpreter.h>
#include <util/string.h>
-#include <util/system.h>
#include <assert.h>
diff --git a/src/chainparamsbase.cpp b/src/chainparamsbase.cpp
index 71978081ce..eb7b31923d 100644
--- a/src/chainparamsbase.cpp
+++ b/src/chainparamsbase.cpp
@@ -5,8 +5,8 @@
#include <chainparamsbase.h>
+#include <common/args.h>
#include <tinyformat.h>
-#include <util/system.h>
#include <assert.h>
diff --git a/src/chainparamsseeds.h b/src/chainparamsseeds.h
index f065647d49..dca6028c63 100644
--- a/src/chainparamsseeds.h
+++ b/src/chainparamsseeds.h
@@ -7,857 +7,895 @@
* Each line contains a BIP155 serialized (networkID, addr, port) tuple.
*/
static const uint8_t chainparams_seed_main[] = {
- 0x01,0x04,0x02,0x03,0x19,0xb5,0x20,0x8d,
- 0x01,0x04,0x02,0x98,0x4e,0x7c,0x20,0x8d,
- 0x01,0x04,0x05,0x27,0x4a,0xa6,0x20,0x8d,
- 0x01,0x04,0x05,0x2d,0x4f,0x51,0x47,0x9c,
- 0x01,0x04,0x05,0x35,0x10,0x80,0x20,0x8d,
- 0x01,0x04,0x05,0x5f,0xba,0x4e,0x20,0x8d,
+ 0x01,0x04,0x01,0x41,0xc3,0x62,0x20,0x8d,
+ 0x01,0x04,0x02,0x3b,0xec,0x38,0x20,0x8d,
+ 0x01,0x04,0x02,0x53,0x72,0x14,0x20,0x8d,
+ 0x01,0x04,0x02,0xf8,0xc2,0x10,0x20,0x8d,
+ 0x01,0x04,0x05,0x02,0x9a,0x06,0x20,0x8d,
+ 0x01,0x04,0x05,0x65,0x8c,0x1e,0x20,0x8d,
0x01,0x04,0x05,0x80,0x57,0x7e,0x20,0x8d,
- 0x01,0x04,0x05,0x85,0x41,0x52,0x20,0x8d,
- 0x01,0x04,0x05,0x92,0x14,0xe5,0x20,0x8d,
- 0x01,0x04,0x05,0xb4,0x29,0x77,0x20,0x8d,
+ 0x01,0x04,0x05,0x90,0x15,0x31,0x20,0x8d,
+ 0x01,0x04,0x05,0xac,0x84,0x68,0x20,0x8d,
0x01,0x04,0x05,0xbc,0x3e,0x12,0x20,0x8d,
- 0x01,0x04,0x05,0xc7,0xad,0x42,0x20,0x8d,
- 0x01,0x04,0x05,0xff,0x61,0x19,0x20,0x8d,
- 0x01,0x04,0x05,0xff,0x67,0xb4,0x20,0x8d,
- 0x01,0x04,0x08,0xd1,0x46,0x4d,0x20,0x8d,
+ 0x01,0x04,0x05,0xc8,0x02,0xb4,0x20,0x8d,
+ 0x01,0x04,0x08,0x81,0xb8,0xff,0x20,0x8d,
0x01,0x04,0x08,0xd1,0x69,0x8a,0x20,0x8d,
- 0x01,0x04,0x12,0xa2,0xd0,0x99,0xbc,0xcc,
- 0x01,0x04,0x17,0xaf,0x00,0xc8,0x20,0x8d,
+ 0x01,0x04,0x0c,0x22,0x62,0x94,0x20,0x8d,
+ 0x01,0x04,0x0e,0xc7,0x66,0x97,0x20,0x8d,
+ 0x01,0x04,0x12,0x1b,0x4f,0x11,0x20,0x8d,
+ 0x01,0x04,0x12,0x1b,0x7c,0xe7,0x20,0x8d,
+ 0x01,0x04,0x12,0xd8,0xf9,0x97,0x20,0x8d,
+ 0x01,0x04,0x17,0x58,0x9b,0x3a,0x20,0x8d,
+ 0x01,0x04,0x17,0x5d,0x65,0x9e,0x20,0x8d,
+ 0x01,0x04,0x17,0x6d,0x9c,0x4c,0x20,0x8d,
+ 0x01,0x04,0x17,0xaf,0x00,0xdc,0x20,0x8d,
0x01,0x04,0x17,0xaf,0x00,0xde,0x20,0x8d,
- 0x01,0x04,0x17,0xe9,0x6b,0x15,0x20,0x8d,
- 0x01,0x04,0x17,0xec,0x19,0xa9,0x20,0x8d,
- 0x01,0x04,0x18,0x23,0x44,0xe5,0x20,0x8d,
- 0x01,0x04,0x18,0x54,0xa4,0x32,0x20,0x8d,
- 0x01,0x04,0x18,0x74,0x99,0x73,0x20,0x8d,
- 0x01,0x04,0x18,0xb8,0x00,0x92,0x20,0x8d,
- 0x01,0x04,0x1b,0x21,0xa0,0xc4,0x20,0x8d,
+ 0x01,0x04,0x18,0xe8,0x24,0xe1,0x20,0x8d,
0x01,0x04,0x1b,0x7c,0x6c,0x13,0x20,0x8d,
0x01,0x04,0x1b,0x94,0xce,0x8c,0x20,0x8d,
- 0x01,0x04,0x1f,0x11,0x40,0xc0,0x20,0x8d,
- 0x01,0x04,0x1f,0x12,0x72,0x87,0x20,0x8d,
+ 0x01,0x04,0x1f,0x07,0x46,0xc3,0x20,0x8d,
+ 0x01,0x04,0x1f,0x19,0x62,0x10,0x20,0x8d,
0x01,0x04,0x1f,0x29,0x17,0xf9,0x20,0x8d,
- 0x01,0x04,0x1f,0x2a,0xb0,0x8a,0x20,0x8d,
+ 0x01,0x04,0x1f,0x2f,0x66,0x5c,0x20,0x8d,
0x01,0x04,0x1f,0x2f,0xca,0x70,0x20,0x8d,
- 0x01,0x04,0x22,0x41,0x2d,0x9d,0x20,0x8d,
- 0x01,0x04,0x22,0x50,0x86,0x44,0x20,0x8d,
+ 0x01,0x04,0x1f,0xa5,0x4e,0x92,0x20,0x8d,
+ 0x01,0x04,0x1f,0xa5,0xe4,0x8a,0x20,0x8d,
+ 0x01,0x04,0x22,0x40,0x65,0x04,0x20,0x8d,
+ 0x01,0x04,0x22,0x69,0x13,0x61,0x20,0x8d,
+ 0x01,0x04,0x22,0x7e,0x6b,0xb3,0x20,0x8d,
0x01,0x04,0x22,0x7e,0x73,0x23,0x20,0x8d,
- 0x01,0x04,0x25,0x01,0xcc,0xe7,0x20,0x8d,
+ 0x01,0x04,0x23,0xf5,0xba,0x75,0x20,0x8d,
+ 0x01,0x04,0x25,0x0f,0x3c,0x90,0x20,0x8d,
+ 0x01,0x04,0x25,0x10,0x69,0x3f,0x20,0x8d,
0x01,0x04,0x25,0x78,0x9b,0x22,0x20,0x8d,
- 0x01,0x04,0x25,0x8f,0x76,0xae,0x20,0x8d,
+ 0x01,0x04,0x25,0x78,0xb3,0x1d,0x20,0x8d,
+ 0x01,0x04,0x25,0x8b,0x66,0x49,0x20,0x8d,
0x01,0x04,0x25,0xc1,0xe3,0x10,0x20,0x8d,
0x01,0x04,0x25,0xdc,0x87,0x97,0x20,0x8d,
- 0x01,0x04,0x25,0xeb,0x92,0xec,0x20,0x8d,
- 0x01,0x04,0x26,0x7c,0x7e,0x2a,0x20,0x8d,
+ 0x01,0x04,0x26,0x35,0x81,0x43,0x20,0x8d,
+ 0x01,0x04,0x26,0x36,0x0e,0x59,0x20,0x8d,
0x01,0x04,0x26,0x8d,0x86,0x8c,0x20,0x8d,
0x01,0x04,0x26,0x91,0x97,0x96,0x20,0x8d,
- 0x01,0x04,0x28,0x73,0x89,0x1c,0x20,0x8d,
0x01,0x04,0x29,0x48,0x9a,0x42,0x20,0x8d,
- 0x01,0x04,0x29,0x4f,0x46,0x92,0x20,0x8d,
- 0x01,0x04,0x2a,0xc1,0x37,0x87,0x20,0x8d,
- 0x01,0x04,0x2b,0xe1,0x3e,0x6b,0x20,0x8d,
+ 0x01,0x04,0x2b,0x8f,0xcb,0xc6,0x20,0x8d,
+ 0x01,0x04,0x2d,0x0f,0x7c,0x75,0x20,0x8d,
0x01,0x04,0x2d,0x2b,0x61,0x67,0x20,0x8d,
- 0x01,0x04,0x2d,0x55,0x30,0x3a,0x20,0x8d,
- 0x01,0x04,0x2d,0x7e,0x1a,0xe5,0x20,0x8d,
+ 0x01,0x04,0x2d,0x2c,0xd5,0x74,0x20,0x8d,
+ 0x01,0x04,0x2d,0x3a,0xbb,0x65,0x20,0x8d,
+ 0x01,0x04,0x2d,0x4f,0xc0,0xec,0x20,0x8d,
+ 0x01,0x04,0x2d,0x51,0xf1,0x61,0x20,0x8d,
+ 0x01,0x04,0x2d,0x53,0xdc,0x66,0x20,0x8d,
+ 0x01,0x04,0x2d,0x53,0xf1,0x2e,0x20,0x8d,
+ 0x01,0x04,0x2d,0x57,0x6a,0x39,0x20,0x8d,
+ 0x01,0x04,0x2d,0x81,0x26,0x05,0x20,0x8d,
+ 0x01,0x04,0x2d,0x82,0x14,0xb1,0x20,0x8d,
0x01,0x04,0x2d,0x86,0x8e,0x28,0x20,0x8d,
- 0x01,0x04,0x2d,0x9a,0xfc,0xa2,0x20,0x8d,
- 0x01,0x04,0x2e,0x0d,0xd8,0xa9,0x20,0x8d,
+ 0x01,0x04,0x2d,0x87,0x04,0x8f,0x20,0x8d,
+ 0x01,0x04,0x2d,0x87,0x5c,0x7f,0x20,0x8d,
+ 0x01,0x04,0x2d,0x91,0xbc,0x70,0x20,0x8d,
0x01,0x04,0x2e,0x17,0x57,0xda,0x20,0x8d,
- 0x01,0x04,0x2e,0x28,0x7f,0xa4,0x20,0x8d,
- 0x01,0x04,0x2e,0x30,0x7e,0x3a,0x20,0x8d,
- 0x01,0x04,0x2e,0x3b,0x0d,0x23,0x20,0x8d,
- 0x01,0x04,0x2e,0x48,0xee,0x11,0x20,0x8d,
- 0x01,0x04,0x2e,0x80,0x8d,0xb8,0x20,0x8d,
- 0x01,0x04,0x2e,0x92,0xf8,0x59,0x20,0x8d,
- 0x01,0x04,0x2e,0xa5,0xdd,0xd1,0x24,0x75,
+ 0x01,0x04,0x2e,0x20,0x32,0x62,0x20,0x8d,
+ 0x01,0x04,0x2e,0x20,0x4e,0x11,0x20,0x8d,
+ 0x01,0x04,0x2e,0x3b,0x28,0x5b,0x20,0x8d,
+ 0x01,0x04,0x2e,0x8a,0xf6,0x4d,0x20,0x8d,
0x01,0x04,0x2e,0xa6,0x8e,0x02,0x20,0x8d,
+ 0x01,0x04,0x2e,0xa6,0xa2,0x3b,0x20,0x8d,
0x01,0x04,0x2e,0xaf,0xb2,0x03,0x20,0x8d,
- 0x01,0x04,0x2f,0x24,0x90,0x33,0x20,0x8d,
- 0x01,0x04,0x2f,0xb4,0x31,0x9e,0x20,0x8d,
- 0x01,0x04,0x31,0xe4,0x83,0x85,0x08,0xa2,
+ 0x01,0x04,0x2e,0xbc,0x0f,0x06,0x20,0x8d,
+ 0x01,0x04,0x2e,0xbc,0x1e,0x76,0x20,0x8d,
+ 0x01,0x04,0x2e,0xdf,0xdf,0xd8,0x20,0x8d,
+ 0x01,0x04,0x2e,0xe2,0x12,0x87,0x20,0x8d,
+ 0x01,0x04,0x2f,0x58,0x56,0x4f,0x20,0x8d,
+ 0x01,0x04,0x2f,0x94,0x07,0x45,0x20,0x8d,
+ 0x01,0x04,0x2f,0xc6,0xdf,0x3c,0x20,0x8d,
0x01,0x04,0x32,0x02,0x0d,0xa4,0x20,0x8d,
- 0x01,0x04,0x32,0x23,0x47,0x33,0x20,0x8d,
+ 0x01,0x04,0x32,0x04,0x87,0x54,0x20,0x8d,
+ 0x01,0x04,0x32,0x35,0x27,0xed,0x20,0x8d,
0x01,0x04,0x32,0x35,0xfa,0xa2,0x20,0x8d,
- 0x01,0x04,0x33,0x44,0x24,0x39,0x20,0x8d,
- 0x01,0x04,0x33,0x8a,0x04,0x87,0x75,0x31,
+ 0x01,0x04,0x32,0x44,0x79,0x2c,0x20,0x8d,
+ 0x01,0x04,0x32,0x75,0x84,0xb2,0x20,0x8d,
0x01,0x04,0x33,0x9a,0x3e,0x67,0x20,0x8d,
0x01,0x04,0x33,0x9e,0x96,0x9b,0x20,0x8d,
+ 0x01,0x04,0x33,0xfa,0x2e,0xd7,0x20,0x8d,
0x01,0x04,0x36,0xb0,0x3f,0x10,0x20,0x8d,
0x01,0x04,0x3a,0x9e,0x00,0x56,0x20,0x8d,
- 0x01,0x04,0x3b,0x8a,0x73,0x89,0x20,0x8d,
- 0x01,0x04,0x3b,0xa7,0xbf,0x3c,0x20,0x8d,
0x01,0x04,0x3c,0xcd,0xcd,0x77,0x20,0x8d,
- 0x01,0x04,0x3c,0xea,0x7a,0xf5,0x20,0x8d,
- 0x01,0x04,0x3c,0xf0,0xd2,0x9b,0x20,0x8d,
- 0x01,0x04,0x3d,0xef,0x5b,0xfa,0x20,0x8d,
- 0x01,0x04,0x3e,0x4a,0x8f,0x0b,0x20,0x8d,
- 0x01,0x04,0x3e,0x8a,0xa2,0x0c,0x20,0x8d,
- 0x01,0x04,0x3e,0xa9,0x4a,0xe9,0x20,0x8d,
+ 0x01,0x04,0x3d,0x4a,0x63,0xc1,0x20,0x8d,
+ 0x01,0x04,0x3d,0x5c,0x3b,0x68,0x20,0x8d,
+ 0x01,0x04,0x3e,0x7a,0xad,0xab,0x20,0x8d,
0x01,0x04,0x3e,0xab,0x81,0x20,0x20,0x8d,
- 0x01,0x04,0x3e,0xd1,0xc6,0x41,0x20,0x8d,
- 0x01,0x04,0x3f,0xf7,0x93,0xa6,0x20,0x8d,
- 0x01,0x04,0x40,0x62,0x4c,0x3e,0x20,0x8d,
+ 0x01,0x04,0x3e,0xb2,0x1b,0xef,0x20,0x8d,
+ 0x01,0x04,0x3e,0xd1,0xd2,0x03,0x20,0x8d,
+ 0x01,0x04,0x3e,0xd7,0x7f,0x49,0x20,0x8d,
+ 0x01,0x04,0x3e,0xee,0x94,0x68,0x20,0x8d,
+ 0x01,0x04,0x3e,0xf5,0x99,0x08,0x20,0x8d,
+ 0x01,0x04,0x40,0x92,0x88,0x2d,0x20,0x8d,
+ 0x01,0x04,0x41,0x15,0x86,0xb8,0x20,0x8d,
+ 0x01,0x04,0x42,0x12,0x0d,0x92,0x20,0x8d,
+ 0x01,0x04,0x42,0x17,0xe9,0x2b,0x20,0x8d,
+ 0x01,0x04,0x42,0x1b,0x62,0xd8,0x20,0x8d,
0x01,0x04,0x42,0x1d,0x81,0xda,0x20,0x8d,
- 0x01,0x04,0x42,0x60,0xeb,0x1c,0x20,0x8d,
- 0x01,0x04,0x42,0x82,0x78,0x34,0x20,0x8d,
- 0x01,0x04,0x42,0xc6,0xd1,0xf3,0x20,0x8d,
+ 0x01,0x04,0x42,0x26,0x5e,0x0d,0x20,0x8d,
+ 0x01,0x04,0x42,0x2d,0x8d,0x2e,0x20,0x8d,
+ 0x01,0x04,0x42,0x3a,0xf3,0xd7,0x20,0x8d,
+ 0x01,0x04,0x42,0x72,0x21,0x31,0x20,0x8d,
+ 0x01,0x04,0x42,0xc6,0xd3,0xa7,0x20,0x8d,
0x01,0x04,0x42,0xd0,0x40,0x80,0x20,0x8d,
- 0x01,0x04,0x42,0xe1,0xe7,0x94,0x20,0x8d,
- 0x01,0x04,0x43,0x37,0x03,0xc8,0x20,0x8d,
- 0x01,0x04,0x43,0x3a,0xe8,0x6b,0x20,0x8d,
- 0x01,0x04,0x43,0xd3,0x5c,0x02,0x20,0x8d,
- 0x01,0x04,0x43,0xdf,0x77,0x7a,0x20,0x8d,
- 0x01,0x04,0x44,0x30,0x83,0xfb,0x20,0x8d,
- 0x01,0x04,0x44,0xb5,0x04,0x0c,0x20,0x8d,
- 0x01,0x04,0x45,0x0e,0xb9,0x09,0x20,0x8d,
- 0x01,0x04,0x45,0x36,0x1d,0xc1,0x20,0x8d,
+ 0x01,0x04,0x42,0xdb,0xc4,0xaa,0x20,0x8d,
+ 0x01,0x04,0x43,0xd2,0xe4,0xcb,0x20,0x8d,
+ 0x01,0x04,0x44,0xb7,0x4b,0xfb,0x20,0x8d,
+ 0x01,0x04,0x44,0xc2,0x7d,0x8c,0x20,0x8d,
+ 0x01,0x04,0x44,0xc7,0x78,0x11,0x20,0x8d,
+ 0x01,0x04,0x45,0x04,0x5e,0xe2,0x20,0x8d,
+ 0x01,0x04,0x45,0x08,0xaf,0xc9,0x20,0x8d,
0x01,0x04,0x45,0x3b,0x12,0x16,0x20,0x8d,
- 0x01,0x04,0x45,0x83,0x65,0xb0,0x20,0x8d,
- 0x01,0x04,0x45,0xa5,0xcd,0x8e,0x22,0x81,
+ 0x01,0x04,0x45,0xc4,0x98,0x21,0x20,0x8d,
0x01,0x04,0x45,0xe4,0xdb,0x7c,0x20,0x8d,
- 0x01,0x04,0x46,0x3b,0x7b,0x19,0x20,0x8d,
- 0x01,0x04,0x46,0x3e,0x0d,0x96,0x20,0x8d,
- 0x01,0x04,0x46,0x42,0xf8,0xaa,0x20,0x8d,
- 0x01,0x04,0x46,0x70,0x99,0xe5,0x20,0x8d,
+ 0x01,0x04,0x46,0x40,0x1b,0x0c,0x20,0x8d,
0x01,0x04,0x46,0xa0,0xf0,0x84,0x20,0x8d,
- 0x01,0x04,0x46,0xbe,0xb1,0xcc,0x20,0x8d,
- 0x01,0x04,0x47,0x1c,0xbd,0xef,0x20,0x8d,
- 0x01,0x04,0x47,0xea,0x7d,0xc6,0x20,0x8d,
- 0x01,0x04,0x48,0x4a,0x7b,0xb3,0x20,0x8d,
- 0x01,0x04,0x48,0xfd,0xec,0xd9,0x20,0x8d,
- 0x01,0x04,0x49,0xdb,0xfe,0x78,0x20,0x8d,
+ 0x01,0x04,0x47,0x4f,0x6d,0x80,0x20,0x8d,
+ 0x01,0x04,0x47,0xb8,0xc1,0x4b,0x20,0x8d,
+ 0x01,0x04,0x48,0x0f,0x3b,0xad,0x20,0x8d,
+ 0x01,0x04,0x48,0x30,0xfd,0xa8,0x20,0x8d,
+ 0x01,0x04,0x48,0xcf,0xab,0xd2,0x20,0x8d,
+ 0x01,0x04,0x49,0x75,0x84,0x8a,0x20,0x8d,
+ 0x01,0x04,0x49,0xd4,0xe2,0x3b,0x20,0x8d,
+ 0x01,0x04,0x4a,0x4c,0x97,0x6e,0x20,0x8d,
0x01,0x04,0x4a,0x5b,0x73,0xe5,0x20,0x8d,
0x01,0x04,0x4a,0x76,0x89,0x77,0x20,0x8d,
- 0x01,0x04,0x4a,0xc3,0xa6,0x64,0x20,0x8d,
+ 0x01,0x04,0x4a,0xd5,0xaf,0x6c,0x20,0x8d,
+ 0x01,0x04,0x4a,0xd5,0xfb,0xef,0x20,0x8d,
0x01,0x04,0x4a,0xdc,0xff,0xbe,0x20,0x8d,
- 0x01,0x04,0x4c,0x43,0xd3,0x6e,0x20,0x8d,
- 0x01,0x04,0x4c,0xa9,0xa3,0x0e,0x20,0x8d,
- 0x01,0x04,0x4d,0x20,0x79,0xa2,0x20,0x8d,
- 0x01,0x04,0x4d,0x35,0x87,0x4a,0x20,0x8d,
+ 0x01,0x04,0x4a,0xdd,0xbd,0x6d,0x20,0x8d,
+ 0x01,0x04,0x4b,0x53,0xcb,0xe1,0x20,0x8d,
+ 0x01,0x04,0x4b,0xac,0x34,0xba,0x20,0x8d,
+ 0x01,0x04,0x4c,0x18,0x8f,0x16,0x20,0x8d,
+ 0x01,0x04,0x4c,0x45,0xca,0xf7,0x20,0x8d,
+ 0x01,0x04,0x4c,0x49,0xc6,0xf2,0x20,0x8d,
+ 0x01,0x04,0x4c,0x77,0xf8,0xf0,0x20,0x8d,
+ 0x01,0x04,0x4d,0x14,0x30,0x90,0x20,0x8d,
+ 0x01,0x04,0x4d,0x16,0x98,0xef,0x20,0x8d,
+ 0x01,0x04,0x4d,0x25,0xe0,0xde,0x20,0x8d,
+ 0x01,0x04,0x4d,0x30,0xc4,0xea,0x20,0x8d,
0x01,0x04,0x4d,0x46,0x10,0xf5,0x20,0x8d,
- 0x01,0x04,0x4d,0x55,0xcc,0x95,0x20,0x8d,
- 0x01,0x04,0x4d,0x6b,0x26,0xef,0x20,0x8d,
- 0x01,0x04,0x4d,0x78,0x1a,0x66,0x20,0x8d,
0x01,0x04,0x4d,0xa2,0xbe,0x5a,0x20,0x8d,
0x01,0x04,0x4e,0x14,0xe3,0xf9,0x20,0x8d,
0x01,0x04,0x4e,0x15,0xa7,0x08,0x20,0x8d,
- 0x01,0x04,0x4e,0x1b,0x8b,0x0d,0x20,0x8d,
- 0x01,0x04,0x4e,0x5a,0x5b,0xdc,0x20,0x8d,
+ 0x01,0x04,0x4e,0x23,0x93,0xcb,0x20,0x8d,
0x01,0x04,0x4e,0x6c,0x6c,0x19,0x20,0x8d,
- 0x01,0x04,0x4e,0x6c,0x6c,0x26,0x20,0x8d,
- 0x01,0x04,0x4f,0x4d,0xb6,0xb7,0x20,0x8d,
- 0x01,0x04,0x4f,0x62,0x9f,0x07,0x2c,0x45,
- 0x01,0x04,0x4f,0xbd,0xd3,0xc9,0x20,0x8d,
- 0x01,0x04,0x50,0x37,0xe1,0x9e,0x20,0x8d,
- 0x01,0x04,0x50,0x53,0xba,0x23,0x20,0x8d,
- 0x01,0x04,0x50,0x58,0xac,0xe3,0xfb,0x08,
- 0x01,0x04,0x50,0xd1,0x57,0x67,0x24,0x75,
+ 0x01,0x04,0x4e,0x9a,0xed,0x3c,0x20,0x8d,
+ 0x01,0x04,0x4f,0x0b,0x1f,0x4c,0x20,0x8d,
+ 0x01,0x04,0x4f,0x57,0x58,0xeb,0x20,0x8d,
+ 0x01,0x04,0x4f,0x65,0x01,0x19,0x20,0x8d,
+ 0x01,0x04,0x4f,0x7c,0x07,0xf1,0x20,0x8d,
+ 0x01,0x04,0x4f,0x7c,0x07,0xfd,0x20,0x8d,
+ 0x01,0x04,0x4f,0x96,0x44,0x2a,0x20,0x8d,
+ 0x01,0x04,0x4f,0xf9,0x0a,0x35,0x20,0x8d,
+ 0x01,0x04,0x50,0x52,0x15,0x4d,0x20,0x8d,
+ 0x01,0x04,0x50,0x52,0x4c,0x3b,0x20,0x8d,
+ 0x01,0x04,0x50,0x58,0xac,0xe3,0x20,0x8d,
+ 0x01,0x04,0x50,0x5d,0xd5,0xf6,0x20,0x8d,
+ 0x01,0x04,0x50,0x6f,0x8e,0xd5,0x20,0x8d,
+ 0x01,0x04,0x50,0xd0,0xe3,0x86,0x20,0x8d,
+ 0x01,0x04,0x50,0xd0,0xe4,0x09,0x20,0x8d,
+ 0x01,0x04,0x50,0xd1,0x40,0x56,0x20,0x8d,
0x01,0x04,0x50,0xe5,0x1c,0x3c,0x20,0x8d,
0x01,0x04,0x51,0x07,0x10,0xb6,0x20,0x8d,
- 0x01,0x04,0x51,0x07,0x11,0xca,0x20,0x8d,
0x01,0x04,0x51,0x13,0x0a,0x02,0x20,0x8d,
- 0x01,0x04,0x51,0x58,0xdd,0xbe,0x20,0x8d,
+ 0x01,0x04,0x51,0xa2,0xc4,0x2b,0x20,0x8d,
0x01,0x04,0x51,0xab,0x16,0x8f,0x20,0x8d,
+ 0x01,0x04,0x51,0xac,0xdd,0x04,0x20,0x8d,
0x01,0x04,0x51,0xe0,0x2c,0xa4,0x20,0x8d,
- 0x01,0x04,0x51,0xe0,0xa0,0x51,0x20,0x8d,
+ 0x01,0x04,0x51,0xf5,0x60,0x24,0x20,0x8d,
0x01,0x04,0x52,0x01,0x44,0x36,0x20,0x8d,
- 0x01,0x04,0x52,0x15,0xa4,0x2f,0x20,0x8d,
- 0x01,0x04,0x52,0x40,0x74,0x05,0x20,0x8d,
0x01,0x04,0x52,0x42,0x0a,0x0b,0x20,0x8d,
+ 0x01,0x04,0x52,0x42,0xd3,0x1f,0x20,0x8d,
+ 0x01,0x04,0x52,0x47,0x04,0x9a,0x20,0x8d,
0x01,0x04,0x52,0x60,0x60,0x28,0x20,0x8d,
0x01,0x04,0x52,0x74,0x32,0x65,0x20,0x8d,
- 0x01,0x04,0x52,0x81,0x44,0x3e,0x20,0x8d,
- 0x01,0x04,0x52,0x88,0x63,0x7a,0x20,0x8d,
- 0x01,0x04,0x52,0x9a,0x18,0xd1,0x20,0x8d,
- 0x01,0x04,0x52,0xc5,0xd7,0x7d,0x20,0x8d,
- 0x01,0x04,0x53,0x80,0x84,0x5b,0x20,0x8d,
+ 0x01,0x04,0x52,0x88,0x62,0xf9,0x20,0x8d,
+ 0x01,0x04,0x52,0xc3,0xed,0xfd,0x20,0x8d,
0x01,0x04,0x53,0x89,0x29,0x0a,0x20,0x8d,
- 0x01,0x04,0x53,0xd0,0x06,0xd3,0x20,0x8d,
+ 0x01,0x04,0x53,0xab,0xaf,0x05,0x20,0x8d,
0x01,0x04,0x53,0xd0,0xc1,0xf2,0x20,0x8d,
- 0x01,0x04,0x53,0xde,0x8a,0x55,0x20,0x8d,
- 0x01,0x04,0x53,0xf0,0x7c,0x44,0x20,0x8d,
- 0x01,0x04,0x53,0xf3,0xbf,0xc7,0x20,0x8d,
- 0x01,0x04,0x54,0x09,0x05,0xd3,0x20,0x8d,
- 0x01,0x04,0x54,0x1c,0x39,0x5a,0x20,0x8d,
+ 0x01,0x04,0x53,0xe9,0x4c,0xa5,0x20,0x8d,
+ 0x01,0x04,0x53,0xf0,0x59,0xc4,0x20,0x8d,
0x01,0x04,0x54,0x26,0x03,0xf9,0x20,0x8d,
- 0x01,0x04,0x54,0x70,0x3c,0x10,0x20,0x8d,
- 0x01,0x04,0x54,0xd7,0x38,0x77,0x20,0x8d,
- 0x01,0x04,0x54,0xe2,0xf3,0xaf,0x20,0x8d,
- 0x01,0x04,0x54,0xf5,0x0e,0x49,0x20,0x8d,
- 0x01,0x04,0x54,0xfc,0x9d,0x5a,0x47,0x9d,
+ 0x01,0x04,0x54,0x36,0x17,0x30,0x20,0x8d,
+ 0x01,0x04,0x54,0x7e,0xd8,0x4d,0x20,0x8d,
+ 0x01,0x04,0x54,0xd3,0xbb,0xd3,0x20,0x8d,
+ 0x01,0x04,0x54,0xf6,0xc8,0x7a,0x20,0x8d,
0x01,0x04,0x54,0xff,0xf4,0x3d,0x20,0x8d,
- 0x01,0x04,0x55,0x17,0x18,0x7b,0x20,0x8d,
- 0x01,0x04,0x55,0x34,0xb9,0x1d,0x21,0xda,
- 0x01,0x04,0x55,0x3a,0x78,0xc9,0x20,0x8d,
- 0x01,0x04,0x55,0x5d,0x60,0x12,0x20,0x8d,
- 0x01,0x04,0x55,0xa5,0x08,0xc5,0x20,0x8d,
- 0x01,0x04,0x55,0xad,0xa5,0x42,0x20,0x8d,
- 0x01,0x04,0x55,0xb8,0x8f,0x69,0x20,0x8d,
- 0x01,0x04,0x55,0xbf,0x4a,0x67,0x20,0x8d,
+ 0x01,0x04,0x55,0xa5,0x2a,0x73,0x20,0x8d,
0x01,0x04,0x55,0xc2,0xee,0x86,0x20,0x8d,
- 0x01,0x04,0x55,0xc3,0x36,0x6e,0x20,0x8d,
- 0x01,0x04,0x55,0xc3,0xc4,0x8e,0x20,0x8d,
- 0x01,0x04,0x55,0xd0,0x45,0x0b,0x20,0x8d,
0x01,0x04,0x55,0xd0,0x45,0x15,0x20,0x8d,
0x01,0x04,0x55,0xd0,0x47,0x24,0x20,0x8d,
- 0x01,0x04,0x55,0xd0,0x47,0x27,0x20,0x8d,
+ 0x01,0x04,0x55,0xd1,0xf0,0x5b,0x20,0x8d,
0x01,0x04,0x55,0xd6,0x76,0x47,0x20,0x8d,
0x01,0x04,0x55,0xd6,0xa1,0xfc,0x20,0x8d,
- 0x01,0x04,0x55,0xd8,0x20,0x49,0x20,0x8d,
- 0x01,0x04,0x55,0xfe,0x62,0xdd,0x20,0x8d,
- 0x01,0x04,0x56,0x3a,0x0b,0x98,0x20,0x8d,
+ 0x01,0x04,0x55,0xec,0xbe,0xfc,0x20,0x8d,
+ 0x01,0x04,0x55,0xf3,0x73,0x88,0x20,0x8d,
+ 0x01,0x04,0x56,0x16,0x14,0x0d,0x20,0x8d,
+ 0x01,0x04,0x56,0x31,0x22,0x5c,0x20,0x8d,
0x01,0x04,0x56,0x5f,0x08,0xf9,0x20,0x8d,
- 0x01,0x04,0x56,0x64,0x1a,0xbc,0x20,0x8d,
- 0x01,0x04,0x56,0x6a,0x8f,0x8f,0xd8,0x4d,
- 0x01,0x04,0x56,0x7c,0x91,0xb8,0x20,0x8d,
- 0x01,0x04,0x56,0x85,0xfb,0xef,0x22,0xc5,
+ 0x01,0x04,0x56,0x68,0xe4,0x0a,0x20,0x8d,
+ 0x01,0x04,0x56,0x68,0xe4,0x17,0x20,0x8d,
0x01,0x04,0x57,0x4f,0x5e,0xdd,0x20,0x8d,
- 0x01,0x04,0x57,0x78,0x08,0x05,0x4e,0x28,
- 0x01,0x04,0x57,0x7d,0x9d,0xdc,0x20,0x8d,
- 0x01,0x04,0x58,0x09,0x4c,0x85,0x20,0x8d,
- 0x01,0x04,0x58,0x5a,0xb8,0x44,0x20,0x8d,
- 0x01,0x04,0x58,0x97,0x65,0x0e,0x13,0x88,
- 0x01,0x04,0x58,0x97,0x65,0xfd,0x13,0x88,
- 0x01,0x04,0x58,0xc6,0x5c,0x2f,0x20,0x8d,
+ 0x01,0x04,0x58,0x0a,0x59,0x17,0x20,0x8d,
+ 0x01,0x04,0x58,0x54,0xdf,0x1e,0x20,0x8d,
+ 0x01,0x04,0x58,0x56,0x7d,0x32,0x20,0x8d,
+ 0x01,0x04,0x58,0x5a,0x4d,0x64,0x20,0x8d,
+ 0x01,0x04,0x58,0x61,0x28,0x32,0x20,0x8d,
+ 0x01,0x04,0x58,0x89,0x6d,0x3e,0x20,0x8d,
+ 0x01,0x04,0x58,0x93,0xf4,0xfa,0x20,0x8d,
0x01,0x04,0x58,0xd0,0x73,0x46,0x20,0x8d,
- 0x01,0x04,0x58,0xd2,0x0f,0x18,0x20,0x8d,
- 0x01,0x04,0x58,0xd4,0x2d,0xa6,0x20,0x8d,
- 0x01,0x04,0x59,0x66,0xce,0xee,0x20,0x8d,
- 0x01,0x04,0x59,0x67,0x6f,0x22,0x20,0x8d,
- 0x01,0x04,0x59,0x72,0x8f,0x71,0x20,0x8d,
- 0x01,0x04,0x59,0x86,0x3e,0x4a,0x20,0x8d,
- 0x01,0x04,0x59,0x98,0x08,0xe7,0x20,0x8d,
- 0x01,0x04,0x59,0xa1,0x1a,0x4e,0x20,0x8d,
- 0x01,0x04,0x59,0xcf,0x83,0x13,0x20,0x8d,
- 0x01,0x04,0x59,0xf8,0xc1,0xe5,0x20,0x8d,
- 0x01,0x04,0x5a,0x03,0x30,0x3e,0x20,0x8d,
- 0x01,0x04,0x5a,0x92,0x79,0x61,0x20,0x8d,
+ 0x01,0x04,0x58,0xd4,0x35,0xf6,0x20,0x8d,
+ 0x01,0x04,0x59,0x23,0x8e,0xa8,0x20,0x8d,
+ 0x01,0x04,0x59,0x4e,0x6f,0xc5,0x20,0x8d,
+ 0x01,0x04,0x59,0x75,0x3b,0x81,0x20,0x8d,
+ 0x01,0x04,0x59,0x93,0x6c,0xc8,0x20,0x8d,
+ 0x01,0x04,0x59,0xa3,0x84,0xb4,0x20,0x8d,
+ 0x01,0x04,0x59,0xa5,0xe8,0xf2,0x20,0x8d,
+ 0x01,0x04,0x59,0xd8,0x15,0x60,0x20,0x8d,
+ 0x01,0x04,0x5a,0x32,0xac,0xb6,0x20,0x8d,
0x01,0x04,0x5a,0x92,0x82,0xd6,0x20,0x8d,
- 0x01,0x04,0x5a,0xc4,0xa9,0x3a,0x20,0x8d,
- 0x01,0x04,0x5a,0xfa,0x09,0x01,0x20,0x8d,
+ 0x01,0x04,0x5a,0x92,0xd0,0xa2,0x20,0x8d,
+ 0x01,0x04,0x5a,0x9c,0x1a,0x94,0x20,0x8d,
+ 0x01,0x04,0x5a,0xa3,0xac,0x8b,0x20,0x8d,
+ 0x01,0x04,0x5a,0xb1,0xa3,0x4d,0x20,0x8d,
+ 0x01,0x04,0x5b,0x43,0x91,0x6e,0x20,0x8d,
0x01,0x04,0x5b,0x5d,0xc2,0x9a,0x20,0x8d,
- 0x01,0x04,0x5b,0x7e,0x28,0x6d,0x20,0x8d,
- 0x01,0x04,0x5b,0xcc,0x63,0xb2,0x20,0x8d,
+ 0x01,0x04,0x5b,0x7b,0xb6,0xa4,0x20,0x8d,
+ 0x01,0x04,0x5b,0x7b,0xb7,0xdb,0x20,0x8d,
+ 0x01,0x04,0x5b,0x87,0x00,0xbb,0x20,0x8d,
+ 0x01,0x04,0x5b,0x93,0xe8,0x62,0x20,0x8d,
+ 0x01,0x04,0x5b,0xb8,0xa8,0xf9,0x20,0x8d,
+ 0x01,0x04,0x5b,0xc1,0xed,0x74,0x20,0x8d,
+ 0x01,0x04,0x5b,0xc7,0x29,0x2d,0x20,0x8d,
0x01,0x04,0x5b,0xcc,0x95,0x05,0x20,0x8d,
- 0x01,0x04,0x5b,0xce,0x11,0xc3,0x20,0x8d,
- 0x01,0x04,0x5b,0xd1,0x33,0x83,0x20,0x8d,
0x01,0x04,0x5b,0xd7,0x5b,0xfe,0x20,0x8d,
- 0x01,0x04,0x5c,0x5b,0x1b,0x3c,0x20,0x8d,
+ 0x01,0x04,0x5b,0xdb,0x19,0xe8,0x20,0x8d,
+ 0x01,0x04,0x5b,0xed,0x58,0xda,0x20,0x8d,
+ 0x01,0x04,0x5c,0x1b,0x96,0x2e,0x20,0x8d,
+ 0x01,0x04,0x5c,0x1b,0x96,0x2f,0x20,0x8d,
0x01,0x04,0x5c,0xdd,0x14,0xe8,0x20,0x8d,
- 0x01,0x04,0x5c,0xff,0x55,0x1f,0x20,0x8d,
- 0x01,0x04,0x5d,0x04,0x65,0x25,0x20,0x8d,
- 0x01,0x04,0x5d,0x2e,0x51,0x05,0x20,0x8d,
- 0x01,0x04,0x5d,0x39,0x51,0xa2,0x20,0x8d,
- 0x01,0x04,0x5d,0x49,0x27,0xc4,0x20,0x8d,
- 0x01,0x04,0x5d,0x5a,0x52,0xe2,0x20,0x8d,
+ 0x01,0x04,0x5c,0xdd,0x7e,0x41,0x20,0x8d,
+ 0x01,0x04,0x5d,0x21,0xc0,0xcc,0x20,0x8d,
+ 0x01,0x04,0x5d,0x29,0xed,0x4e,0x20,0x8d,
0x01,0x04,0x5d,0x5f,0x58,0x0d,0x20,0x8d,
+ 0x01,0x04,0x5d,0x5f,0xe3,0x7d,0x20,0x8d,
+ 0x01,0x04,0x5d,0x67,0x0d,0x01,0x20,0x8d,
+ 0x01,0x04,0x5d,0x73,0x56,0xef,0x20,0x8d,
0x01,0x04,0x5d,0x7b,0xb4,0xa4,0x20,0x8d,
- 0x01,0x04,0x5d,0xbd,0x91,0xa9,0x20,0x8d,
- 0x01,0x04,0x5e,0x11,0xb9,0x6b,0x20,0x8d,
- 0x01,0x04,0x5e,0x4b,0xc6,0x78,0x20,0x8d,
- 0x01,0x04,0x5e,0x72,0xc4,0xa9,0x20,0x8d,
- 0x01,0x04,0x5e,0x8e,0xd5,0xfa,0xd8,0xf8,
+ 0x01,0x04,0x5d,0xba,0xc9,0xad,0x20,0x8d,
+ 0x01,0x04,0x5d,0xbe,0x75,0x1a,0x20,0x8d,
+ 0x01,0x04,0x5e,0x13,0x07,0x37,0x20,0x8d,
+ 0x01,0x04,0x5e,0x17,0x15,0x50,0x20,0x8d,
+ 0x01,0x04,0x5e,0x17,0xcd,0x6e,0x20,0x8d,
+ 0x01,0x04,0x5e,0x83,0x00,0x49,0x20,0x8d,
+ 0x01,0x04,0x5e,0x8e,0xed,0x04,0x20,0x8d,
0x01,0x04,0x5e,0x9a,0x9f,0x63,0x20,0x8d,
- 0x01,0x04,0x5e,0x9e,0xf6,0xb7,0x20,0x8d,
- 0x01,0x04,0x5e,0xef,0x91,0x20,0x20,0x8d,
- 0x01,0x04,0x5f,0x1f,0x0c,0x16,0x20,0x8d,
- 0x01,0x04,0x5f,0x1f,0xc4,0x0f,0x20,0x8d,
- 0x01,0x04,0x5f,0x6e,0x85,0xdf,0x20,0x8d,
+ 0x01,0x04,0x5e,0xca,0x32,0xc8,0x20,0x8d,
+ 0x01,0x04,0x5e,0xe7,0xfd,0x12,0x20,0x8d,
+ 0x01,0x04,0x5f,0x2a,0x8c,0x8e,0x20,0x8d,
+ 0x01,0x04,0x5f,0x43,0x12,0x64,0x20,0x8d,
+ 0x01,0x04,0x5f,0x46,0xee,0xb0,0x20,0x8d,
+ 0x01,0x04,0x5f,0x53,0x49,0x1f,0x20,0x8d,
+ 0x01,0x04,0x5f,0x5a,0x80,0x03,0x20,0x8d,
0x01,0x04,0x5f,0x6e,0xea,0x5d,0x20,0x8d,
0x01,0x04,0x5f,0xa1,0x0c,0x2d,0x20,0x8d,
+ 0x01,0x04,0x5f,0xac,0x3e,0xa7,0x20,0x8d,
+ 0x01,0x04,0x5f,0xb3,0x80,0x57,0x20,0x8d,
0x01,0x04,0x5f,0xbf,0x82,0x64,0x20,0x8d,
- 0x01,0x04,0x5f,0xd0,0x9e,0xa1,0x20,0x8d,
- 0x01,0x04,0x5f,0xd5,0x91,0xda,0x20,0x8d,
0x01,0x04,0x5f,0xd6,0x35,0x9a,0x20,0x8d,
- 0x01,0x04,0x5f,0xd6,0x35,0xa0,0x20,0x8d,
- 0x01,0x04,0x60,0x2c,0x9c,0xc7,0x20,0x8d,
+ 0x01,0x04,0x60,0x03,0x35,0xfe,0x20,0x8d,
0x01,0x04,0x61,0x4b,0x91,0x0c,0x20,0x8d,
+ 0x01,0x04,0x61,0x51,0xc6,0xb4,0x20,0x8d,
+ 0x01,0x04,0x61,0x57,0xd8,0x6e,0x20,0x8d,
+ 0x01,0x04,0x63,0xe5,0xd2,0x6f,0x20,0x8d,
+ 0x01,0x04,0x63,0xf6,0x57,0x02,0x20,0x8d,
+ 0x01,0x04,0x65,0x2b,0x7c,0xc3,0x20,0x8d,
0x01,0x04,0x66,0x84,0xc0,0x8d,0x20,0x8d,
- 0x01,0x04,0x67,0x0e,0xf5,0xfa,0x20,0x8d,
- 0x01,0x04,0x67,0x55,0x26,0xcd,0x20,0x8d,
- 0x01,0x04,0x67,0x58,0x5c,0x4e,0x20,0x8c,
+ 0x01,0x04,0x67,0x15,0x03,0x59,0x20,0x8d,
+ 0x01,0x04,0x67,0x23,0x79,0x48,0x20,0x8d,
0x01,0x04,0x67,0x63,0xa8,0x64,0x20,0x8d,
0x01,0x04,0x67,0x63,0xa8,0x8c,0x20,0x8d,
0x01,0x04,0x67,0x63,0xaa,0xd2,0x20,0x8d,
0x01,0x04,0x67,0x63,0xaa,0xdc,0x20,0x8d,
- 0x01,0x04,0x67,0x64,0x2c,0x46,0x20,0x8d,
- 0x01,0x04,0x67,0xb2,0xec,0x1b,0x20,0x8d,
- 0x01,0x04,0x67,0xd1,0x0c,0x90,0x20,0x8d,
- 0x01,0x04,0x68,0x3b,0x93,0x0f,0x20,0x8d,
- 0x01,0x04,0x68,0x81,0xab,0x79,0x20,0x8d,
- 0x01,0x04,0x68,0xc8,0x41,0xea,0x20,0x8d,
+ 0x01,0x04,0x67,0x69,0xca,0x32,0x20,0x8d,
0x01,0x04,0x68,0xee,0xdc,0xc7,0x20,0x8d,
+ 0x01,0x04,0x68,0xf3,0x21,0xa5,0x20,0x8d,
0x01,0x04,0x68,0xf4,0x49,0x06,0x20,0x8d,
- 0x01,0x04,0x6a,0x47,0x77,0xe6,0x20,0x8d,
- 0x01,0x04,0x6b,0xad,0xa6,0x2b,0x20,0x8d,
- 0x01,0x04,0x6c,0xa1,0x16,0x4e,0x20,0x8d,
- 0x01,0x04,0x6c,0xae,0x3f,0xea,0x20,0x8d,
+ 0x01,0x04,0x6c,0x1a,0x7d,0xd6,0x20,0x8d,
+ 0x01,0x04,0x6d,0x56,0x3c,0x21,0x20,0x8d,
0x01,0x04,0x6d,0x63,0x3f,0x9f,0x20,0x8d,
- 0x01,0x04,0x6d,0x69,0x28,0xf7,0x20,0x8d,
- 0x01,0x04,0x6d,0x6b,0xb9,0x82,0x20,0x8d,
- 0x01,0x04,0x6d,0x6e,0xef,0x04,0x20,0x8d,
- 0x01,0x04,0x6d,0xad,0x29,0x2b,0x20,0x8d,
+ 0x01,0x04,0x6d,0x78,0xc2,0x88,0x20,0x8d,
+ 0x01,0x04,0x6d,0x7b,0xe9,0x8a,0x20,0x8d,
+ 0x01,0x04,0x6d,0x7b,0xf0,0x35,0x20,0x8d,
+ 0x01,0x04,0x6d,0x99,0x5e,0x23,0x20,0x8d,
+ 0x01,0x04,0x6d,0xad,0x7e,0x9d,0x20,0x8d,
+ 0x01,0x04,0x6d,0xc1,0x4c,0xc8,0x20,0x8d,
+ 0x01,0x04,0x6d,0xdd,0xe5,0xc5,0x20,0x8d,
0x01,0x04,0x6d,0xec,0x5a,0x75,0x20,0x8d,
0x01,0x04,0x6d,0xf8,0xce,0x0d,0x20,0x8d,
- 0x01,0x04,0x6d,0xff,0x6a,0xce,0x20,0x8d,
0x01,0x04,0x6f,0x5a,0x8c,0x17,0x20,0x8d,
0x01,0x04,0x6f,0x5a,0x8c,0x2e,0x20,0x8d,
- 0x01,0x04,0x6f,0x5a,0x9f,0xf6,0x20,0x8d,
- 0x01,0x04,0x70,0x76,0xbc,0x32,0x20,0x8d,
- 0x01,0x04,0x73,0x2f,0x8d,0xfa,0x22,0xb5,
+ 0x01,0x04,0x6f,0x5a,0x91,0x25,0x20,0x8d,
+ 0x01,0x04,0x72,0xad,0x9f,0xd1,0x20,0x8d,
0x01,0x04,0x74,0x3a,0xab,0x43,0x20,0x8d,
- 0x01,0x04,0x76,0x5c,0x6b,0x6c,0x20,0x8d,
+ 0x01,0x04,0x77,0x1f,0xb3,0xca,0x20,0x8d,
0x01,0x04,0x77,0x2a,0x37,0xcb,0x20,0x8d,
- 0x01,0x04,0x78,0x4f,0x47,0x48,0x20,0x8d,
- 0x01,0x04,0x79,0x63,0xf0,0x57,0x20,0x8d,
+ 0x01,0x04,0x7a,0xde,0xa0,0xbe,0x20,0x8d,
0x01,0x04,0x7b,0x3c,0xd5,0xc0,0x20,0x8d,
- 0x01,0x04,0x7c,0x9c,0x9e,0x64,0x20,0x8d,
- 0x01,0x04,0x7c,0xde,0x7b,0xee,0x20,0x8d,
- 0x01,0x04,0x7d,0xb2,0x06,0x74,0x20,0x8d,
+ 0x01,0x04,0x7c,0xc5,0x36,0x71,0x20,0x8d,
+ 0x01,0x04,0x7d,0xa8,0x8c,0x6c,0x20,0x8d,
0x01,0x04,0x80,0x00,0xbe,0x1a,0x20,0x8d,
0x01,0x04,0x80,0x41,0xc2,0x88,0x20,0x8d,
0x01,0x04,0x81,0x0d,0xbd,0xd4,0x20,0x8d,
- 0x01,0x04,0x81,0x7e,0xac,0x73,0x20,0x8d,
- 0x01,0x04,0x81,0x92,0x34,0xae,0x20,0x8d,
- 0x01,0x04,0x82,0x2c,0xa8,0xca,0x20,0x8d,
- 0x01,0x04,0x83,0xa1,0x50,0xa6,0x20,0x8d,
+ 0x01,0x04,0x81,0x0d,0xbd,0xd7,0x20,0x8d,
+ 0x01,0x04,0x81,0xe2,0xd8,0x94,0x20,0x8d,
0x01,0x04,0x83,0xbc,0x28,0xbf,0x20,0x8d,
+ 0x01,0x04,0x86,0x41,0x09,0x3f,0x20,0x8d,
+ 0x01,0x04,0x86,0x7a,0xc8,0xa0,0x20,0x8d,
0x01,0x04,0x86,0xc3,0xb9,0x34,0x20,0x8d,
- 0x01,0x04,0x87,0x86,0xee,0x2f,0x20,0x8d,
- 0x01,0x04,0x87,0xb4,0xda,0x3a,0x20,0x8d,
- 0x01,0x04,0x87,0xb5,0xd7,0xed,0x20,0x8d,
- 0x01,0x04,0x88,0x1d,0x6d,0xb4,0x20,0x8d,
+ 0x01,0x04,0x87,0x13,0xfd,0x65,0x20,0x8d,
+ 0x01,0x04,0x88,0x1d,0x6d,0x3a,0x20,0x8d,
0x01,0x04,0x88,0x20,0xee,0x06,0x20,0x8d,
- 0x01,0x04,0x88,0x38,0xaa,0x60,0x20,0x8d,
- 0x01,0x04,0x89,0x19,0x26,0x6c,0x20,0x8d,
+ 0x01,0x04,0x88,0x31,0xc9,0x18,0x20,0x8d,
0x01,0x04,0x89,0xe2,0x22,0x2e,0x20,0x8d,
- 0x01,0x04,0x8a,0xcf,0xd3,0x6a,0x20,0x8d,
+ 0x01,0x04,0x8a,0xcf,0xd3,0xbd,0x20,0x8d,
0x01,0x04,0x8b,0x82,0x29,0x52,0x20,0x8d,
- 0x01,0x04,0x8b,0x99,0xff,0x6b,0x20,0x8d,
- 0x01,0x04,0x8c,0xbe,0x0c,0x81,0x20,0x8d,
+ 0x01,0x04,0x8c,0xee,0xdc,0x63,0x20,0x8d,
0x01,0x04,0x8e,0x36,0xb5,0xda,0x20,0x8d,
+ 0x01,0x04,0x8e,0xa6,0x13,0x17,0x20,0x8d,
+ 0x01,0x04,0x8e,0xfe,0x57,0x73,0x20,0x8d,
0x01,0x04,0x8f,0xb1,0xe5,0x95,0x20,0x8d,
- 0x01,0x04,0x8f,0xb2,0x40,0x0a,0x20,0x8d,
- 0x01,0x04,0x90,0x18,0xf5,0xb7,0x20,0x8d,
- 0x01,0x04,0x90,0x7e,0x82,0xb2,0x20,0x8d,
- 0x01,0x04,0x92,0x04,0x7c,0x81,0x20,0x8d,
+ 0x01,0x04,0x90,0x02,0x65,0x15,0x20,0x8d,
+ 0x01,0x04,0x90,0x18,0xec,0x40,0x20,0x8d,
+ 0x01,0x04,0x91,0x28,0x33,0x34,0x20,0x8d,
0x01,0x04,0x92,0x47,0x45,0x67,0x20,0x8d,
- 0x01,0x04,0x92,0x53,0x38,0x45,0x20,0x8d,
- 0x01,0x04,0x93,0xc2,0xb1,0xa5,0x20,0x8d,
- 0x01,0x04,0x95,0x5a,0xd6,0x4e,0x20,0x8d,
- 0x01,0x04,0x95,0x66,0x9d,0x9c,0x20,0x8d,
- 0x01,0x04,0x97,0xf8,0x9c,0x37,0x20,0x8d,
- 0x01,0x04,0x97,0xfc,0xc1,0xf5,0x20,0x8d,
- 0x01,0x04,0x99,0x5c,0x5d,0x72,0x20,0x8d,
- 0x01,0x04,0x9a,0xd3,0x06,0x02,0x20,0x8d,
- 0x01,0x04,0x9c,0x11,0x67,0x02,0x1f,0x98,
+ 0x01,0x04,0x92,0x78,0xf1,0xad,0x20,0x8d,
+ 0x01,0x04,0x93,0x32,0xee,0x35,0x20,0x8d,
+ 0x01,0x04,0x94,0x67,0x65,0x84,0x20,0x8d,
+ 0x01,0x04,0x95,0x4b,0x30,0x5c,0x20,0x8d,
+ 0x01,0x04,0x98,0x2c,0x89,0x53,0x20,0x8d,
+ 0x01,0x04,0x9a,0x00,0x03,0xc2,0x20,0x8d,
+ 0x01,0x04,0x9a,0x1a,0x89,0x69,0x20,0x8d,
+ 0x01,0x04,0x9a,0x1a,0x9a,0x49,0x20,0x8d,
+ 0x01,0x04,0x9a,0x39,0x05,0x0b,0x20,0x8d,
+ 0x01,0x04,0x9b,0x04,0x37,0x15,0x20,0x8d,
+ 0x01,0x04,0x9c,0x92,0x89,0x8e,0x20,0x8d,
0x01,0x04,0x9c,0x92,0xb1,0xdd,0x20,0x8d,
- 0x01,0x04,0x9d,0x83,0x8f,0xad,0x20,0x8d,
- 0x01,0x04,0x9e,0x3a,0xbc,0x25,0x20,0x8d,
- 0x01,0x04,0x9e,0xf8,0x27,0xef,0x20,0x8d,
- 0x01,0x04,0x9f,0x59,0xe6,0x80,0x20,0x8d,
+ 0x01,0x04,0x9d,0x16,0x48,0xaf,0x20,0x8d,
+ 0x01,0x04,0x9d,0x61,0x00,0x76,0x20,0x8d,
+ 0x01,0x04,0x9e,0x8c,0x8d,0x45,0x20,0x8d,
+ 0x01,0x04,0x9e,0xb5,0x84,0x54,0x20,0x8d,
+ 0x01,0x04,0x9f,0x02,0xd7,0x62,0x20,0x8d,
0x01,0x04,0x9f,0xc4,0x03,0xef,0x20,0x8d,
0x01,0x04,0x9f,0xe0,0xbd,0xfa,0x20,0x8d,
- 0x01,0x04,0xa0,0x48,0x33,0x9a,0x20,0x8d,
- 0x01,0x04,0xa1,0x1d,0xec,0x37,0x20,0x8d,
- 0x01,0x04,0xa1,0x61,0x77,0xa6,0x20,0x8d,
+ 0x01,0x04,0xa0,0x50,0x0c,0x10,0x20,0x8d,
+ 0x01,0x04,0xa1,0xe6,0x26,0xa0,0x20,0x8d,
0x01,0x04,0xa1,0xf6,0x0b,0xe6,0x20,0x8d,
+ 0x01,0x04,0xa2,0x00,0xd2,0x98,0x20,0x8d,
0x01,0x04,0xa2,0x3e,0x12,0xe2,0x20,0x8d,
- 0x01,0x04,0xa2,0xfa,0x7b,0xb3,0x20,0x8d,
- 0x01,0x04,0xa2,0xfa,0xbf,0xde,0x20,0x8d,
0x01,0x04,0xa2,0xfe,0x76,0x14,0x20,0x8d,
- 0x01,0x04,0xa3,0xac,0x51,0x46,0x20,0x8d,
- 0x01,0x04,0xa4,0x5a,0x2f,0x08,0x20,0x8d,
+ 0x01,0x04,0xa3,0x9e,0xa8,0xb5,0x20,0x8d,
+ 0x01,0x04,0xa5,0xad,0x13,0x21,0x20,0x8d,
0x01,0x04,0xa5,0xe4,0xae,0x75,0x20,0x8d,
- 0x01,0x04,0xa6,0x46,0x91,0x97,0x20,0x8d,
- 0x01,0x04,0xa8,0x5b,0xee,0x08,0x20,0x8d,
- 0x01,0x04,0xaa,0xfd,0x0b,0x19,0x20,0x8d,
- 0x01,0x04,0xab,0x67,0xaa,0x73,0x20,0x8d,
- 0x01,0x04,0xac,0x5d,0xa6,0x87,0x20,0x8d,
- 0x01,0x04,0xac,0x67,0xd9,0xec,0x20,0x8d,
+ 0x01,0x04,0xa5,0xff,0xf1,0xb8,0x20,0x8d,
+ 0x01,0x04,0xa7,0x58,0x0b,0xcb,0x20,0x8d,
+ 0x01,0x04,0xa7,0xb3,0x93,0x9b,0x20,0x8d,
+ 0x01,0x04,0xaa,0x11,0x97,0xeb,0x20,0x8d,
+ 0x01,0x04,0xaa,0x40,0xae,0xe6,0x20,0x8d,
+ 0x01,0x04,0xac,0x5c,0x66,0x73,0x20,0x8d,
0x01,0x04,0xac,0x69,0x15,0xd8,0x20,0x8d,
- 0x01,0x04,0xac,0x70,0x99,0x5f,0x20,0x8d,
- 0x01,0x04,0xad,0x03,0xda,0x5b,0x20,0x8d,
- 0x01,0x04,0xad,0x0c,0x77,0x85,0x20,0x8d,
- 0x01,0x04,0xad,0x22,0x7f,0xb5,0x20,0x8d,
- 0x01,0x04,0xad,0x4c,0x7b,0xad,0x20,0x8d,
- 0x01,0x04,0xad,0xb0,0xc6,0x44,0x20,0x8d,
- 0x01,0x04,0xad,0xd0,0x98,0xda,0x20,0x8d,
- 0x01,0x04,0xad,0xf1,0xe3,0xf3,0x20,0x8d,
- 0x01,0x04,0xad,0xf6,0x1b,0x07,0x20,0x8d,
- 0x01,0x04,0xad,0xff,0xf0,0xcd,0x20,0x8d,
- 0x01,0x04,0xae,0x1e,0x2f,0x0f,0x20,0x8d,
- 0x01,0x04,0xae,0x72,0xfa,0x56,0x20,0x8d,
- 0x01,0x04,0xae,0x8a,0x23,0xe5,0x20,0x8d,
- 0x01,0x04,0xae,0x8e,0xbf,0x88,0x20,0x8d,
- 0x01,0x04,0xb0,0x0a,0x8f,0xbe,0x20,0x8d,
+ 0x01,0x04,0xac,0x6f,0xb0,0xf4,0x20,0x8d,
+ 0x01,0x04,0xac,0xff,0x62,0x6c,0x20,0x8d,
+ 0x01,0x04,0xad,0x52,0x05,0xca,0x20,0x8d,
+ 0x01,0x04,0xad,0xb5,0x23,0x32,0x20,0x8d,
+ 0x01,0x04,0xad,0xd4,0xfd,0x89,0x20,0x8d,
+ 0x01,0x04,0xad,0xeb,0x49,0x57,0x20,0x8d,
+ 0x01,0x04,0xae,0x1e,0x1d,0x55,0x20,0x8d,
+ 0x01,0x04,0xae,0x8d,0xd1,0x28,0x20,0x8d,
+ 0x01,0x04,0xb0,0x09,0x11,0x79,0x20,0x8d,
+ 0x01,0x04,0xb0,0x0c,0x10,0x87,0x20,0x8d,
0x01,0x04,0xb0,0x4a,0x88,0xed,0x20,0x8d,
- 0x01,0x04,0xb0,0x76,0xdc,0x1d,0x20,0x8d,
- 0x01,0x04,0xb0,0x7e,0x74,0x07,0x20,0x8d,
+ 0x01,0x04,0xb0,0x4a,0x8b,0x78,0x20,0x8d,
+ 0x01,0x04,0xb0,0x7a,0x7a,0x86,0x20,0x8d,
0x01,0x04,0xb0,0x7e,0xa7,0x0a,0x20,0x8d,
+ 0x01,0x04,0xb0,0x97,0xf4,0x82,0x20,0x8d,
+ 0x01,0x04,0xb0,0xba,0x13,0x6a,0x20,0x8d,
0x01,0x04,0xb0,0xd4,0xb9,0x99,0x20,0x8d,
- 0x01,0x04,0xb0,0xeb,0xd1,0xba,0x20,0x8d,
- 0x01,0x04,0xb1,0x51,0xec,0x75,0x20,0x8d,
- 0x01,0x04,0xb1,0x59,0xcd,0x46,0x20,0x8d,
- 0x01,0x04,0xb2,0x30,0xa8,0x0c,0x20,0x8d,
+ 0x01,0x04,0xb1,0x8e,0x92,0xc1,0x20,0x8d,
+ 0x01,0x04,0xb2,0x15,0x76,0xb2,0x20,0x8d,
+ 0x01,0x04,0xb2,0x3d,0x8d,0xc6,0x20,0x8d,
0x01,0x04,0xb2,0x7c,0xa2,0xd1,0x20,0x8d,
+ 0x01,0x04,0xb2,0x8f,0x19,0xc2,0x20,0x8d,
+ 0x01,0x04,0xb2,0x9a,0xe9,0xc5,0x20,0x8d,
0x01,0x04,0xb2,0x9f,0x62,0x85,0x20,0x8d,
- 0x01,0x04,0xb2,0xc4,0x59,0xd1,0x20,0x8d,
+ 0x01,0x04,0xb2,0xe8,0xba,0xbf,0x20,0x8d,
0x01,0x04,0xb2,0xec,0x89,0x3f,0x20,0x8d,
- 0x01,0x04,0xb2,0xfc,0x7b,0x18,0x20,0x8d,
- 0x01,0x04,0xb3,0x2b,0xaa,0xba,0x20,0x8d,
- 0x01,0x04,0xb4,0x96,0x2e,0xbb,0x20,0x8d,
- 0x01,0x04,0xb5,0x75,0x80,0x8c,0x20,0x8d,
- 0x01,0x04,0xb8,0x13,0x13,0x10,0x20,0x8d,
- 0x01,0x04,0xb9,0x15,0xd9,0x30,0x20,0x8d,
+ 0x01,0x04,0xb3,0x3c,0x95,0x04,0x20,0x8d,
+ 0x01,0x04,0xb8,0xa0,0x6e,0x68,0x20,0x8d,
+ 0x01,0x04,0xb8,0xae,0x25,0x8b,0x20,0x8d,
+ 0x01,0x04,0xb9,0x08,0x68,0xb3,0x20,0x8d,
+ 0x01,0x04,0xb9,0x0e,0x1e,0x19,0x20,0x8d,
0x01,0x04,0xb9,0x19,0x30,0xb8,0x20,0x8d,
- 0x01,0x04,0xb9,0x1f,0x88,0xf6,0x20,0x8d,
0x01,0x04,0xb9,0x34,0x5d,0x2d,0x20,0x8d,
0x01,0x04,0xb9,0x40,0x74,0x0f,0x20,0x8d,
- 0x01,0x04,0xb9,0x44,0xf9,0x5b,0x20,0x8d,
+ 0x01,0x04,0xb9,0x45,0x69,0x75,0x20,0x8d,
0x01,0x04,0xb9,0x62,0x36,0x14,0x20,0x8d,
0x01,0x04,0xb9,0x6b,0x53,0x37,0x20,0x8d,
+ 0x01,0x04,0xb9,0x84,0x6d,0x7a,0x20,0x8d,
+ 0x01,0x04,0xb9,0x87,0x51,0x32,0x20,0x8d,
0x01,0x04,0xb9,0x8c,0xfd,0xa9,0x20,0x8d,
- 0x01,0x04,0xb9,0x94,0x91,0x4a,0x20,0x8d,
+ 0x01,0x04,0xb9,0x94,0x03,0xe3,0x20,0x8d,
+ 0x01,0x04,0xb9,0x9a,0x02,0x03,0x20,0x8d,
+ 0x01,0x04,0xb9,0xa2,0x5c,0x24,0x20,0x8d,
+ 0x01,0x04,0xb9,0xa3,0x2c,0x24,0x20,0x8d,
0x01,0x04,0xb9,0xa5,0xaa,0x13,0x20,0x8d,
0x01,0x04,0xb9,0xa7,0x71,0x3b,0x20,0x8d,
- 0x01,0x04,0xb9,0xb9,0x1a,0x8d,0x1f,0xaf,
- 0x01,0x04,0xb9,0xc5,0xa3,0x88,0x20,0x8d,
+ 0x01,0x04,0xb9,0xb9,0x3b,0x0c,0x20,0x8d,
+ 0x01,0x04,0xb9,0xcb,0x29,0x94,0x20,0x8d,
0x01,0x04,0xb9,0xd1,0x0c,0x4c,0x20,0x8d,
0x01,0x04,0xb9,0xd1,0x46,0x11,0x20,0x8d,
- 0x01,0x04,0xb9,0xe3,0x9c,0xe2,0x20,0x8d,
+ 0x01,0x04,0xb9,0xd2,0x7d,0x21,0x20,0x8d,
0x01,0x04,0xb9,0xe9,0xbd,0xd2,0x20,0x8d,
+ 0x01,0x04,0xb9,0xee,0x83,0x13,0x20,0x8d,
+ 0x01,0x04,0xb9,0xef,0xdc,0xd2,0x20,0x8d,
0x01,0x04,0xb9,0xef,0xdd,0x05,0x20,0x8d,
- 0x01,0x04,0xb9,0xf4,0x64,0x6a,0x20,0x8d,
- 0x01,0x04,0xb9,0xfe,0x61,0xa4,0x20,0x8d,
- 0x01,0x04,0xba,0x21,0xa7,0x0b,0x20,0x8d,
- 0x01,0x04,0xba,0xb0,0x62,0x25,0x20,0x8d,
+ 0x01,0x04,0xb9,0xfa,0x5a,0xf6,0x20,0x8d,
0x01,0x04,0xba,0xf9,0xd9,0x19,0x20,0x8d,
0x01,0x04,0xba,0xfa,0x5f,0x84,0x20,0x8d,
- 0x01,0x04,0xbc,0x20,0x0e,0x1f,0x20,0x8e,
0x01,0x04,0xbc,0x23,0xa7,0x0e,0x20,0x8d,
- 0x01,0x04,0xbc,0x44,0x2d,0x8f,0x20,0x8d,
- 0x01,0x04,0xbc,0x75,0xc8,0xd4,0x20,0x8d,
- 0x01,0x04,0xbc,0x8a,0x58,0x0e,0x20,0x8d,
- 0x01,0x04,0xbc,0x97,0xed,0x9e,0x20,0x8d,
- 0x01,0x04,0xbc,0x9a,0xec,0x31,0x20,0x8d,
- 0x01,0x04,0xbd,0x7b,0xb1,0x80,0x20,0x8d,
+ 0x01,0x04,0xbc,0x44,0x35,0x2c,0x20,0x8d,
+ 0x01,0x04,0xbc,0x78,0xff,0x73,0x20,0x8d,
+ 0x01,0x04,0xbd,0x06,0xc3,0x6f,0x20,0x8d,
+ 0x01,0x04,0xbe,0x02,0x82,0x2c,0x20,0x8d,
+ 0x01,0x04,0xbe,0x0d,0x7a,0x59,0x20,0x8d,
0x01,0x04,0xbe,0x7b,0x1b,0x0b,0x20,0x8d,
0x01,0x04,0xbe,0x91,0x7f,0xfe,0x20,0x8d,
- 0x01,0x04,0xc0,0x45,0x35,0x4d,0x20,0x8d,
+ 0x01,0x04,0xbf,0xdc,0x9c,0x40,0x20,0x8d,
+ 0x01,0x04,0xc0,0x1f,0x88,0x5a,0x20,0x8d,
+ 0x01,0x04,0xc0,0x45,0x35,0x2b,0x20,0x8d,
0x01,0x04,0xc0,0x92,0x89,0x2c,0x20,0x8d,
- 0x01,0x04,0xc0,0xde,0x18,0x36,0x20,0x8d,
- 0x01,0x04,0xc0,0xde,0x93,0x8d,0x20,0x8d,
- 0x01,0x04,0xc1,0x20,0x7f,0xa2,0xee,0x29,
- 0x01,0x04,0xc1,0x6f,0xc6,0xbb,0x1f,0xaf,
- 0x01,0x04,0xc1,0xc4,0x25,0x3e,0x20,0x8d,
- 0x01,0x04,0xc2,0x0d,0x50,0xb9,0x3c,0x46,
- 0x01,0x04,0xc2,0x93,0x71,0xc9,0x20,0x8d,
- 0x01,0x04,0xc2,0xa5,0x1e,0x14,0x20,0x8d,
- 0x01,0x04,0xc2,0xbf,0xef,0x62,0x20,0x8d,
- 0x01,0x04,0xc3,0x38,0x3f,0x04,0x20,0x8d,
- 0x01,0x04,0xc3,0x38,0x3f,0x0a,0x20,0x8d,
- 0x01,0x04,0xc3,0x7b,0xef,0xb9,0x20,0x8d,
- 0x01,0x04,0xc3,0x8c,0xe2,0x9a,0x20,0x8d,
- 0x01,0x04,0xc6,0x01,0xe7,0x06,0x20,0x8d,
- 0x01,0x04,0xc6,0x94,0x70,0x1b,0x20,0x8d,
- 0x01,0x04,0xc7,0x7e,0xea,0xed,0x20,0x8d,
- 0x01,0x04,0xc7,0xc1,0xae,0xad,0x20,0x8d,
+ 0x01,0x04,0xc0,0xae,0x79,0x21,0x20,0x8d,
+ 0x01,0x04,0xc0,0xde,0x93,0xaf,0x20,0x8d,
+ 0x01,0x04,0xc1,0xc6,0x22,0x18,0x20,0x8d,
+ 0x01,0x04,0xc1,0xde,0x82,0x0e,0x20,0x8d,
+ 0x01,0x04,0xc2,0x23,0xb9,0xa7,0x20,0x8d,
+ 0x01,0x04,0xc2,0x36,0x53,0xea,0x20,0x8d,
+ 0x01,0x04,0xc2,0xe9,0x54,0x64,0x20,0x8d,
+ 0x01,0x04,0xc3,0x02,0x49,0x58,0x20,0x8d,
+ 0x01,0x04,0xc3,0x30,0x0c,0x08,0x20,0x8d,
+ 0x01,0x04,0xc3,0x9a,0xc8,0x9d,0x20,0x8d,
+ 0x01,0x04,0xc5,0xd3,0x85,0x0f,0x20,0x8d,
+ 0x01,0x04,0xc6,0x54,0x92,0x08,0x20,0x8d,
+ 0x01,0x04,0xc6,0x62,0x37,0x56,0x20,0x8d,
0x01,0x04,0xc7,0xf7,0x07,0xd0,0x20,0x8d,
- 0x01,0x04,0xc8,0x7a,0xb5,0x2e,0x20,0x8d,
+ 0x01,0x04,0xc8,0x74,0x9a,0x83,0x20,0x8d,
0x01,0x04,0xc9,0xbf,0x06,0x67,0x20,0x8d,
- 0x01,0x04,0xc9,0xd4,0x24,0xd1,0x20,0x8d,
0x01,0x04,0xc9,0xdd,0xea,0xc8,0x20,0x8d,
+ 0x01,0x04,0xca,0x2f,0xe1,0xf2,0x20,0x8d,
+ 0x01,0x04,0xca,0x6b,0xdb,0x82,0x20,0x8d,
0x01,0x04,0xca,0x6c,0xd3,0x87,0x20,0x8d,
- 0x01,0x04,0xca,0xa9,0x11,0xb2,0x20,0x8d,
- 0x01,0x04,0xca,0xb1,0x18,0x8c,0x20,0x8d,
- 0x01,0x04,0xcb,0x82,0x30,0x75,0x22,0xb5,
- 0x01,0x04,0xcb,0x84,0x5e,0xc4,0x20,0x8d,
+ 0x01,0x04,0xca,0x8a,0x0d,0x7a,0x20,0x8d,
+ 0x01,0x04,0xcb,0x56,0xc3,0x20,0x20,0x8d,
+ 0x01,0x04,0xcb,0xb8,0x34,0xf7,0x20,0x8d,
+ 0x01,0x04,0xcc,0x6f,0xa3,0x72,0x20,0x8d,
0x01,0x04,0xcd,0xb2,0x29,0x7c,0x20,0x8d,
- 0x01,0x04,0xce,0x48,0xc9,0xe4,0x20,0x8d,
0x01,0x04,0xce,0xc0,0xcb,0x00,0x20,0x8d,
- 0x01,0x04,0xce,0xdf,0x99,0x34,0x20,0x8d,
- 0x01,0x04,0xcf,0x86,0xd8,0x91,0x20,0x8e,
- 0x01,0x04,0xcf,0xbc,0x9a,0x32,0x20,0x8d,
0x01,0x04,0xcf,0xe5,0x2e,0x50,0x20,0x8d,
+ 0x01,0x04,0xcf,0xf4,0xf8,0x51,0x20,0x8d,
0x01,0x04,0xcf,0xff,0xc1,0x2f,0x20,0x8d,
- 0x01,0x04,0xd0,0x68,0x5c,0x4a,0x20,0x8d,
+ 0x01,0x04,0xd0,0x3b,0x85,0x3f,0x20,0x8d,
0x01,0x04,0xd1,0x3a,0x91,0x9d,0x20,0x8d,
- 0x01,0x04,0xd1,0x3a,0x9e,0xe8,0x20,0x8f,
- 0x01,0x04,0xd1,0x8d,0x2b,0xf3,0x20,0x8d,
- 0x01,0x04,0xd1,0xe2,0x8e,0x3e,0x20,0x8d,
- 0x01,0x04,0xd1,0xed,0x7f,0xe3,0x20,0x8d,
+ 0x01,0x04,0xd1,0x61,0xbd,0xf9,0x20,0x8d,
+ 0x01,0x04,0xd1,0xb1,0x8a,0xf5,0x20,0x8d,
0x01,0x04,0xd1,0xed,0x85,0x36,0x20,0x8d,
- 0x01,0x04,0xd3,0xf8,0x5a,0x32,0x20,0x8d,
- 0x01,0x04,0xd4,0x15,0x12,0x4e,0x20,0x8d,
+ 0x01,0x04,0xd2,0x36,0x25,0xbe,0x20,0x8d,
+ 0x01,0x04,0xd2,0x36,0x27,0xee,0x20,0x8d,
0x01,0x04,0xd4,0x22,0xe1,0x76,0x20,0x8d,
- 0x01,0x04,0xd4,0x33,0x92,0x89,0x20,0x8d,
- 0x01,0x04,0xd4,0xe3,0xd3,0x57,0x20,0x8d,
- 0x01,0x04,0xd5,0x00,0x45,0x4c,0x20,0x8d,
- 0x01,0x04,0xd5,0x05,0x24,0x3a,0x20,0x8d,
+ 0x01,0x04,0xd4,0x29,0x09,0x1e,0x20,0x8d,
+ 0x01,0x04,0xd4,0x33,0x84,0xb0,0x20,0x8d,
+ 0x01,0x04,0xd4,0x45,0x3c,0x4d,0x20,0x8d,
+ 0x01,0x04,0xd4,0x56,0x20,0x6a,0x20,0x8d,
0x01,0x04,0xd5,0x2f,0x40,0x69,0x20,0x8d,
- 0x01,0x04,0xd5,0x59,0x87,0x97,0x20,0x8d,
0x01,0x04,0xd5,0x8d,0x9a,0xc9,0x20,0x8d,
- 0x01,0x04,0xd5,0x9f,0xc6,0x2d,0x20,0x8d,
+ 0x01,0x04,0xd5,0x8e,0x94,0xa9,0x20,0x8d,
0x01,0x04,0xd5,0xb8,0xf4,0x18,0x20,0x8d,
- 0x01,0x04,0xd5,0xd6,0x42,0xb6,0x20,0x8d,
- 0x01,0x04,0xd5,0xe2,0x7b,0x4c,0x20,0x8d,
+ 0x01,0x04,0xd5,0xe3,0x93,0xf4,0x20,0x8d,
+ 0x01,0x04,0xd5,0xfa,0x15,0x70,0x20,0x8d,
0x01,0x04,0xd8,0x92,0xfb,0x08,0x20,0x8d,
- 0x01,0x04,0xd8,0xba,0xee,0x0e,0x20,0x8d,
- 0x01,0x04,0xd9,0x05,0x96,0x72,0x20,0x8d,
+ 0x01,0x04,0xd8,0xe8,0x9d,0x68,0x20,0x8d,
0x01,0x04,0xd9,0x0f,0xb2,0x0b,0x20,0x8d,
- 0x01,0x04,0xd9,0x18,0xef,0x6d,0x20,0x8d,
- 0x01,0x04,0xd9,0x40,0x2f,0x8a,0x20,0x8d,
- 0x01,0x04,0xd9,0x49,0x50,0x68,0x20,0x8d,
- 0x01,0x04,0xd9,0x4f,0xb5,0x26,0x20,0x8d,
+ 0x01,0x04,0xd9,0x1a,0x20,0x0a,0x20,0x8d,
+ 0x01,0x04,0xd9,0x40,0x2f,0xc8,0x20,0x8d,
+ 0x01,0x04,0xd9,0x4c,0x33,0x19,0x20,0x8d,
0x01,0x04,0xd9,0x5c,0x37,0xf6,0x20,0x8d,
- 0x01,0x04,0xd9,0x71,0x79,0xa9,0x20,0x8d,
- 0x01,0x04,0xd9,0x73,0x74,0xfa,0x20,0x8d,
- 0x01,0x04,0xd9,0x9b,0xf4,0xaa,0x20,0x8d,
0x01,0x04,0xd9,0xaa,0x7c,0xaa,0x20,0x8d,
- 0x01,0x04,0xdc,0x84,0x87,0x36,0x20,0x8d,
- 0x01,0x04,0xdc,0xe9,0xb2,0xc7,0x20,0x8d,
- 0x01,0x04,0xde,0x9a,0x6f,0x2e,0x20,0x8d,
- 0x02,0x10,0x20,0x01,0x16,0x20,0x05,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x20,0x8d,
- 0x02,0x10,0x20,0x01,0x19,0xf0,0x60,0x01,0x39,0xaa,0x54,0x00,0x03,0xff,0xfe,0xf0,0x09,0x16,0x20,0x8d,
- 0x02,0x10,0x20,0x01,0x19,0xf0,0x80,0x01,0x0f,0x71,0x54,0x00,0x04,0xff,0xfe,0x10,0x6a,0x63,0x20,0x8d,
+ 0x01,0x04,0xd9,0xb4,0xdd,0xa2,0x20,0x8d,
+ 0x01,0x04,0xd9,0xb4,0xee,0x89,0x20,0x8d,
+ 0x01,0x04,0xdc,0x54,0xe8,0x2e,0x20,0x8d,
+ 0x01,0x04,0xdc,0x85,0x27,0x3d,0x20,0x8d,
+ 0x01,0x04,0xdc,0xe9,0x5b,0xb6,0x20,0x8d,
+ 0x02,0x10,0x20,0x01,0x19,0xf0,0x10,0x00,0x1d,0xb3,0x54,0x00,0x04,0xff,0xfe,0x56,0x5a,0x8d,0x20,0x8d,
+ 0x02,0x10,0x20,0x01,0x19,0xf0,0x00,0x05,0x24,0xda,0x3e,0xec,0xef,0xff,0xfe,0xb9,0xf3,0x6e,0x20,0x8d,
+ 0x02,0x10,0x20,0x01,0x19,0xf0,0x00,0x05,0x24,0xda,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x8d,
+ 0x02,0x10,0x20,0x01,0x19,0xf0,0x00,0x05,0x45,0x35,0x3e,0xec,0xef,0xff,0xfe,0xb9,0x87,0xe4,0x20,0x8d,
+ 0x02,0x10,0x20,0x01,0x19,0xf0,0x00,0x05,0x45,0x35,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x8d,
0x02,0x10,0x20,0x01,0x1b,0xc0,0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x20,0x8d,
- 0x02,0x10,0x20,0x01,0x1c,0x02,0x01,0x1e,0x35,0x00,0xdf,0x25,0x63,0x21,0x82,0x60,0xd9,0xbe,0x20,0x8d,
- 0x02,0x10,0x20,0x01,0x41,0xd0,0x10,0x04,0x1b,0x79,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x93,
+ 0x02,0x10,0x20,0x01,0x1c,0x04,0x40,0x08,0x63,0x00,0x8a,0x5f,0x26,0x78,0x11,0x4b,0xa6,0x60,0x20,0x8d,
0x02,0x10,0x20,0x01,0x41,0xd0,0x02,0x03,0x37,0x39,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x8d,
- 0x02,0x10,0x20,0x01,0x41,0xd0,0x02,0x03,0xaa,0xcc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x8d,
+ 0x02,0x10,0x20,0x01,0x41,0xd0,0x02,0x03,0x8f,0x49,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x8d,
0x02,0x10,0x20,0x01,0x41,0xd0,0x02,0x03,0xbb,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x8d,
0x02,0x10,0x20,0x01,0x41,0xd0,0x00,0x02,0xbf,0x8f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x8d,
- 0x02,0x10,0x20,0x01,0x41,0xd0,0x03,0x03,0x65,0x86,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x8d,
- 0x02,0x10,0x20,0x01,0x41,0xd0,0x06,0x02,0x44,0x93,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x8d,
- 0x02,0x10,0x20,0x01,0x41,0xd0,0x00,0x08,0xb9,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x8d,
+ 0x02,0x10,0x20,0x01,0x41,0xd0,0x03,0x03,0xde,0x8b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x8d,
+ 0x02,0x10,0x20,0x01,0x41,0xd0,0x04,0x03,0x3d,0x61,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x8d,
+ 0x02,0x10,0x20,0x01,0x41,0xd0,0x04,0x05,0x96,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x8d,
+ 0x02,0x10,0x20,0x01,0x41,0xd0,0x00,0x08,0xed,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x8d,
0x02,0x10,0x20,0x01,0x41,0xd0,0x00,0x0a,0x69,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x8d,
0x02,0x10,0x20,0x01,0x41,0xf0,0x00,0x00,0x00,0x00,0x00,0x62,0x69,0x74,0x63,0x6f,0x69,0x6e,0x20,0x8d,
- 0x02,0x10,0x20,0x01,0x44,0xb8,0x02,0x56,0x5d,0x11,0x02,0x16,0x3e,0xff,0xfe,0x39,0xd5,0xd4,0x20,0x8d,
0x02,0x10,0x20,0x01,0x04,0x70,0x1b,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x8d,
- 0x02,0x10,0x20,0x01,0x04,0x70,0x1f,0x07,0x08,0x03,0x02,0x0c,0x29,0xff,0xfe,0x2d,0x58,0x79,0x20,0x8d,
+ 0x02,0x10,0x20,0x01,0x04,0x70,0x1f,0x05,0x04,0x3b,0x28,0x31,0x85,0x30,0x71,0x79,0x58,0x64,0x20,0x8d,
+ 0x02,0x10,0x20,0x01,0x04,0x70,0x1f,0x09,0x0b,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x11,0x20,0x8d,
0x02,0x10,0x20,0x01,0x04,0x70,0x1f,0x15,0x01,0x06,0xe2,0xd5,0x5e,0xff,0xfe,0x42,0x7a,0xe5,0x20,0x8d,
- 0x02,0x10,0x20,0x01,0x04,0x70,0x1f,0x15,0x0c,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x11,0x20,0x8d,
- 0x02,0x10,0x20,0x01,0x04,0x70,0x00,0x26,0x04,0x72,0x00,0x00,0x00,0x00,0x00,0x00,0x0b,0x7c,0x20,0x8d,
+ 0x02,0x10,0x20,0x01,0x04,0x70,0x1f,0x1b,0x03,0x65,0xaa,0x20,0x66,0xff,0xfe,0x3f,0x19,0x09,0x20,0x8d,
+ 0x02,0x10,0x20,0x01,0x04,0x70,0x1f,0x1b,0x05,0xa6,0x02,0x16,0x3e,0xff,0xfe,0x24,0x11,0x62,0x20,0x8d,
+ 0x02,0x10,0x20,0x01,0x04,0x70,0x6a,0x7c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x8d,
0x02,0x10,0x20,0x01,0x04,0x70,0x75,0xe9,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x20,0x8d,
- 0x02,0x10,0x20,0x01,0x04,0x70,0xde,0x5a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xec,0x24,0x75,
- 0x02,0x10,0x20,0x01,0x4b,0xa0,0xba,0xbe,0x05,0x84,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x8d,
+ 0x02,0x10,0x20,0x01,0x04,0x70,0x8c,0xa0,0x00,0x02,0x4e,0x72,0xb9,0xff,0xfe,0x56,0xf8,0xb8,0x20,0x8d,
+ 0x02,0x10,0x20,0x01,0x04,0x70,0xdb,0xc7,0x00,0x00,0x10,0x10,0x00,0x00,0x00,0x00,0x01,0x00,0x20,0x8d,
+ 0x02,0x10,0x20,0x01,0x4b,0xa0,0xca,0xfe,0x14,0xcc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x8d,
0x02,0x10,0x20,0x01,0x4b,0xa0,0xff,0xff,0x00,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x8d,
0x02,0x10,0x20,0x01,0x4d,0xd0,0x35,0x64,0x00,0x00,0x30,0xb7,0x1d,0x7b,0x6f,0xec,0x4c,0x5c,0x20,0x8d,
0x02,0x10,0x20,0x01,0x4d,0xd0,0x35,0x64,0x00,0x00,0x08,0x8e,0xb4,0xff,0x2a,0xd0,0x69,0x9b,0x20,0x8d,
0x02,0x10,0x20,0x01,0x4d,0xd0,0x35,0x64,0x00,0x00,0x9c,0x1c,0xcc,0x31,0x9f,0xe8,0x55,0x05,0x20,0x8d,
0x02,0x10,0x20,0x01,0x4d,0xd0,0x35,0x64,0x00,0x00,0xa0,0xc4,0xd4,0x1f,0x04,0xc4,0x1b,0xb0,0x20,0x8d,
- 0x02,0x10,0x20,0x01,0x4d,0xd0,0x35,0x64,0x00,0x00,0xfd,0x76,0xc1,0xd3,0x18,0x54,0x5b,0xd9,0x20,0x8d,
0x02,0x10,0x20,0x01,0x4d,0xd0,0x35,0x64,0x00,0x01,0x00,0x00,0x00,0x00,0x76,0x76,0x80,0x90,0x20,0x8d,
0x02,0x10,0x20,0x01,0x4d,0xd0,0x35,0x64,0x00,0x01,0xb9,0x77,0xbd,0x71,0x46,0x12,0x8e,0x40,0x20,0x8d,
0x02,0x10,0x20,0x01,0x4d,0xd0,0xaf,0x0e,0x35,0x64,0x00,0x00,0x00,0x00,0x00,0x69,0x00,0x01,0x20,0x8d,
0x02,0x10,0x20,0x01,0x4d,0xd0,0xaf,0x0e,0x35,0x64,0x00,0x00,0x00,0x00,0x00,0x69,0x00,0x90,0x20,0x8d,
- 0x02,0x10,0x20,0x01,0x4d,0xe8,0xb1,0xb2,0x00,0x01,0x00,0x00,0xde,0xad,0xbe,0xef,0x00,0x07,0x20,0x8d,
+ 0x02,0x10,0x20,0x01,0x05,0x60,0x44,0x1f,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,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,0x78,0x0a,0xcc,0x00,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x8d,
+ 0x02,0x10,0x20,0x01,0x06,0x7c,0x25,0xdc,0x00,0x91,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x20,0x8d,
0x02,0x10,0x20,0x01,0x06,0x7c,0x26,0xb4,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x20,0x8d,
0x02,0x10,0x20,0x01,0x06,0x7c,0x2d,0xb8,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x36,0x20,0x8d,
- 0x02,0x10,0x20,0x01,0x07,0xc0,0x23,0x10,0x00,0x00,0xf8,0x16,0x3e,0xff,0xfe,0x0d,0x4a,0xb6,0x20,0x8d,
0x02,0x10,0x20,0x01,0x07,0xc0,0x23,0x10,0x00,0x00,0xf8,0x16,0x3e,0xff,0xfe,0x6c,0x4f,0x58,0x20,0x8d,
- 0x02,0x10,0x20,0x01,0x08,0x61,0x32,0x46,0x0a,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x20,0x8d,
- 0x02,0x10,0x20,0x01,0x0b,0x07,0x02,0xe6,0x38,0xd7,0xba,0x27,0xeb,0xff,0xfe,0x60,0x3d,0xc1,0x20,0x8d,
+ 0x02,0x10,0x20,0x01,0x08,0x61,0x32,0x42,0x84,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x20,0x8d,
+ 0x02,0x10,0x20,0x01,0x08,0xb0,0x13,0x01,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x20,0x8d,
+ 0x02,0x10,0x20,0x01,0xb0,0x30,0x24,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x8d,0x20,0x8d,
+ 0x02,0x10,0x20,0x01,0x0b,0x07,0x02,0xef,0x6e,0x4a,0x00,0x3d,0x97,0x4e,0x78,0x4a,0x68,0x4b,0x20,0x8d,
+ 0x02,0x10,0x20,0x01,0x0b,0x07,0x5d,0x32,0xb1,0x42,0x8f,0x77,0x3c,0x7d,0xa2,0xfd,0xed,0x2e,0x20,0x8d,
0x02,0x10,0x20,0x01,0x0b,0x07,0x64,0x61,0x78,0x11,0x04,0x89,0xd2,0xda,0x0e,0x07,0x1a,0xf7,0x20,0x8d,
- 0x02,0x10,0x20,0x01,0x0b,0x07,0x0a,0xc9,0x44,0x2b,0x79,0xd6,0xbb,0xbe,0xb3,0x7c,0xa7,0x83,0x20,0x8d,
+ 0x02,0x10,0x20,0x01,0x0b,0x07,0x64,0x6b,0x80,0x74,0x32,0xe8,0x92,0x43,0xa3,0x37,0xe6,0x0a,0x20,0x8d,
+ 0x02,0x10,0x20,0x01,0x0b,0x07,0x64,0x6b,0x80,0x74,0x4c,0xc6,0x79,0xa5,0x3a,0xf7,0x71,0x32,0x20,0x8d,
+ 0x02,0x10,0x20,0x01,0x0b,0x07,0x0a,0xd4,0xca,0x4b,0x7d,0xd5,0x84,0x71,0x50,0xc3,0x53,0x63,0x20,0x8d,
+ 0x02,0x10,0x20,0x01,0x0b,0xc8,0x12,0x01,0x07,0x1a,0x2e,0x59,0xe5,0xff,0xfe,0x42,0x52,0xf4,0x20,0x8d,
0x02,0x10,0x20,0x01,0x0b,0xc8,0x16,0x00,0x00,0x00,0x02,0x08,0xa2,0xff,0xfe,0x0c,0x8a,0x2e,0x20,0x8d,
0x02,0x10,0x20,0x01,0x0b,0xc8,0x32,0x3c,0x00,0xff,0xa6,0x34,0x38,0x4f,0x18,0x49,0xf4,0xbc,0x20,0x8d,
0x02,0x10,0x20,0x01,0x0b,0xc8,0x32,0x3c,0x00,0xff,0xd2,0x17,0xc2,0xff,0xfe,0x07,0x2c,0xd9,0x20,0x8d,
- 0x02,0x10,0x20,0x01,0x0b,0xc8,0x3b,0xec,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x8d,
- 0x02,0x10,0x20,0x02,0x2f,0x5b,0xa5,0xf9,0x00,0x00,0x00,0x00,0x00,0x00,0x2f,0x5b,0xa5,0xf9,0x22,0xb5,
- 0x02,0x10,0x20,0x03,0x00,0xcb,0x87,0x13,0x61,0x02,0xaa,0xa1,0x59,0xff,0xfe,0x57,0x77,0x79,0x20,0x8d,
- 0x02,0x10,0x20,0x03,0x00,0xe0,0x37,0x0e,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x20,0x8d,
- 0x02,0x10,0x20,0x03,0x00,0xf6,0x3f,0x10,0x67,0x00,0x4c,0x9f,0x76,0x20,0x83,0x24,0xd4,0xa7,0x20,0x8d,
- 0x02,0x10,0x24,0x00,0x24,0x10,0xce,0xa2,0x0d,0x00,0x41,0xbc,0xc9,0xea,0x86,0x1b,0x51,0xee,0x20,0x8d,
- 0x02,0x10,0x24,0x00,0x24,0x11,0xa3,0xe1,0x49,0x00,0x25,0x68,0x68,0x4b,0x0e,0x99,0x71,0x20,0x20,0x8d,
- 0x02,0x10,0x24,0x00,0x24,0x11,0xa3,0xe1,0x49,0x00,0x29,0x87,0xb8,0x8f,0x61,0xe0,0x84,0xfa,0x20,0x8d,
- 0x02,0x10,0x24,0x00,0x3b,0x00,0x00,0x20,0x00,0x0c,0xba,0xcb,0x29,0xff,0xfe,0xab,0x88,0x86,0x20,0x8d,
+ 0x02,0x10,0x20,0x01,0x0b,0xc8,0x07,0x00,0x2b,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x8d,
+ 0x02,0x10,0x20,0x01,0x0b,0xc8,0x07,0x00,0x8d,0x16,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x8d,
+ 0x02,0x10,0x20,0x01,0x0e,0x68,0x54,0x00,0x58,0xd0,0xbd,0x15,0xea,0x8c,0x5b,0x20,0x75,0x23,0x20,0x8d,
+ 0x02,0x10,0x24,0x00,0x24,0x11,0xa3,0xe1,0x49,0x00,0x72,0x98,0xf5,0x50,0x67,0xe7,0xb9,0x9b,0x20,0x8d,
+ 0x02,0x10,0x24,0x00,0x89,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x93,0xff,0xfe,0x2b,0x5c,0x0b,0x20,0x8d,
+ 0x02,0x10,0x24,0x00,0x89,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x93,0xff,0xfe,0x5a,0x68,0x5c,0x20,0x8d,
0x02,0x10,0x24,0x01,0xb1,0x40,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x02,0x10,0x20,0x8d,
0x02,0x10,0x24,0x01,0xb1,0x40,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x02,0x20,0x20,0x8d,
- 0x02,0x10,0x24,0x01,0xb1,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x42,0x01,0x00,0x20,0x8d,
- 0x02,0x10,0x24,0x01,0xb1,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x01,0x30,0x20,0x8d,
0x02,0x10,0x24,0x01,0xd0,0x02,0x39,0x02,0x07,0x00,0xd7,0x2c,0x5e,0x22,0x4e,0x95,0x38,0x9d,0x20,0x8d,
- 0x02,0x10,0x24,0x04,0x44,0x08,0x67,0x52,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x19,0x99,0x20,0x8d,
- 0x02,0x10,0x24,0x04,0x7a,0x85,0x41,0x61,0x2b,0x00,0x49,0xa1,0x42,0x7a,0x0f,0xac,0x34,0x09,0x20,0x8d,
- 0x02,0x10,0x24,0x05,0x98,0x00,0xb9,0x72,0xab,0x58,0x0c,0x05,0xe9,0x38,0x26,0x7e,0x02,0x71,0x20,0x8d,
+ 0x02,0x10,0x24,0x04,0x44,0x08,0x63,0xa4,0x0a,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x50,0x20,0x8d,
+ 0x02,0x10,0x24,0x06,0x34,0x00,0x02,0x16,0x8b,0x00,0x02,0x11,0x32,0xff,0xfe,0xca,0x33,0x6b,0x20,0x8d,
+ 0x02,0x10,0x24,0x06,0x8c,0x00,0x00,0x00,0x34,0x22,0x01,0x33,0x00,0x18,0x02,0x28,0x01,0x08,0x20,0x8d,
0x02,0x10,0x24,0x06,0xda,0x11,0x01,0x69,0x0b,0x03,0x32,0xb5,0xf9,0x01,0x9f,0x7c,0x3e,0x4b,0x20,0x8d,
- 0x02,0x10,0x24,0x06,0xda,0x14,0x03,0x35,0xb6,0x01,0xce,0xb7,0xb4,0xfc,0xa8,0x55,0xf3,0xa5,0x20,0x8d,
+ 0x02,0x10,0x24,0x06,0xda,0x18,0x09,0xf1,0xf3,0x01,0x7d,0x2e,0xc2,0x56,0xc1,0x12,0xf2,0xbe,0x20,0x8d,
+ 0x02,0x10,0x24,0x06,0xda,0x18,0x09,0xf1,0xf3,0x03,0xc1,0xc9,0xc5,0x69,0xb7,0x99,0x20,0x57,0x20,0x8d,
+ 0x02,0x10,0x24,0x06,0xda,0x1e,0x0a,0x4e,0x8a,0x00,0x20,0xdb,0xdd,0x8d,0x36,0x70,0x28,0xf0,0x20,0x8d,
0x02,0x10,0x24,0x06,0xda,0x1e,0x0a,0x4e,0x8a,0x03,0x2a,0xad,0x49,0x6b,0x76,0x8d,0xe4,0x97,0x20,0x8d,
- 0x02,0x10,0x24,0x07,0x88,0x00,0xbc,0x61,0x22,0x02,0xa0,0xc6,0x01,0x07,0x50,0x2b,0x4e,0x3b,0x20,0x8d,
- 0x02,0x10,0x24,0x09,0x00,0x10,0xca,0x20,0x1d,0xf0,0x02,0x24,0xe8,0xff,0xfe,0x1f,0x60,0xd9,0x20,0x8d,
- 0x02,0x10,0x26,0x00,0x17,0x00,0x22,0xf1,0x64,0x1f,0x00,0xe8,0x39,0xc8,0xeb,0x1d,0xa1,0xeb,0x20,0x8d,
- 0x02,0x10,0x26,0x00,0x17,0x00,0x9c,0x5d,0x0e,0xd0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x20,0x8d,
- 0x02,0x10,0x26,0x00,0x17,0x00,0x9c,0x5d,0x0e,0xd0,0xd0,0xd6,0x01,0xd9,0x5c,0xc2,0xab,0x47,0x20,0x8d,
- 0x02,0x10,0x26,0x00,0x17,0x02,0x1c,0xe0,0x40,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x20,0x8d,
- 0x02,0x10,0x26,0x00,0x1f,0x14,0x04,0x0e,0xe3,0x01,0xd1,0x55,0xaa,0x3a,0x77,0xbe,0x96,0x0e,0x20,0x8d,
- 0x02,0x10,0x26,0x00,0x1f,0x16,0x0a,0x08,0xb9,0x01,0x1a,0xfa,0xef,0x4e,0x4c,0xe7,0x2b,0xa4,0x20,0x8d,
- 0x02,0x10,0x26,0x00,0x1f,0x1c,0x02,0xd3,0x24,0x03,0x5b,0xac,0x3f,0xc6,0x65,0x13,0x7a,0x63,0x20,0x8d,
+ 0x02,0x10,0x24,0x07,0x36,0x40,0x21,0x07,0x12,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x8d,
+ 0x02,0x10,0x24,0x07,0x36,0x40,0x30,0x10,0x40,0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x8d,
+ 0x02,0x10,0x24,0x07,0x88,0x00,0xbc,0x61,0x22,0x02,0xd6,0x3d,0x7e,0xff,0xfe,0x6c,0xdc,0x36,0x20,0x8d,
+ 0x02,0x10,0x26,0x00,0x17,0x00,0x5c,0x5b,0x00,0xb0,0xaa,0xa1,0x59,0xff,0xfe,0x5f,0x61,0x5a,0x20,0x8d,
+ 0x02,0x10,0x26,0x00,0x17,0x00,0xec,0x7b,0x57,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x20,0x8d,
+ 0x02,0x10,0x26,0x00,0x19,0x00,0x40,0x00,0x4c,0xc4,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x20,0x8d,
+ 0x02,0x10,0x26,0x00,0x19,0x00,0x40,0x00,0x4c,0xc4,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x20,0x8d,
+ 0x02,0x10,0x26,0x00,0x19,0x00,0x40,0x00,0x4c,0xc4,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x20,0x8d,
+ 0x02,0x10,0x26,0x00,0x19,0x00,0x40,0x00,0x4c,0xc4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x8d,
+ 0x02,0x10,0x26,0x00,0x19,0x00,0x40,0x30,0xa2,0x5e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x8d,
+ 0x02,0x10,0x26,0x00,0x1f,0x14,0x04,0x0e,0xe3,0x01,0xaf,0xdd,0xad,0x00,0xe5,0x68,0xd2,0x20,0x20,0x8d,
+ 0x02,0x10,0x26,0x00,0x1f,0x1c,0x02,0xd3,0x24,0x00,0xf1,0x5e,0x2f,0x2a,0x76,0x0d,0xa3,0x3d,0x20,0x8d,
0x02,0x10,0x26,0x00,0x21,0x04,0x10,0x03,0xc5,0xab,0xdc,0x5e,0x90,0xff,0xfe,0x18,0x1d,0x08,0x20,0x8d,
0x02,0x10,0x26,0x00,0x3c,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x92,0xff,0xfe,0x92,0x27,0x45,0x20,0x8d,
0x02,0x10,0x26,0x00,0x3c,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x92,0xff,0xfe,0xcf,0x61,0xb6,0x20,0x8d,
- 0x02,0x10,0x26,0x00,0x3c,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x93,0xff,0xfe,0xb3,0x01,0xb6,0x20,0x8d,
0x02,0x10,0x26,0x00,0x3c,0x00,0xe0,0x02,0x2e,0x32,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x14,0x20,0x8d,
+ 0x02,0x10,0x26,0x00,0x3c,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x93,0xff,0xfe,0x2a,0x52,0x66,0x20,0x8d,
+ 0x02,0x10,0x26,0x00,0x3c,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x93,0xff,0xfe,0x74,0x5f,0x59,0x20,0x8d,
+ 0x02,0x10,0x26,0x00,0x3c,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x93,0xff,0xfe,0xe6,0x21,0x46,0x20,0x8d,
0x02,0x10,0x26,0x00,0x3c,0x02,0x00,0x00,0x00,0x00,0xf0,0x3c,0x92,0xff,0xfe,0x5d,0x09,0xfb,0x20,0x8d,
- 0x02,0x10,0x26,0x00,0x40,0x40,0x28,0x54,0x5e,0x00,0xc6,0xe9,0x84,0xff,0xfe,0x46,0x0e,0xe8,0x21,0xda,
- 0x02,0x10,0x26,0x00,0x6c,0x54,0x71,0x00,0x1a,0xd1,0xbd,0xdf,0x55,0x0e,0x91,0xbe,0xf9,0xe1,0x20,0x8d,
+ 0x02,0x10,0x26,0x00,0x40,0x40,0x20,0x04,0x32,0x01,0x45,0x9f,0x8f,0xe8,0x44,0x4d,0xba,0xf1,0x20,0x8d,
+ 0x02,0x10,0x26,0x00,0x40,0x40,0x45,0x41,0x49,0x00,0x04,0xe1,0xb5,0x8a,0x84,0x38,0x45,0x0e,0x20,0x8d,
+ 0x02,0x10,0x26,0x00,0x6c,0x54,0x71,0x00,0x1a,0xd1,0xc9,0x2e,0x03,0x6d,0x06,0x51,0xbd,0x18,0x20,0x8d,
+ 0x02,0x10,0x26,0x00,0x88,0x01,0x2f,0x80,0x04,0x77,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x1c,0x20,0x8d,
+ 0x02,0x10,0x26,0x00,0x88,0x01,0x8d,0x00,0x3e,0xb0,0x02,0x0c,0x29,0xff,0xfe,0xc3,0xd7,0x99,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,0x01,0x84,0x03,0x00,0x0b,0xde,0x3c,0x29,0x8e,0x94,0x1b,0xa8,0xfd,0xe3,0x20,0x8d,
- 0x02,0x10,0x26,0x01,0x01,0x8c,0x80,0x80,0x30,0x0f,0x02,0x19,0xd1,0xff,0xfe,0x75,0xdc,0x2f,0x20,0x8d,
- 0x02,0x10,0x26,0x01,0x01,0x8d,0x46,0x00,0x43,0xf1,0x20,0xe7,0xb3,0xff,0xfe,0xcf,0x0a,0x99,0x20,0x8d,
- 0x02,0x10,0x26,0x01,0x01,0x8d,0x87,0x01,0xc2,0x90,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x30,0x20,0x8d,
- 0x02,0x10,0x26,0x01,0x02,0x46,0x4d,0x7f,0x9e,0x28,0xf3,0x21,0x36,0xca,0x7a,0x71,0xc6,0x87,0x20,0x8d,
- 0x02,0x10,0x26,0x01,0x06,0x40,0xc2,0x01,0x96,0x0d,0x86,0xeb,0xf2,0x7d,0x66,0xa2,0xf2,0xc1,0x20,0x8d,
- 0x02,0x10,0x26,0x02,0x02,0x41,0x75,0xd1,0x2b,0x90,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x40,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,0x01,0x01,0x84,0x03,0x00,0x15,0x6c,0xba,0x4c,0x00,0x30,0x09,0xda,0x6c,0x06,0x20,0x8d,
+ 0x02,0x10,0x26,0x01,0x03,0x46,0x0d,0x7f,0xff,0xf7,0x18,0xc6,0x48,0x56,0xef,0x75,0x74,0x4c,0x20,0x8d,
+ 0x02,0x10,0x26,0x01,0x04,0x05,0x4a,0x00,0x08,0x76,0xc8,0xd3,0xf0,0x81,0x2c,0xe8,0xba,0x8e,0x20,0x8d,
+ 0x02,0x10,0x26,0x02,0x02,0x4c,0x0b,0x8f,0xcd,0x90,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x40,0x20,0x8d,
+ 0x02,0x10,0x26,0x02,0xfe,0xc3,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x69,0x20,0x8d,
+ 0x02,0x10,0x26,0x02,0xff,0x16,0x00,0x01,0x00,0x00,0x00,0x01,0x04,0x12,0x00,0x00,0x00,0x01,0x20,0x8d,
+ 0x02,0x10,0x26,0x03,0x30,0x01,0x26,0x18,0xc0,0x00,0x2e,0xc1,0xdf,0x1f,0xa4,0x63,0x91,0x19,0x20,0x8d,
+ 0x02,0x10,0x26,0x03,0x30,0x03,0x01,0x1b,0xe1,0x00,0x02,0x0c,0x29,0xff,0xfe,0x38,0xbb,0xc0,0x20,0x8d,
0x02,0x10,0x26,0x03,0x30,0x04,0x06,0xa1,0x38,0x00,0x85,0x1f,0x58,0x4d,0x7a,0xba,0xaf,0xfb,0x20,0x8d,
- 0x02,0x10,0x26,0x03,0x30,0x04,0x06,0xa1,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x02,0x20,0x8d,
- 0x02,0x10,0x26,0x03,0x30,0x04,0x07,0x0d,0x14,0x00,0x85,0x32,0x29,0x00,0xce,0x6f,0xac,0xdf,0x20,0x8d,
- 0x02,0x10,0x26,0x03,0x30,0x04,0x07,0x45,0x09,0x00,0xf0,0xd7,0x55,0x6a,0x0a,0x8c,0xce,0xd5,0x20,0x8d,
- 0x02,0x10,0x26,0x03,0x60,0x80,0xc0,0x00,0x5d,0x8a,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x4f,0x20,0x8d,
- 0x02,0x10,0x26,0x03,0x80,0x00,0xd1,0x00,0x89,0x91,0xcc,0x29,0xcc,0xff,0xfe,0x42,0x30,0x0c,0x20,0x8d,
+ 0x02,0x10,0x26,0x03,0x30,0x04,0x06,0xa1,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7b,0xba,0x20,0x8d,
+ 0x02,0x10,0x26,0x03,0x30,0x04,0x06,0xa1,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf6,0x67,0x20,0x8d,
+ 0x02,0x10,0x26,0x03,0x30,0x24,0x16,0x06,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x29,0xec,0x20,0x8d,
+ 0x02,0x10,0x26,0x03,0x30,0x24,0x18,0xee,0x80,0x00,0x02,0x0e,0xc4,0xff,0xfe,0xd1,0xef,0x15,0x20,0x8d,
+ 0x02,0x10,0x26,0x03,0x60,0x00,0xa4,0x00,0x93,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x20,0x8d,
+ 0x02,0x10,0x26,0x03,0x60,0x10,0x70,0x01,0x48,0x30,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x01,0x20,0x8d,
0x02,0x10,0x26,0x03,0x80,0x80,0x1f,0x07,0x6f,0xdd,0x7d,0xe2,0xd9,0x69,0x78,0xc9,0xb7,0xea,0x20,0x8d,
- 0x02,0x10,0x26,0x03,0x80,0x80,0x73,0x00,0x05,0x31,0x00,0x00,0x00,0x00,0x00,0x00,0x13,0xea,0x20,0x8d,
- 0x02,0x10,0x26,0x03,0x80,0xa0,0x07,0x03,0x40,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x20,0x8d,
- 0x02,0x10,0x26,0x04,0x01,0x80,0x00,0xf3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x18,0x20,0x8d,
- 0x02,0x10,0x26,0x04,0x3d,0x08,0x00,0x00,0x00,0x05,0xd9,0x41,0x4b,0x03,0xa0,0x93,0x13,0x1b,0x20,0x8d,
- 0x02,0x10,0x26,0x04,0x7c,0x00,0x01,0x20,0x00,0x4b,0x00,0x00,0x00,0x00,0x00,0x00,0xeb,0x24,0x20,0x8d,
- 0x02,0x10,0x26,0x04,0x0a,0x00,0x00,0x21,0x30,0x43,0xbf,0x6a,0x53,0x5e,0xdf,0xeb,0x5b,0x7b,0x20,0x8d,
- 0x02,0x10,0x26,0x04,0xa8,0x80,0x04,0x00,0x00,0xd0,0x00,0x00,0x00,0x00,0x1c,0xe7,0x40,0x01,0x20,0x8d,
- 0x02,0x10,0x26,0x04,0xa8,0x80,0x04,0x00,0x00,0xd0,0x00,0x00,0x00,0x00,0x1d,0x44,0xe0,0x01,0x20,0x8d,
+ 0x02,0x10,0x26,0x03,0x80,0x80,0xd6,0x00,0x18,0x00,0x7c,0xe1,0x74,0xa2,0x6a,0x8a,0x46,0x43,0x20,0x8d,
+ 0x02,0x10,0x26,0x03,0x80,0x81,0x6c,0x00,0x30,0x6e,0x02,0x15,0x5d,0xff,0xfe,0x02,0x15,0x0a,0x20,0x8d,
+ 0x02,0x10,0x26,0x04,0x3d,0x09,0x71,0x82,0x87,0x00,0xbb,0xa9,0xcd,0xe6,0x5b,0x37,0xa8,0xdf,0x20,0x8d,
+ 0x02,0x10,0x26,0x04,0x40,0x80,0x10,0x36,0x80,0xb1,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xbe,0x20,0x8d,
+ 0x02,0x10,0x26,0x04,0x0a,0x00,0x00,0x03,0x12,0x23,0x02,0x16,0x3e,0xff,0xfe,0x27,0x76,0xe0,0x20,0x8d,
0x02,0x10,0x26,0x04,0xa8,0x80,0x04,0x00,0x00,0xd0,0x00,0x00,0x00,0x00,0x26,0x1f,0x60,0x01,0x20,0x8d,
- 0x02,0x10,0x26,0x04,0xa8,0x80,0x04,0x00,0x00,0xd1,0x00,0x00,0x00,0x00,0x07,0xe2,0xe0,0x01,0x20,0x8d,
- 0x02,0x10,0x26,0x04,0xa8,0x80,0x00,0x04,0x01,0xd0,0x00,0x00,0x00,0x00,0x00,0x14,0x30,0x00,0x20,0x8d,
+ 0x02,0x10,0x26,0x04,0xa8,0x80,0x00,0x04,0x01,0xd0,0x00,0x00,0x00,0x00,0x01,0x3e,0xf0,0x00,0x20,0x8d,
+ 0x02,0x10,0x26,0x04,0xa8,0x80,0x00,0x04,0x01,0xd0,0x00,0x00,0x00,0x00,0x01,0x7a,0x70,0x00,0x20,0x8d,
+ 0x02,0x10,0x26,0x04,0xa8,0x80,0x00,0x04,0x01,0xd0,0x00,0x00,0x00,0x00,0x00,0xc1,0x30,0x00,0x20,0x8d,
0x02,0x10,0x26,0x04,0xa8,0x80,0x00,0x04,0x01,0xd0,0x00,0x00,0x00,0x00,0x00,0xe5,0xb0,0x00,0x20,0x8d,
+ 0x02,0x10,0x26,0x05,0x4a,0x80,0xa3,0x02,0x79,0x40,0x72,0x54,0x1e,0xd4,0x90,0xd7,0x4f,0x39,0x20,0x8d,
+ 0x02,0x10,0x26,0x05,0x4a,0x80,0xa3,0x02,0x79,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x20,0x8d,
0x02,0x10,0x26,0x05,0x64,0x00,0x00,0x30,0xf2,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x8d,
- 0x02,0x10,0x26,0x05,0x6f,0x80,0x00,0x00,0x00,0x07,0xfc,0x1b,0xcc,0xff,0xfe,0x8a,0xd8,0x22,0x20,0x8d,
- 0x02,0x10,0x26,0x05,0xa1,0x40,0x20,0x76,0x82,0x53,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x8d,
- 0x02,0x10,0x26,0x05,0xa1,0x40,0x30,0x07,0x12,0x87,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x8d,
+ 0x02,0x10,0x26,0x05,0xa1,0x40,0x30,0x10,0x40,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,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,0x0b,0x40,0x14,0xd0,0x5b,0x00,0x79,0x88,0x0e,0xb8,0x6b,0xb6,0x66,0xe2,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,0x1a,0x00,0x00,0x01,0x00,0x0d,0x00,0x00,0x00,0x00,0x00,0x11,0x7c,0x4d,0x20,0x8d,
- 0x02,0x10,0x26,0x07,0x53,0x00,0x02,0x03,0x12,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x8d,
+ 0x02,0x10,0x26,0x07,0x53,0x00,0x00,0x61,0x08,0x54,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x8d,
0x02,0x10,0x26,0x07,0x92,0x80,0x00,0x0b,0x07,0x3b,0x02,0x50,0x56,0xff,0xfe,0x14,0x25,0xb5,0x20,0x8d,
0x02,0x10,0x26,0x07,0x92,0x80,0x00,0x0b,0x07,0x3b,0x02,0x50,0x56,0xff,0xfe,0x21,0x9c,0x2f,0x20,0x8d,
0x02,0x10,0x26,0x07,0x92,0x80,0x00,0x0b,0x07,0x3b,0x02,0x50,0x56,0xff,0xfe,0x21,0xbf,0x32,0x20,0x8d,
0x02,0x10,0x26,0x07,0x92,0x80,0x00,0x0b,0x07,0x3b,0x02,0x50,0x56,0xff,0xfe,0x33,0x4d,0x1b,0x20,0x8d,
0x02,0x10,0x26,0x07,0x92,0x80,0x00,0x0b,0x07,0x3b,0x02,0x50,0x56,0xff,0xfe,0x3d,0x04,0x01,0x20,0x8d,
- 0x02,0x10,0x26,0x07,0xf2,0xc0,0xe1,0xc2,0x00,0x69,0x12,0xc3,0x7b,0xff,0xfe,0x4d,0x94,0x31,0x20,0x8d,
- 0x02,0x10,0x26,0x07,0xf2,0xc0,0xe1,0xc2,0x00,0x69,0xec,0xb2,0x6e,0x88,0x9f,0x33,0x50,0x57,0x20,0x8d,
- 0x02,0x10,0x26,0x20,0x00,0x06,0x20,0x03,0x01,0x05,0x02,0xd8,0x61,0xff,0xfe,0x0f,0x08,0x53,0x20,0x8d,
0x02,0x10,0x26,0x20,0x00,0x6e,0xa0,0x00,0x00,0x01,0x00,0x42,0x00,0x42,0x00,0x42,0x00,0x42,0x20,0x8d,
- 0x02,0x10,0x26,0x20,0x00,0xa6,0x20,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x03,0xd5,0x70,0x20,0x8d,
- 0x02,0x10,0x26,0x20,0x00,0xa6,0x20,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x05,0x16,0x2a,0x20,0x8d,
- 0x02,0x10,0x26,0x20,0x00,0xa6,0x20,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x05,0x16,0x31,0x20,0x8d,
- 0x02,0x10,0x26,0x20,0x00,0xa6,0x20,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x0c,0xe6,0x34,0x20,0x8d,
- 0x02,0x10,0x28,0x00,0x00,0x40,0x00,0x33,0x08,0xab,0xa0,0xe7,0xb2,0x15,0xfc,0x83,0x5c,0x31,0x20,0x8d,
- 0x02,0x10,0x28,0x00,0x0b,0xf0,0x01,0x49,0x0f,0x4b,0xf8,0xdf,0x8d,0x7d,0x80,0x1b,0xe2,0x5e,0x20,0x8d,
- 0x02,0x10,0x28,0x04,0x01,0x4c,0x01,0x98,0x80,0xd5,0x76,0x03,0x41,0xd1,0xd3,0xfc,0xe7,0x97,0x20,0x8d,
- 0x02,0x10,0x28,0x04,0x01,0x4d,0xae,0x81,0x82,0x7b,0x99,0xa8,0x1e,0x3f,0x6d,0xb2,0x29,0xdb,0x20,0x8d,
- 0x02,0x10,0x28,0x04,0x0d,0x57,0x55,0x37,0x48,0x00,0x3e,0x7c,0x3f,0xff,0xfe,0x7b,0x80,0xaa,0x20,0x8d,
- 0x02,0x10,0x2a,0x00,0x12,0xe0,0x01,0x01,0x00,0x99,0x02,0x0c,0x29,0xff,0xfe,0x29,0xd0,0x3f,0x20,0x8d,
- 0x02,0x10,0x2a,0x00,0x13,0x28,0xe1,0x01,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x63,0x20,0x8d,
+ 0x02,0x10,0x26,0x20,0x00,0xa6,0x20,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x05,0x16,0x01,0x20,0x8d,
+ 0x02,0x10,0x26,0x20,0x00,0xa6,0x20,0x00,0x00,0x01,0x00,0x02,0x00,0x00,0x00,0x09,0x90,0x0b,0x20,0x8d,
+ 0x02,0x10,0x26,0x20,0x00,0xa6,0x20,0x00,0x00,0x01,0x00,0x02,0x00,0x00,0x00,0x0b,0x30,0x0e,0x20,0x8d,
+ 0x02,0x10,0x28,0x00,0x01,0x50,0x01,0x1d,0x0d,0x2f,0xbd,0xac,0x78,0x07,0x02,0xf5,0x4a,0xa0,0x20,0x8d,
+ 0x02,0x10,0x28,0x03,0x98,0x00,0xa0,0x07,0x82,0xba,0x65,0x0b,0x82,0xb8,0x83,0x77,0x00,0xd0,0x20,0x8d,
+ 0x02,0x10,0x28,0x04,0x01,0x4c,0x01,0x55,0x45,0xe0,0x1e,0x86,0x15,0xa3,0xef,0xd9,0x72,0x87,0x20,0x8d,
+ 0x02,0x10,0x28,0x04,0x01,0x4c,0x65,0x7d,0x40,0x30,0x28,0xb4,0x0e,0xff,0xfe,0x9b,0x88,0x94,0x20,0x8d,
+ 0x02,0x10,0x28,0x04,0x01,0x4d,0x10,0x87,0x94,0x34,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x02,0x20,0x8d,
+ 0x02,0x10,0x28,0x04,0x09,0x54,0x00,0x24,0x00,0x02,0xb3,0x90,0xd8,0x3b,0x35,0x8a,0xdb,0x53,0x20,0x8d,
+ 0x02,0x10,0x28,0x04,0x0d,0x57,0x55,0x4d,0xde,0x00,0x3e,0x7c,0x3f,0xff,0xfe,0x7b,0x80,0xaa,0x20,0x8d,
+ 0x02,0x10,0x2a,0x00,0x10,0x28,0x83,0x8c,0x56,0x3a,0xfd,0x25,0x87,0xb6,0x5a,0x54,0x08,0x11,0x20,0x8d,
+ 0x02,0x10,0x2a,0x00,0x12,0x98,0x80,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x65,0x42,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,0x98,0x00,0x04,0x2a,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0xbc,0x03,0x20,0x8d,
- 0x02,0x10,0x2a,0x00,0x16,0x30,0x00,0x10,0x10,0x03,0x00,0x00,0x0b,0x19,0xb0,0x0b,0xba,0xbe,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,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,0x08,0x5d,0x17,0x77,0x03,0xb0,0xf5,0x41,0x33,0x20,0x8d,
0x02,0x10,0x2a,0x00,0x23,0xc5,0xfe,0x80,0x73,0x01,0xd6,0xae,0x52,0xff,0xfe,0xd5,0x56,0xa5,0x20,0x8d,
- 0x02,0x10,0x2a,0x00,0x23,0xc6,0x5c,0x91,0x58,0x08,0xc0,0x5a,0x4d,0xff,0xfe,0x65,0x9d,0x69,0x20,0x8d,
- 0x02,0x10,0x2a,0x00,0x60,0x20,0x1b,0xfa,0xd4,0x00,0x02,0x0c,0x29,0xff,0xfe,0x61,0x4a,0x4c,0x20,0x8d,
- 0x02,0x10,0x2a,0x00,0x60,0x20,0xb4,0x82,0x92,0x00,0x49,0x1a,0x35,0x8c,0xd8,0xf7,0x01,0xda,0x20,0x8d,
+ 0x02,0x10,0x2a,0x00,0x60,0x20,0x13,0xdc,0xbc,0x00,0x55,0x59,0x02,0x58,0x02,0x7d,0xb5,0x2b,0x20,0x8d,
+ 0x02,0x10,0x2a,0x00,0x60,0x20,0x45,0x03,0x37,0x00,0x02,0x0c,0x29,0xff,0xfe,0x61,0x4a,0x4c,0x20,0x8d,
+ 0x02,0x10,0x2a,0x00,0x60,0x20,0xb4,0x34,0xeb,0x00,0xde,0xa6,0x32,0xff,0xfe,0x0d,0xa5,0xc0,0x20,0x8d,
0x02,0x10,0x2a,0x00,0x60,0x20,0xb4,0x89,0x20,0x00,0x50,0x54,0x00,0xff,0xfe,0xfc,0x5e,0xd8,0x20,0x8d,
+ 0x02,0x10,0x2a,0x00,0x7c,0x80,0x00,0x00,0x01,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x20,0x8d,
0x02,0x10,0x2a,0x00,0x7c,0x80,0x00,0x00,0x00,0x25,0x00,0x00,0x00,0x00,0x00,0x00,0xe3,0x7a,0x20,0x8d,
- 0x02,0x10,0x2a,0x00,0x7c,0x80,0x00,0x00,0x00,0x71,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,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,0xae,0x40,0x24,0x0e,0x32,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x20,0x8d,
+ 0x02,0x10,0x2a,0x00,0xbb,0xe0,0x00,0xcc,0x00,0x00,0x5a,0x11,0x22,0xff,0xfe,0xb4,0x8f,0x5c,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,0xd4,0xe0,0x00,0x02,0xd0,0x02,0x44,0x67,0x31,0xe0,0x6f,0xa5,0xb3,0xef,0x20,0x8d,
+ 0x02,0x10,0x2a,0x00,0x0c,0xa8,0x0a,0x15,0x9a,0x5b,0x8b,0x42,0xa8,0x86,0x7d,0x48,0x7a,0x21,0x20,0x8d,
+ 0x02,0x10,0x2a,0x00,0x0c,0xa8,0x0a,0x1f,0xf9,0xb7,0xcb,0x55,0x57,0x66,0x52,0x4b,0xac,0xaa,0x20,0x8d,
+ 0x02,0x10,0x2a,0x00,0xd4,0xe0,0x00,0xff,0xfc,0x02,0x5e,0x55,0x4a,0x7c,0xb8,0x3b,0xe5,0xa1,0x20,0x8d,
+ 0x02,0x10,0x2a,0x00,0xd5,0x20,0x00,0x09,0x93,0x00,0x42,0x0b,0x54,0x4e,0x80,0x19,0x6d,0x3a,0x20,0x8d,
+ 0x02,0x10,0x2a,0x00,0xd8,0x80,0x00,0x05,0x00,0xc2,0x00,0x00,0x00,0x00,0x00,0x00,0xd3,0x29,0x20,0x8d,
0x02,0x10,0x2a,0x00,0x0e,0xe2,0x12,0x00,0x19,0x00,0x08,0xd3,0xd2,0xff,0xfe,0xb1,0xbc,0x58,0x20,0x8d,
- 0x02,0x10,0x2a,0x01,0x02,0x38,0x42,0x0f,0x92,0x00,0xfa,0x5a,0x1a,0x4b,0x1e,0x6a,0xfa,0xdf,0x20,0x8d,
- 0x02,0x10,0x2a,0x01,0x02,0x38,0x43,0x89,0xc4,0x00,0x3b,0x26,0xd9,0x4e,0x38,0xd5,0x44,0xef,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,0x31,0x00,0xcd,0xa1,0x0c,0x6a,0x2b,0xad,0x24,0x18,0x20,0x8d,
- 0x02,0x10,0x2a,0x01,0x04,0xf8,0x01,0x41,0x22,0x54,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x20,0x8d,
0x02,0x10,0x2a,0x01,0x04,0xf8,0x01,0x73,0x23,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x20,0x8d,
- 0x02,0x10,0x2a,0x01,0x04,0xf8,0x01,0x90,0x91,0xc4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x20,0x8d,
0x02,0x10,0x2a,0x01,0x04,0xf8,0x02,0x00,0x72,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x20,0x8d,
0x02,0x10,0x2a,0x01,0x04,0xf8,0x02,0x02,0x03,0xe6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x20,0x8d,
0x02,0x10,0x2a,0x01,0x04,0xf8,0x02,0x21,0x44,0xd7,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x20,0x8d,
0x02,0x10,0x2a,0x01,0x04,0xf8,0x02,0x31,0x09,0x15,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x20,0x8d,
- 0x02,0x10,0x2a,0x01,0x04,0xf9,0x00,0x2a,0x1c,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x20,0x8d,
+ 0x02,0x10,0x2a,0x01,0x04,0xf8,0x02,0x61,0x2b,0xcd,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x20,0x8d,
+ 0x02,0x10,0x2a,0x01,0x04,0xf8,0x02,0x61,0x3c,0xae,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x20,0x8d,
+ 0x02,0x10,0x2a,0x01,0x04,0xf8,0x02,0x61,0x42,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x20,0x8d,
0x02,0x10,0x2a,0x01,0x04,0xf9,0x00,0x2b,0x02,0x9a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x20,0x8d,
- 0x02,0x10,0x2a,0x01,0x04,0xf9,0x00,0x4a,0x31,0xde,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x20,0x8d,
- 0x02,0x10,0x2a,0x01,0x52,0x00,0x00,0x6c,0x61,0x62,0x7a,0x61,0x74,0x6b,0x6f,0x2e,0x73,0x6b,0x20,0x8d,
- 0x02,0x10,0x2a,0x01,0x63,0x80,0xff,0xfe,0x00,0x73,0x10,0xfb,0xd0,0x12,0x85,0x81,0xb4,0xd7,0x20,0x8d,
+ 0x02,0x10,0x2a,0x01,0x04,0xf9,0x00,0x3a,0x2d,0xd2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x20,0x8d,
0x02,0x10,0x2a,0x01,0x07,0xa7,0x00,0x02,0x28,0x04,0xae,0x1f,0x6b,0xff,0xfe,0x9d,0x6c,0x94,0x20,0x8d,
- 0x02,0x10,0x2a,0x01,0x07,0xc8,0xaa,0xac,0x00,0x89,0x50,0x54,0x00,0xff,0xfe,0xb7,0xf5,0xcb,0x20,0x8d,
+ 0x02,0x10,0x2a,0x01,0x07,0xc8,0xaa,0xc2,0x01,0x80,0x50,0x54,0x00,0xff,0xfe,0x56,0x8d,0x10,0x20,0x8d,
0x02,0x10,0x2a,0x01,0x07,0xc8,0xaa,0xc9,0x00,0xc9,0x50,0x54,0x00,0xff,0xfe,0xdf,0xff,0x95,0x20,0x8d,
- 0x02,0x10,0x2a,0x01,0x07,0xc8,0xd0,0x01,0x01,0xc1,0x50,0x54,0x00,0xff,0xfe,0xee,0x3e,0x1a,0x20,0x8d,
- 0x02,0x10,0x2a,0x01,0x07,0xc8,0xd0,0x09,0x02,0xaa,0x50,0x54,0x00,0xff,0xfe,0x1b,0xa1,0x96,0x2d,0x00,
- 0x02,0x10,0x2a,0x01,0x07,0xc8,0xff,0xfa,0x05,0x0e,0xdd,0xfe,0xc9,0x24,0xca,0x0a,0xcb,0xab,0x20,0x8d,
- 0x02,0x10,0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x93,0xff,0xfe,0x59,0x66,0xdc,0x20,0x8d,
- 0x02,0x10,0x2a,0x01,0x7e,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x93,0xff,0xfe,0x3b,0xbb,0x5b,0x20,0x8d,
+ 0x02,0x10,0x2a,0x01,0x7e,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x93,0xff,0xfe,0x49,0x2f,0x5b,0x20,0x8d,
+ 0x02,0x10,0x2a,0x01,0x87,0x40,0x00,0x01,0x07,0x53,0x00,0x00,0x00,0x00,0x00,0x00,0xe5,0xcb,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,0x9f,0x40,0xa0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x20,0x8d,
- 0x02,0x10,0x2a,0x01,0xcb,0x00,0x0d,0x3d,0x77,0x00,0x02,0x27,0x0e,0xff,0xfe,0x28,0xc5,0x65,0x20,0x8d,
- 0x02,0x10,0x2a,0x01,0x0e,0x0a,0x00,0x20,0x73,0x50,0x91,0x9c,0xb1,0xc3,0x8b,0x83,0xad,0xf9,0x20,0x8d,
+ 0x02,0x10,0x2a,0x01,0xcb,0x00,0x0b,0x63,0xc0,0x00,0x02,0x27,0x0e,0xff,0xfe,0x28,0xc5,0x65,0x20,0x8d,
+ 0x02,0x10,0x2a,0x01,0xcb,0x19,0x06,0x88,0xe9,0x00,0xaa,0x60,0xb6,0xff,0xfe,0x29,0xbb,0xae,0x20,0x8d,
+ 0x02,0x10,0x2a,0x01,0x0e,0x0a,0x01,0x63,0xc0,0xb0,0x9d,0xa5,0x16,0x90,0xa1,0x2b,0xbe,0xde,0x20,0x8d,
+ 0x02,0x10,0x2a,0x01,0x0e,0x0a,0x02,0x82,0x67,0xb0,0xb4,0xf4,0xaa,0xff,0xfe,0x7c,0x44,0xa6,0x20,0x8d,
0x02,0x10,0x2a,0x01,0x0e,0x0a,0x03,0x01,0x70,0x10,0xb8,0x7d,0xe1,0x4b,0xce,0xa9,0xb9,0x98,0x20,0x8d,
- 0x02,0x10,0x2a,0x01,0x0e,0x0a,0x04,0x8b,0x2d,0x10,0x94,0xf2,0x4d,0x5c,0xca,0x5f,0xbf,0x49,0x20,0x8d,
- 0x02,0x10,0x2a,0x01,0x0e,0x0a,0x05,0x30,0xa0,0xa0,0xf4,0x65,0x0a,0xf5,0xbe,0x1b,0x90,0x75,0x20,0x8d,
- 0x02,0x10,0x2a,0x01,0x0e,0x0a,0x0a,0xa7,0xc8,0xc0,0x96,0x79,0xaf,0xfa,0xb6,0xe5,0xef,0xc7,0x20,0x8d,
+ 0x02,0x10,0x2a,0x01,0x0e,0x0a,0x03,0x20,0x39,0xa0,0x32,0x5a,0x3a,0xff,0xfe,0x02,0x31,0x80,0x20,0x8d,
+ 0x02,0x10,0x2a,0x01,0x0e,0x0a,0x03,0x51,0x9f,0xb0,0x6b,0xf2,0x95,0xd6,0xb7,0xbd,0xb8,0x46,0x20,0x8d,
+ 0x02,0x10,0x2a,0x01,0x0e,0x0a,0x05,0xfa,0xa0,0xa0,0xca,0x1f,0x66,0xff,0xfe,0xce,0xb8,0xa2,0x20,0x8d,
+ 0x02,0x10,0x2a,0x01,0x0e,0x0a,0x08,0x3d,0xdd,0x30,0x36,0x76,0x5d,0x8e,0x8a,0x6f,0x11,0x5a,0x20,0x8d,
+ 0x02,0x10,0x2a,0x01,0x0e,0x0a,0x09,0xe9,0xc2,0x40,0x7b,0x44,0xf3,0x2a,0x6e,0xc0,0xa8,0xaf,0x20,0x8d,
+ 0x02,0x10,0x2a,0x01,0x0e,0x0a,0x00,0xb5,0x7f,0x50,0xc2,0x57,0xa5,0x5b,0x48,0x46,0x97,0xe1,0x20,0x8d,
0x02,0x10,0x2a,0x01,0x0e,0x11,0x10,0x0c,0x00,0x70,0xcb,0xc8,0x9e,0x31,0x4b,0x77,0x16,0x26,0x20,0x8d,
- 0x02,0x10,0x2a,0x01,0x0e,0x34,0xee,0x78,0x30,0x60,0x02,0x30,0x48,0xff,0xfe,0x81,0xf1,0xc6,0x20,0x8d,
- 0x02,0x10,0x2a,0x02,0x12,0x10,0x14,0xa9,0x67,0x00,0x0a,0x00,0x27,0xff,0xfe,0x4e,0x82,0xb6,0x20,0x8d,
- 0x02,0x10,0x2a,0x02,0x12,0x10,0x46,0x39,0x0f,0x00,0x10,0xa7,0xe9,0x65,0x50,0x9a,0x7a,0x4a,0x20,0x8d,
- 0x02,0x10,0x2a,0x02,0x12,0x10,0x7c,0x92,0x51,0x00,0x02,0x11,0x32,0xff,0xfe,0xae,0x15,0x2d,0x20,0x8d,
- 0x02,0x10,0x2a,0x02,0x12,0x10,0x86,0xbf,0xf1,0x00,0x31,0x78,0xd7,0x00,0xd4,0x4d,0x6b,0xb1,0x20,0x8d,
- 0x02,0x10,0x2a,0x02,0x12,0x10,0x94,0x87,0xa2,0x00,0xed,0xc1,0x93,0xa4,0x09,0x45,0x9a,0x92,0x20,0x8d,
+ 0x02,0x10,0x2a,0x02,0x12,0x10,0x2c,0xdf,0x46,0x00,0x02,0xbc,0xe0,0x3e,0x43,0xe8,0x47,0x18,0x20,0x8d,
+ 0x02,0x10,0x2a,0x02,0x12,0x10,0x86,0xbf,0xf1,0x00,0xa9,0xac,0xd0,0x41,0x1f,0x8e,0x69,0x25,0x20,0x8d,
+ 0x02,0x10,0x2a,0x02,0x12,0x10,0x94,0xc3,0x34,0x00,0xd8,0xc3,0x74,0x3c,0x90,0xf6,0xa4,0x8a,0x20,0x8d,
+ 0x02,0x10,0x2a,0x02,0x01,0x68,0x20,0x00,0x00,0x96,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x12,0x20,0x8d,
0x02,0x10,0x2a,0x02,0x01,0x68,0x42,0x0b,0x00,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x8d,
- 0x02,0x10,0x2a,0x02,0x01,0x68,0x63,0x28,0x00,0x00,0x4a,0x21,0x0b,0xff,0xfe,0x26,0x38,0xc3,0x20,0x8d,
0x02,0x10,0x2a,0x02,0x01,0x68,0x67,0x6e,0x00,0x00,0xe6,0x5f,0x01,0xff,0xfe,0x09,0x35,0x91,0x20,0x8d,
- 0x02,0x10,0x2a,0x02,0x17,0x48,0xf3,0x9f,0x58,0x72,0xde,0xad,0xbe,0xef,0xb1,0xac,0xc0,0xfe,0x20,0x8d,
+ 0x02,0x10,0x2a,0x02,0x17,0x48,0xf3,0x9f,0x58,0x72,0x02,0x16,0x3e,0xff,0xfe,0x21,0x02,0x66,0x20,0x8d,
0x02,0x10,0x2a,0x02,0x01,0x80,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x05,0x17,0x10,0xb6,0x20,0x8d,
- 0x02,0x10,0x2a,0x02,0x21,0x68,0xa3,0x79,0xd1,0x00,0x96,0xde,0x80,0xff,0xfe,0xa3,0xfd,0x00,0x20,0x8d,
0x02,0x10,0x2a,0x02,0x27,0x80,0x90,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x20,0x8d,
0x02,0x10,0x2a,0x02,0x27,0x80,0x90,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x20,0x8d,
0x02,0x10,0x2a,0x02,0x27,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x1a,0x20,0x8d,
- 0x02,0x10,0x2a,0x02,0x2e,0x02,0x39,0x00,0x54,0x00,0xa0,0x99,0xe1,0xff,0xfe,0xb6,0x0d,0x0e,0x20,0x8d,
- 0x02,0x10,0x2a,0x02,0x2f,0x05,0x66,0x0e,0x8b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x8d,
- 0x02,0x10,0x2a,0x02,0x00,0x58,0x00,0x97,0x7d,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x20,0x8d,
- 0x02,0x10,0x2a,0x02,0x6d,0x40,0x30,0x73,0x0c,0x01,0xde,0xa6,0x32,0xff,0xfe,0x44,0x4b,0x25,0x20,0x8d,
+ 0x02,0x10,0x2a,0x02,0x2f,0x05,0x60,0x08,0xce,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x8d,
+ 0x02,0x10,0x2a,0x02,0x03,0x90,0x90,0x00,0x00,0x00,0xaa,0xa1,0x59,0xff,0xfe,0x43,0xb5,0x7b,0x20,0x8d,
+ 0x02,0x10,0x2a,0x02,0x05,0x78,0x85,0xce,0x16,0x00,0x1e,0x1b,0x0d,0xff,0xfe,0xe3,0x77,0x4b,0x20,0x8d,
+ 0x02,0x10,0x2a,0x02,0x07,0x68,0xf9,0x2b,0xdb,0x46,0x5e,0x46,0x77,0x2b,0x07,0x1d,0x29,0xb7,0x20,0x8d,
0x02,0x10,0x2a,0x02,0x7a,0x01,0x00,0x00,0x00,0x00,0x00,0x91,0x02,0x28,0x00,0x45,0x01,0x30,0x20,0x8d,
+ 0x02,0x10,0x2a,0x02,0x7b,0x40,0x50,0xd0,0xe3,0x86,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x8d,
+ 0x02,0x10,0x2a,0x02,0x7b,0x40,0x50,0xd1,0xe3,0x5b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x8d,
0x02,0x10,0x2a,0x02,0x7b,0x40,0x59,0x28,0x00,0x89,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x8d,
- 0x02,0x10,0x2a,0x02,0x7b,0x40,0xc3,0xb5,0xf5,0x83,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x8d,
- 0x02,0x10,0x2a,0x02,0x83,0x08,0x80,0x87,0xaa,0x00,0x9e,0xa8,0x01,0xb2,0xef,0x98,0x56,0xbf,0x20,0x8d,
+ 0x02,0x10,0x2a,0x02,0x7b,0x40,0xb9,0x45,0x34,0x4d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x8d,
+ 0x02,0x10,0x2a,0x02,0x7b,0x40,0xd4,0x18,0x6d,0x9a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x8d,
+ 0x02,0x10,0x2a,0x02,0x80,0x70,0x0b,0x84,0x6a,0xe0,0xf9,0xc6,0xfb,0xb9,0x1c,0x41,0x81,0xaa,0x20,0x8d,
+ 0x02,0x10,0x2a,0x02,0x80,0x70,0xf1,0x86,0x38,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0xd5,0xa6,0x20,0x8d,
+ 0x02,0x10,0x2a,0x02,0x80,0x84,0x01,0x03,0x68,0x10,0x1e,0x69,0x7a,0xff,0xfe,0xa2,0x1a,0xcc,0x20,0x8d,
+ 0x02,0x10,0x2a,0x02,0x83,0x08,0x80,0x81,0xf3,0x00,0x03,0xb8,0x7e,0xc0,0x28,0x37,0x1b,0x57,0x20,0x8d,
+ 0x02,0x10,0x2a,0x02,0x83,0x88,0xe3,0x02,0x79,0x80,0x6f,0x85,0xa0,0xb3,0x4b,0x4d,0x8b,0x0f,0x20,0x8d,
+ 0x02,0x10,0x2a,0x02,0x83,0x88,0xe5,0xc3,0x4a,0x80,0x02,0x01,0x2e,0xff,0xfe,0x82,0xb3,0xcc,0x20,0x8d,
0x02,0x10,0x2a,0x02,0x84,0x2a,0x01,0xdf,0x8a,0x01,0x1e,0x1b,0x0d,0xff,0xfe,0x0b,0x23,0x6d,0x20,0x8d,
+ 0x02,0x10,0x2a,0x02,0xa2,0x10,0x28,0xbe,0x5f,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x11,0x20,0x8d,
+ 0x02,0x10,0x2a,0x02,0xa4,0x4b,0x5c,0xf9,0x00,0x01,0xb6,0x2e,0x99,0xff,0xfe,0x49,0xd4,0x92,0x20,0x8d,
0x02,0x10,0x2a,0x02,0xa4,0x4d,0x14,0xd6,0x00,0x01,0x02,0xc0,0x08,0xff,0xfe,0x8f,0xb3,0xb2,0x20,0x8d,
0x02,0x10,0x2a,0x02,0xa4,0x5a,0x94,0xcd,0xf0,0x0d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x8d,
- 0x02,0x10,0x2a,0x02,0xa4,0x5f,0x3b,0x9d,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x20,0x8d,
- 0x02,0x10,0x2a,0x02,0xa4,0x67,0x78,0x33,0x00,0x01,0x72,0x85,0xc2,0xff,0xfe,0x2c,0x21,0xe9,0x20,0x8d,
- 0x02,0x10,0x2a,0x02,0xaa,0x14,0x23,0x80,0xb3,0x00,0x40,0x40,0xbe,0x88,0x8b,0x01,0x0d,0x38,0x20,0x8d,
+ 0x02,0x10,0x2a,0x02,0xa4,0x5f,0x3b,0x9d,0x00,0x31,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x99,0x20,0x8d,
+ 0x02,0x10,0x2a,0x02,0xa4,0x64,0x3d,0x6b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x02,0x20,0x8d,
+ 0x02,0x10,0x2a,0x02,0xa4,0x6c,0x7f,0x8e,0x00,0x01,0x35,0xbf,0x3a,0xeb,0x13,0x7c,0x1d,0x35,0x20,0x8d,
+ 0x02,0x10,0x2a,0x02,0xa4,0x6d,0x03,0x6f,0x00,0x01,0x02,0x0d,0xb9,0xff,0xfe,0x4e,0x63,0x98,0x20,0x8d,
+ 0x02,0x10,0x2a,0x02,0xc2,0x05,0x20,0x21,0x42,0x16,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x8d,
0x02,0x10,0x2a,0x02,0xc2,0x06,0x20,0x44,0x98,0x26,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x8d,
- 0x02,0x10,0x2a,0x02,0xc2,0x06,0x20,0x82,0x12,0x46,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x8d,
- 0x02,0x10,0x2a,0x02,0xc2,0x06,0x30,0x08,0x23,0x68,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x8d,
- 0x02,0x10,0x2a,0x02,0xc2,0x07,0x00,0x00,0x49,0x71,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x14,0xd4,
+ 0x02,0x10,0x2a,0x02,0xc2,0x06,0x20,0x75,0x33,0x51,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x8d,
+ 0x02,0x10,0x2a,0x02,0xc2,0x07,0x00,0x00,0x38,0x29,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x8d,
0x02,0x10,0x2a,0x02,0xc2,0x07,0x20,0x14,0x41,0x99,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x8d,
- 0x02,0x10,0x2a,0x02,0xc2,0x07,0x20,0x24,0x61,0x15,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x8d,
+ 0x02,0x10,0x2a,0x02,0xc2,0x07,0x20,0x14,0x87,0x57,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x8d,
0x02,0x10,0x2a,0x02,0xc2,0x07,0x20,0x26,0x66,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x8d,
+ 0x02,0x10,0x2a,0x02,0xc2,0x07,0x20,0x34,0x73,0x58,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x8d,
0x02,0x10,0x2a,0x02,0xc2,0x07,0x30,0x02,0x74,0x68,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x8d,
+ 0x02,0x10,0x2a,0x02,0xc2,0x07,0x30,0x08,0x45,0x92,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x8d,
+ 0x02,0x10,0x2a,0x02,0xcb,0x43,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x78,0x20,0x8d,
+ 0x02,0x10,0x2a,0x02,0x0e,0x5e,0x00,0x01,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x27,0x20,0x8d,
0x02,0x10,0x2a,0x02,0x0e,0x98,0x00,0x20,0x15,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x8d,
- 0x02,0x10,0x2a,0x03,0x40,0x00,0x00,0x06,0x41,0x6c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x43,0x20,0x8d,
- 0x02,0x10,0x2a,0x03,0x40,0x00,0x00,0x06,0xf8,0x14,0x54,0x8b,0x17,0xff,0xfe,0x31,0xb6,0x4a,0x20,0x8d,
+ 0x02,0x10,0x2a,0x03,0x40,0x00,0x00,0x28,0x00,0x68,0x74,0x11,0x53,0xff,0xfe,0x4c,0x02,0x1d,0x20,0x8d,
+ 0x02,0x10,0x2a,0x03,0x40,0x00,0x00,0x65,0x0f,0xdc,0x34,0x62,0x66,0xff,0xfe,0x05,0xec,0x5c,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,0x94,0xe0,0xff,0xff,0x01,0x85,0x02,0x43,0x02,0x18,0x00,0x00,0x00,0x19,0x20,0x8d,
0x02,0x10,0x2a,0x03,0xb0,0xc0,0x00,0x01,0x00,0xe0,0x00,0x00,0x00,0x00,0x03,0x97,0x60,0x01,0x20,0x8d,
- 0x02,0x10,0x2a,0x03,0xb0,0xc0,0x00,0x02,0x00,0xf0,0x00,0x00,0x00,0x00,0x01,0x63,0x30,0x01,0x20,0x8d,
- 0x02,0x10,0x2a,0x03,0xb0,0xc0,0x00,0x02,0x00,0xf0,0x00,0x00,0x00,0x00,0x01,0x8a,0xd0,0x01,0x20,0x8d,
- 0x02,0x10,0x2a,0x03,0xb0,0xc0,0x00,0x03,0x00,0xd0,0x00,0x00,0x00,0x00,0x0f,0x3e,0x20,0x01,0x20,0x8d,
- 0x02,0x10,0x2a,0x03,0xe2,0xc0,0x13,0x47,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x20,0x8d,
- 0x02,0x10,0x2a,0x03,0x0e,0xc0,0x00,0x00,0x09,0x28,0x00,0x00,0x00,0x00,0x07,0x01,0x07,0x01,0x20,0x8d,
- 0x02,0x10,0x2a,0x04,0x52,0xc0,0x01,0x03,0xc4,0x55,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x8e,
- 0x02,0x10,0x2a,0x04,0x52,0xc0,0x30,0x07,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x20,0x8d,
+ 0x02,0x10,0x2a,0x03,0xb0,0xc0,0x00,0x01,0x00,0xe0,0x00,0x00,0x00,0x00,0x07,0x94,0x90,0x01,0x20,0x8d,
+ 0x02,0x10,0x2a,0x03,0xb0,0xc0,0x00,0x02,0x00,0xf0,0x00,0x00,0x00,0x00,0x02,0x88,0xc0,0x01,0x20,0x8d,
+ 0x02,0x10,0x2a,0x03,0xb0,0xc0,0x00,0x02,0x00,0xf0,0x00,0x00,0x00,0x00,0x03,0x0c,0x00,0x01,0x20,0x8d,
+ 0x02,0x10,0x2a,0x03,0xb0,0xc0,0x00,0x03,0x00,0xd0,0x00,0x00,0x00,0x00,0x0e,0x3b,0x50,0x01,0x20,0x8d,
+ 0x02,0x10,0x2a,0x03,0xcf,0xc0,0x80,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x5f,0xd6,0x35,0x57,0x20,0x8d,
+ 0x02,0x10,0x2a,0x04,0x21,0x80,0xdc,0x05,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3b,0x20,0x8d,
+ 0x02,0x10,0x2a,0x04,0x21,0x80,0xff,0xff,0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x20,0x8d,
+ 0x02,0x10,0x2a,0x04,0x52,0xc0,0x01,0x03,0xc4,0x55,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x8d,
0x02,0x10,0x2a,0x04,0xbc,0x40,0x1d,0xc3,0x00,0x8d,0x00,0x00,0x00,0x00,0x00,0x02,0x10,0x01,0x20,0x8d,
- 0x02,0x10,0x2a,0x05,0x15,0x00,0x07,0x02,0x00,0x00,0x1c,0x00,0x40,0xff,0xfe,0x00,0x00,0x0c,0x20,0x8d,
- 0x02,0x10,0x2a,0x05,0x35,0x80,0xd1,0x01,0x37,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x8d,
- 0x02,0x10,0x2a,0x05,0x35,0x80,0xdb,0x0b,0x16,0x00,0xc4,0x89,0x76,0xed,0x31,0x3d,0x0b,0x33,0x20,0x8d,
- 0x02,0x10,0x2a,0x05,0xd0,0x14,0x0a,0x55,0x40,0x01,0x81,0x27,0xaf,0xa7,0xda,0xf9,0xd9,0x1b,0x20,0x8d,
- 0x02,0x10,0x2a,0x05,0xd0,0x14,0x0a,0x55,0x40,0x01,0xf6,0xab,0xdd,0x5e,0x40,0x39,0xb4,0x6c,0x20,0x8d,
- 0x02,0x10,0x2a,0x05,0xd0,0x14,0x0a,0x55,0x40,0x03,0x65,0x23,0x50,0xa1,0x01,0x52,0xe8,0x8c,0x20,0x8d,
- 0x02,0x10,0x2a,0x05,0xd0,0x1a,0x0b,0x7b,0x3c,0x01,0x8b,0xf7,0xae,0x14,0xaf,0xb3,0x33,0xae,0x20,0x8d,
+ 0x02,0x10,0x2a,0x05,0x35,0x80,0xdc,0x0b,0x16,0x00,0xde,0xf4,0x5a,0x62,0xde,0x42,0x32,0x4a,0x20,0x8d,
+ 0x02,0x10,0x2a,0x05,0xd0,0x14,0x0a,0x55,0x40,0x00,0x8d,0xde,0x06,0x9f,0x4a,0xc7,0x0b,0x26,0x20,0x8d,
+ 0x02,0x10,0x2a,0x05,0xd0,0x16,0x09,0x8f,0x52,0x01,0x6b,0xe0,0xa4,0xde,0x80,0xc7,0x32,0xd5,0x20,0x8d,
+ 0x02,0x10,0x2a,0x05,0xd0,0x18,0x0a,0x75,0x6c,0x03,0x07,0x5b,0x2c,0x73,0x8c,0xaa,0x41,0x4b,0x20,0x8d,
0x02,0x10,0x2a,0x05,0xf4,0x80,0x18,0x00,0x06,0x97,0x54,0x00,0x02,0xff,0xfe,0xb6,0xc3,0x6d,0x20,0x8d,
0x02,0x10,0x2a,0x06,0xe0,0x40,0x76,0x03,0x29,0x18,0xc6,0xef,0x46,0x4e,0x9f,0xe5,0x73,0xec,0x20,0x8d,
- 0x02,0x10,0x2a,0x07,0xab,0xc4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x09,0x46,0x20,0x8d,
+ 0x02,0x10,0x2a,0x07,0xab,0xc4,0x00,0x00,0x00,0x00,0x00,0x89,0x02,0x34,0x01,0x80,0x01,0x94,0x20,0x8d,
+ 0x02,0x10,0x2a,0x07,0xd8,0x84,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x12,0x7e,0x20,0x8d,
+ 0x02,0x10,0x2a,0x09,0x26,0x81,0x10,0x10,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x20,0x8d,
0x02,0x10,0x2a,0x09,0x26,0x81,0x01,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x10,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,0x0c,0x5a,0x80,0x12,0x10,0xa8,0x00,0x6a,0xf7,0x28,0xff,0xfe,0xe5,0x6b,0x3a,0x20,0x8d,
- 0x02,0x10,0x2a,0x0d,0x56,0x00,0x00,0x24,0x0a,0x8e,0x00,0x00,0x00,0x00,0x00,0x00,0xa9,0x1e,0xd8,0x4d,
- 0x02,0x10,0x2a,0x0d,0x7c,0x40,0x30,0x00,0x0b,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x20,0x8d,
+ 0x02,0x10,0x2a,0x0b,0xf3,0x00,0x00,0x02,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x20,0x8d,
0x02,0x10,0x2a,0x0d,0x83,0x40,0x00,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x20,0x8d,
- 0x02,0x10,0x2a,0x0f,0xdf,0x00,0x00,0x00,0x20,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x62,0x20,0x8d,
- 0x02,0x10,0x2a,0x10,0x37,0x81,0x16,0xb9,0x00,0x01,0xfe,0x3f,0xdb,0xff,0xfe,0x04,0x2d,0x4c,0x20,0x8d,
- 0x02,0x10,0x2a,0x10,0x37,0x81,0x08,0x4b,0x00,0x01,0xb1,0x23,0x63,0x06,0x94,0x3a,0xf0,0x9b,0x20,0x8d,
+ 0x02,0x10,0x2a,0x0e,0x8f,0x02,0x21,0xd1,0x01,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x20,0x8d,
+ 0x02,0x10,0x2a,0x0e,0xb7,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x55,0xd1,0xf0,0x5b,0x20,0x8d,
+ 0x02,0x10,0x2a,0x10,0x37,0x81,0x2c,0x19,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x8d,
0x02,0x10,0x2a,0x10,0xd2,0x00,0x00,0x01,0x00,0x33,0xa6,0xbf,0x01,0xff,0xfe,0x6a,0x46,0xa9,0x20,0x8d,
- 0x02,0x10,0x2c,0x0f,0xf4,0xc0,0x22,0x02,0x20,0xb0,0x26,0x1c,0x04,0xff,0xfe,0x14,0xda,0xa0,0x20,0x8d,
- 0x02,0x10,0x2c,0x0f,0xf8,0xf0,0xda,0x51,0x00,0x00,0x70,0xc3,0xee,0xa9,0x97,0x17,0x95,0x79,0x20,0x8d,
+ 0x02,0x10,0x2a,0x12,0x8e,0x40,0x56,0x68,0xe4,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x8d,
+ 0x02,0x10,0x2a,0x12,0x8e,0x40,0x56,0x68,0xe4,0x0b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x8d,
+ 0x02,0x10,0x2a,0x12,0x8e,0x40,0x56,0x68,0xe4,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x8d,
+ 0x02,0x10,0x2a,0x12,0x8e,0x40,0x56,0x68,0xe4,0x0d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x8d,
+ 0x02,0x10,0x2a,0x12,0x8e,0x40,0x56,0x68,0xe4,0x0e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x8d,
+ 0x02,0x10,0x2a,0x12,0x8e,0x40,0x56,0x68,0xe4,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x8d,
+ 0x02,0x10,0x2a,0x12,0x8e,0x40,0x56,0x68,0xe4,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x8d,
+ 0x02,0x10,0x2a,0x12,0x8e,0x40,0x56,0x68,0xe4,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x8d,
+ 0x02,0x10,0x2a,0x12,0x8e,0x40,0x56,0x68,0xe4,0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x8d,
+ 0x02,0x10,0x2a,0x12,0x8e,0x40,0x56,0x68,0xe4,0x17,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x8d,
+ 0x02,0x10,0x2c,0x0f,0xf8,0xf0,0xda,0x51,0x00,0x00,0x3a,0x45,0xfc,0x57,0x5e,0x30,0x25,0x93,0x20,0x8d,
+ 0x04,0x20,0xd0,0x60,0x63,0xb5,0x63,0xa7,0x98,0x2a,0x1b,0x8f,0x42,0xb2,0xf8,0xd8,0xf3,0x4a,0x5b,0x2c,0x10,0x64,0x88,0xa7,0x51,0x23,0xca,0x58,0xad,0x92,0x3d,0xa9,0x1f,0x3c,0x20,0x8d,
+ 0x04,0x20,0xe2,0xe3,0xbb,0x69,0x18,0xc2,0xfb,0x4e,0xaf,0xd3,0x74,0x91,0x91,0x2f,0x0a,0x2f,0x6b,0xb9,0x32,0x11,0x74,0x06,0xdd,0x23,0x87,0xda,0xa1,0xe7,0x94,0x21,0x48,0x75,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,0xec,0x82,0xc1,0x2f,0x8c,0xe8,0x1e,0x8e,0xce,0x00,0x2a,0x38,0x61,0x09,0x51,0x6e,0xf1,0xdd,0x4b,0x3d,0x64,0x95,0x72,0xee,0x7e,0x45,0xb8,0x17,0xfc,0x91,0xb2,0x1f,0x20,0x8d,
+ 0x04,0x20,0xff,0xfc,0x02,0x19,0x7f,0x99,0x4e,0x6f,0x39,0x10,0x86,0x3f,0xe4,0xb6,0xd1,0xb0,0x6a,0x2c,0x4e,0x57,0xd4,0x08,0x61,0x18,0xfa,0x62,0x61,0x44,0xad,0x7c,0xdf,0xfc,0x20,0x8d,
+ 0x04,0x20,0xff,0xd8,0x39,0x93,0x9a,0x94,0x57,0xcd,0x48,0xe3,0x3e,0x98,0x79,0xa6,0x3f,0x69,0x7e,0x36,0x10,0x70,0x8d,0xbc,0x15,0x08,0x64,0x51,0xc7,0x56,0x35,0x63,0xf3,0x93,0x20,0x8d,
+ 0x04,0x20,0x06,0x42,0xf9,0x1f,0x80,0x8c,0x16,0xcf,0x73,0x9a,0xb1,0x50,0xcc,0x7e,0x11,0xf7,0x42,0xc3,0x83,0x59,0x39,0x92,0x6f,0xd8,0x20,0x4a,0x3d,0x5a,0x82,0x86,0xee,0xcf,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,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,0x0c,0xa0,0x19,0x89,0xe0,0x8c,0x4a,0x83,0xae,0xce,0x5c,0xf9,0x73,0x24,0x25,0xe0,0x8d,0x01,0x2a,0xb1,0xac,0x8b,0x8a,0xe3,0xd5,0x3a,0x21,0x16,0x9f,0x96,0xf1,0x8e,0x20,0x8d,
+ 0x04,0x20,0x0c,0xa0,0x19,0x8a,0x74,0x59,0x74,0x6e,0x26,0x69,0x90,0xca,0x65,0xe8,0x83,0xfc,0x25,0xec,0xe7,0xb6,0x85,0xf5,0xf8,0x37,0x08,0x42,0xbe,0xb0,0x38,0x4a,0x8e,0x2b,0x20,0x8d,
+ 0x04,0x20,0x15,0x91,0xb2,0x2a,0x36,0x3a,0x0d,0xcf,0x8c,0xe7,0xc9,0x48,0xd8,0xf4,0xe1,0xa8,0x94,0x9f,0x97,0x20,0x72,0x70,0x6a,0x83,0x28,0xd2,0xe8,0x29,0x11,0xb6,0x0e,0x6c,0x20,0x8d,
+ 0x04,0x20,0x19,0x2a,0x86,0x86,0x62,0x65,0x95,0x44,0x4e,0xb7,0x5e,0xe6,0x54,0x75,0xc5,0xe6,0x41,0x4e,0x7b,0x0c,0x20,0x1a,0xd5,0x26,0xbe,0x2b,0xdb,0x85,0xa8,0xc5,0xdc,0x3a,0x20,0x8d,
+ 0x04,0x20,0x19,0x2a,0x86,0x86,0x62,0x9d,0x3f,0x41,0x4d,0x7f,0x3a,0xf1,0xa4,0xd2,0x9b,0x99,0xc2,0x62,0x22,0xa5,0x6d,0x6d,0xb1,0x29,0x3b,0x79,0xf1,0xe6,0xe2,0xaf,0x6d,0xfd,0x20,0x8d,
+ 0x04,0x20,0x19,0x2a,0x86,0x86,0x62,0xc2,0xbd,0xcd,0xa2,0x34,0xc9,0x5e,0x0b,0xdb,0x6e,0x6e,0x92,0xa2,0x4f,0xf1,0x0a,0x59,0x6c,0x19,0x9c,0xd0,0xd8,0x3c,0x50,0x3b,0x41,0x27,0x20,0x8d,
+ 0x04,0x20,0x1c,0xe0,0xbe,0xd4,0x48,0xe2,0x00,0xc5,0xf0,0x0d,0x65,0x08,0x59,0xc2,0x3f,0x09,0x4d,0x98,0x2c,0x14,0xc9,0x71,0xc8,0x8b,0x53,0x29,0xa8,0xb5,0x8c,0x7b,0x22,0xb0,0x20,0x8d,
+ 0x04,0x20,0x23,0x33,0x80,0xcc,0x5a,0xeb,0x86,0x37,0x03,0x4f,0x8b,0x97,0xac,0xb5,0xf9,0xd0,0x2e,0xd8,0x9b,0xca,0xff,0xef,0x63,0x22,0x2c,0x3d,0x7e,0x83,0x39,0x14,0x10,0xc7,0x20,0x8d,
+ 0x04,0x20,0x23,0x33,0x80,0xcc,0x5b,0x25,0x8f,0xfc,0xa0,0xef,0x50,0xeb,0x4b,0x2c,0xd7,0x89,0xf2,0x2b,0xe3,0x4f,0xe9,0x6a,0x93,0x19,0xff,0x69,0x92,0x1b,0x8b,0x13,0xbd,0x67,0x20,0x8d,
+ 0x04,0x20,0x23,0x33,0x80,0xcc,0x5c,0xef,0x09,0x60,0xd5,0x10,0x6b,0x0d,0x33,0x5f,0x71,0x35,0x02,0xb9,0x19,0x4a,0xd6,0xe3,0xc7,0x34,0x27,0x40,0xc5,0x5d,0xfa,0xd1,0x23,0x28,0x20,0x8d,
+ 0x04,0x20,0x23,0x33,0x80,0xcc,0x5d,0x0b,0x5e,0x1d,0x3b,0xc6,0x3f,0x78,0xe8,0x51,0x0e,0xbf,0x78,0xee,0x47,0xf8,0x6f,0x01,0xab,0x21,0x16,0xcc,0x52,0xe6,0xad,0xd4,0x02,0x02,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,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,0x38,0x1b,0x57,0x6c,0xf9,0x80,0x4e,0x28,0x33,0xb5,0x01,0xce,0x8e,0x83,0x62,0xcd,0xee,0x3b,0x0b,0xf5,0x9f,0x7c,0xfe,0x9a,0x3f,0x0a,0x0a,0x2a,0x91,0x60,0x85,0x23,0x20,0x8d,
+ 0x04,0x20,0x3e,0x7e,0xe8,0x36,0x75,0x4f,0x00,0x38,0xda,0x70,0x03,0xde,0x23,0x02,0xe5,0x8a,0x02,0x6e,0xd3,0x91,0xa9,0x54,0xfb,0x2d,0xdb,0xbd,0x1f,0xd2,0x8a,0x98,0xae,0x16,0x20,0x8d,
+ 0x04,0x20,0x44,0xf1,0x1b,0x9d,0x03,0xaa,0x5a,0x96,0x97,0xc8,0x66,0x71,0x48,0x41,0xaa,0x55,0xa2,0x81,0xa5,0xa4,0x0a,0x82,0xe5,0x5f,0x5d,0x93,0xb7,0x2a,0x43,0x65,0xc9,0x32,0x20,0x8d,
+ 0x04,0x20,0x4c,0xdd,0xa4,0x94,0x32,0xb9,0xc3,0xec,0x54,0xe2,0x8c,0x52,0x31,0xc4,0xc1,0x02,0xa6,0x4f,0x4c,0xd2,0xc6,0xc5,0xbc,0xed,0xf1,0x94,0xbd,0xc3,0x34,0x66,0xab,0xab,0x20,0x8d,
+ 0x04,0x20,0x57,0xda,0x1d,0xc7,0xe7,0xba,0x3a,0x4b,0xd6,0x3c,0xbb,0x2a,0xd4,0x2c,0xe5,0xb7,0x8e,0x44,0x7e,0x56,0xe4,0x6d,0x9d,0x4f,0xce,0x69,0xf8,0xfc,0x7a,0xc1,0x74,0x41,0x20,0x8d,
0x04,0x20,0x53,0xcd,0x56,0x48,0x48,0x8c,0x47,0x07,0x91,0x41,0x82,0x65,0x5b,0x76,0x64,0x03,0x4e,0x09,0xe6,0x6f,0x7e,0x8c,0xbf,0x10,0x84,0xe6,0x54,0xeb,0x56,0xc5,0xbd,0x88,0x20,0x8d,
+ 0x04,0x20,0x5f,0xd5,0x6d,0xd5,0x32,0xe0,0x8b,0xd6,0x36,0x84,0x4a,0x4d,0x01,0x5e,0x36,0xf5,0xad,0x24,0xb0,0x01,0x5a,0xe1,0xb3,0xec,0x0c,0xc7,0x0b,0xd8,0x6f,0x63,0xf0,0x8c,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,0x63,0xac,0x1d,0x42,0xcf,0x49,0xa5,0xa0,0x7a,0x1b,0xc2,0x77,0x70,0x7d,0xb7,0x52,0xcb,0x29,0x51,0x7c,0xb7,0xf0,0xd7,0x37,0x18,0x15,0xb7,0x4c,0x39,0xe5,0xa6,0xef,0x20,0x8d,
0x04,0x20,0x65,0x98,0x55,0xd0,0x8a,0xe0,0x29,0xe6,0x5e,0xef,0xb7,0x8b,0x8f,0xc9,0x27,0x53,0x3d,0xd0,0x8c,0xa2,0xfa,0x32,0x2f,0xad,0xf9,0xdc,0xe2,0x4b,0x14,0x66,0x3e,0x23,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,0x89,0x60,0xc6,0xee,0x04,0xdf,0xa8,0x07,0xcd,0x57,0x38,0xea,0x8f,0xf1,0xfc,0x3e,0x23,0x93,0xa2,0x3e,0xa9,0xd9,0x90,0xe8,0xf0,0x8e,0x2e,0xe1,0xa0,0xdc,0x35,0x09,0x20,0x8d,
+ 0x04,0x20,0x8c,0x8d,0x69,0xb5,0xd4,0x91,0x45,0xfc,0xe0,0xdc,0x84,0x99,0xb3,0x54,0x59,0x4d,0xfe,0x24,0x1c,0xfa,0x6a,0x70,0x90,0xa5,0x7b,0x85,0x44,0x9d,0xdc,0xdf,0xb3,0x2a,0x20,0x8d,
+ 0x04,0x20,0x96,0x87,0xdd,0x04,0x33,0x9d,0x2c,0x25,0xed,0xe3,0x8d,0xb2,0x7b,0xbd,0x87,0x9d,0xdb,0xb4,0x9b,0x5b,0x38,0x2a,0x98,0x1b,0xa4,0xc1,0xac,0x79,0xa2,0xde,0x59,0xb0,0x20,0x8d,
+ 0x04,0x20,0xa3,0xeb,0x33,0xe3,0xfc,0x39,0xaa,0x60,0xc1,0x1e,0xb6,0xf2,0x3d,0x31,0x62,0x3b,0x91,0xd9,0xd6,0xb6,0xf8,0x7a,0x77,0xb1,0x87,0x10,0xc6,0x3e,0x95,0xad,0xb4,0x51,0x20,0x8d,
+ 0x04,0x20,0xb1,0xdd,0xb8,0x4b,0x84,0x82,0xe1,0x97,0x5c,0xf0,0x81,0x80,0xde,0x30,0xdd,0xe5,0x01,0xda,0x67,0x6c,0x57,0x16,0x9d,0xec,0x06,0xee,0xc8,0x8e,0x3a,0x35,0x6e,0x5b,0x20,0x8d,
+ 0x04,0x20,0xb2,0x32,0x14,0x4f,0xbd,0xef,0x43,0x29,0x2e,0xd5,0xe0,0xa7,0x17,0x35,0xb2,0x32,0xbb,0x53,0xea,0xda,0x78,0xef,0xfa,0xfc,0x98,0xa2,0x2a,0xbc,0x51,0xd3,0x21,0x12,0x20,0x8d,
+ 0x04,0x20,0xc4,0x58,0x41,0xc7,0x7d,0x9c,0xf9,0x68,0x15,0xb6,0x32,0x16,0xb9,0xdc,0xfd,0x0b,0x68,0xa2,0x51,0x57,0x4b,0xcc,0x6d,0xa7,0x2c,0x64,0xb0,0xb1,0xf5,0x66,0x93,0x7a,0x20,0x8d,
0x05,0x20,0xd7,0x7a,0x53,0x89,0xfe,0x02,0x6a,0x59,0xb7,0x0e,0xf8,0x6d,0x9d,0x81,0xbb,0x9f,0x01,0xc0,0xc4,0xee,0x7b,0x36,0x10,0x33,0x07,0xd2,0x29,0xd8,0xec,0xcd,0x8e,0xa3,0x00,0x00,
0x05,0x20,0xd7,0xf1,0x19,0x9e,0x7d,0x0f,0x43,0x97,0x33,0x56,0xe8,0x12,0x1d,0x7d,0xa0,0x4d,0x21,0x5a,0x60,0x73,0xc8,0x7e,0x10,0x55,0x60,0x56,0xbb,0x65,0x50,0xa4,0x17,0x59,0x00,0x00,
- 0x05,0x20,0xd1,0x17,0xe2,0x34,0x4a,0x61,0x70,0x8b,0x04,0xa2,0xb4,0xb0,0x65,0x59,0x52,0x75,0x67,0x86,0xe6,0x48,0x33,0x31,0x5d,0x87,0x38,0x57,0xd3,0xf8,0x40,0x07,0x73,0xa8,0x00,0x00,
0x05,0x20,0xd9,0x9c,0x20,0xfe,0xc2,0xe6,0x6a,0x16,0x30,0x81,0x54,0xc9,0x3f,0x9a,0x89,0x10,0xa9,0x4b,0xf1,0x05,0x56,0xd5,0x04,0x2d,0xb7,0x6a,0x7b,0x67,0x8d,0xf0,0xbe,0x8f,0x00,0x00,
- 0x05,0x20,0xdc,0xdb,0x2d,0x39,0xd5,0xe4,0xda,0xb5,0xb6,0x6e,0x98,0x33,0x8f,0x51,0x99,0x54,0x38,0x53,0xa8,0x4e,0xda,0x29,0xd8,0xb5,0x57,0x9d,0x36,0xf0,0x97,0x37,0x18,0x3f,0x00,0x00,
0x05,0x20,0xe1,0x44,0x2d,0x6e,0xd3,0xd9,0xf0,0x95,0x6c,0x52,0x2e,0x44,0x3c,0x27,0x3d,0x78,0xac,0x6e,0x8f,0x27,0x1c,0x0c,0xc0,0x78,0x22,0x3e,0xa1,0x84,0x01,0x42,0x08,0x5c,0x00,0x00,
0x05,0x20,0xe3,0xa5,0x88,0x11,0x4d,0x3d,0xfb,0x02,0xec,0x1f,0xda,0x48,0x86,0x12,0xf6,0x12,0xd9,0x3e,0x68,0x49,0xa7,0xae,0x37,0xfd,0x02,0x48,0x38,0x8b,0xdc,0xd4,0xa6,0x8f,0x00,0x00,
0x05,0x20,0xe5,0x19,0x24,0x71,0xab,0x61,0xb0,0xfe,0x44,0x4a,0x74,0x8d,0xca,0x90,0xc3,0xd6,0x24,0xb4,0xd5,0x03,0xe7,0xf3,0x4f,0xbe,0x12,0x72,0xd6,0xa0,0x4b,0x22,0x0b,0xe1,0x00,0x00,
- 0x05,0x20,0xee,0xab,0xea,0x3b,0xc2,0x8a,0xe2,0xb3,0xe5,0xe7,0x92,0xf0,0x88,0x05,0x68,0x8d,0x2f,0xe7,0x2c,0xd2,0x00,0x39,0xd4,0x5d,0x07,0xfc,0xa1,0xd6,0xbf,0x89,0xa2,0x40,0x00,0x00,
0x05,0x20,0xf2,0x74,0x4c,0x90,0xc3,0xd9,0x34,0x4d,0x5f,0x6e,0xdb,0xdd,0x7d,0xef,0xa5,0xed,0x6e,0x59,0x9e,0x31,0x41,0x94,0x38,0x84,0xc5,0x08,0xd2,0x23,0xb3,0xa7,0xe0,0x2c,0x00,0x00,
0x05,0x20,0xf3,0x77,0xe5,0xa7,0x11,0xef,0x65,0x91,0x23,0xb8,0x32,0x06,0xcb,0xc0,0x91,0xf7,0x21,0x1d,0x70,0xbc,0x83,0x1b,0x86,0x34,0x35,0x31,0x0f,0x9f,0xc1,0x0d,0xbb,0x56,0x00,0x00,
0x05,0x20,0xfe,0xb0,0x99,0x79,0x95,0x58,0x71,0xb5,0x63,0xcc,0x33,0xeb,0x55,0x91,0x8c,0xb4,0x3a,0xf2,0x8b,0x2d,0x8e,0x47,0xbe,0x25,0x47,0x12,0xcd,0x14,0x48,0xf0,0x1d,0xea,0x00,0x00,
- 0x05,0x20,0xfc,0x79,0x14,0x77,0x6b,0x0e,0x34,0x8d,0xde,0x01,0x33,0xed,0xb4,0x0e,0xa7,0xc9,0x15,0x4f,0xd0,0x27,0x2c,0xd6,0x5f,0xe9,0x63,0x82,0x8d,0xd5,0x0c,0x9e,0x18,0x29,0x00,0x00,
0x05,0x20,0x07,0x61,0x26,0xd7,0x6c,0x05,0xbf,0xf6,0x2d,0x8c,0xca,0xc4,0x65,0xd3,0xd3,0xb2,0x49,0xe9,0xcc,0x53,0x1e,0xca,0x77,0x84,0xb6,0x10,0x5e,0xc2,0x5a,0xfe,0x28,0xb3,0x00,0x00,
0x05,0x20,0x03,0xaa,0x47,0xe9,0xe2,0x77,0xeb,0xa5,0x72,0x27,0x23,0x8b,0x13,0x62,0x61,0x32,0xb5,0xb2,0x1b,0x5a,0x18,0xb2,0xf9,0x26,0x06,0x84,0xee,0x28,0x42,0xac,0xba,0xbc,0x00,0x00,
- 0x05,0x20,0x08,0xc6,0x19,0x31,0x40,0x96,0xf3,0xe2,0x81,0x4e,0x88,0x54,0x54,0x9e,0xbf,0xfa,0x38,0x7a,0xfa,0x38,0x96,0x13,0x2a,0xc4,0x69,0xa2,0xae,0xe5,0x94,0xc7,0x16,0xb7,0x00,0x00,
0x05,0x20,0x0a,0x26,0x27,0x23,0xdd,0xf3,0x56,0xbe,0x9e,0x9e,0xa7,0xc6,0x3c,0xc5,0x99,0xc4,0x87,0x3b,0x4d,0xb9,0x13,0x62,0x91,0xf2,0x25,0x1c,0x02,0x42,0x63,0xe3,0x63,0x7a,0x00,0x00,
0x05,0x20,0x0c,0x50,0x55,0x46,0x87,0x5a,0x8d,0x14,0xfb,0xa7,0x29,0x70,0x18,0xa6,0x29,0x80,0x8c,0x33,0x42,0x5a,0x8f,0xe4,0x84,0x64,0x3d,0x0e,0xb5,0xbd,0x36,0x34,0x42,0xb6,0x00,0x00,
0x05,0x20,0x17,0x0c,0x56,0xce,0x72,0xa5,0xa0,0xe6,0x23,0x06,0xa3,0xc7,0x08,0x43,0x18,0xee,0x3a,0x46,0x35,0x5d,0x17,0xf6,0x78,0x96,0xa0,0x9c,0x51,0xef,0xbe,0x23,0xfd,0x71,0x00,0x00,
0x05,0x20,0x18,0x31,0xb3,0x9a,0xf8,0x8c,0xec,0x99,0x2e,0x7d,0xe4,0x90,0xa2,0x54,0x27,0xbd,0xe5,0xc8,0x65,0xdf,0x1f,0xaa,0x8f,0xe9,0x0f,0x64,0x85,0x09,0xc3,0x70,0x62,0x13,0x00,0x00,
- 0x05,0x20,0x1a,0x35,0x98,0x78,0xb1,0xd9,0x48,0x62,0xe9,0x23,0x10,0xfe,0x71,0xdb,0x10,0x5f,0x28,0xc8,0xf3,0xda,0x33,0x9b,0x26,0xcb,0x4d,0xbe,0x7b,0x03,0x76,0xb9,0xe0,0x54,0x00,0x00,
+ 0x05,0x20,0x1d,0x3a,0xac,0x0e,0x8c,0x62,0x35,0xb0,0xa4,0xaf,0xf0,0x47,0xf7,0x5a,0x55,0x8a,0x12,0x69,0xff,0x27,0xad,0xd9,0x9e,0x9f,0xa5,0xec,0x9e,0x24,0x38,0x8e,0x24,0xed,0x00,0x00,
0x05,0x20,0x27,0x7a,0xaf,0x5a,0x9c,0xf4,0x72,0xfe,0x3c,0xdd,0x7a,0xba,0xd7,0x98,0x31,0xde,0x73,0xce,0x84,0x5b,0x41,0xe7,0x9a,0x6a,0xe2,0xc1,0x3b,0x5b,0x37,0x23,0xc7,0xdf,0x00,0x00,
0x05,0x20,0x20,0x90,0xe3,0xd3,0xad,0x87,0xeb,0x2a,0xd9,0x29,0x17,0x74,0x47,0xc9,0x54,0x57,0xfa,0x3d,0x71,0x02,0x11,0xb2,0xc3,0x87,0x31,0xb3,0x9b,0x6f,0x2e,0xfc,0x30,0xea,0x00,0x00,
0x05,0x20,0x22,0x56,0xd6,0x98,0x11,0x61,0xe1,0x5a,0x34,0x9f,0xe2,0x9d,0xf5,0x2b,0xbd,0xbc,0xcc,0x1c,0xf5,0x1d,0x68,0xa5,0xca,0xb1,0xb5,0x4b,0xf1,0xb5,0xff,0x1e,0xdd,0xc0,0x00,0x00,
- 0x05,0x20,0x37,0x3e,0x28,0x39,0xef,0xa6,0xbc,0xf8,0xf1,0xba,0x11,0x40,0x87,0x42,0xff,0x58,0x46,0x8f,0xb0,0x80,0xfe,0x20,0x75,0xc5,0x43,0xce,0xec,0x9b,0x5d,0x37,0x19,0xf4,0x00,0x00,
- 0x05,0x20,0x3e,0xe3,0xe0,0xa9,0xbc,0xf4,0x2e,0x59,0xd9,0x20,0xee,0xdf,0x74,0x61,0x4d,0x99,0x0c,0x5c,0x15,0x30,0x9b,0x72,0x16,0x79,0x15,0xf4,0x7a,0xca,0x34,0xcc,0x81,0x99,0x00,0x00,
+ 0x05,0x20,0x29,0xf2,0xb7,0xee,0xf1,0x70,0x02,0xe3,0xb5,0x89,0x73,0x69,0xd4,0x40,0x19,0xb1,0xd6,0x10,0xd8,0xfd,0x13,0xe8,0x9a,0xdb,0x40,0xc8,0xa9,0xb9,0x46,0x03,0x11,0x12,0x00,0x00,
+ 0x05,0x20,0x2d,0xfc,0xd7,0xed,0xc7,0x20,0x05,0x1d,0xcf,0xe6,0x5d,0x0b,0x38,0xc1,0xda,0x85,0xd6,0x30,0x84,0x13,0x35,0xb8,0x72,0x3d,0xff,0xa2,0xc3,0xc4,0xf6,0x38,0xef,0xc4,0x00,0x00,
+ 0x05,0x20,0x31,0x0f,0x30,0x0b,0x9d,0x70,0x0c,0x7c,0xf7,0x98,0x7e,0x1c,0xf4,0x33,0xdc,0x64,0x17,0xf7,0x00,0x7a,0x0c,0x04,0xb5,0x83,0xfc,0x5f,0xa6,0x52,0x39,0x79,0x63,0x87,0x00,0x00,
0x05,0x20,0x39,0xca,0x8e,0x62,0x0a,0x36,0xa7,0x68,0x22,0xc4,0xcc,0x4a,0xa9,0x16,0x69,0x4b,0x8a,0x1c,0x5f,0x6e,0x4a,0x98,0xb6,0x95,0x82,0xb3,0x66,0x66,0xc5,0x29,0x3a,0xb0,0x00,0x00,
- 0x05,0x20,0x3b,0xd0,0x80,0xc4,0xab,0x82,0x83,0x11,0x48,0xe5,0x3b,0x23,0x3b,0x17,0x04,0x0f,0xd8,0x39,0x7c,0x1b,0x70,0x73,0x68,0x98,0x11,0x22,0x49,0x51,0x8f,0x20,0x65,0x65,0x00,0x00,
- 0x05,0x20,0x47,0x1f,0x83,0xc8,0xa3,0x87,0x35,0xcf,0x8e,0x8d,0x22,0xfe,0xf0,0x02,0x63,0x04,0x3a,0x6a,0x49,0x1a,0x3b,0x70,0x17,0xeb,0x05,0xed,0xaf,0x61,0xb6,0x26,0xb8,0x21,0x00,0x00,
- 0x05,0x20,0x45,0xbd,0x33,0x3d,0x81,0x1e,0x14,0x52,0x88,0x8a,0xa7,0x46,0x0f,0x37,0x25,0xd0,0x59,0x9f,0x78,0xb5,0x7f,0x4a,0xf1,0x54,0x8c,0x2d,0x36,0x32,0xf8,0x10,0xf3,0xcc,0x00,0x00,
- 0x05,0x20,0x4a,0x8b,0x40,0x25,0xdc,0x06,0x2a,0xed,0x44,0x35,0xec,0x06,0x9e,0x73,0x70,0xf0,0x07,0x06,0x35,0xd1,0x60,0x4f,0x22,0xe8,0xbf,0x8a,0xdf,0xd9,0xeb,0x97,0x73,0x06,0x00,0x00,
0x05,0x20,0x4e,0x77,0x2e,0x12,0x91,0x67,0x6b,0x94,0xc4,0x92,0x2f,0x19,0x67,0x7d,0xcd,0x47,0x02,0xad,0xf8,0x60,0x72,0xed,0x73,0xf1,0x10,0x99,0x2c,0x05,0x61,0x66,0x55,0xd9,0x00,0x00,
0x05,0x20,0x5a,0x29,0xfe,0x8a,0xaa,0x9d,0x78,0x81,0x04,0x53,0x37,0xf5,0x6f,0xb6,0xe1,0x57,0x08,0x80,0xcf,0xf6,0x03,0x11,0x92,0x8d,0x08,0xe3,0x99,0x9f,0x98,0x4a,0x27,0x6b,0x00,0x00,
- 0x05,0x20,0x5a,0x65,0x0a,0x52,0x9b,0xc7,0x2e,0x92,0x79,0x7b,0xd3,0xf7,0xa4,0x35,0xbe,0x8e,0xb1,0xea,0x2d,0x7e,0x73,0x84,0x6a,0x3f,0xc9,0x9a,0x62,0xe3,0xc6,0x17,0x0e,0x7c,0x00,0x00,
0x05,0x20,0x5c,0x40,0x7f,0x80,0x43,0x91,0x9c,0xfc,0x04,0xdc,0xdc,0x8e,0x01,0xda,0xc8,0xaf,0x90,0x62,0x64,0x16,0xf7,0x11,0xe4,0x87,0xac,0xa4,0x06,0x6f,0x8d,0x87,0x4e,0xd6,0x00,0x00,
0x05,0x20,0x5e,0x69,0x4f,0x31,0x33,0xa7,0xea,0x3e,0xf4,0x7a,0x0a,0x1e,0x74,0x09,0x07,0xa1,0x50,0xf7,0x03,0xf5,0xc6,0x19,0xeb,0x95,0xaa,0x63,0x17,0x10,0x6e,0x68,0xca,0x10,0x00,0x00,
0x05,0x20,0x67,0x82,0xfc,0x36,0xea,0xae,0x95,0x3b,0x5d,0x46,0xf3,0xf4,0x6c,0x50,0x69,0x29,0xc7,0x47,0x87,0xca,0xa6,0x40,0x12,0x40,0x6d,0x12,0x94,0x35,0x17,0x8a,0xba,0x56,0x00,0x00,
0x05,0x20,0x67,0xab,0xce,0xf2,0xe3,0xf3,0xf6,0x19,0xf6,0x56,0xa2,0x4c,0xca,0x91,0x4b,0x93,0xfe,0xbc,0x85,0x50,0x5c,0x20,0x51,0x69,0xfb,0xf0,0x92,0xbb,0x57,0xa3,0x0d,0x05,0x00,0x00,
0x05,0x20,0x62,0xcc,0x44,0x66,0x31,0x76,0x1b,0x43,0xbe,0xe1,0xc9,0x1d,0x20,0x26,0x7d,0xa7,0x06,0x31,0x57,0x0d,0xb9,0x58,0x20,0xb3,0xca,0xb2,0x5e,0x0a,0x15,0x0b,0xba,0x0d,0x00,0x00,
+ 0x05,0x20,0x77,0xa7,0xc2,0xc7,0xa0,0xc1,0x40,0x3c,0xa0,0x94,0x9c,0xa6,0x6b,0x09,0x6b,0xad,0xae,0x4a,0x65,0x2b,0xbb,0x33,0x26,0x3d,0x3b,0x3b,0xd5,0x52,0x14,0xf9,0x28,0x08,0x00,0x00,
0x05,0x20,0x71,0x68,0x1b,0xc7,0x48,0x8f,0xe9,0xa3,0x53,0x29,0xb6,0x23,0x5a,0x25,0x02,0x45,0x72,0xca,0xa1,0xb6,0x06,0xfc,0xda,0x65,0x71,0x37,0xe6,0xd9,0x30,0x81,0x02,0xfe,0x00,0x00,
- 0x05,0x20,0x72,0x8b,0x72,0x38,0xfe,0x44,0xe9,0xc2,0xf4,0xbc,0xd8,0xce,0x1c,0xd5,0x50,0xb1,0x63,0x56,0x74,0x5e,0xf2,0xd3,0xe5,0xd5,0x29,0xe4,0x34,0x1d,0xf5,0x1c,0x7a,0xb9,0x00,0x00,
0x05,0x20,0x76,0x74,0x80,0x6c,0xab,0x7b,0x36,0x3a,0x6a,0x78,0xa4,0xa8,0xb8,0xb7,0xe7,0xf9,0x34,0x47,0x6d,0x34,0xca,0xa2,0xc6,0xef,0x81,0xab,0x62,0xb1,0x46,0x86,0xaf,0xd0,0x00,0x00,
+ 0x05,0x20,0x7b,0x8e,0x51,0x44,0xa2,0xfb,0xe2,0xde,0x06,0xad,0xe5,0xe5,0x3b,0x79,0xb3,0xd9,0x3e,0x74,0xb0,0x3f,0x55,0x13,0xc1,0xa6,0x72,0x2c,0x25,0x25,0x58,0xec,0x3b,0x5a,0x00,0x00,
0x05,0x20,0x80,0xfc,0x95,0xc8,0x95,0x91,0x2f,0x6b,0x6e,0xc4,0x2b,0xe1,0x2f,0xa0,0xcb,0xb8,0x76,0x5f,0x6f,0x1c,0x27,0xb0,0x3a,0x2c,0xb9,0x8d,0x6c,0x55,0xbd,0x02,0x60,0xe0,0x00,0x00,
- 0x05,0x20,0x80,0xc6,0x6f,0xb3,0x18,0x5a,0x1a,0xde,0x4e,0xde,0x50,0xd2,0xc6,0x3f,0xc5,0x96,0x09,0x35,0x3a,0x4d,0x88,0x5f,0xa3,0x49,0x37,0xff,0xe6,0xc5,0x43,0x10,0xaf,0xa8,0x00,0x00,
+ 0x05,0x20,0x89,0x52,0xac,0x8f,0x35,0xe0,0xac,0xfb,0xbb,0xc7,0xcd,0x1a,0x24,0x0a,0xb4,0xc5,0x11,0xff,0x5a,0xf0,0xbe,0xc1,0xad,0xaf,0x0d,0x87,0xf4,0xa9,0xda,0x12,0xf8,0x12,0x00,0x00,
0x05,0x20,0x8a,0x32,0x54,0x37,0x12,0x24,0xb5,0x1d,0xba,0x3c,0x45,0x03,0x2e,0xda,0xfe,0xf1,0x87,0x8f,0x31,0xe5,0xfe,0xed,0xfa,0x38,0x25,0x00,0x99,0xa5,0xf4,0x51,0x02,0xf7,0x00,0x00,
- 0x05,0x20,0x97,0x4e,0x74,0xcd,0x8b,0x37,0x76,0x15,0x3b,0x6d,0xb5,0xa4,0xa0,0x4b,0xf7,0x34,0x98,0x48,0x67,0x1e,0x99,0xe7,0x24,0xf4,0x00,0xf7,0x06,0x9c,0x45,0x69,0x34,0x01,0x00,0x00,
0x05,0x20,0x91,0x06,0xd1,0x9e,0xbd,0xab,0xc4,0x61,0xb3,0x0a,0xc2,0x3b,0x29,0xf3,0x10,0x38,0xee,0xbd,0x9d,0xe3,0x99,0x97,0x30,0x70,0x6e,0xe6,0xfb,0x6a,0x3c,0x07,0x3d,0xfd,0x00,0x00,
- 0x05,0x20,0x9c,0x97,0xc1,0xad,0xf4,0xd2,0x07,0xae,0xe8,0x3e,0x14,0x42,0x36,0x85,0x71,0xa0,0xa7,0xef,0x72,0x44,0xf1,0x74,0x8b,0x6f,0xa5,0xa4,0x2c,0x0d,0xcc,0x9f,0xb0,0x9d,0x00,0x00,
0x05,0x20,0x9d,0x0d,0x0f,0x58,0x1a,0x5c,0xb4,0x1a,0xeb,0xef,0x8e,0x91,0x8d,0x8c,0x1b,0x57,0x5d,0x6d,0x97,0x24,0x28,0x45,0x54,0x8a,0x3a,0xd5,0x05,0xfb,0x76,0xac,0x25,0x52,0x00,0x00,
0x05,0x20,0xa4,0xb3,0x30,0x54,0x28,0x0f,0xfb,0xe5,0x76,0xb0,0x31,0xb2,0x65,0x62,0x56,0x72,0x7c,0xc9,0xcd,0x07,0x4d,0x5f,0xb1,0x69,0xe0,0xf7,0x35,0x3d,0x30,0x3c,0x7d,0x64,0x00,0x00,
0x05,0x20,0xa9,0xa9,0xe5,0xae,0x01,0xc2,0x5e,0x76,0x2f,0x5d,0xa3,0x07,0xdc,0xce,0xb8,0xbc,0x6f,0x47,0xaf,0x3a,0x37,0xf8,0x5c,0x86,0xff,0xe9,0xb6,0xa5,0x00,0x93,0x76,0x11,0x00,0x00,
0x05,0x20,0xb2,0x63,0x45,0xf5,0x36,0xb0,0x79,0x58,0x0d,0x8a,0x54,0x52,0x16,0x2f,0x1f,0x74,0x93,0xe0,0x30,0x82,0x1b,0xe4,0x01,0x76,0xf5,0x03,0xa1,0x19,0xa3,0x8d,0x0e,0xce,0x00,0x00,
- 0x05,0x20,0xb5,0x55,0x31,0x3f,0xe7,0xc7,0x17,0xe4,0x31,0x87,0x47,0x45,0x7c,0x67,0x43,0x5c,0x82,0x73,0xd6,0x62,0x64,0x94,0x92,0x32,0x2d,0x81,0x0e,0x01,0x35,0xc0,0x7e,0xb7,0x00,0x00,
0x05,0x20,0xb5,0x83,0x6f,0xb6,0x11,0xd8,0x0e,0xa8,0x57,0xda,0x15,0x20,0x5b,0x1a,0x6d,0x21,0x15,0x5a,0xbd,0xb4,0x17,0x11,0xc2,0xfb,0x0e,0xfc,0xde,0xe8,0x26,0x56,0xa8,0xac,0x00,0x00,
- 0x05,0x20,0xba,0xe0,0xd1,0xe5,0x2e,0x27,0x5b,0x1d,0x36,0x57,0x77,0xaf,0x64,0x04,0xfc,0xe1,0x8f,0x8c,0xf1,0x25,0x81,0x2b,0x4f,0x6a,0xf8,0x55,0x48,0xc2,0x5e,0x6f,0x62,0x43,0x00,0x00,
+ 0x05,0x20,0xb9,0x54,0x08,0xb2,0xaa,0xe6,0xea,0x55,0x16,0xa7,0x51,0x0f,0x8f,0xa1,0xc9,0xd0,0x7d,0x69,0x94,0x6b,0x26,0x6a,0xc5,0x81,0x41,0x5e,0x77,0x0e,0x47,0xec,0x10,0x8b,0x00,0x00,
0x05,0x20,0xc0,0xb9,0x7b,0x21,0xbd,0xa2,0x48,0xda,0x8a,0x3e,0xc3,0x6c,0xac,0xfd,0x6d,0x63,0x21,0xb6,0xb3,0x37,0xa9,0x4d,0x42,0x2c,0x9e,0x75,0x61,0x07,0xdc,0xc9,0xab,0x9b,0x00,0x00,
0x05,0x20,0xc8,0xdc,0x00,0xc8,0xdf,0xa1,0xb2,0xe9,0x9f,0x00,0xb3,0x86,0x93,0xc3,0xbc,0x6d,0x56,0xe2,0x83,0xfc,0xf4,0x6e,0x55,0x5d,0xed,0x4e,0x53,0xe6,0xd1,0x4c,0x38,0x3c,0x00,0x00,
0x05,0x20,0xcc,0xaf,0x6c,0x3b,0xd0,0x13,0x76,0x23,0xc3,0x36,0xbb,0x64,0x4a,0x4a,0x06,0x93,0x69,0x6d,0xb0,0x10,0x6e,0x66,0xa4,0x61,0xf8,0x2d,0xe7,0x80,0x72,0x4d,0x53,0x94,0x00,0x00,
0x05,0x20,0xce,0x25,0x15,0xbd,0x08,0xe9,0x67,0x1c,0xa2,0xa5,0x16,0x0e,0x38,0xd9,0xe4,0xc6,0x20,0x31,0x86,0x23,0x21,0x5a,0x5a,0x76,0x1e,0x74,0xd5,0xd3,0x4e,0x86,0x61,0xf4,0x00,0x00,
0x06,0x10,0xfc,0x32,0x17,0xea,0xe4,0x15,0xc3,0xbf,0x98,0x08,0x14,0x9d,0xb5,0xa2,0xc9,0xaa,0x20,0x8d,
0x06,0x10,0xfc,0xc7,0xbe,0x49,0xcc,0xd1,0xdc,0x91,0x31,0x25,0xf0,0xda,0x45,0x7d,0x08,0xce,0x20,0x8d,
+ 0x06,0x10,0xfc,0xdc,0x73,0xae,0xb1,0xa9,0x1b,0xf8,0xd4,0xc2,0x08,0x11,0xa4,0xc7,0xc3,0x4e,0x20,0x8d,
};
static const uint8_t chainparams_seed_test[] = {
diff --git a/src/coins.cpp b/src/coins.cpp
index 5a6ae525a7..0fe642e46b 100644
--- a/src/coins.cpp
+++ b/src/coins.cpp
@@ -34,7 +34,7 @@ size_t CCoinsViewBacked::EstimateSize() const { return base->EstimateSize(); }
CCoinsViewCache::CCoinsViewCache(CCoinsView* baseIn, bool deterministic) :
CCoinsViewBacked(baseIn), m_deterministic(deterministic),
- cacheCoins(0, SaltedOutpointHasher(/*deterministic=*/deterministic))
+ cacheCoins(0, SaltedOutpointHasher(/*deterministic=*/deterministic), CCoinsMap::key_equal{}, &m_cache_coins_memory_resource)
{}
size_t CCoinsViewCache::DynamicMemoryUsage() const {
@@ -253,9 +253,12 @@ bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlockIn
bool CCoinsViewCache::Flush() {
bool fOk = base->BatchWrite(cacheCoins, hashBlock, /*erase=*/true);
- if (fOk && !cacheCoins.empty()) {
- /* BatchWrite must erase all cacheCoins elements when erase=true. */
- throw std::logic_error("Not all cached coins were erased");
+ if (fOk) {
+ if (!cacheCoins.empty()) {
+ /* BatchWrite must erase all cacheCoins elements when erase=true. */
+ throw std::logic_error("Not all cached coins were erased");
+ }
+ ReallocateCache();
}
cachedCoinsUsage = 0;
return fOk;
@@ -314,7 +317,9 @@ void CCoinsViewCache::ReallocateCache()
// Cache should be empty when we're calling this.
assert(cacheCoins.size() == 0);
cacheCoins.~CCoinsMap();
- ::new (&cacheCoins) CCoinsMap(0, SaltedOutpointHasher(/*deterministic=*/m_deterministic));
+ m_cache_coins_memory_resource.~CCoinsMapMemoryResource();
+ ::new (&m_cache_coins_memory_resource) CCoinsMapMemoryResource{};
+ ::new (&cacheCoins) CCoinsMap{0, SaltedOutpointHasher{/*deterministic=*/m_deterministic}, CCoinsMap::key_equal{}, &m_cache_coins_memory_resource};
}
void CCoinsViewCache::SanityCheck() const
diff --git a/src/coins.h b/src/coins.h
index dd336b210a..039a07054d 100644
--- a/src/coins.h
+++ b/src/coins.h
@@ -11,6 +11,7 @@
#include <memusage.h>
#include <primitives/transaction.h>
#include <serialize.h>
+#include <support/allocators/pool.h>
#include <uint256.h>
#include <util/hasher.h>
@@ -131,7 +132,23 @@ struct CCoinsCacheEntry
CCoinsCacheEntry(Coin&& coin_, unsigned char flag) : coin(std::move(coin_)), flags(flag) {}
};
-typedef std::unordered_map<COutPoint, CCoinsCacheEntry, SaltedOutpointHasher> CCoinsMap;
+/**
+ * PoolAllocator's MAX_BLOCK_SIZE_BYTES parameter here uses sizeof the data, and adds the size
+ * of 4 pointers. We do not know the exact node size used in the std::unordered_node implementation
+ * because it is implementation defined. Most implementations have an overhead of 1 or 2 pointers,
+ * so nodes can be connected in a linked list, and in some cases the hash value is stored as well.
+ * Using an additional sizeof(void*)*4 for MAX_BLOCK_SIZE_BYTES should thus be sufficient so that
+ * all implementations can allocate the nodes from the PoolAllocator.
+ */
+using CCoinsMap = std::unordered_map<COutPoint,
+ CCoinsCacheEntry,
+ SaltedOutpointHasher,
+ std::equal_to<COutPoint>,
+ PoolAllocator<std::pair<const COutPoint, CCoinsCacheEntry>,
+ sizeof(std::pair<const COutPoint, CCoinsCacheEntry>) + sizeof(void*) * 4,
+ alignof(void*)>>;
+
+using CCoinsMapMemoryResource = CCoinsMap::allocator_type::ResourceType;
/** Cursor for iterating over CoinsView state */
class CCoinsViewCursor
@@ -220,6 +237,7 @@ protected:
* declared as "const".
*/
mutable uint256 hashBlock;
+ mutable CCoinsMapMemoryResource m_cache_coins_memory_resource{};
mutable CCoinsMap cacheCoins;
/* Cached dynamic memory usage for the inner Coin objects. */
diff --git a/src/common/args.cpp b/src/common/args.cpp
new file mode 100644
index 0000000000..d29b8648bf
--- /dev/null
+++ b/src/common/args.cpp
@@ -0,0 +1,823 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2022 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 <common/args.h>
+
+#include <chainparamsbase.h>
+#include <logging.h>
+#include <sync.h>
+#include <tinyformat.h>
+#include <univalue.h>
+#include <util/check.h>
+#include <util/fs.h>
+#include <util/fs_helpers.h>
+#include <util/settings.h>
+#include <util/strencodings.h>
+
+#ifdef WIN32
+#include <codecvt> /* for codecvt_utf8_utf16 */
+#include <shellapi.h> /* for CommandLineToArgvW */
+#include <shlobj.h> /* for CSIDL_APPDATA */
+#endif
+
+#include <algorithm>
+#include <cassert>
+#include <cstdint>
+#include <cstdlib>
+#include <cstring>
+#include <filesystem>
+#include <map>
+#include <optional>
+#include <stdexcept>
+#include <string>
+#include <utility>
+
+const char * const BITCOIN_CONF_FILENAME = "bitcoin.conf";
+const char * const BITCOIN_SETTINGS_FILENAME = "settings.json";
+
+ArgsManager gArgs;
+
+/**
+ * Interpret a string argument as a boolean.
+ *
+ * The definition of LocaleIndependentAtoi<int>() requires that non-numeric string values
+ * like "foo", return 0. This means that if a user unintentionally supplies a
+ * non-integer argument here, the return value is always false. This means that
+ * -foo=false does what the user probably expects, but -foo=true is well defined
+ * but does not do what they probably expected.
+ *
+ * The return value of LocaleIndependentAtoi<int>(...) is zero when given input not
+ * representable as an int.
+ *
+ * For a more extensive discussion of this topic (and a wide range of opinions
+ * on the Right Way to change this code), see PR12713.
+ */
+static bool InterpretBool(const std::string& strValue)
+{
+ if (strValue.empty())
+ return true;
+ return (LocaleIndependentAtoi<int>(strValue) != 0);
+}
+
+static std::string SettingName(const std::string& arg)
+{
+ return arg.size() > 0 && arg[0] == '-' ? arg.substr(1) : arg;
+}
+
+/**
+ * Parse "name", "section.name", "noname", "section.noname" settings keys.
+ *
+ * @note Where an option was negated can be later checked using the
+ * IsArgNegated() method. One use case for this is to have a way to disable
+ * options that are not normally boolean (e.g. using -nodebuglogfile to request
+ * that debug log output is not sent to any file at all).
+ */
+KeyInfo InterpretKey(std::string key)
+{
+ KeyInfo result;
+ // Split section name from key name for keys like "testnet.foo" or "regtest.bar"
+ size_t option_index = key.find('.');
+ if (option_index != std::string::npos) {
+ result.section = key.substr(0, option_index);
+ key.erase(0, option_index + 1);
+ }
+ if (key.substr(0, 2) == "no") {
+ key.erase(0, 2);
+ result.negated = true;
+ }
+ result.name = key;
+ return result;
+}
+
+/**
+ * Interpret settings value based on registered flags.
+ *
+ * @param[in] key key information to know if key was negated
+ * @param[in] value string value of setting to be parsed
+ * @param[in] flags ArgsManager registered argument flags
+ * @param[out] error Error description if settings value is not valid
+ *
+ * @return parsed settings value if it is valid, otherwise nullopt accompanied
+ * by a descriptive error string
+ */
+std::optional<util::SettingsValue> InterpretValue(const KeyInfo& key, const std::string* value,
+ unsigned int flags, std::string& error)
+{
+ // Return negated settings as false values.
+ if (key.negated) {
+ if (flags & ArgsManager::DISALLOW_NEGATION) {
+ error = strprintf("Negating of -%s is meaningless and therefore forbidden", key.name);
+ return std::nullopt;
+ }
+ // Double negatives like -nofoo=0 are supported (but discouraged)
+ if (value && !InterpretBool(*value)) {
+ LogPrintf("Warning: parsed potentially confusing double-negative -%s=%s\n", key.name, *value);
+ return true;
+ }
+ return false;
+ }
+ if (!value && (flags & ArgsManager::DISALLOW_ELISION)) {
+ error = strprintf("Can not set -%s with no value. Please specify value with -%s=value.", key.name, key.name);
+ return std::nullopt;
+ }
+ return value ? *value : "";
+}
+
+// Define default constructor and destructor that are not inline, so code instantiating this class doesn't need to
+// #include class definitions for all members.
+// For example, m_settings has an internal dependency on univalue.
+ArgsManager::ArgsManager() = default;
+ArgsManager::~ArgsManager() = default;
+
+std::set<std::string> ArgsManager::GetUnsuitableSectionOnlyArgs() const
+{
+ std::set<std::string> unsuitables;
+
+ LOCK(cs_args);
+
+ // if there's no section selected, don't worry
+ if (m_network.empty()) return std::set<std::string> {};
+
+ // if it's okay to use the default section for this network, don't worry
+ if (m_network == CBaseChainParams::MAIN) return std::set<std::string> {};
+
+ for (const auto& arg : m_network_only_args) {
+ if (OnlyHasDefaultSectionSetting(m_settings, m_network, SettingName(arg))) {
+ unsuitables.insert(arg);
+ }
+ }
+ return unsuitables;
+}
+
+std::list<SectionInfo> ArgsManager::GetUnrecognizedSections() const
+{
+ // Section names to be recognized in the config file.
+ static const std::set<std::string> available_sections{
+ CBaseChainParams::REGTEST,
+ CBaseChainParams::SIGNET,
+ CBaseChainParams::TESTNET,
+ CBaseChainParams::MAIN
+ };
+
+ LOCK(cs_args);
+ std::list<SectionInfo> unrecognized = m_config_sections;
+ unrecognized.remove_if([](const SectionInfo& appeared){ return available_sections.find(appeared.m_name) != available_sections.end(); });
+ return unrecognized;
+}
+
+void ArgsManager::SelectConfigNetwork(const std::string& network)
+{
+ LOCK(cs_args);
+ m_network = network;
+}
+
+bool ArgsManager::ParseParameters(int argc, const char* const argv[], std::string& error)
+{
+ LOCK(cs_args);
+ m_settings.command_line_options.clear();
+
+ for (int i = 1; i < argc; i++) {
+ std::string key(argv[i]);
+
+#ifdef MAC_OSX
+ // At the first time when a user gets the "App downloaded from the
+ // internet" warning, and clicks the Open button, macOS passes
+ // a unique process serial number (PSN) as -psn_... command-line
+ // argument, which we filter out.
+ if (key.substr(0, 5) == "-psn_") continue;
+#endif
+
+ if (key == "-") break; //bitcoin-tx using stdin
+ std::optional<std::string> val;
+ size_t is_index = key.find('=');
+ if (is_index != std::string::npos) {
+ val = key.substr(is_index + 1);
+ key.erase(is_index);
+ }
+#ifdef WIN32
+ key = ToLower(key);
+ if (key[0] == '/')
+ key[0] = '-';
+#endif
+
+ if (key[0] != '-') {
+ if (!m_accept_any_command && m_command.empty()) {
+ // The first non-dash arg is a registered command
+ std::optional<unsigned int> flags = GetArgFlags(key);
+ if (!flags || !(*flags & ArgsManager::COMMAND)) {
+ error = strprintf("Invalid command '%s'", argv[i]);
+ return false;
+ }
+ }
+ m_command.push_back(key);
+ while (++i < argc) {
+ // The remaining args are command args
+ m_command.push_back(argv[i]);
+ }
+ break;
+ }
+
+ // Transform --foo to -foo
+ if (key.length() > 1 && key[1] == '-')
+ key.erase(0, 1);
+
+ // Transform -foo to foo
+ key.erase(0, 1);
+ KeyInfo keyinfo = InterpretKey(key);
+ std::optional<unsigned int> flags = GetArgFlags('-' + keyinfo.name);
+
+ // Unknown command line options and command line options with dot
+ // characters (which are returned from InterpretKey with nonempty
+ // section strings) are not valid.
+ if (!flags || !keyinfo.section.empty()) {
+ error = strprintf("Invalid parameter %s", argv[i]);
+ return false;
+ }
+
+ std::optional<util::SettingsValue> value = InterpretValue(keyinfo, val ? &*val : nullptr, *flags, error);
+ if (!value) return false;
+
+ m_settings.command_line_options[keyinfo.name].push_back(*value);
+ }
+
+ // we do not allow -includeconf from command line, only -noincludeconf
+ if (auto* includes = util::FindKey(m_settings.command_line_options, "includeconf")) {
+ const util::SettingsSpan values{*includes};
+ // Range may be empty if -noincludeconf was passed
+ if (!values.empty()) {
+ error = "-includeconf cannot be used from commandline; -includeconf=" + values.begin()->write();
+ return false; // pick first value as example
+ }
+ }
+ return true;
+}
+
+std::optional<unsigned int> ArgsManager::GetArgFlags(const std::string& name) const
+{
+ LOCK(cs_args);
+ for (const auto& arg_map : m_available_args) {
+ const auto search = arg_map.second.find(name);
+ if (search != arg_map.second.end()) {
+ return search->second.m_flags;
+ }
+ }
+ return std::nullopt;
+}
+
+fs::path ArgsManager::GetPathArg(std::string arg, const fs::path& default_value) const
+{
+ if (IsArgNegated(arg)) return fs::path{};
+ std::string path_str = GetArg(arg, "");
+ if (path_str.empty()) return default_value;
+ fs::path result = fs::PathFromString(path_str).lexically_normal();
+ // Remove trailing slash, if present.
+ return result.has_filename() ? result : result.parent_path();
+}
+
+const fs::path& ArgsManager::GetBlocksDirPath() const
+{
+ LOCK(cs_args);
+ fs::path& path = m_cached_blocks_path;
+
+ // Cache the path to avoid calling fs::create_directories on every call of
+ // this function
+ if (!path.empty()) return path;
+
+ if (IsArgSet("-blocksdir")) {
+ path = fs::absolute(GetPathArg("-blocksdir"));
+ if (!fs::is_directory(path)) {
+ path = "";
+ return path;
+ }
+ } else {
+ path = GetDataDirBase();
+ }
+
+ path /= fs::PathFromString(BaseParams().DataDir());
+ path /= "blocks";
+ fs::create_directories(path);
+ return path;
+}
+
+const fs::path& ArgsManager::GetDataDir(bool net_specific) const
+{
+ LOCK(cs_args);
+ fs::path& path = net_specific ? m_cached_network_datadir_path : m_cached_datadir_path;
+
+ // Used cached path if available
+ if (!path.empty()) return path;
+
+ const fs::path datadir{GetPathArg("-datadir")};
+ if (!datadir.empty()) {
+ path = fs::absolute(datadir);
+ if (!fs::is_directory(path)) {
+ path = "";
+ return path;
+ }
+ } else {
+ path = GetDefaultDataDir();
+ }
+
+ if (net_specific && !BaseParams().DataDir().empty()) {
+ path /= fs::PathFromString(BaseParams().DataDir());
+ }
+
+ return path;
+}
+
+void ArgsManager::ClearPathCache()
+{
+ LOCK(cs_args);
+
+ m_cached_datadir_path = fs::path();
+ m_cached_network_datadir_path = fs::path();
+ m_cached_blocks_path = fs::path();
+}
+
+std::optional<const ArgsManager::Command> ArgsManager::GetCommand() const
+{
+ Command ret;
+ LOCK(cs_args);
+ auto it = m_command.begin();
+ if (it == m_command.end()) {
+ // No command was passed
+ return std::nullopt;
+ }
+ if (!m_accept_any_command) {
+ // The registered command
+ ret.command = *(it++);
+ }
+ while (it != m_command.end()) {
+ // The unregistered command and args (if any)
+ ret.args.push_back(*(it++));
+ }
+ return ret;
+}
+
+std::vector<std::string> ArgsManager::GetArgs(const std::string& strArg) const
+{
+ std::vector<std::string> result;
+ for (const util::SettingsValue& value : GetSettingsList(strArg)) {
+ result.push_back(value.isFalse() ? "0" : value.isTrue() ? "1" : value.get_str());
+ }
+ return result;
+}
+
+bool ArgsManager::IsArgSet(const std::string& strArg) const
+{
+ return !GetSetting(strArg).isNull();
+}
+
+bool ArgsManager::GetSettingsPath(fs::path* filepath, bool temp, bool backup) const
+{
+ fs::path settings = GetPathArg("-settings", BITCOIN_SETTINGS_FILENAME);
+ if (settings.empty()) {
+ return false;
+ }
+ if (backup) {
+ settings += ".bak";
+ }
+ if (filepath) {
+ *filepath = fsbridge::AbsPathJoin(GetDataDirNet(), temp ? settings + ".tmp" : settings);
+ }
+ return true;
+}
+
+static void SaveErrors(const std::vector<std::string> errors, std::vector<std::string>* error_out)
+{
+ for (const auto& error : errors) {
+ if (error_out) {
+ error_out->emplace_back(error);
+ } else {
+ LogPrintf("%s\n", error);
+ }
+ }
+}
+
+bool ArgsManager::ReadSettingsFile(std::vector<std::string>* errors)
+{
+ fs::path path;
+ if (!GetSettingsPath(&path, /* temp= */ false)) {
+ return true; // Do nothing if settings file disabled.
+ }
+
+ LOCK(cs_args);
+ m_settings.rw_settings.clear();
+ std::vector<std::string> read_errors;
+ if (!util::ReadSettings(path, m_settings.rw_settings, read_errors)) {
+ SaveErrors(read_errors, errors);
+ return false;
+ }
+ for (const auto& setting : m_settings.rw_settings) {
+ KeyInfo key = InterpretKey(setting.first); // Split setting key into section and argname
+ if (!GetArgFlags('-' + key.name)) {
+ LogPrintf("Ignoring unknown rw_settings value %s\n", setting.first);
+ }
+ }
+ return true;
+}
+
+bool ArgsManager::WriteSettingsFile(std::vector<std::string>* errors, bool backup) const
+{
+ fs::path path, path_tmp;
+ if (!GetSettingsPath(&path, /*temp=*/false, backup) || !GetSettingsPath(&path_tmp, /*temp=*/true, backup)) {
+ throw std::logic_error("Attempt to write settings file when dynamic settings are disabled.");
+ }
+
+ LOCK(cs_args);
+ std::vector<std::string> write_errors;
+ if (!util::WriteSettings(path_tmp, m_settings.rw_settings, write_errors)) {
+ SaveErrors(write_errors, errors);
+ return false;
+ }
+ if (!RenameOver(path_tmp, path)) {
+ SaveErrors({strprintf("Failed renaming settings file %s to %s\n", fs::PathToString(path_tmp), fs::PathToString(path))}, errors);
+ return false;
+ }
+ return true;
+}
+
+util::SettingsValue ArgsManager::GetPersistentSetting(const std::string& name) const
+{
+ LOCK(cs_args);
+ return util::GetSetting(m_settings, m_network, name, !UseDefaultSection("-" + name),
+ /*ignore_nonpersistent=*/true, /*get_chain_name=*/false);
+}
+
+bool ArgsManager::IsArgNegated(const std::string& strArg) const
+{
+ return GetSetting(strArg).isFalse();
+}
+
+std::string ArgsManager::GetArg(const std::string& strArg, const std::string& strDefault) const
+{
+ return GetArg(strArg).value_or(strDefault);
+}
+
+std::optional<std::string> ArgsManager::GetArg(const std::string& strArg) const
+{
+ const util::SettingsValue value = GetSetting(strArg);
+ return SettingToString(value);
+}
+
+std::optional<std::string> SettingToString(const util::SettingsValue& value)
+{
+ if (value.isNull()) return std::nullopt;
+ if (value.isFalse()) return "0";
+ if (value.isTrue()) return "1";
+ if (value.isNum()) return value.getValStr();
+ return value.get_str();
+}
+
+std::string SettingToString(const util::SettingsValue& value, const std::string& strDefault)
+{
+ return SettingToString(value).value_or(strDefault);
+}
+
+int64_t ArgsManager::GetIntArg(const std::string& strArg, int64_t nDefault) const
+{
+ return GetIntArg(strArg).value_or(nDefault);
+}
+
+std::optional<int64_t> ArgsManager::GetIntArg(const std::string& strArg) const
+{
+ const util::SettingsValue value = GetSetting(strArg);
+ return SettingToInt(value);
+}
+
+std::optional<int64_t> SettingToInt(const util::SettingsValue& value)
+{
+ if (value.isNull()) return std::nullopt;
+ if (value.isFalse()) return 0;
+ if (value.isTrue()) return 1;
+ if (value.isNum()) return value.getInt<int64_t>();
+ return LocaleIndependentAtoi<int64_t>(value.get_str());
+}
+
+int64_t SettingToInt(const util::SettingsValue& value, int64_t nDefault)
+{
+ return SettingToInt(value).value_or(nDefault);
+}
+
+bool ArgsManager::GetBoolArg(const std::string& strArg, bool fDefault) const
+{
+ return GetBoolArg(strArg).value_or(fDefault);
+}
+
+std::optional<bool> ArgsManager::GetBoolArg(const std::string& strArg) const
+{
+ const util::SettingsValue value = GetSetting(strArg);
+ return SettingToBool(value);
+}
+
+std::optional<bool> SettingToBool(const util::SettingsValue& value)
+{
+ if (value.isNull()) return std::nullopt;
+ if (value.isBool()) return value.get_bool();
+ return InterpretBool(value.get_str());
+}
+
+bool SettingToBool(const util::SettingsValue& value, bool fDefault)
+{
+ return SettingToBool(value).value_or(fDefault);
+}
+
+bool ArgsManager::SoftSetArg(const std::string& strArg, const std::string& strValue)
+{
+ LOCK(cs_args);
+ if (IsArgSet(strArg)) return false;
+ ForceSetArg(strArg, strValue);
+ return true;
+}
+
+bool ArgsManager::SoftSetBoolArg(const std::string& strArg, bool fValue)
+{
+ if (fValue)
+ return SoftSetArg(strArg, std::string("1"));
+ else
+ return SoftSetArg(strArg, std::string("0"));
+}
+
+void ArgsManager::ForceSetArg(const std::string& strArg, const std::string& strValue)
+{
+ LOCK(cs_args);
+ m_settings.forced_settings[SettingName(strArg)] = strValue;
+}
+
+void ArgsManager::AddCommand(const std::string& cmd, const std::string& help)
+{
+ Assert(cmd.find('=') == std::string::npos);
+ Assert(cmd.at(0) != '-');
+
+ LOCK(cs_args);
+ m_accept_any_command = false; // latch to false
+ std::map<std::string, Arg>& arg_map = m_available_args[OptionsCategory::COMMANDS];
+ auto ret = arg_map.emplace(cmd, Arg{"", help, ArgsManager::COMMAND});
+ Assert(ret.second); // Fail on duplicate commands
+}
+
+void ArgsManager::AddArg(const std::string& name, const std::string& help, unsigned int flags, const OptionsCategory& cat)
+{
+ Assert((flags & ArgsManager::COMMAND) == 0); // use AddCommand
+
+ // Split arg name from its help param
+ size_t eq_index = name.find('=');
+ if (eq_index == std::string::npos) {
+ eq_index = name.size();
+ }
+ std::string arg_name = name.substr(0, eq_index);
+
+ LOCK(cs_args);
+ std::map<std::string, Arg>& arg_map = m_available_args[cat];
+ auto ret = arg_map.emplace(arg_name, Arg{name.substr(eq_index, name.size() - eq_index), help, flags});
+ assert(ret.second); // Make sure an insertion actually happened
+
+ if (flags & ArgsManager::NETWORK_ONLY) {
+ m_network_only_args.emplace(arg_name);
+ }
+}
+
+void ArgsManager::AddHiddenArgs(const std::vector<std::string>& names)
+{
+ for (const std::string& name : names) {
+ AddArg(name, "", ArgsManager::ALLOW_ANY, OptionsCategory::HIDDEN);
+ }
+}
+
+std::string ArgsManager::GetHelpMessage() const
+{
+ const bool show_debug = GetBoolArg("-help-debug", false);
+
+ std::string usage;
+ LOCK(cs_args);
+ for (const auto& arg_map : m_available_args) {
+ switch(arg_map.first) {
+ case OptionsCategory::OPTIONS:
+ usage += HelpMessageGroup("Options:");
+ break;
+ case OptionsCategory::CONNECTION:
+ usage += HelpMessageGroup("Connection options:");
+ break;
+ case OptionsCategory::ZMQ:
+ usage += HelpMessageGroup("ZeroMQ notification options:");
+ break;
+ case OptionsCategory::DEBUG_TEST:
+ usage += HelpMessageGroup("Debugging/Testing options:");
+ break;
+ case OptionsCategory::NODE_RELAY:
+ usage += HelpMessageGroup("Node relay options:");
+ break;
+ case OptionsCategory::BLOCK_CREATION:
+ usage += HelpMessageGroup("Block creation options:");
+ break;
+ case OptionsCategory::RPC:
+ usage += HelpMessageGroup("RPC server options:");
+ break;
+ case OptionsCategory::WALLET:
+ usage += HelpMessageGroup("Wallet options:");
+ break;
+ case OptionsCategory::WALLET_DEBUG_TEST:
+ if (show_debug) usage += HelpMessageGroup("Wallet debugging/testing options:");
+ break;
+ case OptionsCategory::CHAINPARAMS:
+ usage += HelpMessageGroup("Chain selection options:");
+ break;
+ case OptionsCategory::GUI:
+ usage += HelpMessageGroup("UI Options:");
+ break;
+ case OptionsCategory::COMMANDS:
+ usage += HelpMessageGroup("Commands:");
+ break;
+ case OptionsCategory::REGISTER_COMMANDS:
+ usage += HelpMessageGroup("Register Commands:");
+ break;
+ default:
+ break;
+ }
+
+ // When we get to the hidden options, stop
+ if (arg_map.first == OptionsCategory::HIDDEN) break;
+
+ for (const auto& arg : arg_map.second) {
+ if (show_debug || !(arg.second.m_flags & ArgsManager::DEBUG_ONLY)) {
+ std::string name;
+ if (arg.second.m_help_param.empty()) {
+ name = arg.first;
+ } else {
+ name = arg.first + arg.second.m_help_param;
+ }
+ usage += HelpMessageOpt(name, arg.second.m_help_text);
+ }
+ }
+ }
+ return usage;
+}
+
+bool HelpRequested(const ArgsManager& args)
+{
+ return args.IsArgSet("-?") || args.IsArgSet("-h") || args.IsArgSet("-help") || args.IsArgSet("-help-debug");
+}
+
+void SetupHelpOptions(ArgsManager& args)
+{
+ args.AddArg("-?", "Print this help message and exit", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
+ args.AddHiddenArgs({"-h", "-help"});
+}
+
+static const int screenWidth = 79;
+static const int optIndent = 2;
+static const int msgIndent = 7;
+
+std::string HelpMessageGroup(const std::string &message) {
+ return std::string(message) + std::string("\n\n");
+}
+
+std::string HelpMessageOpt(const std::string &option, const std::string &message) {
+ return std::string(optIndent,' ') + std::string(option) +
+ std::string("\n") + std::string(msgIndent,' ') +
+ FormatParagraph(message, screenWidth - msgIndent, msgIndent) +
+ std::string("\n\n");
+}
+
+fs::path GetDefaultDataDir()
+{
+ // Windows: C:\Users\Username\AppData\Roaming\Bitcoin
+ // macOS: ~/Library/Application Support/Bitcoin
+ // Unix-like: ~/.bitcoin
+#ifdef WIN32
+ // Windows
+ return GetSpecialFolderPath(CSIDL_APPDATA) / "Bitcoin";
+#else
+ fs::path pathRet;
+ char* pszHome = getenv("HOME");
+ if (pszHome == nullptr || strlen(pszHome) == 0)
+ pathRet = fs::path("/");
+ else
+ pathRet = fs::path(pszHome);
+#ifdef MAC_OSX
+ // macOS
+ return pathRet / "Library/Application Support/Bitcoin";
+#else
+ // Unix-like
+ return pathRet / ".bitcoin";
+#endif
+#endif
+}
+
+bool CheckDataDirOption(const ArgsManager& args)
+{
+ const fs::path datadir{args.GetPathArg("-datadir")};
+ return datadir.empty() || fs::is_directory(fs::absolute(datadir));
+}
+
+fs::path ArgsManager::GetConfigFilePath() const
+{
+ return GetConfigFile(*this, GetPathArg("-conf", BITCOIN_CONF_FILENAME));
+}
+
+std::string ArgsManager::GetChainName() const
+{
+ auto get_net = [&](const std::string& arg) {
+ LOCK(cs_args);
+ util::SettingsValue value = util::GetSetting(m_settings, /* section= */ "", SettingName(arg),
+ /* ignore_default_section_config= */ false,
+ /*ignore_nonpersistent=*/false,
+ /* get_chain_name= */ true);
+ return value.isNull() ? false : value.isBool() ? value.get_bool() : InterpretBool(value.get_str());
+ };
+
+ const bool fRegTest = get_net("-regtest");
+ const bool fSigNet = get_net("-signet");
+ const bool fTestNet = get_net("-testnet");
+ const bool is_chain_arg_set = IsArgSet("-chain");
+
+ if ((int)is_chain_arg_set + (int)fRegTest + (int)fSigNet + (int)fTestNet > 1) {
+ throw std::runtime_error("Invalid combination of -regtest, -signet, -testnet and -chain. Can use at most one.");
+ }
+ if (fRegTest)
+ return CBaseChainParams::REGTEST;
+ if (fSigNet) {
+ return CBaseChainParams::SIGNET;
+ }
+ if (fTestNet)
+ return CBaseChainParams::TESTNET;
+
+ return GetArg("-chain", CBaseChainParams::MAIN);
+}
+
+bool ArgsManager::UseDefaultSection(const std::string& arg) const
+{
+ return m_network == CBaseChainParams::MAIN || m_network_only_args.count(arg) == 0;
+}
+
+util::SettingsValue ArgsManager::GetSetting(const std::string& arg) const
+{
+ LOCK(cs_args);
+ return util::GetSetting(
+ m_settings, m_network, SettingName(arg), !UseDefaultSection(arg),
+ /*ignore_nonpersistent=*/false, /*get_chain_name=*/false);
+}
+
+std::vector<util::SettingsValue> ArgsManager::GetSettingsList(const std::string& arg) const
+{
+ LOCK(cs_args);
+ return util::GetSettingsList(m_settings, m_network, SettingName(arg), !UseDefaultSection(arg));
+}
+
+void ArgsManager::logArgsPrefix(
+ const std::string& prefix,
+ const std::string& section,
+ const std::map<std::string, std::vector<util::SettingsValue>>& args) const
+{
+ std::string section_str = section.empty() ? "" : "[" + section + "] ";
+ for (const auto& arg : args) {
+ for (const auto& value : arg.second) {
+ std::optional<unsigned int> flags = GetArgFlags('-' + arg.first);
+ if (flags) {
+ std::string value_str = (*flags & SENSITIVE) ? "****" : value.write();
+ LogPrintf("%s %s%s=%s\n", prefix, section_str, arg.first, value_str);
+ }
+ }
+ }
+}
+
+void ArgsManager::LogArgs() const
+{
+ LOCK(cs_args);
+ for (const auto& section : m_settings.ro_config) {
+ logArgsPrefix("Config file arg:", section.first, section.second);
+ }
+ for (const auto& setting : m_settings.rw_settings) {
+ LogPrintf("Setting file arg: %s = %s\n", setting.first, setting.second.write());
+ }
+ logArgsPrefix("Command-line arg:", "", m_settings.command_line_options);
+}
+
+namespace common {
+#ifdef WIN32
+WinCmdLineArgs::WinCmdLineArgs()
+{
+ wchar_t** wargv = CommandLineToArgvW(GetCommandLineW(), &argc);
+ std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t> utf8_cvt;
+ argv = new char*[argc];
+ args.resize(argc);
+ for (int i = 0; i < argc; i++) {
+ args[i] = utf8_cvt.to_bytes(wargv[i]);
+ argv[i] = &*args[i].begin();
+ }
+ LocalFree(wargv);
+}
+
+WinCmdLineArgs::~WinCmdLineArgs()
+{
+ delete[] argv;
+}
+
+std::pair<int, char**> WinCmdLineArgs::get()
+{
+ return std::make_pair(argc, argv);
+}
+#endif
+} // namespace common
diff --git a/src/common/args.h b/src/common/args.h
new file mode 100644
index 0000000000..430c392e2b
--- /dev/null
+++ b/src/common/args.h
@@ -0,0 +1,465 @@
+// Copyright (c) 2023 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_COMMON_ARGS_H
+#define BITCOIN_COMMON_ARGS_H
+
+#include <compat/compat.h>
+#include <sync.h>
+#include <util/fs.h>
+#include <util/settings.h>
+
+#include <iosfwd>
+#include <list>
+#include <map>
+#include <optional>
+#include <set>
+#include <stdint.h>
+#include <string>
+#include <vector>
+
+class ArgsManager;
+
+extern const char * const BITCOIN_CONF_FILENAME;
+extern const char * const BITCOIN_SETTINGS_FILENAME;
+
+// Return true if -datadir option points to a valid directory or is not specified.
+bool CheckDataDirOption(const ArgsManager& args);
+fs::path GetConfigFile(const ArgsManager& args, const fs::path& configuration_file_path);
+
+/**
+ * Most paths passed as configuration arguments are treated as relative to
+ * the datadir if they are not absolute.
+ *
+ * @param args Parsed arguments and settings.
+ * @param path The path to be conditionally prefixed with datadir.
+ * @param net_specific Use network specific datadir variant
+ * @return The normalized path.
+ */
+fs::path AbsPathForConfigVal(const ArgsManager& args, const fs::path& path, bool net_specific = true);
+
+inline bool IsSwitchChar(char c)
+{
+#ifdef WIN32
+ return c == '-' || c == '/';
+#else
+ return c == '-';
+#endif
+}
+
+enum class OptionsCategory {
+ OPTIONS,
+ CONNECTION,
+ WALLET,
+ WALLET_DEBUG_TEST,
+ ZMQ,
+ DEBUG_TEST,
+ CHAINPARAMS,
+ NODE_RELAY,
+ BLOCK_CREATION,
+ RPC,
+ GUI,
+ COMMANDS,
+ REGISTER_COMMANDS,
+
+ HIDDEN // Always the last option to avoid printing these in the help
+};
+
+struct KeyInfo {
+ std::string name;
+ std::string section;
+ bool negated{false};
+};
+
+KeyInfo InterpretKey(std::string key);
+
+std::optional<util::SettingsValue> InterpretValue(const KeyInfo& key, const std::string* value,
+ unsigned int flags, std::string& error);
+
+struct SectionInfo {
+ std::string m_name;
+ std::string m_file;
+ int m_line;
+};
+
+std::string SettingToString(const util::SettingsValue&, const std::string&);
+std::optional<std::string> SettingToString(const util::SettingsValue&);
+
+int64_t SettingToInt(const util::SettingsValue&, int64_t);
+std::optional<int64_t> SettingToInt(const util::SettingsValue&);
+
+bool SettingToBool(const util::SettingsValue&, bool);
+std::optional<bool> SettingToBool(const util::SettingsValue&);
+
+class ArgsManager
+{
+public:
+ /**
+ * Flags controlling how config and command line arguments are validated and
+ * interpreted.
+ */
+ enum Flags : uint32_t {
+ ALLOW_ANY = 0x01, //!< disable validation
+ // ALLOW_BOOL = 0x02, //!< unimplemented, draft implementation in #16545
+ // ALLOW_INT = 0x04, //!< unimplemented, draft implementation in #16545
+ // ALLOW_STRING = 0x08, //!< unimplemented, draft implementation in #16545
+ // ALLOW_LIST = 0x10, //!< unimplemented, draft implementation in #16545
+ DISALLOW_NEGATION = 0x20, //!< disallow -nofoo syntax
+ DISALLOW_ELISION = 0x40, //!< disallow -foo syntax that doesn't assign any value
+
+ DEBUG_ONLY = 0x100,
+ /* Some options would cause cross-contamination if values for
+ * mainnet were used while running on regtest/testnet (or vice-versa).
+ * Setting them as NETWORK_ONLY ensures that sharing a config file
+ * between mainnet and regtest/testnet won't cause problems due to these
+ * parameters by accident. */
+ NETWORK_ONLY = 0x200,
+ // This argument's value is sensitive (such as a password).
+ SENSITIVE = 0x400,
+ COMMAND = 0x800,
+ };
+
+protected:
+ struct Arg
+ {
+ std::string m_help_param;
+ std::string m_help_text;
+ unsigned int m_flags;
+ };
+
+ mutable RecursiveMutex cs_args;
+ util::Settings m_settings GUARDED_BY(cs_args);
+ std::vector<std::string> m_command GUARDED_BY(cs_args);
+ std::string m_network GUARDED_BY(cs_args);
+ std::set<std::string> m_network_only_args GUARDED_BY(cs_args);
+ std::map<OptionsCategory, std::map<std::string, Arg>> m_available_args GUARDED_BY(cs_args);
+ bool m_accept_any_command GUARDED_BY(cs_args){true};
+ std::list<SectionInfo> m_config_sections GUARDED_BY(cs_args);
+ mutable fs::path m_cached_blocks_path GUARDED_BY(cs_args);
+ mutable fs::path m_cached_datadir_path GUARDED_BY(cs_args);
+ mutable fs::path m_cached_network_datadir_path GUARDED_BY(cs_args);
+
+ [[nodiscard]] bool ReadConfigStream(std::istream& stream, const std::string& filepath, std::string& error, bool ignore_invalid_keys = false);
+
+ /**
+ * Returns true if settings values from the default section should be used,
+ * depending on the current network and whether the setting is
+ * network-specific.
+ */
+ bool UseDefaultSection(const std::string& arg) const EXCLUSIVE_LOCKS_REQUIRED(cs_args);
+
+ public:
+ /**
+ * Get setting value.
+ *
+ * Result will be null if setting was unset, true if "-setting" argument was passed
+ * false if "-nosetting" argument was passed, and a string if a "-setting=value"
+ * argument was passed.
+ */
+ util::SettingsValue GetSetting(const std::string& arg) const;
+
+ /**
+ * Get list of setting values.
+ */
+ std::vector<util::SettingsValue> GetSettingsList(const std::string& arg) const;
+
+ ArgsManager();
+ ~ArgsManager();
+
+ /**
+ * Select the network in use
+ */
+ void SelectConfigNetwork(const std::string& network);
+
+ [[nodiscard]] bool ParseParameters(int argc, const char* const argv[], std::string& error);
+
+ /**
+ * Return config file path (read-only)
+ */
+ fs::path GetConfigFilePath() const;
+ [[nodiscard]] bool ReadConfigFiles(std::string& error, bool ignore_invalid_keys = false);
+
+ /**
+ * Log warnings for options in m_section_only_args when
+ * they are specified in the default section but not overridden
+ * on the command line or in a network-specific section in the
+ * config file.
+ */
+ std::set<std::string> GetUnsuitableSectionOnlyArgs() const;
+
+ /**
+ * Log warnings for unrecognized section names in the config file.
+ */
+ std::list<SectionInfo> GetUnrecognizedSections() const;
+
+ struct Command {
+ /** The command (if one has been registered with AddCommand), or empty */
+ std::string command;
+ /**
+ * If command is non-empty: Any args that followed it
+ * If command is empty: The unregistered command and any args that followed it
+ */
+ std::vector<std::string> args;
+ };
+ /**
+ * Get the command and command args (returns std::nullopt if no command provided)
+ */
+ std::optional<const Command> GetCommand() const;
+
+ /**
+ * Get blocks directory path
+ *
+ * @return Blocks path which is network specific
+ */
+ const fs::path& GetBlocksDirPath() const;
+
+ /**
+ * Get data directory path
+ *
+ * @return Absolute path on success, otherwise an empty path when a non-directory path would be returned
+ */
+ const fs::path& GetDataDirBase() const { return GetDataDir(false); }
+
+ /**
+ * Get data directory path with appended network identifier
+ *
+ * @return Absolute path on success, otherwise an empty path when a non-directory path would be returned
+ */
+ const fs::path& GetDataDirNet() const { return GetDataDir(true); }
+
+ /**
+ * Clear cached directory paths
+ */
+ void ClearPathCache();
+
+ /**
+ * Return a vector of strings of the given argument
+ *
+ * @param strArg Argument to get (e.g. "-foo")
+ * @return command-line arguments
+ */
+ std::vector<std::string> GetArgs(const std::string& strArg) const;
+
+ /**
+ * Return true if the given argument has been manually set
+ *
+ * @param strArg Argument to get (e.g. "-foo")
+ * @return true if the argument has been set
+ */
+ bool IsArgSet(const std::string& strArg) const;
+
+ /**
+ * Return true if the argument was originally passed as a negated option,
+ * i.e. -nofoo.
+ *
+ * @param strArg Argument to get (e.g. "-foo")
+ * @return true if the argument was passed negated
+ */
+ bool IsArgNegated(const std::string& strArg) const;
+
+ /**
+ * Return string argument or default value
+ *
+ * @param strArg Argument to get (e.g. "-foo")
+ * @param strDefault (e.g. "1")
+ * @return command-line argument or default value
+ */
+ std::string GetArg(const std::string& strArg, const std::string& strDefault) const;
+ std::optional<std::string> GetArg(const std::string& strArg) const;
+
+ /**
+ * Return path argument or default value
+ *
+ * @param arg Argument to get a path from (e.g., "-datadir", "-blocksdir" or "-walletdir")
+ * @param default_value Optional default value to return instead of the empty path.
+ * @return normalized path if argument is set, with redundant "." and ".."
+ * path components and trailing separators removed (see patharg unit test
+ * for examples or implementation for details). If argument is empty or not
+ * set, default_value is returned unchanged.
+ */
+ fs::path GetPathArg(std::string arg, const fs::path& default_value = {}) const;
+
+ /**
+ * Return integer argument or default value
+ *
+ * @param strArg Argument to get (e.g. "-foo")
+ * @param nDefault (e.g. 1)
+ * @return command-line argument (0 if invalid number) or default value
+ */
+ int64_t GetIntArg(const std::string& strArg, int64_t nDefault) const;
+ std::optional<int64_t> GetIntArg(const std::string& strArg) const;
+
+ /**
+ * Return boolean argument or default value
+ *
+ * @param strArg Argument to get (e.g. "-foo")
+ * @param fDefault (true or false)
+ * @return command-line argument or default value
+ */
+ bool GetBoolArg(const std::string& strArg, bool fDefault) const;
+ std::optional<bool> GetBoolArg(const std::string& strArg) const;
+
+ /**
+ * Set an argument if it doesn't already have a value
+ *
+ * @param strArg Argument to set (e.g. "-foo")
+ * @param strValue Value (e.g. "1")
+ * @return true if argument gets set, false if it already had a value
+ */
+ bool SoftSetArg(const std::string& strArg, const std::string& strValue);
+
+ /**
+ * Set a boolean argument if it doesn't already have a value
+ *
+ * @param strArg Argument to set (e.g. "-foo")
+ * @param fValue Value (e.g. false)
+ * @return true if argument gets set, false if it already had a value
+ */
+ bool SoftSetBoolArg(const std::string& strArg, bool fValue);
+
+ // Forces an arg setting. Called by SoftSetArg() if the arg hasn't already
+ // been set. Also called directly in testing.
+ void ForceSetArg(const std::string& strArg, const std::string& strValue);
+
+ /**
+ * Returns the appropriate chain name from the program arguments.
+ * @return CBaseChainParams::MAIN by default; raises runtime error if an invalid combination is given.
+ */
+ std::string GetChainName() const;
+
+ /**
+ * Add argument
+ */
+ void AddArg(const std::string& name, const std::string& help, unsigned int flags, const OptionsCategory& cat);
+
+ /**
+ * Add subcommand
+ */
+ void AddCommand(const std::string& cmd, const std::string& help);
+
+ /**
+ * Add many hidden arguments
+ */
+ void AddHiddenArgs(const std::vector<std::string>& args);
+
+ /**
+ * Clear available arguments
+ */
+ void ClearArgs() {
+ LOCK(cs_args);
+ m_available_args.clear();
+ m_network_only_args.clear();
+ }
+
+ /**
+ * Get the help string
+ */
+ std::string GetHelpMessage() const;
+
+ /**
+ * Return Flags for known arg.
+ * Return nullopt for unknown arg.
+ */
+ std::optional<unsigned int> GetArgFlags(const std::string& name) const;
+
+ /**
+ * Get settings file path, or return false if read-write settings were
+ * disabled with -nosettings.
+ */
+ bool GetSettingsPath(fs::path* filepath = nullptr, bool temp = false, bool backup = false) const;
+
+ /**
+ * Read settings file. Push errors to vector, or log them if null.
+ */
+ bool ReadSettingsFile(std::vector<std::string>* errors = nullptr);
+
+ /**
+ * Write settings file or backup settings file. Push errors to vector, or
+ * log them if null.
+ */
+ bool WriteSettingsFile(std::vector<std::string>* errors = nullptr, bool backup = false) const;
+
+ /**
+ * Get current setting from config file or read/write settings file,
+ * ignoring nonpersistent command line or forced settings values.
+ */
+ util::SettingsValue GetPersistentSetting(const std::string& name) const;
+
+ /**
+ * Access settings with lock held.
+ */
+ template <typename Fn>
+ void LockSettings(Fn&& fn)
+ {
+ LOCK(cs_args);
+ fn(m_settings);
+ }
+
+ /**
+ * Log the config file options and the command line arguments,
+ * useful for troubleshooting.
+ */
+ void LogArgs() const;
+
+private:
+ /**
+ * Get data directory path
+ *
+ * @param net_specific Append network identifier to the returned path
+ * @return Absolute path on success, otherwise an empty path when a non-directory path would be returned
+ */
+ const fs::path& GetDataDir(bool net_specific) const;
+
+ // Helper function for LogArgs().
+ void logArgsPrefix(
+ const std::string& prefix,
+ const std::string& section,
+ const std::map<std::string, std::vector<util::SettingsValue>>& args) const;
+};
+
+extern ArgsManager gArgs;
+
+/**
+ * @return true if help has been requested via a command-line arg
+ */
+bool HelpRequested(const ArgsManager& args);
+
+/** Add help options to the args manager */
+void SetupHelpOptions(ArgsManager& args);
+
+/**
+ * Format a string to be used as group of options in help messages
+ *
+ * @param message Group name (e.g. "RPC server options:")
+ * @return the formatted string
+ */
+std::string HelpMessageGroup(const std::string& message);
+
+/**
+ * Format a string to be used as option description in help messages
+ *
+ * @param option Option message (e.g. "-rpcuser=<user>")
+ * @param message Option description (e.g. "Username for JSON-RPC connections")
+ * @return the formatted string
+ */
+std::string HelpMessageOpt(const std::string& option, const std::string& message);
+
+namespace common {
+#ifdef WIN32
+class WinCmdLineArgs
+{
+public:
+ WinCmdLineArgs();
+ ~WinCmdLineArgs();
+ std::pair<int, char**> get();
+
+private:
+ int argc;
+ char** argv;
+ std::vector<std::string> args;
+};
+#endif
+} // namespace common
+
+#endif // BITCOIN_COMMON_ARGS_H
diff --git a/src/common/config.cpp b/src/common/config.cpp
new file mode 100644
index 0000000000..747503ad2a
--- /dev/null
+++ b/src/common/config.cpp
@@ -0,0 +1,220 @@
+// Copyright (c) 2023 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 <common/args.h>
+
+#include <logging.h>
+#include <sync.h>
+#include <tinyformat.h>
+#include <univalue.h>
+#include <util/fs.h>
+#include <util/settings.h>
+#include <util/string.h>
+
+#include <algorithm>
+#include <cassert>
+#include <cstdlib>
+#include <fstream>
+#include <iostream>
+#include <list>
+#include <map>
+#include <memory>
+#include <optional>
+#include <string>
+#include <string_view>
+#include <utility>
+#include <vector>
+
+fs::path GetConfigFile(const ArgsManager& args, const fs::path& configuration_file_path)
+{
+ return AbsPathForConfigVal(args, configuration_file_path, /*net_specific=*/false);
+}
+
+static bool GetConfigOptions(std::istream& stream, const std::string& filepath, std::string& error, std::vector<std::pair<std::string, std::string>>& options, std::list<SectionInfo>& sections)
+{
+ std::string str, prefix;
+ std::string::size_type pos;
+ int linenr = 1;
+ while (std::getline(stream, str)) {
+ bool used_hash = false;
+ if ((pos = str.find('#')) != std::string::npos) {
+ str = str.substr(0, pos);
+ used_hash = true;
+ }
+ const static std::string pattern = " \t\r\n";
+ str = TrimString(str, pattern);
+ if (!str.empty()) {
+ if (*str.begin() == '[' && *str.rbegin() == ']') {
+ const std::string section = str.substr(1, str.size() - 2);
+ sections.emplace_back(SectionInfo{section, filepath, linenr});
+ prefix = section + '.';
+ } else if (*str.begin() == '-') {
+ error = strprintf("parse error on line %i: %s, options in configuration file must be specified without leading -", linenr, str);
+ return false;
+ } else if ((pos = str.find('=')) != std::string::npos) {
+ std::string name = prefix + TrimString(std::string_view{str}.substr(0, pos), pattern);
+ std::string_view value = TrimStringView(std::string_view{str}.substr(pos + 1), pattern);
+ if (used_hash && name.find("rpcpassword") != std::string::npos) {
+ error = strprintf("parse error on line %i, using # in rpcpassword can be ambiguous and should be avoided", linenr);
+ return false;
+ }
+ options.emplace_back(name, value);
+ if ((pos = name.rfind('.')) != std::string::npos && prefix.length() <= pos) {
+ sections.emplace_back(SectionInfo{name.substr(0, pos), filepath, linenr});
+ }
+ } else {
+ error = strprintf("parse error on line %i: %s", linenr, str);
+ if (str.size() >= 2 && str.substr(0, 2) == "no") {
+ error += strprintf(", if you intended to specify a negated option, use %s=1 instead", str);
+ }
+ return false;
+ }
+ }
+ ++linenr;
+ }
+ return true;
+}
+
+bool IsConfSupported(KeyInfo& key, std::string& error) {
+ if (key.name == "conf") {
+ error = "conf cannot be set in the configuration file; use includeconf= if you want to include additional config files";
+ return false;
+ }
+ if (key.name == "reindex") {
+ // reindex can be set in a config file but it is strongly discouraged as this will cause the node to reindex on
+ // every restart. Allow the config but throw a warning
+ LogPrintf("Warning: reindex=1 is set in the configuration file, which will significantly slow down startup. Consider removing or commenting out this option for better performance, unless there is currently a condition which makes rebuilding the indexes necessary\n");
+ return true;
+ }
+ return true;
+}
+
+bool ArgsManager::ReadConfigStream(std::istream& stream, const std::string& filepath, std::string& error, bool ignore_invalid_keys)
+{
+ LOCK(cs_args);
+ std::vector<std::pair<std::string, std::string>> options;
+ if (!GetConfigOptions(stream, filepath, error, options, m_config_sections)) {
+ return false;
+ }
+ for (const std::pair<std::string, std::string>& option : options) {
+ KeyInfo key = InterpretKey(option.first);
+ std::optional<unsigned int> flags = GetArgFlags('-' + key.name);
+ if (!IsConfSupported(key, error)) return false;
+ if (flags) {
+ std::optional<util::SettingsValue> value = InterpretValue(key, &option.second, *flags, error);
+ if (!value) {
+ return false;
+ }
+ m_settings.ro_config[key.section][key.name].push_back(*value);
+ } else {
+ if (ignore_invalid_keys) {
+ LogPrintf("Ignoring unknown configuration value %s\n", option.first);
+ } else {
+ error = strprintf("Invalid configuration value %s", option.first);
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+bool ArgsManager::ReadConfigFiles(std::string& error, bool ignore_invalid_keys)
+{
+ {
+ LOCK(cs_args);
+ m_settings.ro_config.clear();
+ m_config_sections.clear();
+ }
+
+ const auto conf_path{GetConfigFilePath()};
+ std::ifstream stream{conf_path};
+
+ // not ok to have a config file specified that cannot be opened
+ if (IsArgSet("-conf") && !stream.good()) {
+ error = strprintf("specified config file \"%s\" could not be opened.", fs::PathToString(conf_path));
+ return false;
+ }
+ // ok to not have a config file
+ if (stream.good()) {
+ if (!ReadConfigStream(stream, fs::PathToString(conf_path), error, ignore_invalid_keys)) {
+ return false;
+ }
+ // `-includeconf` cannot be included in the command line arguments except
+ // as `-noincludeconf` (which indicates that no included conf file should be used).
+ bool use_conf_file{true};
+ {
+ LOCK(cs_args);
+ if (auto* includes = util::FindKey(m_settings.command_line_options, "includeconf")) {
+ // ParseParameters() fails if a non-negated -includeconf is passed on the command-line
+ assert(util::SettingsSpan(*includes).last_negated());
+ use_conf_file = false;
+ }
+ }
+ if (use_conf_file) {
+ std::string chain_id = GetChainName();
+ std::vector<std::string> conf_file_names;
+
+ auto add_includes = [&](const std::string& network, size_t skip = 0) {
+ size_t num_values = 0;
+ LOCK(cs_args);
+ if (auto* section = util::FindKey(m_settings.ro_config, network)) {
+ if (auto* values = util::FindKey(*section, "includeconf")) {
+ for (size_t i = std::max(skip, util::SettingsSpan(*values).negated()); i < values->size(); ++i) {
+ conf_file_names.push_back((*values)[i].get_str());
+ }
+ num_values = values->size();
+ }
+ }
+ return num_values;
+ };
+
+ // We haven't set m_network yet (that happens in SelectParams()), so manually check
+ // for network.includeconf args.
+ const size_t chain_includes = add_includes(chain_id);
+ const size_t default_includes = add_includes({});
+
+ for (const std::string& conf_file_name : conf_file_names) {
+ std::ifstream conf_file_stream{GetConfigFile(*this, fs::PathFromString(conf_file_name))};
+ if (conf_file_stream.good()) {
+ if (!ReadConfigStream(conf_file_stream, conf_file_name, error, ignore_invalid_keys)) {
+ return false;
+ }
+ LogPrintf("Included configuration file %s\n", conf_file_name);
+ } else {
+ error = "Failed to include configuration file " + conf_file_name;
+ return false;
+ }
+ }
+
+ // Warn about recursive -includeconf
+ conf_file_names.clear();
+ add_includes(chain_id, /* skip= */ chain_includes);
+ add_includes({}, /* skip= */ default_includes);
+ std::string chain_id_final = GetChainName();
+ if (chain_id_final != chain_id) {
+ // Also warn about recursive includeconf for the chain that was specified in one of the includeconfs
+ add_includes(chain_id_final);
+ }
+ for (const std::string& conf_file_name : conf_file_names) {
+ tfm::format(std::cerr, "warning: -includeconf cannot be used from included files; ignoring -includeconf=%s\n", conf_file_name);
+ }
+ }
+ }
+
+ // If datadir is changed in .conf file:
+ ClearPathCache();
+ if (!CheckDataDirOption(*this)) {
+ error = strprintf("specified data directory \"%s\" does not exist.", GetArg("-datadir", ""));
+ return false;
+ }
+ return true;
+}
+
+fs::path AbsPathForConfigVal(const ArgsManager& args, const fs::path& path, bool net_specific)
+{
+ if (path.is_absolute()) {
+ return path;
+ }
+ return fsbridge::AbsPathJoin(net_specific ? args.GetDataDirNet() : args.GetDataDirBase(), path);
+}
diff --git a/src/common/init.cpp b/src/common/init.cpp
index 159eb7e2ef..6ffa44847a 100644
--- a/src/common/init.cpp
+++ b/src/common/init.cpp
@@ -2,11 +2,11 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include <common/init.h>
#include <chainparams.h>
-#include <fs.h>
+#include <common/args.h>
+#include <common/init.h>
#include <tinyformat.h>
-#include <util/system.h>
+#include <util/fs.h>
#include <util/translation.h>
#include <algorithm>
diff --git a/src/compat/assumptions.h b/src/compat/assumptions.h
index 92615b582a..4488db0886 100644
--- a/src/compat/assumptions.h
+++ b/src/compat/assumptions.h
@@ -8,6 +8,7 @@
#ifndef BITCOIN_COMPAT_ASSUMPTIONS_H
#define BITCOIN_COMPAT_ASSUMPTIONS_H
+#include <cstddef>
#include <limits>
// Assumption: We assume that the macro NDEBUG is not defined.
diff --git a/src/compat/compat.h b/src/compat/compat.h
index 88f58120b8..8195bceaec 100644
--- a/src/compat/compat.h
+++ b/src/compat/compat.h
@@ -62,15 +62,6 @@ typedef unsigned int SOCKET;
#endif
#endif
-// Windows doesn't define S_IRUSR or S_IWUSR. We define both
-// here, with the same values as glibc (see stat.h).
-#ifdef WIN32
-#ifndef S_IRUSR
-#define S_IRUSR 0400
-#define S_IWUSR 0200
-#endif
-#endif
-
// Windows defines MAX_PATH as it's maximum path length.
// We define MAX_PATH for use on non-Windows systems.
#ifndef WIN32
diff --git a/src/dbwrapper.cpp b/src/dbwrapper.cpp
index 0c6debfa80..2aade14ef4 100644
--- a/src/dbwrapper.cpp
+++ b/src/dbwrapper.cpp
@@ -4,12 +4,12 @@
#include <dbwrapper.h>
-#include <fs.h>
#include <logging.h>
#include <random.h>
#include <tinyformat.h>
+#include <util/fs.h>
+#include <util/fs_helpers.h>
#include <util/strencodings.h>
-#include <util/system.h>
#include <algorithm>
#include <cassert>
diff --git a/src/dbwrapper.h b/src/dbwrapper.h
index 578d9880ac..35782edca6 100644
--- a/src/dbwrapper.h
+++ b/src/dbwrapper.h
@@ -6,11 +6,11 @@
#define BITCOIN_DBWRAPPER_H
#include <clientversion.h>
-#include <fs.h>
#include <logging.h>
#include <serialize.h>
#include <span.h>
#include <streams.h>
+#include <util/fs.h>
#include <cstddef>
#include <cstdint>
diff --git a/src/dummywallet.cpp b/src/dummywallet.cpp
index 028c6ebae1..9160ec19e6 100644
--- a/src/dummywallet.cpp
+++ b/src/dummywallet.cpp
@@ -2,7 +2,8 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include <util/system.h>
+#include <common/args.h>
+#include <logging.h>
#include <walletinitinterface.h>
class ArgsManager;
diff --git a/src/flatfile.cpp b/src/flatfile.cpp
index d6e84d02c1..59861a08ad 100644
--- a/src/flatfile.cpp
+++ b/src/flatfile.cpp
@@ -8,7 +8,7 @@
#include <flatfile.h>
#include <logging.h>
#include <tinyformat.h>
-#include <util/system.h>
+#include <util/fs_helpers.h>
FlatFileSeq::FlatFileSeq(fs::path dir, const char* prefix, size_t chunk_size) :
m_dir(std::move(dir)),
diff --git a/src/flatfile.h b/src/flatfile.h
index e4be9a9cb1..26b466db71 100644
--- a/src/flatfile.h
+++ b/src/flatfile.h
@@ -8,8 +8,8 @@
#include <string>
-#include <fs.h>
#include <serialize.h>
+#include <util/fs.h>
struct FlatFilePos
{
diff --git a/src/headerssync.cpp b/src/headerssync.cpp
index 757b942cd9..a3adfb4f70 100644
--- a/src/headerssync.cpp
+++ b/src/headerssync.cpp
@@ -24,11 +24,11 @@ static_assert(sizeof(CompressedHeader) == 48);
HeadersSyncState::HeadersSyncState(NodeId id, const Consensus::Params& consensus_params,
const CBlockIndex* chain_start, const arith_uint256& minimum_required_work) :
+ m_commit_offset(GetRand<unsigned>(HEADER_COMMITMENT_PERIOD)),
m_id(id), m_consensus_params(consensus_params),
m_chain_start(chain_start),
m_minimum_required_work(minimum_required_work),
m_current_chain_work(chain_start->nChainWork),
- m_commit_offset(GetRand<unsigned>(HEADER_COMMITMENT_PERIOD)),
m_last_header_received(m_chain_start->GetBlockHeader()),
m_current_height(chain_start->nHeight)
{
diff --git a/src/headerssync.h b/src/headerssync.h
index 16da964246..e93f67e6da 100644
--- a/src/headerssync.h
+++ b/src/headerssync.h
@@ -175,6 +175,13 @@ public:
*/
CBlockLocator NextHeadersRequestLocator() const;
+protected:
+ /** The (secret) offset on the heights for which to create commitments.
+ *
+ * m_header_commitments entries are created at any height h for which
+ * (h % HEADER_COMMITMENT_PERIOD) == m_commit_offset. */
+ const unsigned m_commit_offset;
+
private:
/** Clear out all download state that might be in progress (freeing any used
* memory), and mark this object as no longer usable.
@@ -222,12 +229,6 @@ private:
/** A queue of commitment bits, created during the 1st phase, and verified during the 2nd. */
bitdeque<> m_header_commitments;
- /** The (secret) offset on the heights for which to create commitments.
- *
- * m_header_commitments entries are created at any height h for which
- * (h % HEADER_COMMITMENT_PERIOD) == m_commit_offset. */
- const unsigned m_commit_offset;
-
/** m_max_commitments is a bound we calculate on how long an honest peer's chain could be,
* given the MTP rule.
*
diff --git a/src/httprpc.cpp b/src/httprpc.cpp
index 86166a5ca4..bf3fa6298d 100644
--- a/src/httprpc.cpp
+++ b/src/httprpc.cpp
@@ -4,13 +4,14 @@
#include <httprpc.h>
+#include <common/args.h>
#include <crypto/hmac_sha256.h>
#include <httpserver.h>
+#include <logging.h>
#include <rpc/protocol.h>
#include <rpc/server.h>
#include <util/strencodings.h>
#include <util/string.h>
-#include <util/system.h>
#include <walletinitinterface.h>
#include <algorithm>
diff --git a/src/httpserver.cpp b/src/httpserver.cpp
index 942caa042d..4f8a2b4d8d 100644
--- a/src/httpserver.cpp
+++ b/src/httpserver.cpp
@@ -9,7 +9,9 @@
#include <httpserver.h>
#include <chainparamsbase.h>
+#include <common/args.h>
#include <compat/compat.h>
+#include <logging.h>
#include <netbase.h>
#include <node/interface_ui.h>
#include <rpc/protocol.h> // For HTTP status codes
@@ -17,7 +19,6 @@
#include <sync.h>
#include <util/strencodings.h>
#include <util/syscall_sandbox.h>
-#include <util/system.h>
#include <util/threadnames.h>
#include <util/translation.h>
@@ -673,6 +674,9 @@ std::optional<std::string> HTTPRequest::GetQueryParameter(const std::string& key
std::optional<std::string> GetQueryParameterFromUri(const char* uri, const std::string& key)
{
evhttp_uri* uri_parsed{evhttp_uri_parse(uri)};
+ if (!uri_parsed) {
+ throw std::runtime_error("URI parsing failed, it likely contained RFC 3986 invalid characters");
+ }
const char* query{evhttp_uri_get_query(uri_parsed)};
std::optional<std::string> result;
diff --git a/src/i2p.cpp b/src/i2p.cpp
index a3bfc23a65..c67b6ed185 100644
--- a/src/i2p.cpp
+++ b/src/i2p.cpp
@@ -3,21 +3,21 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <chainparams.h>
+#include <common/args.h>
#include <compat/compat.h>
#include <compat/endian.h>
#include <crypto/sha256.h>
-#include <fs.h>
#include <i2p.h>
#include <logging.h>
#include <netaddress.h>
#include <netbase.h>
#include <random.h>
#include <tinyformat.h>
+#include <util/fs.h>
#include <util/readwritefile.h>
#include <util/sock.h>
#include <util/spanparsing.h>
#include <util/strencodings.h>
-#include <util/system.h>
#include <util/threadinterrupt.h>
#include <chrono>
diff --git a/src/i2p.h b/src/i2p.h
index 6e7bafc945..c9c99292d9 100644
--- a/src/i2p.h
+++ b/src/i2p.h
@@ -6,9 +6,9 @@
#define BITCOIN_I2P_H
#include <compat/compat.h>
-#include <fs.h>
#include <netaddress.h>
#include <sync.h>
+#include <util/fs.h>
#include <util/sock.h>
#include <util/threadinterrupt.h>
diff --git a/src/index/base.cpp b/src/index/base.cpp
index 8a311296c2..237c8e8be0 100644
--- a/src/index/base.cpp
+++ b/src/index/base.cpp
@@ -3,6 +3,7 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <chainparams.h>
+#include <common/args.h>
#include <index/base.h>
#include <interfaces/chain.h>
#include <kernel/chain.h>
@@ -14,7 +15,6 @@
#include <shutdown.h>
#include <tinyformat.h>
#include <util/syscall_sandbox.h>
-#include <util/system.h>
#include <util/thread.h>
#include <util/translation.h>
#include <validation.h> // For g_chainman
diff --git a/src/index/blockfilterindex.cpp b/src/index/blockfilterindex.cpp
index 59bf6d34cf..e6300ce3dd 100644
--- a/src/index/blockfilterindex.cpp
+++ b/src/index/blockfilterindex.cpp
@@ -4,11 +4,12 @@
#include <map>
+#include <common/args.h>
#include <dbwrapper.h>
#include <hash.h>
#include <index/blockfilterindex.h>
#include <node/blockstorage.h>
-#include <util/system.h>
+#include <util/fs_helpers.h>
#include <validation.h>
using node::UndoReadFromDisk;
diff --git a/src/index/coinstatsindex.cpp b/src/index/coinstatsindex.cpp
index 4d637e217a..5bc6ad3d31 100644
--- a/src/index/coinstatsindex.cpp
+++ b/src/index/coinstatsindex.cpp
@@ -4,6 +4,7 @@
#include <chainparams.h>
#include <coins.h>
+#include <common/args.h>
#include <crypto/muhash.h>
#include <index/coinstatsindex.h>
#include <kernel/coinstats.h>
@@ -12,7 +13,6 @@
#include <serialize.h>
#include <txdb.h>
#include <undo.h>
-#include <util/system.h>
#include <validation.h>
using kernel::CCoinsStats;
diff --git a/src/index/txindex.cpp b/src/index/txindex.cpp
index 9095e7afeb..49bddf2d4d 100644
--- a/src/index/txindex.cpp
+++ b/src/index/txindex.cpp
@@ -4,10 +4,10 @@
#include <index/txindex.h>
+#include <common/args.h>
#include <index/disktxpos.h>
#include <logging.h>
#include <node/blockstorage.h>
-#include <util/system.h>
#include <validation.h>
using node::OpenBlockFile;
diff --git a/src/init.cpp b/src/init.cpp
index 16909f7e47..525648b812 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -18,9 +18,9 @@
#include <blockfilter.h>
#include <chain.h>
#include <chainparams.h>
+#include <common/args.h>
#include <consensus/amount.h>
#include <deploymentstatus.h>
-#include <fs.h>
#include <hash.h>
#include <httprpc.h>
#include <httpserver.h>
@@ -70,6 +70,8 @@
#include <txmempool.h>
#include <util/asmap.h>
#include <util/check.h>
+#include <util/fs.h>
+#include <util/fs_helpers.h>
#include <util/moneystr.h>
#include <util/strencodings.h>
#include <util/string.h>
diff --git a/src/init/bitcoin-gui.cpp b/src/init/bitcoin-gui.cpp
index 100b4ef7ee..ddbdaa6cd0 100644
--- a/src/init/bitcoin-gui.cpp
+++ b/src/init/bitcoin-gui.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 <common/args.h>
#include <interfaces/chain.h>
#include <interfaces/echo.h>
#include <interfaces/init.h>
@@ -10,7 +11,6 @@
#include <interfaces/wallet.h>
#include <node/context.h>
#include <util/check.h>
-#include <util/system.h>
#include <memory>
diff --git a/src/init/bitcoin-node.cpp b/src/init/bitcoin-node.cpp
index 1418e63777..b04596f986 100644
--- a/src/init/bitcoin-node.cpp
+++ b/src/init/bitcoin-node.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 <common/args.h>
#include <interfaces/chain.h>
#include <interfaces/echo.h>
#include <interfaces/init.h>
@@ -10,7 +11,6 @@
#include <interfaces/wallet.h>
#include <node/context.h>
#include <util/check.h>
-#include <util/system.h>
#include <memory>
diff --git a/src/init/bitcoin-qt.cpp b/src/init/bitcoin-qt.cpp
index e27be0e598..dd5826d982 100644
--- a/src/init/bitcoin-qt.cpp
+++ b/src/init/bitcoin-qt.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 <common/args.h>
#include <interfaces/chain.h>
#include <interfaces/echo.h>
#include <interfaces/init.h>
@@ -9,7 +10,6 @@
#include <interfaces/wallet.h>
#include <node/context.h>
#include <util/check.h>
-#include <util/system.h>
#include <memory>
diff --git a/src/init/bitcoind.cpp b/src/init/bitcoind.cpp
index 7ad1f64e64..210608370c 100644
--- a/src/init/bitcoind.cpp
+++ b/src/init/bitcoind.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 <common/args.h>
#include <interfaces/chain.h>
#include <interfaces/echo.h>
#include <interfaces/init.h>
@@ -9,7 +10,6 @@
#include <interfaces/wallet.h>
#include <node/context.h>
#include <util/check.h>
-#include <util/system.h>
#include <memory>
diff --git a/src/init/common.cpp b/src/init/common.cpp
index a7829c5d99..9a52a09cea 100644
--- a/src/init/common.cpp
+++ b/src/init/common.cpp
@@ -7,12 +7,13 @@
#endif
#include <clientversion.h>
-#include <fs.h>
+#include <common/args.h>
#include <logging.h>
#include <node/interface_ui.h>
#include <tinyformat.h>
+#include <util/fs.h>
+#include <util/fs_helpers.h>
#include <util/string.h>
-#include <util/system.h>
#include <util/time.h>
#include <util/translation.h>
diff --git a/src/interfaces/wallet.h b/src/interfaces/wallet.h
index 86707b20b1..8c31112fc9 100644
--- a/src/interfaces/wallet.h
+++ b/src/interfaces/wallet.h
@@ -6,11 +6,11 @@
#define BITCOIN_INTERFACES_WALLET_H
#include <consensus/amount.h>
-#include <fs.h>
#include <interfaces/chain.h> // For ChainClient
#include <pubkey.h> // For CKeyID and CScriptID (definitions needed in CTxDestination instantiation)
#include <script/standard.h> // For CTxDestination
#include <support/allocators/secure.h> // For SecureString
+#include <util/fs.h>
#include <util/message.h>
#include <util/result.h>
#include <util/ui_change_type.h>
@@ -35,6 +35,7 @@ struct bilingual_str;
namespace wallet {
class CCoinControl;
class CWallet;
+enum class AddressPurpose;
enum isminetype : unsigned int;
struct CRecipient;
struct WalletContext;
@@ -103,7 +104,7 @@ public:
virtual bool haveWatchOnly() = 0;
//! Add or update address.
- virtual bool setAddressBook(const CTxDestination& dest, const std::string& name, const std::string& purpose) = 0;
+ virtual bool setAddressBook(const CTxDestination& dest, const std::string& name, const std::optional<wallet::AddressPurpose>& purpose) = 0;
// Remove address.
virtual bool delAddressBook(const CTxDestination& dest) = 0;
@@ -112,7 +113,7 @@ public:
virtual bool getAddress(const CTxDestination& dest,
std::string* name,
wallet::isminetype* is_mine,
- std::string* purpose) = 0;
+ wallet::AddressPurpose* purpose) = 0;
//! Get wallet address list.
virtual std::vector<WalletAddress> getAddresses() const = 0;
@@ -293,7 +294,7 @@ public:
using AddressBookChangedFn = std::function<void(const CTxDestination& address,
const std::string& label,
bool is_mine,
- const std::string& purpose,
+ wallet::AddressPurpose purpose,
ChangeType status)>;
virtual std::unique_ptr<Handler> handleAddressBookChanged(AddressBookChangedFn fn) = 0;
@@ -352,11 +353,11 @@ struct WalletAddress
{
CTxDestination dest;
wallet::isminetype is_mine;
+ wallet::AddressPurpose purpose;
std::string name;
- std::string purpose;
- WalletAddress(CTxDestination dest, wallet::isminetype is_mine, std::string name, std::string purpose)
- : dest(std::move(dest)), is_mine(is_mine), name(std::move(name)), purpose(std::move(purpose))
+ WalletAddress(CTxDestination dest, wallet::isminetype is_mine, wallet::AddressPurpose purpose, std::string name)
+ : dest(std::move(dest)), is_mine(is_mine), purpose(std::move(purpose)), name(std::move(name))
{
}
};
diff --git a/src/ipc/interfaces.cpp b/src/ipc/interfaces.cpp
index 396f3ddf25..d804d9d291 100644
--- a/src/ipc/interfaces.cpp
+++ b/src/ipc/interfaces.cpp
@@ -2,7 +2,6 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include <fs.h>
#include <interfaces/init.h>
#include <interfaces/ipc.h>
#include <ipc/capnp/protocol.h>
@@ -10,6 +9,7 @@
#include <ipc/protocol.h>
#include <logging.h>
#include <tinyformat.h>
+#include <util/fs.h>
#include <util/system.h>
#include <cstdio>
diff --git a/src/ipc/process.cpp b/src/ipc/process.cpp
index 4dc88ae44b..9657dcd092 100644
--- a/src/ipc/process.cpp
+++ b/src/ipc/process.cpp
@@ -2,11 +2,11 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include <fs.h>
#include <ipc/process.h>
#include <ipc/protocol.h>
#include <mp/util.h>
#include <tinyformat.h>
+#include <util/fs.h>
#include <util/strencodings.h>
#include <cstdint>
diff --git a/src/ipc/process.h b/src/ipc/process.h
index 4bb2930d9c..40f2d2acf6 100644
--- a/src/ipc/process.h
+++ b/src/ipc/process.h
@@ -5,6 +5,8 @@
#ifndef BITCOIN_IPC_PROCESS_H
#define BITCOIN_IPC_PROCESS_H
+#include <util/fs.h>
+
#include <memory>
#include <string>
diff --git a/src/kernel/chainparams.cpp b/src/kernel/chainparams.cpp
index e0c4aff6f4..2827737ee1 100644
--- a/src/kernel/chainparams.cpp
+++ b/src/kernel/chainparams.cpp
@@ -103,8 +103,8 @@ public:
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("0x00000000000000000000000000000000000000003404ba0801921119f903495e");
- consensus.defaultAssumeValid = uint256S("0x00000000000000000009c97098b5295f7e5f183ac811fb5d1534040adb93cabd"); // 751565
+ consensus.nMinimumChainWork = uint256S("0x000000000000000000000000000000000000000044a50fe819c39ad624021859");
+ consensus.defaultAssumeValid = uint256S("0x000000000000000000035c3f0d31e71a5ee24c5aaf3354689f65bd7b07dee632"); // 784000
/**
* The message start string is designed to be unlikely to occur in normal data.
@@ -117,8 +117,8 @@ public:
pchMessageStart[3] = 0xd9;
nDefaultPort = 8333;
nPruneAfterHeight = 100000;
- m_assumed_blockchain_size = 496;
- m_assumed_chain_state_size = 6;
+ m_assumed_blockchain_size = 540;
+ m_assumed_chain_state_size = 7;
genesis = CreateGenesisBlock(1231006505, 2083236893, 0x1d00ffff, 1, 50 * COIN);
consensus.hashGenesisBlock = genesis.GetHash();
@@ -178,10 +178,10 @@ public:
};
chainTxData = ChainTxData{
- // Data from RPC: getchaintxstats 4096 00000000000000000009c97098b5295f7e5f183ac811fb5d1534040adb93cabd
- .nTime = 1661697692,
- .nTxCount = 760120522,
- .dTxRate = 2.925802860942233,
+ // Data from RPC: getchaintxstats 4096 000000000000000000035c3f0d31e71a5ee24c5aaf3354689f65bd7b07dee632
+ .nTime = 1680665245,
+ .nTxCount = 820876044,
+ .dTxRate = 3.672283614033389,
};
}
};
@@ -223,8 +223,8 @@ public:
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("0x00000000000000000000000000000000000000000000076f6e7cbd0beade5d20");
- consensus.defaultAssumeValid = uint256S("0x0000000000000004877fa2d36316398528de4f347df2f8a96f76613a298ce060"); // 2344474
+ consensus.nMinimumChainWork = uint256S("0x000000000000000000000000000000000000000000000977edb0244170858d07");
+ consensus.defaultAssumeValid = uint256S("0x0000000000000021bc50a89cde4870d4a81ffe0153b3c8de77b435a2fd3f6761"); // 2429000
pchMessageStart[0] = 0x0b;
pchMessageStart[1] = 0x11;
@@ -233,7 +233,7 @@ public:
nDefaultPort = 18333;
nPruneAfterHeight = 1000;
m_assumed_blockchain_size = 42;
- m_assumed_chain_state_size = 2;
+ m_assumed_chain_state_size = 3;
genesis = CreateGenesisBlock(1296688602, 414098458, 0x1d00ffff, 1, 50 * COIN);
consensus.hashGenesisBlock = genesis.GetHash();
@@ -274,10 +274,10 @@ public:
};
chainTxData = ChainTxData{
- // Data from RPC: getchaintxstats 4096 0000000000000004877fa2d36316398528de4f347df2f8a96f76613a298ce060
- .nTime = 1661705221,
- .nTxCount = 63531852,
- .dTxRate = 0.1079119341520164,
+ // Data from RPC: getchaintxstats 4096 0000000000000021bc50a89cde4870d4a81ffe0153b3c8de77b435a2fd3f6761
+ .nTime = 1681542696,
+ .nTxCount = 65345929,
+ .dTxRate = 0.09855282814711661,
};
}
};
@@ -300,15 +300,15 @@ public:
vSeeds.emplace_back("178.128.221.177");
vSeeds.emplace_back("v7ajjeirttkbnt32wpy3c6w3emwnfr3fkla7hpxcfokr3ysd3kqtzmqd.onion:38333");
- consensus.nMinimumChainWork = uint256S("0x000000000000000000000000000000000000000000000000000001291fc22898");
- consensus.defaultAssumeValid = uint256S("0x000000d1a0e224fa4679d2fb2187ba55431c284fa1b74cbc8cfda866fd4d2c09"); // 105495
+ consensus.nMinimumChainWork = uint256S("0x000000000000000000000000000000000000000000000000000001899d8142b0");
+ consensus.defaultAssumeValid = uint256S("0x0000004429ef154f7e00b4f6b46bfbe2d2678ecd351d95bbfca437ab9a5b84ec"); // 138000
m_assumed_blockchain_size = 1;
m_assumed_chain_state_size = 0;
chainTxData = ChainTxData{
- // Data from RPC: getchaintxstats 4096 000000d1a0e224fa4679d2fb2187ba55431c284fa1b74cbc8cfda866fd4d2c09
- .nTime = 1661702566,
- .nTxCount = 1903567,
- .dTxRate = 0.02336701143027275,
+ // Data from RPC: getchaintxstats 4096 0000004429ef154f7e00b4f6b46bfbe2d2678ecd351d95bbfca437ab9a5b84ec
+ .nTime = 1681127428,
+ .nTxCount = 2226359,
+ .dTxRate = 0.006424463050600656,
};
} else {
bin = *options.challenge;
diff --git a/src/kernel/mempool_persist.cpp b/src/kernel/mempool_persist.cpp
index a14b2e6163..71f3aac366 100644
--- a/src/kernel/mempool_persist.cpp
+++ b/src/kernel/mempool_persist.cpp
@@ -6,7 +6,6 @@
#include <clientversion.h>
#include <consensus/amount.h>
-#include <fs.h>
#include <logging.h>
#include <primitives/transaction.h>
#include <serialize.h>
@@ -15,7 +14,8 @@
#include <sync.h>
#include <txmempool.h>
#include <uint256.h>
-#include <util/system.h>
+#include <util/fs.h>
+#include <util/fs_helpers.h>
#include <util/time.h>
#include <validation.h>
diff --git a/src/kernel/mempool_persist.h b/src/kernel/mempool_persist.h
index ca4917e38b..cb09119e4a 100644
--- a/src/kernel/mempool_persist.h
+++ b/src/kernel/mempool_persist.h
@@ -5,7 +5,7 @@
#ifndef BITCOIN_KERNEL_MEMPOOL_PERSIST_H
#define BITCOIN_KERNEL_MEMPOOL_PERSIST_H
-#include <fs.h>
+#include <util/fs.h>
class Chainstate;
class CTxMemPool;
diff --git a/src/logging.cpp b/src/logging.cpp
index a9b2a2b33a..7725fefeb7 100644
--- a/src/logging.cpp
+++ b/src/logging.cpp
@@ -3,8 +3,8 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include <fs.h>
#include <logging.h>
+#include <util/fs.h>
#include <util/string.h>
#include <util/threadnames.h>
#include <util/time.h>
@@ -352,7 +352,7 @@ std::string BCLog::Logger::LogTimestampStr(const std::string& str)
const auto now{SystemClock::now()};
const auto now_seconds{std::chrono::time_point_cast<std::chrono::seconds>(now)};
strStamped = FormatISO8601DateTime(TicksSinceEpoch<std::chrono::seconds>(now_seconds));
- if (m_log_time_micros) {
+ if (m_log_time_micros && !strStamped.empty()) {
strStamped.pop_back();
strStamped += strprintf(".%06dZ", Ticks<std::chrono::microseconds>(now - now_seconds));
}
diff --git a/src/logging.h b/src/logging.h
index 954731d214..e7c554e79f 100644
--- a/src/logging.h
+++ b/src/logging.h
@@ -6,9 +6,9 @@
#ifndef BITCOIN_LOGGING_H
#define BITCOIN_LOGGING_H
-#include <fs.h>
#include <threadsafety.h>
#include <tinyformat.h>
+#include <util/fs.h>
#include <util/string.h>
#include <atomic>
diff --git a/src/memusage.h b/src/memusage.h
index 9755be0ff5..bb39066a7d 100644
--- a/src/memusage.h
+++ b/src/memusage.h
@@ -7,6 +7,7 @@
#include <indirectmap.h>
#include <prevector.h>
+#include <support/allocators/pool.h>
#include <cassert>
#include <cstdlib>
@@ -166,6 +167,25 @@ static inline size_t DynamicUsage(const std::unordered_map<X, Y, Z>& m)
return MallocUsage(sizeof(unordered_node<std::pair<const X, Y> >)) * m.size() + MallocUsage(sizeof(void*) * m.bucket_count());
}
+template <class Key, class T, class Hash, class Pred, std::size_t MAX_BLOCK_SIZE_BYTES, std::size_t ALIGN_BYTES>
+static inline size_t DynamicUsage(const std::unordered_map<Key,
+ T,
+ Hash,
+ Pred,
+ PoolAllocator<std::pair<const Key, T>,
+ MAX_BLOCK_SIZE_BYTES,
+ ALIGN_BYTES>>& m)
+{
+ auto* pool_resource = m.get_allocator().resource();
+
+ // The allocated chunks are stored in a std::list. Size per node should
+ // therefore be 3 pointers: next, previous, and a pointer to the chunk.
+ size_t estimated_list_node_size = MallocUsage(sizeof(void*) * 3);
+ size_t usage_resource = estimated_list_node_size * pool_resource->NumAllocatedChunks();
+ size_t usage_chunks = MallocUsage(pool_resource->ChunkSizeBytes()) * pool_resource->NumAllocatedChunks();
+ return usage_resource + usage_chunks + MallocUsage(sizeof(void*) * m.bucket_count());
}
+} // namespace memusage
+
#endif // BITCOIN_MEMUSAGE_H
diff --git a/src/net.cpp b/src/net.cpp
index 59a84f2fdf..337cf60680 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -13,10 +13,10 @@
#include <addrman.h>
#include <banman.h>
#include <clientversion.h>
+#include <common/args.h>
#include <compat/compat.h>
#include <consensus/consensus.h>
#include <crypto/sha256.h>
-#include <fs.h>
#include <i2p.h>
#include <logging.h>
#include <net_permissions.h>
@@ -27,10 +27,10 @@
#include <protocol.h>
#include <random.h>
#include <scheduler.h>
+#include <util/fs.h>
#include <util/sock.h>
#include <util/strencodings.h>
#include <util/syscall_sandbox.h>
-#include <util/system.h>
#include <util/thread.h>
#include <util/threadinterrupt.h>
#include <util/trace.h>
@@ -573,7 +573,10 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
pszDest ? pszDest : "",
conn_type,
/*inbound_onion=*/false,
- CNodeOptions{ .i2p_sam_session = std::move(i2p_transient_session) });
+ CNodeOptions{
+ .i2p_sam_session = std::move(i2p_transient_session),
+ .recv_flood_size = nReceiveFloodSize,
+ });
pnode->AddRef();
// We're making a new connection, harvest entropy from the time (and our peer count)
@@ -917,7 +920,7 @@ bool CConnman::AttemptToEvictConnection()
.m_is_local = node->addr.IsLocal(),
.m_network = node->ConnectedThroughNetwork(),
.m_noban = node->HasPermission(NetPermissionFlags::NoBan),
- .m_conn_type = node->GetConnectionType(),
+ .m_conn_type = node->m_conn_type,
};
vEvictionCandidates.push_back(candidate);
}
@@ -1051,8 +1054,9 @@ void CConnman::CreateNodeFromAcceptedSocket(std::unique_ptr<Sock>&& sock,
ConnectionType::INBOUND,
inbound_onion,
CNodeOptions{
- .permission_flags = permission_flags,
- .prefer_evict = discouraged,
+ .permission_flags = permission_flags,
+ .prefer_evict = discouraged,
+ .recv_flood_size = nReceiveFloodSize,
});
pnode->AddRef();
m_msgproc->InitializeNode(*pnode, nodeServices);
@@ -1092,7 +1096,7 @@ bool CConnman::AddConnection(const std::string& address, ConnectionType conn_typ
// Count existing connections
int existing_connections = WITH_LOCK(m_nodes_mutex,
- return std::count_if(m_nodes.begin(), m_nodes.end(), [conn_type](CNode* node) { return node->GetConnectionType() == conn_type; }););
+ return std::count_if(m_nodes.begin(), m_nodes.end(), [conn_type](CNode* node) { return node->m_conn_type == conn_type; }););
// Max connections of specified type already exist
if (max_connections != std::nullopt && existing_connections >= max_connections) return false;
@@ -1328,7 +1332,7 @@ void CConnman::SocketHandlerConnected(const std::vector<CNode*>& nodes,
}
RecordBytesRecv(nBytes);
if (notify) {
- pnode->MarkReceivedMsgsForProcessing(nReceiveFloodSize);
+ pnode->MarkReceivedMsgsForProcessing();
WakeMessageHandler();
}
}
@@ -1699,10 +1703,11 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
//
CAddress addrConnect;
- // Only connect out to one peer per network group (/16 for IPv4).
+ // Only connect out to one peer per ipv4/ipv6 network group (/16 for IPv4).
int nOutboundFullRelay = 0;
int nOutboundBlockRelay = 0;
- std::set<std::vector<unsigned char> > setConnected;
+ int outbound_privacy_network_peers = 0;
+ std::set<std::vector<unsigned char>> setConnected; // netgroups of our ipv4/ipv6 outbound peers
{
LOCK(m_nodes_mutex);
@@ -1710,8 +1715,8 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
if (pnode->IsFullOutboundConn()) nOutboundFullRelay++;
if (pnode->IsBlockOnlyConn()) nOutboundBlockRelay++;
- // Make sure our persistent outbound slots belong to different netgroups.
- switch (pnode->GetConnectionType()) {
+ // Make sure our persistent outbound slots to ipv4/ipv6 peers belong to different netgroups.
+ switch (pnode->m_conn_type) {
// We currently don't take inbound connections into account. Since they are
// free to make, an attacker could make them to prevent us from connecting to
// certain peers.
@@ -1724,7 +1729,19 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
case ConnectionType::MANUAL:
case ConnectionType::OUTBOUND_FULL_RELAY:
case ConnectionType::BLOCK_RELAY:
- setConnected.insert(m_netgroupman.GetGroup(pnode->addr));
+ CAddress address{pnode->addr};
+ if (address.IsTor() || address.IsI2P() || address.IsCJDNS()) {
+ // Since our addrman-groups for these networks are
+ // random, without relation to the route we
+ // take to connect to these peers or to the
+ // difficulty in obtaining addresses with diverse
+ // groups, we don't worry about diversity with
+ // respect to our addrman groups when connecting to
+ // these networks.
+ ++outbound_privacy_network_peers;
+ } else {
+ setConnected.insert(m_netgroupman.GetGroup(address));
+ }
} // no default case, so the compiler can warn about missing cases
}
}
@@ -1882,8 +1899,11 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
}
LogPrint(BCLog::NET, "Making feeler connection to %s\n", addrConnect.ToStringAddrPort());
}
-
- OpenNetworkConnection(addrConnect, (int)setConnected.size() >= std::min(nMaxConnections - 1, 2), &grant, nullptr, conn_type);
+ // Record addrman failure attempts when node has at least 2 persistent outbound connections to peers with
+ // different netgroups in ipv4/ipv6 networks + all peers in Tor/I2P/CJDNS networks.
+ // Don't record addrman failure attempts when node is offline. This can be identified since all local
+ // network connections(if any) belong in the same netgroup and size of setConnected would only be 1.
+ OpenNetworkConnection(addrConnect, (int)setConnected.size() + outbound_privacy_network_peers >= std::min(nMaxConnections - 1, 2), &grant, nullptr, conn_type);
}
}
}
@@ -2594,6 +2614,11 @@ size_t CConnman::GetNodeCount(ConnectionDirection flags) const
return nNum;
}
+uint32_t CConnman::GetMappedAS(const CNetAddr& addr) const
+{
+ return m_netgroupman.GetMappedAS(addr);
+}
+
void CConnman::GetNodeStats(std::vector<CNodeStats>& vstats) const
{
vstats.clear();
@@ -2602,7 +2627,7 @@ void CConnman::GetNodeStats(std::vector<CNodeStats>& vstats) const
for (CNode* pnode : m_nodes) {
vstats.emplace_back();
pnode->CopyStats(vstats.back());
- vstats.back().m_mapped_as = m_netgroupman.GetMappedAS(pnode->addr);
+ vstats.back().m_mapped_as = GetMappedAS(pnode->addr);
}
}
@@ -2754,8 +2779,6 @@ ServiceFlags CConnman::GetLocalServices() const
return nLocalServices;
}
-unsigned int CConnman::GetReceiveFloodSize() const { return nReceiveFloodSize; }
-
CNode::CNode(NodeId idIn,
std::shared_ptr<Sock> sock,
const CAddress& addrIn,
@@ -2777,9 +2800,10 @@ CNode::CNode(NodeId idIn,
m_inbound_onion{inbound_onion},
m_prefer_evict{node_opts.prefer_evict},
nKeyedNetGroup{nKeyedNetGroupIn},
+ m_conn_type{conn_type_in},
id{idIn},
nLocalHostNonce{nLocalHostNonceIn},
- m_conn_type{conn_type_in},
+ m_recv_flood_size{node_opts.recv_flood_size},
m_i2p_sam_session{std::move(node_opts.i2p_sam_session)}
{
if (inbound_onion) assert(conn_type_in == ConnectionType::INBOUND);
@@ -2795,7 +2819,7 @@ CNode::CNode(NodeId idIn,
}
}
-void CNode::MarkReceivedMsgsForProcessing(unsigned int recv_flood_size)
+void CNode::MarkReceivedMsgsForProcessing()
{
AssertLockNotHeld(m_msg_process_queue_mutex);
@@ -2809,10 +2833,10 @@ void CNode::MarkReceivedMsgsForProcessing(unsigned int recv_flood_size)
LOCK(m_msg_process_queue_mutex);
m_msg_process_queue.splice(m_msg_process_queue.end(), vRecvMsg);
m_msg_process_queue_size += nSizeAdded;
- fPauseRecv = m_msg_process_queue_size > recv_flood_size;
+ fPauseRecv = m_msg_process_queue_size > m_recv_flood_size;
}
-std::optional<std::pair<CNetMessage, bool>> CNode::PollMessage(size_t recv_flood_size)
+std::optional<std::pair<CNetMessage, bool>> CNode::PollMessage()
{
LOCK(m_msg_process_queue_mutex);
if (m_msg_process_queue.empty()) return std::nullopt;
@@ -2821,7 +2845,7 @@ std::optional<std::pair<CNetMessage, bool>> CNode::PollMessage(size_t recv_flood
// Just take one message
msgs.splice(msgs.begin(), m_msg_process_queue, m_msg_process_queue.begin());
m_msg_process_queue_size -= msgs.front().m_raw_message_size;
- fPauseRecv = m_msg_process_queue_size > recv_flood_size;
+ fPauseRecv = m_msg_process_queue_size > m_recv_flood_size;
return std::make_pair(std::move(msgs.front()), !m_msg_process_queue.empty());
}
diff --git a/src/net.h b/src/net.h
index 7bb164003e..908b16f35e 100644
--- a/src/net.h
+++ b/src/net.h
@@ -236,6 +236,14 @@ public:
std::string m_type;
CNetMessage(CDataStream&& recv_in) : m_recv(std::move(recv_in)) {}
+ // Only one CNetMessage object will exist for the same message on either
+ // the receive or processing queue. For performance reasons we therefore
+ // delete the copy constructor and assignment operator to avoid the
+ // possibility of copying CNetMessage objects.
+ CNetMessage(CNetMessage&&) = default;
+ CNetMessage(const CNetMessage&) = delete;
+ CNetMessage& operator=(CNetMessage&&) = default;
+ CNetMessage& operator=(const CNetMessage&) = delete;
void SetVersion(int nVersionIn)
{
@@ -342,6 +350,7 @@ struct CNodeOptions
NetPermissionFlags permission_flags = NetPermissionFlags::None;
std::unique_ptr<i2p::sam::Session> i2p_sam_session = nullptr;
bool prefer_evict = false;
+ size_t recv_flood_size{DEFAULT_MAXRECEIVEBUFFER * 1000};
};
/** Information about a peer */
@@ -410,13 +419,10 @@ public:
std::atomic_bool fPauseRecv{false};
std::atomic_bool fPauseSend{false};
- const ConnectionType& GetConnectionType() const
- {
- return m_conn_type;
- }
+ const ConnectionType m_conn_type;
/** Move all messages from the received queue to the processing queue. */
- void MarkReceivedMsgsForProcessing(unsigned int recv_flood_size)
+ void MarkReceivedMsgsForProcessing()
EXCLUSIVE_LOCKS_REQUIRED(!m_msg_process_queue_mutex);
/** Poll the next message from the processing queue of this connection.
@@ -424,7 +430,7 @@ public:
* Returns std::nullopt if the processing queue is empty, or a pair
* consisting of the message and a bool that indicates if the processing
* queue has more entries. */
- std::optional<std::pair<CNetMessage, bool>> PollMessage(size_t recv_flood_size)
+ std::optional<std::pair<CNetMessage, bool>> PollMessage()
EXCLUSIVE_LOCKS_REQUIRED(!m_msg_process_queue_mutex);
/** Account for the total size of a sent message in the per msg type connection stats. */
@@ -614,9 +620,9 @@ public:
private:
const NodeId id;
const uint64_t nLocalHostNonce;
- const ConnectionType m_conn_type;
std::atomic<int> m_greatest_common_version{INIT_PROTO_VERSION};
+ const size_t m_recv_flood_size;
std::list<CNetMessage> vRecvMsg; // Used only by SocketHandler thread
Mutex m_msg_process_queue_mutex;
@@ -845,6 +851,7 @@ public:
bool AddConnection(const std::string& address, ConnectionType conn_type) EXCLUSIVE_LOCKS_REQUIRED(!m_unused_i2p_sessions_mutex);
size_t GetNodeCount(ConnectionDirection) const;
+ uint32_t GetMappedAS(const CNetAddr& addr) const;
void GetNodeStats(std::vector<CNodeStats>& vstats) const;
bool DisconnectNode(const std::string& node);
bool DisconnectNode(const CSubNet& subnet);
@@ -879,8 +886,6 @@ public:
/** Get a unique deterministic randomizer. */
CSipHasher GetDeterministicRandomizer(uint64_t id) const;
- unsigned int GetReceiveFloodSize() const;
-
void WakeMessageHandler() EXCLUSIVE_LOCKS_REQUIRED(!mutexMsgProc);
/** Return true if we should disconnect the peer for failing an inactivity check. */
diff --git a/src/net_processing.cpp b/src/net_processing.cpp
index 3df5374e21..f5552cfcd8 100644
--- a/src/net_processing.cpp
+++ b/src/net_processing.cpp
@@ -10,6 +10,7 @@
#include <blockencodings.h>
#include <blockfilter.h>
#include <chainparams.h>
+#include <common/args.h>
#include <consensus/amount.h>
#include <consensus/validation.h>
#include <deploymentstatus.h>
@@ -39,7 +40,6 @@
#include <txrequest.h>
#include <util/check.h> // For NDEBUG compile time check
#include <util/strencodings.h>
-#include <util/system.h>
#include <util/trace.h>
#include <validation.h>
@@ -135,7 +135,7 @@ static constexpr double BLOCK_DOWNLOAD_TIMEOUT_PER_PEER = 0.5;
/** Maximum number of headers to announce when relaying blocks with headers message.*/
static const unsigned int MAX_BLOCKS_TO_ANNOUNCE = 8;
/** Maximum number of unconnecting headers announcements before DoS score */
-static const int MAX_UNCONNECTING_HEADERS = 10;
+static const int MAX_NUM_UNCONNECTING_HEADERS_MSGS = 10;
/** Minimum blocks required to signal NODE_NETWORK_LIMITED */
static const unsigned int NODE_NETWORK_LIMITED_MIN_BLOCKS = 288;
/** Average delay between local address broadcasts */
@@ -278,6 +278,9 @@ struct Peer {
/** A bloom filter for which transactions to announce to the peer. See BIP37. */
std::unique_ptr<CBloomFilter> m_bloom_filter PT_GUARDED_BY(m_bloom_filter_mutex) GUARDED_BY(m_bloom_filter_mutex){nullptr};
+ /** A rolling bloom filter of all announced tx CInvs to this peer */
+ CRollingBloomFilter m_recently_announced_invs GUARDED_BY(NetEventsInterface::g_msgproc_mutex){INVENTORY_MAX_RECENT_RELAY, 0.000001};
+
mutable RecursiveMutex m_tx_inventory_mutex;
/** A filter of all the txids and wtxids that the peer has announced to
* us or we have announced to the peer. We use this to avoid announcing
@@ -289,7 +292,8 @@ struct Peer {
* this does not have to be sorted. */
std::set<uint256> m_tx_inventory_to_send GUARDED_BY(m_tx_inventory_mutex);
/** Whether the peer has requested us to send our complete mempool. Only
- * permitted if the peer has NetPermissionFlags::Mempool. See BIP35. */
+ * permitted if the peer has NetPermissionFlags::Mempool or we advertise
+ * NODE_BLOOM. See BIP35. */
bool m_send_mempool GUARDED_BY(m_tx_inventory_mutex){false};
/** The last time a BIP35 `mempool` request was serviced. */
std::atomic<std::chrono::seconds> m_last_mempool_req{0s};
@@ -385,13 +389,22 @@ struct Peer {
/** Whether we've sent our peer a sendheaders message. **/
std::atomic<bool> m_sent_sendheaders{false};
+ /** Length of current-streak of unconnecting headers announcements */
+ int m_num_unconnecting_headers_msgs GUARDED_BY(NetEventsInterface::g_msgproc_mutex){0};
+
+ /** When to potentially disconnect peer for stalling headers download */
+ std::chrono::microseconds m_headers_sync_timeout GUARDED_BY(NetEventsInterface::g_msgproc_mutex){0us};
+
+ /** Whether this peer wants invs or headers (when possible) for block announcements */
+ bool m_prefers_headers GUARDED_BY(NetEventsInterface::g_msgproc_mutex){false};
+
explicit Peer(NodeId id, ServiceFlags our_services)
: m_id{id}
, m_our_services{our_services}
{}
private:
- Mutex m_tx_relay_mutex;
+ mutable Mutex m_tx_relay_mutex;
/** Transaction relay data. May be a nullptr. */
std::unique_ptr<TxRelay> m_tx_relay GUARDED_BY(m_tx_relay_mutex);
@@ -414,12 +427,8 @@ struct CNodeState {
const CBlockIndex* pindexLastCommonBlock{nullptr};
//! The best header we have sent our peer.
const CBlockIndex* pindexBestHeaderSent{nullptr};
- //! Length of current-streak of unconnecting headers announcements
- int nUnconnectingHeaders{0};
//! Whether we've started headers synchronization with this peer.
bool fSyncStarted{false};
- //! When to potentially disconnect peer for stalling headers download
- std::chrono::microseconds m_headers_sync_timeout{0us};
//! Since when we're stalling block download progress (in microseconds), or 0.
std::chrono::microseconds m_stalling_since{0us};
std::list<QueuedBlock> vBlocksInFlight;
@@ -428,8 +437,6 @@ struct CNodeState {
int nBlocksInFlight{0};
//! Whether we consider this a preferred download peer.
bool fPreferredDownload{false};
- //! Whether this peer wants invs or headers (when possible) for block announcements.
- bool fPreferHeaders{false};
/** Whether this peer wants invs or cmpctblocks (when possible) for block announcements. */
bool m_requested_hb_cmpctblocks{false};
/** Whether this peer will send us cmpctblocks if we request them. */
@@ -478,9 +485,6 @@ struct CNodeState {
//! Whether this peer is an inbound connection
const bool m_is_inbound;
- //! A rolling bloom filter of all announced tx CInvs to this peer.
- CRollingBloomFilter m_recently_announced_invs = CRollingBloomFilter{INVENTORY_MAX_RECENT_RELAY, 0.000001};
-
CNodeState(bool is_inbound) : m_is_inbound(is_inbound) {}
};
@@ -666,7 +670,8 @@ private:
/** Potentially fetch blocks from this peer upon receipt of a new headers tip */
void HeadersDirectFetchBlocks(CNode& pfrom, const Peer& peer, const CBlockIndex& last_header);
/** Update peer state based on received headers message */
- void UpdatePeerStateForReceivedHeaders(CNode& pfrom, const CBlockIndex& last_header, bool received_new_header, bool may_have_more_headers);
+ void UpdatePeerStateForReceivedHeaders(CNode& pfrom, Peer& peer, const CBlockIndex& last_header, bool received_new_header, bool may_have_more_headers)
+ EXCLUSIVE_LOCKS_REQUIRED(g_msgproc_mutex);
void SendBlockTransactions(CNode& pfrom, Peer& peer, const CBlock& block, const BlockTransactionsRequest& req);
@@ -900,19 +905,21 @@ private:
std::atomic<std::chrono::seconds> m_last_tip_update{0s};
/** 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);
+ CTransactionRef FindTxForGetData(const Peer::TxRelay& tx_relay, const GenTxid& gtxid, const std::chrono::seconds mempool_req, const std::chrono::seconds now)
+ EXCLUSIVE_LOCKS_REQUIRED(NetEventsInterface::g_msgproc_mutex);
void ProcessGetData(CNode& pfrom, Peer& peer, const std::atomic<bool>& interruptMsgProc)
- EXCLUSIVE_LOCKS_REQUIRED(!m_most_recent_block_mutex, peer.m_getdata_requests_mutex) LOCKS_EXCLUDED(::cs_main);
+ EXCLUSIVE_LOCKS_REQUIRED(!m_most_recent_block_mutex, peer.m_getdata_requests_mutex, NetEventsInterface::g_msgproc_mutex)
+ LOCKS_EXCLUDED(::cs_main);
/** Process a new block. Perform any post-processing housekeeping */
void ProcessBlock(CNode& node, const std::shared_ptr<const CBlock>& block, bool force_processing, bool min_pow_checked);
/** Relay map (txid or wtxid -> CTransactionRef) */
typedef std::map<uint256, CTransactionRef> MapRelay;
- MapRelay mapRelay GUARDED_BY(cs_main);
+ MapRelay mapRelay GUARDED_BY(NetEventsInterface::g_msgproc_mutex);
/** Expiration-time ordered list of (expire time, relay map entry) pairs. */
- std::deque<std::pair<std::chrono::microseconds, MapRelay::iterator>> g_relay_expiration GUARDED_BY(cs_main);
+ std::deque<std::pair<std::chrono::microseconds, MapRelay::iterator>> g_relay_expiration GUARDED_BY(NetEventsInterface::g_msgproc_mutex);
/**
* When a peer sends us a valid block, instruct it to announce blocks to us
@@ -2248,7 +2255,7 @@ void PeerManagerImpl::ProcessGetBlockData(CNode& pfrom, Peer& peer, const CInv&
}
}
-CTransactionRef PeerManagerImpl::FindTxForGetData(const CNode& peer, const GenTxid& gtxid, const std::chrono::seconds mempool_req, const std::chrono::seconds now)
+CTransactionRef PeerManagerImpl::FindTxForGetData(const Peer::TxRelay& tx_relay, const GenTxid& gtxid, const std::chrono::seconds mempool_req, const std::chrono::seconds now)
{
auto txinfo = m_mempool.info(gtxid);
if (txinfo.tx) {
@@ -2260,16 +2267,13 @@ CTransactionRef PeerManagerImpl::FindTxForGetData(const CNode& peer, const GenTx
}
}
- {
- LOCK(cs_main);
- // Otherwise, the transaction must have been announced recently.
- if (State(peer.GetId())->m_recently_announced_invs.contains(gtxid.GetHash())) {
- // If it was, it can be relayed from either the mempool...
- if (txinfo.tx) return std::move(txinfo.tx);
- // ... or the relay pool.
- auto mi = mapRelay.find(gtxid.GetHash());
- if (mi != mapRelay.end()) return mi->second;
- }
+ // Otherwise, the transaction must have been announced recently.
+ if (tx_relay.m_recently_announced_invs.contains(gtxid.GetHash())) {
+ // If it was, it can be relayed from either the mempool...
+ if (txinfo.tx) return std::move(txinfo.tx);
+ // ... or the relay pool.
+ auto mi = mapRelay.find(gtxid.GetHash());
+ if (mi != mapRelay.end()) return mi->second;
}
return {};
@@ -2306,7 +2310,7 @@ void PeerManagerImpl::ProcessGetData(CNode& pfrom, Peer& peer, const std::atomic
continue;
}
- CTransactionRef tx = FindTxForGetData(pfrom, ToGenTxid(inv), mempool_req, now);
+ CTransactionRef tx = FindTxForGetData(*tx_relay, ToGenTxid(inv), mempool_req, now);
if (tx) {
// WTX and WITNESS_TX imply we serialize with witness
int nSendFlags = (inv.IsMsgTx() ? SERIALIZE_TRANSACTION_NO_WITNESS : 0);
@@ -2330,8 +2334,7 @@ void PeerManagerImpl::ProcessGetData(CNode& pfrom, Peer& peer, const std::atomic
for (const uint256& parent_txid : parent_ids_to_add) {
// Relaying a transaction with a recent but unconfirmed parent.
if (WITH_LOCK(tx_relay->m_tx_inventory_mutex, return !tx_relay->m_tx_inventory_known_filter.contains(parent_txid))) {
- LOCK(cs_main);
- State(pfrom.GetId())->m_recently_announced_invs.insert(parent_txid);
+ tx_relay->m_recently_announced_invs.insert(parent_txid);
}
}
} else {
@@ -2430,38 +2433,35 @@ arith_uint256 PeerManagerImpl::GetAntiDoSWorkThreshold()
*
* We'll send a getheaders message in response to try to connect the chain.
*
- * The peer can send up to MAX_UNCONNECTING_HEADERS in a row that
+ * The peer can send up to MAX_NUM_UNCONNECTING_HEADERS_MSGS in a row that
* don't connect before given DoS points.
*
* Once a headers message is received that is valid and does connect,
- * nUnconnectingHeaders gets reset back to 0.
+ * m_num_unconnecting_headers_msgs gets reset back to 0.
*/
void PeerManagerImpl::HandleFewUnconnectingHeaders(CNode& pfrom, Peer& peer,
const std::vector<CBlockHeader>& headers)
{
- const CNetMsgMaker msgMaker(pfrom.GetCommonVersion());
-
- LOCK(cs_main);
- CNodeState *nodestate = State(pfrom.GetId());
-
- nodestate->nUnconnectingHeaders++;
+ peer.m_num_unconnecting_headers_msgs++;
// Try to fill in the missing headers.
- if (MaybeSendGetHeaders(pfrom, GetLocator(m_chainman.m_best_header), peer)) {
- LogPrint(BCLog::NET, "received header %s: missing prev block %s, sending getheaders (%d) to end (peer=%d, nUnconnectingHeaders=%d)\n",
+ const CBlockIndex* best_header{WITH_LOCK(cs_main, return m_chainman.m_best_header)};
+ if (MaybeSendGetHeaders(pfrom, GetLocator(best_header), peer)) {
+ LogPrint(BCLog::NET, "received header %s: missing prev block %s, sending getheaders (%d) to end (peer=%d, m_num_unconnecting_headers_msgs=%d)\n",
headers[0].GetHash().ToString(),
headers[0].hashPrevBlock.ToString(),
- m_chainman.m_best_header->nHeight,
- pfrom.GetId(), nodestate->nUnconnectingHeaders);
+ best_header->nHeight,
+ pfrom.GetId(), peer.m_num_unconnecting_headers_msgs);
}
+
// Set hashLastUnknownBlock for this peer, so that if we
// eventually get the headers - even from a different peer -
// we can use this peer to download.
- UpdateBlockAvailability(pfrom.GetId(), headers.back().GetHash());
+ WITH_LOCK(cs_main, UpdateBlockAvailability(pfrom.GetId(), headers.back().GetHash()));
// The peer may just be broken, so periodically assign DoS points if this
// condition persists.
- if (nodestate->nUnconnectingHeaders % MAX_UNCONNECTING_HEADERS == 0) {
- Misbehaving(peer, 20, strprintf("%d non-connecting headers", nodestate->nUnconnectingHeaders));
+ if (peer.m_num_unconnecting_headers_msgs % MAX_NUM_UNCONNECTING_HEADERS_MSGS == 0) {
+ Misbehaving(peer, 20, strprintf("%d non-connecting headers", peer.m_num_unconnecting_headers_msgs));
}
}
@@ -2709,15 +2709,16 @@ void PeerManagerImpl::HeadersDirectFetchBlocks(CNode& pfrom, const Peer& peer, c
* whether that header was new and whether the headers message was full,
* update the state we keep for the peer.
*/
-void PeerManagerImpl::UpdatePeerStateForReceivedHeaders(CNode& pfrom,
+void PeerManagerImpl::UpdatePeerStateForReceivedHeaders(CNode& pfrom, Peer& peer,
const CBlockIndex& last_header, bool received_new_header, bool may_have_more_headers)
{
+ if (peer.m_num_unconnecting_headers_msgs > 0) {
+ LogPrint(BCLog::NET, "peer=%d: resetting m_num_unconnecting_headers_msgs (%d -> 0)\n", pfrom.GetId(), peer.m_num_unconnecting_headers_msgs);
+ }
+ peer.m_num_unconnecting_headers_msgs = 0;
+
LOCK(cs_main);
CNodeState *nodestate = State(pfrom.GetId());
- if (nodestate->nUnconnectingHeaders > 0) {
- LogPrint(BCLog::NET, "peer=%d: resetting nUnconnectingHeaders (%d -> 0)\n", pfrom.GetId(), nodestate->nUnconnectingHeaders);
- }
- nodestate->nUnconnectingHeaders = 0;
UpdateBlockAvailability(pfrom.GetId(), last_header.GetBlockHash());
@@ -2902,7 +2903,7 @@ void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, Peer& peer,
}
}
- UpdatePeerStateForReceivedHeaders(pfrom, *pindexLast, received_new_header, nCount == MAX_HEADERS_RESULTS);
+ UpdatePeerStateForReceivedHeaders(pfrom, peer, *pindexLast, received_new_header, nCount == MAX_HEADERS_RESULTS);
// Consider immediately downloading blocks.
HeadersDirectFetchBlocks(pfrom, peer, *pindexLast);
@@ -3296,11 +3297,13 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
if (greatest_common_version >= WTXID_RELAY_VERSION && m_txreconciliation) {
// Per BIP-330, we announce txreconciliation support if:
// - protocol version per the peer's VERSION message supports WTXID_RELAY;
- // - transaction relay is supported per the peer's VERSION message (see m_relays_txs);
- // - this is not a block-relay-only connection and not a feeler (see m_relays_txs);
+ // - transaction relay is supported per the peer's VERSION message
+ // - this is not a block-relay-only connection and not a feeler
// - this is not an addr fetch connection;
// - we are not in -blocksonly mode.
- if (pfrom.m_relays_txs && !pfrom.IsAddrFetchConn() && !m_ignore_incoming_txs) {
+ const auto* tx_relay = peer->GetTxRelay();
+ if (tx_relay && WITH_LOCK(tx_relay->m_bloom_filter_mutex, return tx_relay->m_relay_txs) &&
+ !pfrom.IsAddrFetchConn() && !m_ignore_incoming_txs) {
const uint64_t recon_salt = m_txreconciliation->PreRegisterPeer(pfrom.GetId());
m_connman.PushMessage(&pfrom, msg_maker.Make(NetMsgType::SENDTXRCNCL,
TXRECONCILIATION_VERSION, recon_salt));
@@ -3360,10 +3363,11 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
if (fLogIPs)
remoteAddr = ", peeraddr=" + pfrom.addr.ToStringAddrPort();
- LogPrint(BCLog::NET, "receive version message: %s: version %d, blocks=%d, us=%s, txrelay=%d, peer=%d%s\n",
+ const auto mapped_as{m_connman.GetMappedAS(pfrom.addr)};
+ LogPrint(BCLog::NET, "receive version message: %s: version %d, blocks=%d, us=%s, txrelay=%d, peer=%d%s%s\n",
cleanSubVer, pfrom.nVersion,
peer->m_starting_height, addrMe.ToStringAddrPort(), fRelay, pfrom.GetId(),
- remoteAddr);
+ remoteAddr, (mapped_as ? strprintf(", mapped_as=%d", mapped_as) : ""));
int64_t nTimeOffset = nTime - GetTime();
pfrom.nTimeOffset = nTimeOffset;
@@ -3403,9 +3407,11 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
}
if (!pfrom.IsInboundConn()) {
- LogPrintf("New outbound peer connected: version: %d, blocks=%d, peer=%d%s (%s)\n",
+ const auto mapped_as{m_connman.GetMappedAS(pfrom.addr)};
+ LogPrintf("New outbound peer connected: version: %d, blocks=%d, peer=%d%s%s (%s)\n",
pfrom.nVersion.load(), peer->m_starting_height,
pfrom.GetId(), (fLogIPs ? strprintf(", peeraddr=%s", pfrom.addr.ToStringAddrPort()) : ""),
+ (mapped_as ? strprintf(", mapped_as=%d", mapped_as) : ""),
pfrom.ConnectionTypeAsString());
}
@@ -3446,8 +3452,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
}
if (msg_type == NetMsgType::SENDHEADERS) {
- LOCK(cs_main);
- State(pfrom.GetId())->fPreferHeaders = true;
+ peer->m_prefers_headers = true;
return;
}
@@ -3529,7 +3534,8 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
// Peer must not offer us reconciliations if they specified no tx relay support in VERSION.
// This flag might also be false in other cases, but the RejectIncomingTxs check above
// eliminates them, so that this flag fully represents what we are looking for.
- if (!pfrom.m_relays_txs) {
+ const auto* tx_relay = peer->GetTxRelay();
+ if (!tx_relay || !WITH_LOCK(tx_relay->m_bloom_filter_mutex, return tx_relay->m_relay_txs)) {
LogPrintLevel(BCLog::NET, BCLog::Level::Debug, "sendtxrcncl received from peer=%d which indicated no tx relay to us; disconnecting\n", pfrom.GetId());
pfrom.fDisconnect = true;
return;
@@ -4595,6 +4601,8 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
}
if (msg_type == NetMsgType::MEMPOOL) {
+ // Only process received mempool messages if we advertise NODE_BLOOM
+ // or if the peer has mempool permissions.
if (!(peer->m_our_services & NODE_BLOOM) && !pfrom.HasPermission(NetPermissionFlags::Mempool))
{
if (!pfrom.HasPermission(NetPermissionFlags::NoBan))
@@ -4887,7 +4895,7 @@ bool PeerManagerImpl::ProcessMessages(CNode* pfrom, std::atomic<bool>& interrupt
// Don't bother if send buffer is too full to respond anyway
if (pfrom->fPauseSend) return false;
- auto poll_result{pfrom->PollMessage(m_connman.GetReceiveFloodSize())};
+ auto poll_result{pfrom->PollMessage()};
if (!poll_result) {
// No message to process
return false;
@@ -4938,7 +4946,6 @@ void PeerManagerImpl::ConsiderEviction(CNode& pto, Peer& peer, std::chrono::seco
AssertLockHeld(cs_main);
CNodeState &state = *State(pto.GetId());
- const CNetMsgMaker msgMaker(pto.GetCommonVersion());
if (!state.m_chain_sync.m_protect && pto.IsOutboundOrBlockRelayConn() && state.fSyncStarted) {
// This is an outbound peer subject to disconnection if they don't
@@ -5429,7 +5436,7 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
LogPrint(BCLog::NET, "initial getheaders (%d) to peer=%d (startheight:%d)\n", pindexStart->nHeight, pto->GetId(), peer->m_starting_height);
state.fSyncStarted = true;
- state.m_headers_sync_timeout = current_time + HEADERS_DOWNLOAD_TIMEOUT_BASE +
+ peer->m_headers_sync_timeout = current_time + HEADERS_DOWNLOAD_TIMEOUT_BASE +
(
// Convert HEADERS_DOWNLOAD_TIMEOUT_PER_HEADER to microseconds before scaling
// to maintain precision
@@ -5454,7 +5461,7 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
// add all to the inv queue.
LOCK(peer->m_block_inv_mutex);
std::vector<CBlock> vHeaders;
- bool fRevertToInv = ((!state.fPreferHeaders &&
+ bool fRevertToInv = ((!peer->m_prefers_headers &&
(!state.m_requested_hb_cmpctblocks || peer->m_blocks_for_headers_relay.size() > 1)) ||
peer->m_blocks_for_headers_relay.size() > MAX_BLOCKS_TO_ANNOUNCE);
const CBlockIndex *pBestIndex = nullptr; // last header queued for delivery
@@ -5531,7 +5538,7 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
m_connman.PushMessage(pto, msgMaker.Make(NetMsgType::CMPCTBLOCK, cmpctblock));
}
state.pindexBestHeaderSent = pBestIndex;
- } else if (state.fPreferHeaders) {
+ } else if (peer->m_prefers_headers) {
if (vHeaders.size() > 1) {
LogPrint(BCLog::NET, "%s: %u headers, range (%s, %s), to peer=%d\n", __func__,
vHeaders.size(),
@@ -5685,7 +5692,7 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
}
if (tx_relay->m_bloom_filter && !tx_relay->m_bloom_filter->IsRelevantAndUpdate(*txinfo.tx)) continue;
// Send
- State(pto->GetId())->m_recently_announced_invs.insert(hash);
+ tx_relay->m_recently_announced_invs.insert(hash);
vInv.push_back(inv);
nRelayedTransactions++;
{
@@ -5756,10 +5763,10 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
}
}
// Check for headers sync timeouts
- if (state.fSyncStarted && state.m_headers_sync_timeout < std::chrono::microseconds::max()) {
+ if (state.fSyncStarted && peer->m_headers_sync_timeout < std::chrono::microseconds::max()) {
// Detect whether this is a stalling initial-headers-sync peer
if (m_chainman.m_best_header->Time() <= GetAdjustedTime() - 24h) {
- if (current_time > state.m_headers_sync_timeout && nSyncStarted == 1 && (m_num_preferred_download_peers - state.fPreferredDownload >= 1)) {
+ if (current_time > peer->m_headers_sync_timeout && nSyncStarted == 1 && (m_num_preferred_download_peers - state.fPreferredDownload >= 1)) {
// Disconnect a peer (without NetPermissionFlags::NoBan permission) if it is our only sync peer,
// and we have others we could be using instead.
// Note: If all our peers are inbound, then we won't
@@ -5778,13 +5785,13 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
// this peer (eventually).
state.fSyncStarted = false;
nSyncStarted--;
- state.m_headers_sync_timeout = 0us;
+ peer->m_headers_sync_timeout = 0us;
}
}
} else {
// After we've caught up once, reset the timeout so we can't trigger
// disconnect later.
- state.m_headers_sync_timeout = std::chrono::microseconds::max();
+ peer->m_headers_sync_timeout = std::chrono::microseconds::max();
}
}
diff --git a/src/node/blockmanager_args.cpp b/src/node/blockmanager_args.cpp
index 5fb5c8beed..06a1934947 100644
--- a/src/node/blockmanager_args.cpp
+++ b/src/node/blockmanager_args.cpp
@@ -4,7 +4,7 @@
#include <node/blockmanager_args.h>
-#include <util/system.h>
+#include <common/args.h>
#include <validation.h>
namespace node {
diff --git a/src/node/blockstorage.cpp b/src/node/blockstorage.cpp
index 53721b807c..abd71ca50b 100644
--- a/src/node/blockstorage.cpp
+++ b/src/node/blockstorage.cpp
@@ -6,18 +6,19 @@
#include <chain.h>
#include <clientversion.h>
+#include <common/args.h>
#include <consensus/validation.h>
#include <flatfile.h>
-#include <fs.h>
#include <hash.h>
-#include <logging.h>
#include <kernel/chainparams.h>
+#include <logging.h>
#include <pow.h>
#include <reverse_iterator.h>
#include <shutdown.h>
#include <signet.h>
#include <streams.h>
#include <undo.h>
+#include <util/fs.h>
#include <util/syscall_sandbox.h>
#include <util/system.h>
#include <validation.h>
@@ -619,7 +620,18 @@ bool BlockManager::FindBlockPos(FlatFilePos& pos, unsigned int nAddSize, unsigne
bool finalize_undo = false;
if (!fKnown) {
- while (m_blockfile_info[nFile].nSize + nAddSize >= (gArgs.GetBoolArg("-fastprune", false) ? 0x10000 /* 64kb */ : MAX_BLOCKFILE_SIZE)) {
+ unsigned int max_blockfile_size{MAX_BLOCKFILE_SIZE};
+ // Use smaller blockfiles in test-only -fastprune mode - but avoid
+ // the possibility of having a block not fit into the block file.
+ if (gArgs.GetBoolArg("-fastprune", false)) {
+ max_blockfile_size = 0x10000; // 64kiB
+ if (nAddSize >= max_blockfile_size) {
+ // dynamically adjust the blockfile size to be larger than the added size
+ max_blockfile_size = nAddSize + 1;
+ }
+ }
+ assert(nAddSize < max_blockfile_size);
+ while (m_blockfile_info[nFile].nSize + nAddSize >= max_blockfile_size) {
// when the undo file is keeping up with the block file, we want to flush it explicitly
// when it is lagging behind (more blocks arrive than are being connected), we let the
// undo block write case handle it
diff --git a/src/node/blockstorage.h b/src/node/blockstorage.h
index 5ba0045b8b..3eb27cc72d 100644
--- a/src/node/blockstorage.h
+++ b/src/node/blockstorage.h
@@ -7,12 +7,12 @@
#include <attributes.h>
#include <chain.h>
-#include <fs.h>
#include <kernel/blockmanager_opts.h>
#include <kernel/cs_main.h>
#include <protocol.h>
#include <sync.h>
#include <txdb.h>
+#include <util/fs.h>
#include <atomic>
#include <cstdint>
diff --git a/src/node/caches.cpp b/src/node/caches.cpp
index 7622a03e19..7403f7ddea 100644
--- a/src/node/caches.cpp
+++ b/src/node/caches.cpp
@@ -4,9 +4,9 @@
#include <node/caches.h>
+#include <common/args.h>
#include <index/txindex.h>
#include <txdb.h>
-#include <util/system.h>
namespace node {
CacheSizes CalculateCacheSizes(const ArgsManager& args, size_t n_indexes)
diff --git a/src/node/chainstate.cpp b/src/node/chainstate.cpp
index cfd3472592..f60ff83a0d 100644
--- a/src/node/chainstate.cpp
+++ b/src/node/chainstate.cpp
@@ -16,6 +16,7 @@
#include <tinyformat.h>
#include <txdb.h>
#include <uint256.h>
+#include <util/fs.h>
#include <util/time.h>
#include <util/translation.h>
#include <validation.h>
diff --git a/src/node/chainstatemanager_args.cpp b/src/node/chainstatemanager_args.cpp
index 9801e6e959..b97344c9aa 100644
--- a/src/node/chainstatemanager_args.cpp
+++ b/src/node/chainstatemanager_args.cpp
@@ -5,13 +5,13 @@
#include <node/chainstatemanager_args.h>
#include <arith_uint256.h>
+#include <common/args.h>
#include <kernel/chainstatemanager_opts.h>
#include <node/coins_view_args.h>
#include <node/database_args.h>
#include <tinyformat.h>
#include <uint256.h>
#include <util/strencodings.h>
-#include <util/system.h>
#include <util/translation.h>
#include <validation.h>
diff --git a/src/node/coins_view_args.cpp b/src/node/coins_view_args.cpp
index 67c9b8dbac..5d55143e83 100644
--- a/src/node/coins_view_args.cpp
+++ b/src/node/coins_view_args.cpp
@@ -4,8 +4,8 @@
#include <node/coins_view_args.h>
+#include <common/args.h>
#include <txdb.h>
-#include <util/system.h>
namespace node {
void ReadCoinsViewArgs(const ArgsManager& args, CoinsViewOptions& options)
diff --git a/src/node/database_args.cpp b/src/node/database_args.cpp
index 2c53b4b47e..aba3c38ff3 100644
--- a/src/node/database_args.cpp
+++ b/src/node/database_args.cpp
@@ -4,8 +4,8 @@
#include <node/database_args.h>
+#include <common/args.h>
#include <dbwrapper.h>
-#include <util/system.h>
namespace node {
void ReadDatabaseArgs(const ArgsManager& args, DBOptions& options)
diff --git a/src/node/interfaces.cpp b/src/node/interfaces.cpp
index b397661df4..5fcace833f 100644
--- a/src/node/interfaces.cpp
+++ b/src/node/interfaces.cpp
@@ -7,6 +7,7 @@
#include <blockfilter.h>
#include <chain.h>
#include <chainparams.h>
+#include <common/args.h>
#include <deploymentstatus.h>
#include <external_signer.h>
#include <index/blockfilterindex.h>
@@ -43,7 +44,6 @@
#include <uint256.h>
#include <univalue.h>
#include <util/check.h>
-#include <util/system.h>
#include <util/translation.h>
#include <validation.h>
#include <validationinterface.h>
@@ -241,6 +241,7 @@ public:
if (command == "") return {};
ExternalSigner::Enumerate(command, signers, Params().NetworkIDString());
std::vector<std::unique_ptr<interfaces::ExternalSigner>> result;
+ result.reserve(signers.size());
for (auto& signer : signers) {
result.emplace_back(std::make_unique<ExternalSignerImpl>(std::move(signer)));
}
diff --git a/src/node/mempool_args.cpp b/src/node/mempool_args.cpp
index a0a2e43107..f193469506 100644
--- a/src/node/mempool_args.cpp
+++ b/src/node/mempool_args.cpp
@@ -7,6 +7,7 @@
#include <kernel/mempool_limits.h>
#include <kernel/mempool_options.h>
+#include <common/args.h>
#include <consensus/amount.h>
#include <kernel/chainparams.h>
#include <logging.h>
@@ -16,7 +17,6 @@
#include <tinyformat.h>
#include <util/error.h>
#include <util/moneystr.h>
-#include <util/system.h>
#include <util/translation.h>
#include <chrono>
diff --git a/src/node/mempool_persist_args.cpp b/src/node/mempool_persist_args.cpp
index 4e775869c6..97ecdd651b 100644
--- a/src/node/mempool_persist_args.cpp
+++ b/src/node/mempool_persist_args.cpp
@@ -4,8 +4,8 @@
#include <node/mempool_persist_args.h>
-#include <fs.h>
-#include <util/system.h>
+#include <common/args.h>
+#include <util/fs.h>
#include <validation.h>
namespace node {
diff --git a/src/node/mempool_persist_args.h b/src/node/mempool_persist_args.h
index f719ec62ab..3b101f0930 100644
--- a/src/node/mempool_persist_args.h
+++ b/src/node/mempool_persist_args.h
@@ -5,7 +5,7 @@
#ifndef BITCOIN_NODE_MEMPOOL_PERSIST_ARGS_H
#define BITCOIN_NODE_MEMPOOL_PERSIST_ARGS_H
-#include <fs.h>
+#include <util/fs.h>
class ArgsManager;
diff --git a/src/node/miner.cpp b/src/node/miner.cpp
index c7bc9a9a3d..aa1a9a155c 100644
--- a/src/node/miner.cpp
+++ b/src/node/miner.cpp
@@ -8,6 +8,7 @@
#include <chain.h>
#include <chainparams.h>
#include <coins.h>
+#include <common/args.h>
#include <consensus/amount.h>
#include <consensus/consensus.h>
#include <consensus/merkle.h>
@@ -20,7 +21,6 @@
#include <primitives/transaction.h>
#include <timedata.h>
#include <util/moneystr.h>
-#include <util/system.h>
#include <validation.h>
#include <algorithm>
diff --git a/src/node/txreconciliation.cpp b/src/node/txreconciliation.cpp
index ed04a78cec..9938759074 100644
--- a/src/node/txreconciliation.cpp
+++ b/src/node/txreconciliation.cpp
@@ -4,6 +4,7 @@
#include <node/txreconciliation.h>
+#include <logging.h>
#include <util/check.h>
#include <util/system.h>
diff --git a/src/node/utxo_snapshot.cpp b/src/node/utxo_snapshot.cpp
index cccf95e552..3dae46fb84 100644
--- a/src/node/utxo_snapshot.cpp
+++ b/src/node/utxo_snapshot.cpp
@@ -4,14 +4,14 @@
#include <node/utxo_snapshot.h>
-#include <fs.h>
+#include <common/args.h>
#include <logging.h>
#include <streams.h>
#include <sync.h>
#include <tinyformat.h>
#include <txdb.h>
#include <uint256.h>
-#include <util/system.h>
+#include <util/fs.h>
#include <validation.h>
#include <cassert>
diff --git a/src/node/utxo_snapshot.h b/src/node/utxo_snapshot.h
index c5c018c9e8..44ddd77dc3 100644
--- a/src/node/utxo_snapshot.h
+++ b/src/node/utxo_snapshot.h
@@ -6,11 +6,11 @@
#ifndef BITCOIN_NODE_UTXO_SNAPSHOT_H
#define BITCOIN_NODE_UTXO_SNAPSHOT_H
-#include <fs.h>
#include <kernel/cs_main.h>
#include <serialize.h>
#include <sync.h>
#include <uint256.h>
+#include <util/fs.h>
#include <cstdint>
#include <optional>
diff --git a/src/node/validation_cache_args.cpp b/src/node/validation_cache_args.cpp
index 5ea0a8ca0a..ddf24f798d 100644
--- a/src/node/validation_cache_args.cpp
+++ b/src/node/validation_cache_args.cpp
@@ -6,7 +6,7 @@
#include <kernel/validation_cache_sizes.h>
-#include <util/system.h>
+#include <common/args.h>
#include <algorithm>
#include <cstddef>
diff --git a/src/outputtype.cpp b/src/outputtype.cpp
index 270212dca5..9a3870d8dc 100644
--- a/src/outputtype.cpp
+++ b/src/outputtype.cpp
@@ -32,8 +32,6 @@ std::optional<OutputType> ParseOutputType(const std::string& type)
return OutputType::BECH32;
} else if (type == OUTPUT_TYPE_STRING_BECH32M) {
return OutputType::BECH32M;
- } else if (type == OUTPUT_TYPE_STRING_UNKNOWN) {
- return OutputType::UNKNOWN;
}
return std::nullopt;
}
diff --git a/src/policy/fees.cpp b/src/policy/fees.cpp
index d244de1bb2..6121224979 100644
--- a/src/policy/fees.cpp
+++ b/src/policy/fees.cpp
@@ -7,7 +7,6 @@
#include <clientversion.h>
#include <consensus/amount.h>
-#include <fs.h>
#include <kernel/mempool_entry.h>
#include <logging.h>
#include <policy/feerate.h>
@@ -18,6 +17,7 @@
#include <sync.h>
#include <tinyformat.h>
#include <uint256.h>
+#include <util/fs.h>
#include <util/serfloat.h>
#include <util/system.h>
#include <util/time.h>
diff --git a/src/policy/fees.h b/src/policy/fees.h
index 1c24b8c7c3..775a72a764 100644
--- a/src/policy/fees.h
+++ b/src/policy/fees.h
@@ -6,12 +6,12 @@
#define BITCOIN_POLICY_FEES_H
#include <consensus/amount.h>
-#include <fs.h>
#include <policy/feerate.h>
#include <random.h>
#include <sync.h>
#include <threadsafety.h>
#include <uint256.h>
+#include <util/fs.h>
#include <array>
#include <map>
diff --git a/src/policy/fees_args.cpp b/src/policy/fees_args.cpp
index 1aeb2ab983..988b6d443a 100644
--- a/src/policy/fees_args.cpp
+++ b/src/policy/fees_args.cpp
@@ -4,7 +4,7 @@
#include <policy/fees_args.h>
-#include <util/system.h>
+#include <common/args.h>
namespace {
const char* FEE_ESTIMATES_FILENAME = "fee_estimates.dat";
diff --git a/src/policy/fees_args.h b/src/policy/fees_args.h
index 6b65ce0aa9..ef5cf144af 100644
--- a/src/policy/fees_args.h
+++ b/src/policy/fees_args.h
@@ -5,7 +5,7 @@
#ifndef BITCOIN_POLICY_FEES_ARGS_H
#define BITCOIN_POLICY_FEES_ARGS_H
-#include <fs.h>
+#include <util/fs.h>
class ArgsManager;
diff --git a/src/protocol.cpp b/src/protocol.cpp
index aa59bae6ff..5725813b7e 100644
--- a/src/protocol.cpp
+++ b/src/protocol.cpp
@@ -7,6 +7,8 @@
#include <util/system.h>
+#include <atomic>
+
static std::atomic<bool> g_initial_block_download_completed(false);
namespace NetMsgType {
diff --git a/src/psbt.cpp b/src/psbt.cpp
index fe45f2318c..009ed966ed 100644
--- a/src/psbt.cpp
+++ b/src/psbt.cpp
@@ -442,6 +442,38 @@ bool SignPSBTInput(const SigningProvider& provider, PartiallySignedTransaction&
return sig_complete;
}
+void RemoveUnnecessaryTransactions(PartiallySignedTransaction& psbtx, const int& sighash_type)
+{
+ // Only drop non_witness_utxos if sighash_type != SIGHASH_ANYONECANPAY
+ if ((sighash_type & 0x80) != SIGHASH_ANYONECANPAY) {
+ // Figure out if any non_witness_utxos should be dropped
+ std::vector<unsigned int> to_drop;
+ for (unsigned int i = 0; i < psbtx.inputs.size(); ++i) {
+ const auto& input = psbtx.inputs.at(i);
+ int wit_ver;
+ std::vector<unsigned char> wit_prog;
+ if (input.witness_utxo.IsNull() || !input.witness_utxo.scriptPubKey.IsWitnessProgram(wit_ver, wit_prog)) {
+ // There's a non-segwit input or Segwit v0, so we cannot drop any witness_utxos
+ to_drop.clear();
+ break;
+ }
+ if (wit_ver == 0) {
+ // Segwit v0, so we cannot drop any non_witness_utxos
+ to_drop.clear();
+ break;
+ }
+ if (input.non_witness_utxo) {
+ to_drop.push_back(i);
+ }
+ }
+
+ // Drop the non_witness_utxos that we can drop
+ for (unsigned int i : to_drop) {
+ psbtx.inputs.at(i).non_witness_utxo = nullptr;
+ }
+ }
+}
+
bool FinalizePSBT(PartiallySignedTransaction& psbtx)
{
// Finalize input signatures -- in case we have partial signatures that add up to a complete
diff --git a/src/psbt.h b/src/psbt.h
index c497584f36..9464b10268 100644
--- a/src/psbt.h
+++ b/src/psbt.h
@@ -1231,6 +1231,9 @@ bool PSBTInputSignedAndVerified(const PartiallySignedTransaction psbt, unsigned
**/
bool SignPSBTInput(const SigningProvider& provider, PartiallySignedTransaction& psbt, int index, const PrecomputedTransactionData* txdata, int sighash = SIGHASH_ALL, SignatureData* out_sigdata = nullptr, bool finalize = true);
+/** Reduces the size of the PSBT by dropping unnecessary `non_witness_utxos` (i.e. complete previous transactions) from a psbt when all inputs are segwit v1. */
+void RemoveUnnecessaryTransactions(PartiallySignedTransaction& psbtx, const int& sighash_type);
+
/** Counts the unsigned inputs of a PSBT. */
size_t CountPSBTUnsignedInputs(const PartiallySignedTransaction& psbt);
diff --git a/src/qt/addresstablemodel.cpp b/src/qt/addresstablemodel.cpp
index e402c51ac4..0d0f1a4d15 100644
--- a/src/qt/addresstablemodel.cpp
+++ b/src/qt/addresstablemodel.cpp
@@ -8,6 +8,7 @@
#include <qt/walletmodel.h>
#include <key_io.h>
+#include <wallet/types.h>
#include <wallet/wallet.h>
#include <algorithm>
@@ -52,17 +53,16 @@ struct AddressTableEntryLessThan
};
/* Determine address type from address purpose */
-static AddressTableEntry::Type translateTransactionType(const QString &strPurpose, bool isMine)
+static AddressTableEntry::Type translateTransactionType(wallet::AddressPurpose purpose, bool isMine)
{
- AddressTableEntry::Type addressType = AddressTableEntry::Hidden;
// "refund" addresses aren't shown, and change addresses aren't returned by getAddresses at all.
- if (strPurpose == "send")
- addressType = AddressTableEntry::Sending;
- else if (strPurpose == "receive")
- addressType = AddressTableEntry::Receiving;
- else if (strPurpose == "unknown" || strPurpose == "") // if purpose not set, guess
- addressType = (isMine ? AddressTableEntry::Receiving : AddressTableEntry::Sending);
- return addressType;
+ switch (purpose) {
+ case wallet::AddressPurpose::SEND: return AddressTableEntry::Sending;
+ case wallet::AddressPurpose::RECEIVE: return AddressTableEntry::Receiving;
+ case wallet::AddressPurpose::REFUND: return AddressTableEntry::Hidden;
+ // No default case to allow for compiler to warn
+ }
+ assert(false);
}
// Private implementation
@@ -85,7 +85,7 @@ public:
continue;
}
AddressTableEntry::Type addressType = translateTransactionType(
- QString::fromStdString(address.purpose), address.is_mine);
+ address.purpose, address.is_mine);
cachedAddressTable.append(AddressTableEntry(addressType,
QString::fromStdString(address.name),
QString::fromStdString(EncodeDestination(address.dest))));
@@ -97,7 +97,7 @@ public:
std::sort(cachedAddressTable.begin(), cachedAddressTable.end(), AddressTableEntryLessThan());
}
- void updateEntry(const QString &address, const QString &label, bool isMine, const QString &purpose, int status)
+ void updateEntry(const QString &address, const QString &label, bool isMine, wallet::AddressPurpose purpose, int status)
{
// Find address / label in model
QList<AddressTableEntry>::iterator lower = std::lower_bound(
@@ -239,7 +239,7 @@ bool AddressTableModel::setData(const QModelIndex &index, const QVariant &value,
if(!index.isValid())
return false;
AddressTableEntry *rec = static_cast<AddressTableEntry*>(index.internalPointer());
- std::string strPurpose = (rec->type == AddressTableEntry::Sending ? "send" : "receive");
+ wallet::AddressPurpose purpose = rec->type == AddressTableEntry::Sending ? wallet::AddressPurpose::SEND : wallet::AddressPurpose::RECEIVE;
editStatus = OK;
if(role == Qt::EditRole)
@@ -253,7 +253,7 @@ bool AddressTableModel::setData(const QModelIndex &index, const QVariant &value,
editStatus = NO_CHANGES;
return false;
}
- walletModel->wallet().setAddressBook(curAddress, value.toString().toStdString(), strPurpose);
+ walletModel->wallet().setAddressBook(curAddress, value.toString().toStdString(), purpose);
} else if(index.column() == Address) {
CTxDestination newAddress = DecodeDestination(value.toString().toStdString());
// Refuse to set invalid address, set error status and return false
@@ -282,7 +282,7 @@ bool AddressTableModel::setData(const QModelIndex &index, const QVariant &value,
// Remove old entry
walletModel->wallet().delAddressBook(curAddress);
// Add new entry with new address
- walletModel->wallet().setAddressBook(newAddress, value.toString().toStdString(), strPurpose);
+ walletModel->wallet().setAddressBook(newAddress, value.toString().toStdString(), purpose);
}
}
return true;
@@ -334,7 +334,7 @@ QModelIndex AddressTableModel::index(int row, int column, const QModelIndex &par
}
void AddressTableModel::updateEntry(const QString &address,
- const QString &label, bool isMine, const QString &purpose, int status)
+ const QString &label, bool isMine, wallet::AddressPurpose purpose, int status)
{
// Update address book model from Bitcoin core
priv->updateEntry(address, label, isMine, purpose, status);
@@ -365,7 +365,7 @@ QString AddressTableModel::addRow(const QString &type, const QString &label, con
}
// Add entry
- walletModel->wallet().setAddressBook(DecodeDestination(strAddress), strLabel, "send");
+ walletModel->wallet().setAddressBook(DecodeDestination(strAddress), strLabel, wallet::AddressPurpose::SEND);
}
else if(type == Receive)
{
@@ -416,18 +416,18 @@ QString AddressTableModel::labelForAddress(const QString &address) const
return QString();
}
-QString AddressTableModel::purposeForAddress(const QString &address) const
+std::optional<wallet::AddressPurpose> AddressTableModel::purposeForAddress(const QString &address) const
{
- std::string purpose;
+ wallet::AddressPurpose purpose;
if (getAddressData(address, /* name= */ nullptr, &purpose)) {
- return QString::fromStdString(purpose);
+ return purpose;
}
- return QString();
+ return std::nullopt;
}
bool AddressTableModel::getAddressData(const QString &address,
std::string* name,
- std::string* purpose) const {
+ wallet::AddressPurpose* purpose) const {
CTxDestination destination = DecodeDestination(address.toStdString());
return walletModel->wallet().getAddress(destination, name, /* is_mine= */ nullptr, purpose);
}
diff --git a/src/qt/addresstablemodel.h b/src/qt/addresstablemodel.h
index 6cc14654ef..599aa89cad 100644
--- a/src/qt/addresstablemodel.h
+++ b/src/qt/addresstablemodel.h
@@ -5,6 +5,8 @@
#ifndef BITCOIN_QT_ADDRESSTABLEMODEL_H
#define BITCOIN_QT_ADDRESSTABLEMODEL_H
+#include <optional>
+
#include <QAbstractTableModel>
#include <QStringList>
@@ -16,6 +18,9 @@ class WalletModel;
namespace interfaces {
class Wallet;
}
+namespace wallet {
+enum class AddressPurpose;
+} // namespace wallet
/**
Qt model of the address book in the core. This allows views to access and modify the address book.
@@ -71,7 +76,7 @@ public:
QString labelForAddress(const QString &address) const;
/** Look up purpose for address in address book, if not found return empty string. */
- QString purposeForAddress(const QString &address) const;
+ std::optional<wallet::AddressPurpose> purposeForAddress(const QString &address) const;
/* Look up row index of an address in the model.
Return -1 if not found.
@@ -89,7 +94,7 @@ private:
EditStatus editStatus = OK;
/** Look up address book data given an address string. */
- bool getAddressData(const QString &address, std::string* name, std::string* purpose) const;
+ bool getAddressData(const QString &address, std::string* name, wallet::AddressPurpose* purpose) const;
/** Notify listeners that data changed. */
void emitDataChanged(int index);
@@ -97,7 +102,7 @@ private:
public Q_SLOTS:
/* Update address list from core.
*/
- void updateEntry(const QString &address, const QString &label, bool isMine, const QString &purpose, int status);
+ void updateEntry(const QString &address, const QString &label, bool isMine, wallet::AddressPurpose purpose, int status);
friend class AddressTablePriv;
};
diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp
index 2c413e8b43..2f00009596 100644
--- a/src/qt/bitcoin.cpp
+++ b/src/qt/bitcoin.cpp
@@ -9,6 +9,7 @@
#include <qt/bitcoin.h>
#include <chainparams.h>
+#include <common/args.h>
#include <common/init.h>
#include <init.h>
#include <interfaces/handler.h>
@@ -40,6 +41,7 @@
#include <qt/paymentserver.h>
#include <qt/walletcontroller.h>
#include <qt/walletmodel.h>
+#include <wallet/types.h>
#endif // ENABLE_WALLET
#include <boost/signals2/connection.hpp>
@@ -79,6 +81,9 @@ Q_DECLARE_METATYPE(CAmount)
Q_DECLARE_METATYPE(SynchronizationState)
Q_DECLARE_METATYPE(SyncType)
Q_DECLARE_METATYPE(uint256)
+#ifdef ENABLE_WALLET
+Q_DECLARE_METATYPE(wallet::AddressPurpose)
+#endif // ENABLE_WALLET
static void RegisterMetaTypes()
{
@@ -88,7 +93,8 @@ static void RegisterMetaTypes()
qRegisterMetaType<SyncType>();
#ifdef ENABLE_WALLET
qRegisterMetaType<WalletModel*>();
- #endif
+ qRegisterMetaType<wallet::AddressPurpose>();
+ #endif // ENABLE_WALLET
// Register typedefs (see https://doc.qt.io/qt-5/qmetatype.html#qRegisterMetaType)
// IMPORTANT: if CAmount is no longer a typedef use the normal variant above (see https://doc.qt.io/qt-5/qmetatype.html#qRegisterMetaType-1)
qRegisterMetaType<CAmount>("CAmount");
@@ -489,7 +495,7 @@ static void SetupUIArgs(ArgsManager& argsman)
int GuiMain(int argc, char* argv[])
{
#ifdef WIN32
- util::WinCmdLineArgs winArgs;
+ common::WinCmdLineArgs winArgs;
std::tie(argc, argv) = winArgs.get();
#endif
diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp
index 0eae7d3e79..d26ef52eb4 100644
--- a/src/qt/bitcoingui.cpp
+++ b/src/qt/bitcoingui.cpp
@@ -689,6 +689,10 @@ void BitcoinGUI::setWalletController(WalletController* wallet_controller)
GUIUtil::ExceptionSafeConnect(wallet_controller, &WalletController::walletAdded, this, &BitcoinGUI::addWallet);
connect(wallet_controller, &WalletController::walletRemoved, this, &BitcoinGUI::removeWallet);
+ connect(wallet_controller, &WalletController::destroyed, this, [this] {
+ // wallet_controller gets destroyed manually, but it leaves our member copy dangling
+ m_wallet_controller = nullptr;
+ });
auto activity = new LoadWalletsActivity(m_wallet_controller, this);
activity->load();
@@ -701,7 +705,7 @@ WalletController* BitcoinGUI::getWalletController()
void BitcoinGUI::addWallet(WalletModel* walletModel)
{
- if (!walletFrame) return;
+ if (!walletFrame || !m_wallet_controller) return;
WalletView* wallet_view = new WalletView(walletModel, platformStyle, walletFrame);
if (!walletFrame->addView(wallet_view)) return;
@@ -753,7 +757,7 @@ void BitcoinGUI::removeWallet(WalletModel* walletModel)
void BitcoinGUI::setCurrentWallet(WalletModel* wallet_model)
{
- if (!walletFrame) return;
+ if (!walletFrame || !m_wallet_controller) return;
walletFrame->setCurrentWallet(wallet_model);
for (int index = 0; index < m_wallet_selector->count(); ++index) {
if (m_wallet_selector->itemData(index).value<WalletModel*>() == wallet_model) {
diff --git a/src/qt/bitcoinstrings.cpp b/src/qt/bitcoinstrings.cpp
index 27aa39a024..71c05768db 100644
--- a/src/qt/bitcoinstrings.cpp
+++ b/src/qt/bitcoinstrings.cpp
@@ -14,13 +14,22 @@ QT_TRANSLATE_NOOP("bitcoin-core", ""
"%s corrupt. Try using the wallet tool bitcoin-wallet to salvage or restoring "
"a backup."),
QT_TRANSLATE_NOOP("bitcoin-core", ""
+"%s failed to validate the -assumeutxo snapshot state. This indicates a "
+"hardware problem, or a bug in the software, or a bad software modification "
+"that allowed an invalid snapshot to be loaded. As a result of this, the node "
+"will shut down and stop using any state that was built on the snapshot, "
+"resetting the chain height from %d to %d. On the next restart, the node will "
+"resume syncing from %d without using any snapshot data. Please report this "
+"incident to %s, including how you obtained the snapshot. The invalid "
+"snapshot chainstate has been left on disk in case it is helpful in "
+"diagnosing the issue that caused this error."),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
+"%s is set very high! Fees this large could be paid on a single transaction."),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
"%s request to listen on port %u. This port is considered \"bad\" and thus it "
"is unlikely that any peer will connect to it. See doc/p2p-bad-ports.md for "
"details and a full list."),
QT_TRANSLATE_NOOP("bitcoin-core", ""
-"-maxtxfee is set very high! Fees this large could be paid on a single "
-"transaction."),
-QT_TRANSLATE_NOOP("bitcoin-core", ""
"-reindex-chainstate option is not compatible with -blockfilterindex. Please "
"temporarily disable blockfilterindex while using -reindex-chainstate, or "
"replace -reindex-chainstate with -reindex to fully rebuild all indexes."),
@@ -90,8 +99,8 @@ QT_TRANSLATE_NOOP("bitcoin-core", ""
"Failed to rename invalid peers.dat file. Please move or delete it and try "
"again."),
QT_TRANSLATE_NOOP("bitcoin-core", ""
-"Fee estimation failed. Fallbackfee is disabled. Wait a few blocks or enable -"
-"fallbackfee."),
+"Fee estimation failed. Fallbackfee is disabled. Wait a few blocks or enable "
+"%s."),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"File %s already exists. If you are sure this is what you want, move it out "
"of the way first."),
@@ -99,8 +108,8 @@ QT_TRANSLATE_NOOP("bitcoin-core", ""
"Incompatible options: -dnsseed=1 was explicitly specified, but -onlynet "
"forbids connections to IPv4/IPv6"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
-"Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay "
-"fee of %s to prevent stuck transactions)"),
+"Invalid amount for %s=<amount>: '%s' (must be at least the minrelay fee of "
+"%s to prevent stuck transactions)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Invalid or corrupt peers.dat (%s). If you believe this is a bug, please "
"report it to %s. As a workaround, you can move the file (%s) out of the way "
@@ -186,9 +195,18 @@ QT_TRANSLATE_NOOP("bitcoin-core", ""
"Total length of network version string (%i) exceeds maximum length (%i). "
"Reduce the number or size of uacomments."),
QT_TRANSLATE_NOOP("bitcoin-core", ""
+"Transaction requires one destination of non-0 value, a non-0 feerate, or a "
+"pre-selected input"),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
+"UTXO snapshot failed to validate. Restart to resume normal initial block "
+"download, or try loading a different snapshot."),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
"Unable to replay blocks. You will need to rebuild the database using -"
"reindex-chainstate."),
QT_TRANSLATE_NOOP("bitcoin-core", ""
+"Unconfirmed UTXOs are available, but spending them creates a chain of "
+"transactions that will be rejected by the mempool"),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
"Unexpected legacy entry in descriptor wallet found. Loading wallet %s\n"
"\n"
"The wallet might have been tampered with or created with malicious intent.\n"),
@@ -233,6 +251,7 @@ QT_TRANSLATE_NOOP("bitcoin-core", ""
QT_TRANSLATE_NOOP("bitcoin-core", "%s is set very high!"),
QT_TRANSLATE_NOOP("bitcoin-core", "-maxmempool must be at least %d MB"),
QT_TRANSLATE_NOOP("bitcoin-core", "A fatal internal error occurred, see debug.log for details"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Block verification was interrupted"),
QT_TRANSLATE_NOOP("bitcoin-core", "Cannot resolve -%s address: '%s'"),
QT_TRANSLATE_NOOP("bitcoin-core", "Cannot set -forcednsseed to true when setting -dnsseed to false."),
QT_TRANSLATE_NOOP("bitcoin-core", "Cannot set -peerblockfilters without -blockfilterindex."),
@@ -255,6 +274,7 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Error loading %s: Wallet corrupted"),
QT_TRANSLATE_NOOP("bitcoin-core", "Error loading %s: Wallet requires newer version of %s"),
QT_TRANSLATE_NOOP("bitcoin-core", "Error loading block database"),
QT_TRANSLATE_NOOP("bitcoin-core", "Error opening block database"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Error reading configuration file: %s"),
QT_TRANSLATE_NOOP("bitcoin-core", "Error reading from database, shutting down."),
QT_TRANSLATE_NOOP("bitcoin-core", "Error reading next record from wallet database"),
QT_TRANSLATE_NOOP("bitcoin-core", "Error: Cannot extract destination from the generated scriptpubkey"),
@@ -293,10 +313,9 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Invalid -i2psam address or hostname: '%s'"),
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid -onion address or hostname: '%s'"),
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid -proxy address or hostname: '%s'"),
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid P2P permission: '%s'"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for %s=<amount>: '%s' (must be at least %s)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for %s=<amount>: '%s'"),
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -%s=<amount>: '%s'"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -discardfee=<amount>: '%s'"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -fallbackfee=<amount>: '%s'"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid netmask specified in -whitelist: '%s'"),
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid port specified in %s: '%s'"),
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid pre-selected input %s"),
@@ -323,11 +342,14 @@ QT_TRANSLATE_NOOP("bitcoin-core", "SQLiteDatabase: Failed to prepare statement t
QT_TRANSLATE_NOOP("bitcoin-core", "SQLiteDatabase: Failed to read database verification error: %s"),
QT_TRANSLATE_NOOP("bitcoin-core", "SQLiteDatabase: Unexpected application id. Expected %u, got %u"),
QT_TRANSLATE_NOOP("bitcoin-core", "Section [%s] is not recognized."),
+QT_TRANSLATE_NOOP("bitcoin-core", "Settings file could not be read"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Settings file could not be written"),
QT_TRANSLATE_NOOP("bitcoin-core", "Signing transaction failed"),
QT_TRANSLATE_NOOP("bitcoin-core", "Specified -walletdir \"%s\" does not exist"),
QT_TRANSLATE_NOOP("bitcoin-core", "Specified -walletdir \"%s\" is a relative path"),
QT_TRANSLATE_NOOP("bitcoin-core", "Specified -walletdir \"%s\" is not a directory"),
QT_TRANSLATE_NOOP("bitcoin-core", "Specified blocks directory \"%s\" does not exist."),
+QT_TRANSLATE_NOOP("bitcoin-core", "Specified data directory \"%s\" does not exist."),
QT_TRANSLATE_NOOP("bitcoin-core", "Starting network threads…"),
QT_TRANSLATE_NOOP("bitcoin-core", "The source code is available from %s."),
QT_TRANSLATE_NOOP("bitcoin-core", "The specified config file %s does not exist"),
diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp
index 8411ec4696..837e5f4fed 100644
--- a/src/qt/clientmodel.cpp
+++ b/src/qt/clientmodel.cpp
@@ -11,6 +11,7 @@
#include <qt/peertablesortproxy.h>
#include <clientversion.h>
+#include <common/args.h>
#include <interfaces/handler.h>
#include <interfaces/node.h>
#include <net.h>
diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp
index e1b1ae12e9..50d3c2e559 100644
--- a/src/qt/coincontroldialog.cpp
+++ b/src/qt/coincontroldialog.cpp
@@ -412,8 +412,7 @@ void CoinControlDialog::updateLabels(CCoinControl& m_coin_control, WalletModel *
unsigned int nQuantity = 0;
bool fWitness = false;
- std::vector<COutPoint> vCoinControl;
- m_coin_control.ListSelected(vCoinControl);
+ auto vCoinControl{m_coin_control.ListSelected()};
size_t i = 0;
for (const auto& out : model->wallet().getCoins(vCoinControl)) {
diff --git a/src/qt/editaddressdialog.cpp b/src/qt/editaddressdialog.cpp
index 9b3319415d..092a89fa11 100644
--- a/src/qt/editaddressdialog.cpp
+++ b/src/qt/editaddressdialog.cpp
@@ -8,6 +8,8 @@
#include <qt/addresstablemodel.h>
#include <qt/guiutil.h>
+#include <wallet/types.h>
+
#include <QDataWidgetMapper>
#include <QMessageBox>
@@ -137,9 +139,9 @@ QString EditAddressDialog::getDuplicateAddressWarning() const
{
QString dup_address = ui->addressEdit->text();
QString existing_label = model->labelForAddress(dup_address);
- QString existing_purpose = model->purposeForAddress(dup_address);
+ auto existing_purpose = model->purposeForAddress(dup_address);
- if (existing_purpose == "receive" &&
+ if (existing_purpose == wallet::AddressPurpose::RECEIVE &&
(mode == NewSendingAddress || mode == EditSendingAddress)) {
return tr(
"Address \"%1\" already exists as a receiving address with label "
diff --git a/src/qt/forms/psbtoperationsdialog.ui b/src/qt/forms/psbtoperationsdialog.ui
index caae0dab2a..5194826371 100644
--- a/src/qt/forms/psbtoperationsdialog.ui
+++ b/src/qt/forms/psbtoperationsdialog.ui
@@ -11,7 +11,7 @@
</rect>
</property>
<property name="windowTitle">
- <string>Dialog</string>
+ <string>PSBT Operations</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp
index 83c78d5c18..dc7daed4bc 100644
--- a/src/qt/guiutil.cpp
+++ b/src/qt/guiutil.cpp
@@ -12,16 +12,18 @@
#include <base58.h>
#include <chainparams.h>
-#include <fs.h>
+#include <common/args.h>
#include <interfaces/node.h>
#include <key_io.h>
+#include <logging.h>
#include <policy/policy.h>
#include <primitives/transaction.h>
#include <protocol.h>
#include <script/script.h>
#include <script/standard.h>
#include <util/exception.h>
-#include <util/system.h>
+#include <util/fs.h>
+#include <util/fs_helpers.h>
#include <util/time.h>
#ifdef WIN32
@@ -673,12 +675,17 @@ QString NetworkToQString(Network net)
{
switch (net) {
case NET_UNROUTABLE: return QObject::tr("Unroutable");
- case NET_IPV4: return "IPv4";
- case NET_IPV6: return "IPv6";
- case NET_ONION: return "Onion";
- case NET_I2P: return "I2P";
- case NET_CJDNS: return "CJDNS";
- case NET_INTERNAL: return QObject::tr("Internal");
+ //: Name of IPv4 network in peer info
+ case NET_IPV4: return QObject::tr("IPv4", "network name");
+ //: Name of IPv6 network in peer info
+ case NET_IPV6: return QObject::tr("IPv6", "network name");
+ //: Name of Tor network in peer info
+ case NET_ONION: return QObject::tr("Onion", "network name");
+ //: Name of I2P network in peer info
+ case NET_I2P: return QObject::tr("I2P", "network name");
+ //: Name of CJDNS network in peer info
+ case NET_CJDNS: return QObject::tr("CJDNS", "network name");
+ case NET_INTERNAL: return "Internal"; // should never actually happen
case NET_MAX: assert(false);
} // no default case, so the compiler can warn about missing cases
assert(false);
diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h
index 87a323bde9..7f06fdfe37 100644
--- a/src/qt/guiutil.h
+++ b/src/qt/guiutil.h
@@ -6,10 +6,10 @@
#define BITCOIN_QT_GUIUTIL_H
#include <consensus/amount.h>
-#include <fs.h>
#include <net.h>
#include <netaddress.h>
#include <util/check.h>
+#include <util/fs.h>
#include <QApplication>
#include <QEvent>
diff --git a/src/qt/intro.cpp b/src/qt/intro.cpp
index 12aa02340a..a54ba19354 100644
--- a/src/qt/intro.cpp
+++ b/src/qt/intro.cpp
@@ -7,16 +7,17 @@
#endif
#include <chainparams.h>
-#include <fs.h>
#include <qt/intro.h>
#include <qt/forms/ui_intro.h>
+#include <util/fs.h>
#include <qt/guiconstants.h>
#include <qt/guiutil.h>
#include <qt/optionsmodel.h>
+#include <common/args.h>
#include <interfaces/node.h>
-#include <util/system.h>
+#include <util/fs_helpers.h>
#include <validation.h>
#include <QFileDialog>
@@ -318,7 +319,7 @@ void Intro::on_dataDirectory_textChanged(const QString &dataDirStr)
void Intro::on_ellipsisButton_clicked()
{
- QString dir = QDir::toNativeSeparators(QFileDialog::getExistingDirectory(nullptr, "Choose data directory", ui->dataDirectory->text()));
+ QString dir = QDir::toNativeSeparators(QFileDialog::getExistingDirectory(nullptr, tr("Choose data directory"), ui->dataDirectory->text()));
if(!dir.isEmpty())
ui->dataDirectory->setText(dir);
}
diff --git a/src/qt/locale/bitcoin_en.ts b/src/qt/locale/bitcoin_en.ts
index ebce81b198..644ef5afc2 100644
--- a/src/qt/locale/bitcoin_en.ts
+++ b/src/qt/locale/bitcoin_en.ts
@@ -329,7 +329,7 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
<context>
<name>BitcoinApplication</name>
<message>
- <location filename="../bitcoin.cpp" line="+283"/>
+ <location filename="../bitcoin.cpp" line="+267"/>
<source>Settings file %1 might be corrupt or invalid.</source>
<translation type="unfinished"></translation>
</message>
@@ -417,7 +417,7 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+160"/>
+ <location line="+161"/>
<source>&amp;Minimize</source>
<translation type="unfinished"></translation>
</message>
@@ -427,7 +427,7 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+395"/>
+ <location line="+407"/>
<source>Network activity disabled.</source>
<extracomment>A substring of the tooltip.</extracomment>
<translation type="unfinished"></translation>
@@ -438,7 +438,7 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-1159"/>
+ <location line="-1172"/>
<source>Send coins to a Bitcoin address</source>
<translation>Send coins to a Bitcoin address</translation>
</message>
@@ -533,7 +533,7 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+119"/>
+ <location line="+120"/>
<source>&amp;File</source>
<translation>&amp;File</translation>
</message>
@@ -553,7 +553,7 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
<translation>Tabs toolbar</translation>
</message>
<message>
- <location line="+459"/>
+ <location line="+471"/>
<source>Syncing Headers (%1%)…</source>
<translation type="unfinished"></translation>
</message>
@@ -578,7 +578,7 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-832"/>
+ <location line="-845"/>
<source>Request payments (generates QR codes and bitcoin: URIs)</source>
<translation type="unfinished"></translation>
</message>
@@ -598,7 +598,7 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
<translation type="unfinished"></translation>
</message>
<message numerus="yes">
- <location line="+748"/>
+ <location line="+761"/>
<source>Processed %n block(s) of transaction history.</source>
<translation>
<numerusform>Processed %n block of transaction history.</numerusform>
@@ -646,7 +646,7 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
<translation>Up to date</translation>
</message>
<message>
- <location line="-817"/>
+ <location line="-830"/>
<source>Ctrl+Q</source>
<translation type="unfinished"></translation>
</message>
@@ -772,7 +772,7 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+71"/>
+ <location line="+72"/>
<source>&amp;Window</source>
<translation type="unfinished">&amp;Window</translation>
</message>
@@ -792,7 +792,7 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+260"/>
+ <location line="+272"/>
<source>%1 client</source>
<translation type="unfinished"></translation>
</message>
@@ -1429,28 +1429,33 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
<location line="+162"/>
<source>%n GB of space available</source>
<translation type="unfinished">
- <numerusform></numerusform>
- <numerusform></numerusform>
+ <numerusform>%n GB of space available</numerusform>
+ <numerusform>%n GB of space available</numerusform>
</translation>
</message>
<message numerus="yes">
<location line="+2"/>
<source>(of %n GB needed)</source>
<translation type="unfinished">
- <numerusform></numerusform>
- <numerusform></numerusform>
+ <numerusform>(of %n GB needed)</numerusform>
+ <numerusform>(of %n GB needed)</numerusform>
</translation>
</message>
<message numerus="yes">
<location line="+3"/>
<source>(%n GB needed for full chain)</source>
<translation type="unfinished">
- <numerusform></numerusform>
- <numerusform></numerusform>
+ <numerusform>(%n GB needed for full chain)</numerusform>
+ <numerusform>(%n GB needed for full chain)</numerusform>
</translation>
</message>
<message>
- <location line="+72"/>
+ <location line="+17"/>
+ <source>Choose data directory</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+55"/>
<source>At least %1 GB of data will be stored in this directory, and it will grow over time.</source>
<translation type="unfinished"></translation>
</message>
@@ -2211,7 +2216,7 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
<name>PSBTOperationsDialog</name>
<message>
<location filename="../forms/psbtoperationsdialog.ui" line="+14"/>
- <source>Dialog</source>
+ <source>PSBT Operations</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -2240,7 +2245,7 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../psbtoperationsdialog.cpp" line="+61"/>
+ <location filename="../psbtoperationsdialog.cpp" line="+60"/>
<source>Failed to load transaction: %1</source>
<translation type="unfinished"></translation>
</message>
@@ -2498,7 +2503,7 @@ If you are receiving this error you should request the merchant provide a BIP21
<translation type="unfinished">Amount</translation>
</message>
<message>
- <location filename="../guiutil.cpp" line="+129"/>
+ <location filename="../guiutil.cpp" line="+130"/>
<source>Enter a Bitcoin address (e.g. %1)</source>
<translation type="unfinished"></translation>
</message>
@@ -2513,12 +2518,42 @@ If you are receiving this error you should request the merchant provide a BIP21
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+6"/>
- <source>Internal</source>
+ <location line="+2"/>
+ <source>IPv4</source>
+ <comment>network name</comment>
+ <extracomment>Name of IPv4 network in peer info</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+13"/>
+ <location line="+2"/>
+ <source>IPv6</source>
+ <comment>network name</comment>
+ <extracomment>Name of IPv6 network in peer info</extracomment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Onion</source>
+ <comment>network name</comment>
+ <extracomment>Name of Tor network in peer info</extracomment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>I2P</source>
+ <comment>network name</comment>
+ <extracomment>Name of I2P network in peer info</extracomment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>CJDNS</source>
+ <comment>network name</comment>
+ <extracomment>Name of CJDNS network in peer info</extracomment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+14"/>
<source>Inbound</source>
<extracomment>An inbound connection from a peer. An inbound connection is a connection initiated by a peer.</extracomment>
<translation type="unfinished"></translation>
@@ -2660,11 +2695,13 @@ If you are receiving this error you should request the merchant provide a BIP21
</message>
<message>
<location line="+2"/>
+ <location filename="../rpcconsole.cpp" line="+988"/>
<source>%1 kB</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="+2"/>
+ <location filename="../rpcconsole.cpp" line="+2"/>
<source>%1 MB</source>
<translation type="unfinished"></translation>
</message>
@@ -2674,34 +2711,24 @@ If you are receiving this error you should request the merchant provide a BIP21
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoin.cpp" line="-288"/>
+ <location filename="../bitcoin.cpp" line="-281"/>
<source>Do you want to reset settings to default values, or to abort without making changes?</source>
<extracomment>Explanatory text shown on startup when the settings file cannot be read. Prompts user to make a choice between resetting or aborting.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+24"/>
+ <location line="+20"/>
<source>A fatal error occurred. Check that settings file is writable, or try running with -nosettings.</source>
<extracomment>Explanatory text shown on startup when the settings file could not be written. Prompts user to check that we have the ability to write to the file. Explains that the user has the option of running without a settings file.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+386"/>
- <source>Error: Specified data directory &quot;%1&quot; does not exist.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+9"/>
- <source>Error: Cannot parse configuration file: %1.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+14"/>
+ <location line="+394"/>
<source>Error: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+74"/>
+ <location line="+71"/>
<source>%1 didn&apos;t yet exit safely…</source>
<translation type="unfinished"></translation>
</message>
@@ -2909,7 +2936,7 @@ If you are receiving this error you should request the merchant provide a BIP21
</message>
<message>
<location line="+68"/>
- <location filename="../rpcconsole.cpp" line="+1155"/>
+ <location filename="../rpcconsole.cpp" line="+165"/>
<source>Select a peer to view detailed information.</source>
<translation type="unfinished"></translation>
</message>
@@ -3142,7 +3169,7 @@ If you are receiving this error you should request the merchant provide a BIP21
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../rpcconsole.cpp" line="-202"/>
+ <location filename="../rpcconsole.cpp" line="-203"/>
<source>In:</source>
<translation type="unfinished"></translation>
</message>
@@ -3314,12 +3341,12 @@ If you are receiving this error you should request the merchant provide a BIP21
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+78"/>
+ <location line="+79"/>
<source>Executing command without any wallet</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+320"/>
+ <location line="+316"/>
<source>Ctrl+I</source>
<translation type="unfinished"></translation>
</message>
@@ -3339,12 +3366,12 @@ If you are receiving this error you should request the merchant provide a BIP21
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-325"/>
+ <location line="-321"/>
<source>Executing command using &quot;%1&quot; wallet</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-146"/>
+ <location line="-147"/>
<source>Welcome to the %1 RPC console.
Use up and down arrows to navigate history, and %2 to clear screen.
Use %3 and %4 to increase or decrease the font size.
@@ -3356,7 +3383,7 @@ For more information on using this console, type %6.
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+156"/>
+ <location line="+157"/>
<source>Executing…</source>
<extracomment>A console message indicating an entered command is currently being executed.</extracomment>
<translation type="unfinished"></translation>
@@ -3491,7 +3518,47 @@ For more information on using this console, type %6.
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+125"/>
+ <location line="+46"/>
+ <source>Base58 (Legacy)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+0"/>
+ <source>Not recommended due to higher fees and less protection against typos.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Base58 (P2SH-SegWit)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+0"/>
+ <source>Generates an address compatible with older wallets.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Bech32 (SegWit)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+0"/>
+ <source>Generates a native segwit address (BIP-173). Some old wallets don&apos;t support it.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Bech32m (Taproot)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+0"/>
+ <source>Bech32m (BIP-350) is an upgrade to Bech32, wallet support is still limited.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+75"/>
<source>Could not unlock wallet.</source>
<translation type="unfinished"></translation>
</message>
@@ -3644,7 +3711,7 @@ For more information on using this console, type %6.
<name>SendCoinsDialog</name>
<message>
<location filename="../forms/sendcoinsdialog.ui" line="+14"/>
- <location filename="../sendcoinsdialog.cpp" line="+755"/>
+ <location filename="../sendcoinsdialog.cpp" line="+765"/>
<source>Send Coins</source>
<translation>Send Coins</translation>
</message>
@@ -3831,7 +3898,7 @@ Note: Since the fee is calculated on a per-byte basis, a fee rate of &quot;100
<translation>S&amp;end</translation>
</message>
<message>
- <location filename="../sendcoinsdialog.cpp" line="-660"/>
+ <location filename="../sendcoinsdialog.cpp" line="-670"/>
<source>Copy quantity</source>
<translation type="unfinished"></translation>
</message>
@@ -3913,12 +3980,12 @@ Note: Since the fee is calculated on a per-byte basis, a fee rate of &quot;100
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+66"/>
+ <location line="+67"/>
<source>To review recipient list click &quot;Show Details…&quot;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+60"/>
+ <location line="+62"/>
<source>Sign failed</source>
<translation type="unfinished"></translation>
</message>
@@ -3929,13 +3996,13 @@ Note: Since the fee is calculated on a per-byte basis, a fee rate of &quot;100
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+5"/>
+ <location line="+6"/>
<source>External signer failure</source>
<extracomment>&quot;External signer&quot; means using devices such as hardware wallets.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-34"/>
+ <location line="-36"/>
<source>Save Transaction Data</source>
<translation type="unfinished"></translation>
</message>
@@ -3946,17 +4013,18 @@ Note: Since the fee is calculated on a per-byte basis, a fee rate of &quot;100
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+7"/>
+ <location line="+8"/>
<source>PSBT saved</source>
+ <extracomment>Popup message when a PSBT has been saved to a file</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+266"/>
+ <location line="+273"/>
<source>External balance:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-315"/>
+ <location line="-324"/>
<source>or</source>
<translation type="unfinished"></translation>
</message>
@@ -3966,7 +4034,7 @@ Note: Since the fee is calculated on a per-byte basis, a fee rate of &quot;100
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-30"/>
+ <location line="-31"/>
<source>Please, review your transaction proposal. This will produce a Partially Signed Bitcoin Transaction (PSBT) which you can save or copy and then sign with e.g. an offline %1 wallet, or a PSBT-compatible hardware wallet.</source>
<extracomment>Text to inform a user attempting to create a transaction of their current options. At this stage, a user can only create a PSBT. This string is displayed when private keys are disabled and an external signer is not available.</extracomment>
<translation type="unfinished"></translation>
@@ -3995,7 +4063,14 @@ Note: Since the fee is calculated on a per-byte basis, a fee rate of &quot;100
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+16"/>
+ <location line="+5"/>
+ <source>%1 kvB</source>
+ <comment>PSBT transaction creation</comment>
+ <extracomment>When reviewing a newly created PSBT (via Send flow), the transaction fee is shown, with &quot;virtual size&quot; of the transaction displayed for context</extracomment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+12"/>
<source>Not signalling Replace-By-Fee, BIP-125.</source>
<translation type="unfinished"></translation>
</message>
@@ -4005,12 +4080,29 @@ Note: Since the fee is calculated on a per-byte basis, a fee rate of &quot;100
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+99"/>
+ <location line="+24"/>
+ <source>Unsigned Transaction</source>
+ <comment>PSBT copied</comment>
+ <extracomment>Caption of &quot;PSBT has been copied&quot; messagebox</extracomment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>The PSBT has been copied to the clipboard. You can also save it.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+29"/>
+ <source>PSBT saved to disk</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+49"/>
<source>Confirm send coins</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+222"/>
+ <location line="+227"/>
<source>Watch-only balance:</source>
<translation type="unfinished"></translation>
</message>
@@ -4049,8 +4141,14 @@ Note: Since the fee is calculated on a per-byte basis, a fee rate of &quot;100
<source>A fee higher than %1 is considered an absurdly high fee.</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <location line="+74"/>
+ <location line="+35"/>
+ <source>%1/kvB</source>
+ <translation type="unfinished"></translation>
+ </message>
<message numerus="yes">
- <location line="+123"/>
+ <location line="+14"/>
<source>Estimated to begin confirmation within %n block(s).</source>
<translation>
<numerusform>Estimated to begin confirmation within %n block.</numerusform>
@@ -4493,17 +4591,19 @@ Note: Since the fee is calculated on a per-byte basis, a fee rate of &quot;100
</message>
<message>
<location line="-88"/>
+ <location line="+95"/>
<source>own address</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+0"/>
+ <location line="-95"/>
<location line="+69"/>
+ <location line="+28"/>
<source>watch-only</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-67"/>
+ <location line="-95"/>
<source>label</source>
<translation type="unfinished"></translation>
</message>
@@ -4967,7 +5067,7 @@ Note: Since the fee is calculated on a per-byte basis, a fee rate of &quot;100
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+169"/>
+ <location line="+170"/>
<source>Range:</source>
<translation type="unfinished"></translation>
</message>
@@ -5123,6 +5223,12 @@ Go to File &gt; Open Wallet to load a wallet.
<translation type="unfinished"></translation>
</message>
<message>
+ <location line="+0"/>
+ <source>Copied to clipboard</source>
+ <comment>Fee-bump PSBT saved</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<location line="+8"/>
<source>Can&apos;t sign transaction.</source>
<translation type="unfinished"></translation>
@@ -5156,7 +5262,7 @@ Go to File &gt; Open Wallet to load a wallet.
<translation type="unfinished">Export the data in the current tab to a file</translation>
</message>
<message>
- <location line="+162"/>
+ <location line="+163"/>
<source>Backup Wallet</source>
<translation type="unfinished"></translation>
</message>
@@ -5205,17 +5311,12 @@ Go to File &gt; Open Wallet to load a wallet.
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+3"/>
+ <location line="+15"/>
<source>%s request to listen on port %u. This port is considered &quot;bad&quot; and thus it is unlikely that any peer will connect to it. See doc/p2p-bad-ports.md for details and a full list.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+4"/>
- <source>-maxtxfee is set very high! Fees this large could be paid on a single transaction.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+15"/>
+ <location line="+16"/>
<source>Cannot downgrade wallet from version %i to version %i. Wallet version unchanged.</source>
<translation type="unfinished"></translation>
</message>
@@ -5280,22 +5381,12 @@ Go to File &gt; Open Wallet to load a wallet.
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+6"/>
- <source>Fee estimation failed. Fallbackfee is disabled. Wait a few blocks or enable -fallbackfee.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+3"/>
+ <location line="+9"/>
<source>File %s already exists. If you are sure this is what you want, move it out of the way first.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+6"/>
- <source>Invalid amount for -maxtxfee=&lt;amount&gt;: &apos;%s&apos; (must be at least the minrelay fee of %s to prevent stuck transactions)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+3"/>
+ <location line="+9"/>
<source>Invalid or corrupt peers.dat (%s). If you believe this is a bug, please report it to %s. As a workaround, you can move the file (%s) out of the way (rename, move, or delete) to have a new one created on the next start.</source>
<translation type="unfinished"></translation>
</message>
@@ -5395,12 +5486,12 @@ Go to File &gt; Open Wallet to load a wallet.
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+3"/>
+ <location line="+9"/>
<source>Unable to replay blocks. You will need to rebuild the database using -reindex-chainstate.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+7"/>
+ <location line="+10"/>
<source>Unknown wallet file format &quot;%s&quot; provided. Please provide one of &quot;bdb&quot; or &quot;sqlite&quot;.</source>
<translation type="unfinished"></translation>
</message>
@@ -5455,7 +5546,7 @@ Go to File &gt; Open Wallet to load a wallet.
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+1"/>
+ <location line="+2"/>
<source>Cannot resolve -%s address: &apos;%s&apos;</source>
<translation type="unfinished"></translation>
</message>
@@ -5475,12 +5566,22 @@ Go to File &gt; Open Wallet to load a wallet.
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-90"/>
+ <location line="-100"/>
<source>The -txindex upgrade started by a previous version cannot be completed. Restart with the previous version or run a full -reindex.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-126"/>
+ <location line="-142"/>
+ <source>%s failed to validate the -assumeutxo snapshot state. This indicates a hardware problem, or a bug in the software, or a bad software modification that allowed an invalid snapshot to be loaded. As a result of this, the node will shut down and stop using any state that was built on the snapshot, resetting the chain height from %d to %d. On the next restart, the node will resume syncing from %d without using any snapshot data. Please report this incident to %s, including how you obtained the snapshot. The invalid snapshot chainstate has been left on disk in case it is helpful in diagnosing the issue that caused this error.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+10"/>
+ <source>%s is set very high! Fees this large could be paid on a single transaction.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+6"/>
<source>-reindex-chainstate option is not compatible with -blockfilterindex. Please temporarily disable blockfilterindex while using -reindex-chainstate, or replace -reindex-chainstate with -reindex to fully rebuild all indexes.</source>
<translation type="unfinished"></translation>
</message>
@@ -5525,12 +5626,22 @@ Go to File &gt; Open Wallet to load a wallet.
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+9"/>
+ <location line="+3"/>
+ <source>Fee estimation failed. Fallbackfee is disabled. Wait a few blocks or enable %s.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+6"/>
<source>Incompatible options: -dnsseed=1 was explicitly specified, but -onlynet forbids connections to IPv4/IPv6</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+21"/>
+ <location line="+3"/>
+ <source>Invalid amount for %s=&lt;amount&gt;: &apos;%s&apos; (must be at least the minrelay fee of %s to prevent stuck transactions)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+18"/>
<source>Outbound connections restricted to CJDNS (-onlynet=cjdns) but -cjdnsreachable is not provided</source>
<translation type="unfinished"></translation>
</message>
@@ -5560,7 +5671,22 @@ Go to File &gt; Open Wallet to load a wallet.
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+27"/>
+ <location line="+24"/>
+ <source>Transaction requires one destination of non-0 value, a non-0 feerate, or a pre-selected input</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>UTXO snapshot failed to validate. Restart to resume normal initial block download, or try loading a different snapshot.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>Unconfirmed UTXOs are available, but spending them creates a chain of transactions that will be rejected by the mempool</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
<source>Unexpected legacy entry in descriptor wallet found. Loading wallet %s
The wallet might have been tampered with or created with malicious intent.
@@ -5594,7 +5720,12 @@ Unable to restore backup of wallet.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+10"/>
+ <location line="+6"/>
+ <source>Block verification was interrupted</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+5"/>
<source>Config setting for %s only applied on %s network when in [%s] section.</source>
<translation type="unfinished"></translation>
</message>
@@ -5685,6 +5816,11 @@ Unable to restore backup of wallet.</source>
</message>
<message>
<location line="+1"/>
+ <source>Error reading configuration file: %s</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
<source>Error reading from database, shutting down.</source>
<translation type="unfinished"></translation>
</message>
@@ -5875,22 +6011,17 @@ Unable to restore backup of wallet.</source>
</message>
<message>
<location line="+1"/>
- <source>Invalid amount for -%s=&lt;amount&gt;: &apos;%s&apos;</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+1"/>
- <source>Invalid amount for -discardfee=&lt;amount&gt;: &apos;%s&apos;</source>
+ <source>Invalid amount for %s=&lt;amount&gt;: &apos;%s&apos; (must be at least %s)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="+1"/>
- <source>Invalid amount for -fallbackfee=&lt;amount&gt;: &apos;%s&apos;</source>
+ <source>Invalid amount for %s=&lt;amount&gt;: &apos;%s&apos;</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="+1"/>
- <source>Invalid amount for -paytxfee=&lt;amount&gt;: &apos;%s&apos; (must be at least %s)</source>
+ <source>Invalid amount for -%s=&lt;amount&gt;: &apos;%s&apos;</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -6024,7 +6155,7 @@ Unable to restore backup of wallet.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+1"/>
+ <location line="+3"/>
<source>Signing transaction failed</source>
<translation type="unfinished"></translation>
</message>
@@ -6050,6 +6181,11 @@ Unable to restore backup of wallet.</source>
</message>
<message>
<location line="+1"/>
+ <source>Specified data directory &quot;%s&quot; does not exist.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
<source>Starting network threads…</source>
<translation type="unfinished"></translation>
</message>
@@ -6234,12 +6370,12 @@ Unable to restore backup of wallet.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoin.cpp" line="-514"/>
+ <location line="-44"/>
<source>Settings file could not be read</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+23"/>
+ <location line="+1"/>
<source>Settings file could not be written</source>
<translation type="unfinished"></translation>
</message>
diff --git a/src/qt/locale/bitcoin_en.xlf b/src/qt/locale/bitcoin_en.xlf
index 4920a08d72..d816cea7c4 100644
--- a/src/qt/locale/bitcoin_en.xlf
+++ b/src/qt/locale/bitcoin_en.xlf
@@ -281,609 +281,591 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
<group restype="x-trolltech-linguist-context" resname="BitcoinApplication">
<trans-unit id="_msg61">
<source xml:space="preserve">Settings file %1 might be corrupt or invalid.</source>
- <context-group purpose="location"><context context-type="linenumber">283</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">267</context></context-group>
</trans-unit>
<trans-unit id="_msg62">
<source xml:space="preserve">Runaway exception</source>
- <context-group purpose="location"><context context-type="linenumber">461</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">445</context></context-group>
</trans-unit>
<trans-unit id="_msg63">
<source xml:space="preserve">A fatal error occurred. %1 can no longer continue safely and will quit.</source>
- <context-group purpose="location"><context context-type="linenumber">462</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">446</context></context-group>
</trans-unit>
<trans-unit id="_msg64">
<source xml:space="preserve">Internal error</source>
- <context-group purpose="location"><context context-type="linenumber">471</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">455</context></context-group>
</trans-unit>
<trans-unit id="_msg65">
<source xml:space="preserve">An internal error occurred. %1 will attempt to continue safely. This is an unexpected bug which can be reported as described below.</source>
- <context-group purpose="location"><context context-type="linenumber">472</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">456</context></context-group>
</trans-unit>
</group>
<group restype="x-trolltech-linguist-context" resname="QObject">
<trans-unit id="_msg66">
<source xml:space="preserve">Do you want to reset settings to default values, or to abort without making changes?</source>
- <context-group purpose="location"><context context-type="linenumber">184</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">175</context></context-group>
<note annotates="source" from="developer">Explanatory text shown on startup when the settings file cannot be read. Prompts user to make a choice between resetting or aborting.</note>
</trans-unit>
<trans-unit id="_msg67">
<source xml:space="preserve">A fatal error occurred. Check that settings file is writable, or try running with -nosettings.</source>
- <context-group purpose="location"><context context-type="linenumber">208</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">195</context></context-group>
<note annotates="source" from="developer">Explanatory text shown on startup when the settings file could not be written. Prompts user to check that we have the ability to write to the file. Explains that the user has the option of running without a settings file.</note>
</trans-unit>
<trans-unit id="_msg68">
- <source xml:space="preserve">Error: Specified data directory &quot;%1&quot; does not exist.</source>
- <context-group purpose="location"><context context-type="linenumber">594</context></context-group>
- </trans-unit>
- <trans-unit id="_msg69">
- <source xml:space="preserve">Error: Cannot parse configuration file: %1.</source>
- <context-group purpose="location"><context context-type="linenumber">603</context></context-group>
- </trans-unit>
- <trans-unit id="_msg70">
<source xml:space="preserve">Error: %1</source>
- <context-group purpose="location"><context context-type="linenumber">617</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">589</context></context-group>
</trans-unit>
- <trans-unit id="_msg71">
+ <trans-unit id="_msg69">
<source xml:space="preserve">%1 didn&apos;t yet exit safely…</source>
- <context-group purpose="location"><context context-type="linenumber">691</context></context-group>
- </trans-unit>
- </group>
- <group restype="x-trolltech-linguist-context" resname="bitcoin-core">
- <trans-unit id="_msg72">
- <source xml:space="preserve">Settings file could not be read</source>
- <context-group purpose="location"><context context-type="linenumber">177</context></context-group>
- </trans-unit>
- <trans-unit id="_msg73">
- <source xml:space="preserve">Settings file could not be written</source>
- <context-group purpose="location"><context context-type="linenumber">200</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">660</context></context-group>
</trans-unit>
</group>
</body></file>
<file original="../bitcoingui.cpp" datatype="cpp" source-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="BitcoinGUI">
- <trans-unit id="_msg74">
+ <trans-unit id="_msg70">
<source xml:space="preserve">&amp;Overview</source>
<context-group purpose="location"><context context-type="linenumber">253</context></context-group>
</trans-unit>
- <trans-unit id="_msg75">
+ <trans-unit id="_msg71">
<source xml:space="preserve">Show general overview of wallet</source>
<context-group purpose="location"><context context-type="linenumber">254</context></context-group>
</trans-unit>
- <trans-unit id="_msg76">
+ <trans-unit id="_msg72">
<source xml:space="preserve">&amp;Transactions</source>
<context-group purpose="location"><context context-type="linenumber">274</context></context-group>
</trans-unit>
- <trans-unit id="_msg77">
+ <trans-unit id="_msg73">
<source xml:space="preserve">Browse transaction history</source>
<context-group purpose="location"><context context-type="linenumber">275</context></context-group>
</trans-unit>
- <trans-unit id="_msg78">
+ <trans-unit id="_msg74">
<source xml:space="preserve">E&amp;xit</source>
<context-group purpose="location"><context context-type="linenumber">294</context></context-group>
</trans-unit>
- <trans-unit id="_msg79">
+ <trans-unit id="_msg75">
<source xml:space="preserve">Quit application</source>
<context-group purpose="location"><context context-type="linenumber">295</context></context-group>
</trans-unit>
- <trans-unit id="_msg80">
+ <trans-unit id="_msg76">
<source xml:space="preserve">&amp;About %1</source>
<context-group purpose="location"><context context-type="linenumber">298</context></context-group>
</trans-unit>
- <trans-unit id="_msg81">
+ <trans-unit id="_msg77">
<source xml:space="preserve">Show information about %1</source>
<context-group purpose="location"><context context-type="linenumber">299</context></context-group>
</trans-unit>
- <trans-unit id="_msg82">
+ <trans-unit id="_msg78">
<source xml:space="preserve">About &amp;Qt</source>
<context-group purpose="location"><context context-type="linenumber">302</context></context-group>
</trans-unit>
- <trans-unit id="_msg83">
+ <trans-unit id="_msg79">
<source xml:space="preserve">Show information about Qt</source>
<context-group purpose="location"><context context-type="linenumber">303</context></context-group>
</trans-unit>
- <trans-unit id="_msg84">
+ <trans-unit id="_msg80">
<source xml:space="preserve">Modify configuration options for %1</source>
<context-group purpose="location"><context context-type="linenumber">306</context></context-group>
</trans-unit>
- <trans-unit id="_msg85">
+ <trans-unit id="_msg81">
<source xml:space="preserve">Create a new wallet</source>
<context-group purpose="location"><context context-type="linenumber">350</context></context-group>
</trans-unit>
- <trans-unit id="_msg86">
+ <trans-unit id="_msg82">
<source xml:space="preserve">&amp;Minimize</source>
- <context-group purpose="location"><context context-type="linenumber">510</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">511</context></context-group>
</trans-unit>
- <trans-unit id="_msg87">
+ <trans-unit id="_msg83">
<source xml:space="preserve">Wallet:</source>
- <context-group purpose="location"><context context-type="linenumber">589</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">590</context></context-group>
</trans-unit>
- <trans-unit id="_msg88">
+ <trans-unit id="_msg84">
<source xml:space="preserve">Network activity disabled.</source>
- <context-group purpose="location"><context context-type="linenumber">984</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">997</context></context-group>
<note annotates="source" from="developer">A substring of the tooltip.</note>
</trans-unit>
- <trans-unit id="_msg89">
+ <trans-unit id="_msg85">
<source xml:space="preserve">Proxy is &lt;b&gt;enabled&lt;/b&gt;: %1</source>
- <context-group purpose="location"><context context-type="linenumber">1420</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1433</context></context-group>
</trans-unit>
- <trans-unit id="_msg90">
+ <trans-unit id="_msg86">
<source xml:space="preserve">Send coins to a Bitcoin address</source>
<context-group purpose="location"><context context-type="linenumber">261</context></context-group>
</trans-unit>
- <trans-unit id="_msg91">
+ <trans-unit id="_msg87">
<source xml:space="preserve">Backup wallet to another location</source>
<context-group purpose="location"><context context-type="linenumber">314</context></context-group>
</trans-unit>
- <trans-unit id="_msg92">
+ <trans-unit id="_msg88">
<source xml:space="preserve">Change the passphrase used for wallet encryption</source>
<context-group purpose="location"><context context-type="linenumber">316</context></context-group>
</trans-unit>
- <trans-unit id="_msg93">
+ <trans-unit id="_msg89">
<source xml:space="preserve">&amp;Send</source>
<context-group purpose="location"><context context-type="linenumber">260</context></context-group>
</trans-unit>
- <trans-unit id="_msg94">
+ <trans-unit id="_msg90">
<source xml:space="preserve">&amp;Receive</source>
<context-group purpose="location"><context context-type="linenumber">267</context></context-group>
</trans-unit>
- <trans-unit id="_msg95">
+ <trans-unit id="_msg91">
<source xml:space="preserve">&amp;Options…</source>
<context-group purpose="location"><context context-type="linenumber">305</context></context-group>
</trans-unit>
- <trans-unit id="_msg96">
+ <trans-unit id="_msg92">
<source xml:space="preserve">&amp;Encrypt Wallet…</source>
<context-group purpose="location"><context context-type="linenumber">310</context></context-group>
</trans-unit>
- <trans-unit id="_msg97">
+ <trans-unit id="_msg93">
<source xml:space="preserve">Encrypt the private keys that belong to your wallet</source>
<context-group purpose="location"><context context-type="linenumber">311</context></context-group>
</trans-unit>
- <trans-unit id="_msg98">
+ <trans-unit id="_msg94">
<source xml:space="preserve">&amp;Backup Wallet…</source>
<context-group purpose="location"><context context-type="linenumber">313</context></context-group>
</trans-unit>
- <trans-unit id="_msg99">
+ <trans-unit id="_msg95">
<source xml:space="preserve">&amp;Change Passphrase…</source>
<context-group purpose="location"><context context-type="linenumber">315</context></context-group>
</trans-unit>
- <trans-unit id="_msg100">
+ <trans-unit id="_msg96">
<source xml:space="preserve">Sign &amp;message…</source>
<context-group purpose="location"><context context-type="linenumber">317</context></context-group>
</trans-unit>
- <trans-unit id="_msg101">
+ <trans-unit id="_msg97">
<source xml:space="preserve">Sign messages with your Bitcoin addresses to prove you own them</source>
<context-group purpose="location"><context context-type="linenumber">318</context></context-group>
</trans-unit>
- <trans-unit id="_msg102">
+ <trans-unit id="_msg98">
<source xml:space="preserve">&amp;Verify message…</source>
<context-group purpose="location"><context context-type="linenumber">319</context></context-group>
</trans-unit>
- <trans-unit id="_msg103">
+ <trans-unit id="_msg99">
<source xml:space="preserve">Verify messages to ensure they were signed with specified Bitcoin addresses</source>
<context-group purpose="location"><context context-type="linenumber">320</context></context-group>
</trans-unit>
- <trans-unit id="_msg104">
+ <trans-unit id="_msg100">
<source xml:space="preserve">&amp;Load PSBT from file…</source>
<context-group purpose="location"><context context-type="linenumber">321</context></context-group>
</trans-unit>
- <trans-unit id="_msg105">
+ <trans-unit id="_msg101">
<source xml:space="preserve">Open &amp;URI…</source>
<context-group purpose="location"><context context-type="linenumber">337</context></context-group>
</trans-unit>
- <trans-unit id="_msg106">
+ <trans-unit id="_msg102">
<source xml:space="preserve">Close Wallet…</source>
<context-group purpose="location"><context context-type="linenumber">345</context></context-group>
</trans-unit>
- <trans-unit id="_msg107">
+ <trans-unit id="_msg103">
<source xml:space="preserve">Create Wallet…</source>
<context-group purpose="location"><context context-type="linenumber">348</context></context-group>
</trans-unit>
- <trans-unit id="_msg108">
+ <trans-unit id="_msg104">
<source xml:space="preserve">Close All Wallets…</source>
<context-group purpose="location"><context context-type="linenumber">358</context></context-group>
</trans-unit>
- <trans-unit id="_msg109">
+ <trans-unit id="_msg105">
<source xml:space="preserve">&amp;File</source>
- <context-group purpose="location"><context context-type="linenumber">477</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">478</context></context-group>
</trans-unit>
- <trans-unit id="_msg110">
+ <trans-unit id="_msg106">
<source xml:space="preserve">&amp;Settings</source>
- <context-group purpose="location"><context context-type="linenumber">497</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">498</context></context-group>
</trans-unit>
- <trans-unit id="_msg111">
+ <trans-unit id="_msg107">
<source xml:space="preserve">&amp;Help</source>
- <context-group purpose="location"><context context-type="linenumber">558</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">559</context></context-group>
</trans-unit>
- <trans-unit id="_msg112">
+ <trans-unit id="_msg108">
<source xml:space="preserve">Tabs toolbar</source>
- <context-group purpose="location"><context context-type="linenumber">569</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">570</context></context-group>
</trans-unit>
- <trans-unit id="_msg113">
+ <trans-unit id="_msg109">
<source xml:space="preserve">Syncing Headers (%1%)…</source>
- <context-group purpose="location"><context context-type="linenumber">1028</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1041</context></context-group>
</trans-unit>
- <trans-unit id="_msg114">
+ <trans-unit id="_msg110">
<source xml:space="preserve">Synchronizing with network…</source>
- <context-group purpose="location"><context context-type="linenumber">1086</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1099</context></context-group>
</trans-unit>
- <trans-unit id="_msg115">
+ <trans-unit id="_msg111">
<source xml:space="preserve">Indexing blocks on disk…</source>
- <context-group purpose="location"><context context-type="linenumber">1091</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1104</context></context-group>
</trans-unit>
- <trans-unit id="_msg116">
+ <trans-unit id="_msg112">
<source xml:space="preserve">Processing blocks on disk…</source>
- <context-group purpose="location"><context context-type="linenumber">1093</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1106</context></context-group>
</trans-unit>
- <trans-unit id="_msg117">
+ <trans-unit id="_msg113">
<source xml:space="preserve">Connecting to peers…</source>
- <context-group purpose="location"><context context-type="linenumber">1100</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1113</context></context-group>
</trans-unit>
- <trans-unit id="_msg118">
+ <trans-unit id="_msg114">
<source xml:space="preserve">Request payments (generates QR codes and bitcoin: URIs)</source>
<context-group purpose="location"><context context-type="linenumber">268</context></context-group>
</trans-unit>
- <trans-unit id="_msg119">
+ <trans-unit id="_msg115">
<source xml:space="preserve">Show the list of used sending addresses and labels</source>
<context-group purpose="location"><context context-type="linenumber">333</context></context-group>
</trans-unit>
- <trans-unit id="_msg120">
+ <trans-unit id="_msg116">
<source xml:space="preserve">Show the list of used receiving addresses and labels</source>
<context-group purpose="location"><context context-type="linenumber">335</context></context-group>
</trans-unit>
- <trans-unit id="_msg121">
+ <trans-unit id="_msg117">
<source xml:space="preserve">&amp;Command-line options</source>
<context-group purpose="location"><context context-type="linenumber">361</context></context-group>
</trans-unit>
<group restype="x-gettext-plurals">
- <context-group purpose="location"><context context-type="linenumber">1109</context></context-group>
- <trans-unit id="_msg122[0]">
+ <context-group purpose="location"><context context-type="linenumber">1122</context></context-group>
+ <trans-unit id="_msg118[0]">
<source xml:space="preserve">Processed %n block(s) of transaction history.</source>
</trans-unit>
- <trans-unit id="_msg122[1]">
+ <trans-unit id="_msg118[1]">
<source xml:space="preserve">Processed %n block(s) of transaction history.</source>
</trans-unit>
</group>
- <trans-unit id="_msg123">
+ <trans-unit id="_msg119">
<source xml:space="preserve">%1 behind</source>
- <context-group purpose="location"><context context-type="linenumber">1132</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1145</context></context-group>
</trans-unit>
- <trans-unit id="_msg124">
+ <trans-unit id="_msg120">
<source xml:space="preserve">Catching up…</source>
- <context-group purpose="location"><context context-type="linenumber">1137</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1150</context></context-group>
</trans-unit>
- <trans-unit id="_msg125">
+ <trans-unit id="_msg121">
<source xml:space="preserve">Last received block was generated %1 ago.</source>
- <context-group purpose="location"><context context-type="linenumber">1156</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1169</context></context-group>
</trans-unit>
- <trans-unit id="_msg126">
+ <trans-unit id="_msg122">
<source xml:space="preserve">Transactions after this will not yet be visible.</source>
- <context-group purpose="location"><context context-type="linenumber">1158</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1171</context></context-group>
</trans-unit>
- <trans-unit id="_msg127">
+ <trans-unit id="_msg123">
<source xml:space="preserve">Error</source>
- <context-group purpose="location"><context context-type="linenumber">1183</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1196</context></context-group>
</trans-unit>
- <trans-unit id="_msg128">
+ <trans-unit id="_msg124">
<source xml:space="preserve">Warning</source>
- <context-group purpose="location"><context context-type="linenumber">1187</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1200</context></context-group>
</trans-unit>
- <trans-unit id="_msg129">
+ <trans-unit id="_msg125">
<source xml:space="preserve">Information</source>
- <context-group purpose="location"><context context-type="linenumber">1191</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1204</context></context-group>
</trans-unit>
- <trans-unit id="_msg130">
+ <trans-unit id="_msg126">
<source xml:space="preserve">Up to date</source>
- <context-group purpose="location"><context context-type="linenumber">1113</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1126</context></context-group>
</trans-unit>
- <trans-unit id="_msg131">
+ <trans-unit id="_msg127">
<source xml:space="preserve">Ctrl+Q</source>
<context-group purpose="location"><context context-type="linenumber">296</context></context-group>
</trans-unit>
- <trans-unit id="_msg132">
+ <trans-unit id="_msg128">
<source xml:space="preserve">Load Partially Signed Bitcoin Transaction</source>
<context-group purpose="location"><context context-type="linenumber">322</context></context-group>
</trans-unit>
- <trans-unit id="_msg133">
+ <trans-unit id="_msg129">
<source xml:space="preserve">Load PSBT from &amp;clipboard…</source>
<context-group purpose="location"><context context-type="linenumber">323</context></context-group>
</trans-unit>
- <trans-unit id="_msg134">
+ <trans-unit id="_msg130">
<source xml:space="preserve">Load Partially Signed Bitcoin Transaction from clipboard</source>
<context-group purpose="location"><context context-type="linenumber">324</context></context-group>
</trans-unit>
- <trans-unit id="_msg135">
+ <trans-unit id="_msg131">
<source xml:space="preserve">Node window</source>
<context-group purpose="location"><context context-type="linenumber">326</context></context-group>
</trans-unit>
- <trans-unit id="_msg136">
+ <trans-unit id="_msg132">
<source xml:space="preserve">Open node debugging and diagnostic console</source>
<context-group purpose="location"><context context-type="linenumber">327</context></context-group>
</trans-unit>
- <trans-unit id="_msg137">
+ <trans-unit id="_msg133">
<source xml:space="preserve">&amp;Sending addresses</source>
<context-group purpose="location"><context context-type="linenumber">332</context></context-group>
</trans-unit>
- <trans-unit id="_msg138">
+ <trans-unit id="_msg134">
<source xml:space="preserve">&amp;Receiving addresses</source>
<context-group purpose="location"><context context-type="linenumber">334</context></context-group>
</trans-unit>
- <trans-unit id="_msg139">
+ <trans-unit id="_msg135">
<source xml:space="preserve">Open a bitcoin: URI</source>
<context-group purpose="location"><context context-type="linenumber">338</context></context-group>
</trans-unit>
- <trans-unit id="_msg140">
+ <trans-unit id="_msg136">
<source xml:space="preserve">Open Wallet</source>
<context-group purpose="location"><context context-type="linenumber">340</context></context-group>
</trans-unit>
- <trans-unit id="_msg141">
+ <trans-unit id="_msg137">
<source xml:space="preserve">Open a wallet</source>
<context-group purpose="location"><context context-type="linenumber">342</context></context-group>
</trans-unit>
- <trans-unit id="_msg142">
+ <trans-unit id="_msg138">
<source xml:space="preserve">Close wallet</source>
<context-group purpose="location"><context context-type="linenumber">346</context></context-group>
</trans-unit>
- <trans-unit id="_msg143">
+ <trans-unit id="_msg139">
<source xml:space="preserve">Restore Wallet…</source>
<context-group purpose="location"><context context-type="linenumber">353</context></context-group>
<note annotates="source" from="developer">Name of the menu item that restores wallet from a backup file.</note>
</trans-unit>
- <trans-unit id="_msg144">
+ <trans-unit id="_msg140">
<source xml:space="preserve">Restore a wallet from a backup file</source>
<context-group purpose="location"><context context-type="linenumber">356</context></context-group>
<note annotates="source" from="developer">Status tip for Restore Wallet menu item</note>
</trans-unit>
- <trans-unit id="_msg145">
+ <trans-unit id="_msg141">
<source xml:space="preserve">Close all wallets</source>
<context-group purpose="location"><context context-type="linenumber">359</context></context-group>
</trans-unit>
- <trans-unit id="_msg146">
+ <trans-unit id="_msg142">
<source xml:space="preserve">Show the %1 help message to get a list with possible Bitcoin command-line options</source>
<context-group purpose="location"><context context-type="linenumber">363</context></context-group>
</trans-unit>
- <trans-unit id="_msg147">
+ <trans-unit id="_msg143">
<source xml:space="preserve">&amp;Mask values</source>
<context-group purpose="location"><context context-type="linenumber">365</context></context-group>
</trans-unit>
- <trans-unit id="_msg148">
+ <trans-unit id="_msg144">
<source xml:space="preserve">Mask the values in the Overview tab</source>
<context-group purpose="location"><context context-type="linenumber">367</context></context-group>
</trans-unit>
- <trans-unit id="_msg149">
+ <trans-unit id="_msg145">
<source xml:space="preserve">default wallet</source>
<context-group purpose="location"><context context-type="linenumber">398</context></context-group>
</trans-unit>
- <trans-unit id="_msg150">
+ <trans-unit id="_msg146">
<source xml:space="preserve">No wallets available</source>
<context-group purpose="location"><context context-type="linenumber">418</context></context-group>
</trans-unit>
- <trans-unit id="_msg151">
+ <trans-unit id="_msg147">
<source xml:space="preserve">Wallet Data</source>
<context-group purpose="location"><context context-type="linenumber">424</context></context-group>
<note annotates="source" from="developer">Name of the wallet data file format.</note>
</trans-unit>
- <trans-unit id="_msg152">
+ <trans-unit id="_msg148">
<source xml:space="preserve">Load Wallet Backup</source>
<context-group purpose="location"><context context-type="linenumber">427</context></context-group>
<note annotates="source" from="developer">The title for Restore Wallet File Windows</note>
</trans-unit>
- <trans-unit id="_msg153">
+ <trans-unit id="_msg149">
<source xml:space="preserve">Restore Wallet</source>
<context-group purpose="location"><context context-type="linenumber">435</context></context-group>
<note annotates="source" from="developer">Title of pop-up window shown when the user is attempting to restore a wallet.</note>
</trans-unit>
- <trans-unit id="_msg154">
+ <trans-unit id="_msg150">
<source xml:space="preserve">Wallet Name</source>
<context-group purpose="location"><context context-type="linenumber">437</context></context-group>
<note annotates="source" from="developer">Label of the input field where the name of the wallet is entered.</note>
</trans-unit>
- <trans-unit id="_msg155">
+ <trans-unit id="_msg151">
<source xml:space="preserve">&amp;Window</source>
- <context-group purpose="location"><context context-type="linenumber">508</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">509</context></context-group>
</trans-unit>
- <trans-unit id="_msg156">
+ <trans-unit id="_msg152">
<source xml:space="preserve">Ctrl+M</source>
- <context-group purpose="location"><context context-type="linenumber">511</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">512</context></context-group>
</trans-unit>
- <trans-unit id="_msg157">
+ <trans-unit id="_msg153">
<source xml:space="preserve">Zoom</source>
- <context-group purpose="location"><context context-type="linenumber">520</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">521</context></context-group>
</trans-unit>
- <trans-unit id="_msg158">
+ <trans-unit id="_msg154">
<source xml:space="preserve">Main Window</source>
- <context-group purpose="location"><context context-type="linenumber">538</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">539</context></context-group>
</trans-unit>
- <trans-unit id="_msg159">
+ <trans-unit id="_msg155">
<source xml:space="preserve">%1 client</source>
- <context-group purpose="location"><context context-type="linenumber">798</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">811</context></context-group>
</trans-unit>
- <trans-unit id="_msg160">
+ <trans-unit id="_msg156">
<source xml:space="preserve">&amp;Hide</source>
- <context-group purpose="location"><context context-type="linenumber">863</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">876</context></context-group>
</trans-unit>
- <trans-unit id="_msg161">
+ <trans-unit id="_msg157">
<source xml:space="preserve">S&amp;how</source>
- <context-group purpose="location"><context context-type="linenumber">864</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">877</context></context-group>
</trans-unit>
<group restype="x-gettext-plurals">
- <context-group purpose="location"><context context-type="linenumber">981</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">994</context></context-group>
<note annotates="source" from="developer">A substring of the tooltip.</note>
- <trans-unit id="_msg162[0]">
+ <trans-unit id="_msg158[0]">
<source xml:space="preserve">%n active connection(s) to Bitcoin network.</source>
</trans-unit>
- <trans-unit id="_msg162[1]">
+ <trans-unit id="_msg158[1]">
<source xml:space="preserve">%n active connection(s) to Bitcoin network.</source>
</trans-unit>
</group>
- <trans-unit id="_msg163">
+ <trans-unit id="_msg159">
<source xml:space="preserve">Click for more actions.</source>
- <context-group purpose="location"><context context-type="linenumber">991</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1004</context></context-group>
<note annotates="source" from="developer">A substring of the tooltip. &quot;More actions&quot; are available via the context menu.</note>
</trans-unit>
- <trans-unit id="_msg164">
+ <trans-unit id="_msg160">
<source xml:space="preserve">Show Peers tab</source>
- <context-group purpose="location"><context context-type="linenumber">1008</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1021</context></context-group>
<note annotates="source" from="developer">A context menu item. The &quot;Peers tab&quot; is an element of the &quot;Node window&quot;.</note>
</trans-unit>
- <trans-unit id="_msg165">
+ <trans-unit id="_msg161">
<source xml:space="preserve">Disable network activity</source>
- <context-group purpose="location"><context context-type="linenumber">1016</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1029</context></context-group>
<note annotates="source" from="developer">A context menu item.</note>
</trans-unit>
- <trans-unit id="_msg166">
+ <trans-unit id="_msg162">
<source xml:space="preserve">Enable network activity</source>
- <context-group purpose="location"><context context-type="linenumber">1018</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1031</context></context-group>
<note annotates="source" from="developer">A context menu item. The network activity was disabled previously.</note>
</trans-unit>
- <trans-unit id="_msg167">
+ <trans-unit id="_msg163">
<source xml:space="preserve">Pre-syncing Headers (%1%)…</source>
- <context-group purpose="location"><context context-type="linenumber">1035</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1048</context></context-group>
</trans-unit>
- <trans-unit id="_msg168">
+ <trans-unit id="_msg164">
<source xml:space="preserve">Error: %1</source>
- <context-group purpose="location"><context context-type="linenumber">1184</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1197</context></context-group>
</trans-unit>
- <trans-unit id="_msg169">
+ <trans-unit id="_msg165">
<source xml:space="preserve">Warning: %1</source>
- <context-group purpose="location"><context context-type="linenumber">1188</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1201</context></context-group>
</trans-unit>
- <trans-unit id="_msg170">
+ <trans-unit id="_msg166">
<source xml:space="preserve">Date: %1
</source>
- <context-group purpose="location"><context context-type="linenumber">1296</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1309</context></context-group>
</trans-unit>
- <trans-unit id="_msg171">
+ <trans-unit id="_msg167">
<source xml:space="preserve">Amount: %1
</source>
- <context-group purpose="location"><context context-type="linenumber">1297</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1310</context></context-group>
</trans-unit>
- <trans-unit id="_msg172">
+ <trans-unit id="_msg168">
<source xml:space="preserve">Wallet: %1
</source>
- <context-group purpose="location"><context context-type="linenumber">1299</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1312</context></context-group>
</trans-unit>
- <trans-unit id="_msg173">
+ <trans-unit id="_msg169">
<source xml:space="preserve">Type: %1
</source>
- <context-group purpose="location"><context context-type="linenumber">1301</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1314</context></context-group>
</trans-unit>
- <trans-unit id="_msg174">
+ <trans-unit id="_msg170">
<source xml:space="preserve">Label: %1
</source>
- <context-group purpose="location"><context context-type="linenumber">1303</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1316</context></context-group>
</trans-unit>
- <trans-unit id="_msg175">
+ <trans-unit id="_msg171">
<source xml:space="preserve">Address: %1
</source>
- <context-group purpose="location"><context context-type="linenumber">1305</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1318</context></context-group>
</trans-unit>
- <trans-unit id="_msg176">
+ <trans-unit id="_msg172">
<source xml:space="preserve">Sent transaction</source>
- <context-group purpose="location"><context context-type="linenumber">1306</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1319</context></context-group>
</trans-unit>
- <trans-unit id="_msg177">
+ <trans-unit id="_msg173">
<source xml:space="preserve">Incoming transaction</source>
- <context-group purpose="location"><context context-type="linenumber">1306</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1319</context></context-group>
</trans-unit>
- <trans-unit id="_msg178">
+ <trans-unit id="_msg174">
<source xml:space="preserve">HD key generation is &lt;b&gt;enabled&lt;/b&gt;</source>
- <context-group purpose="location"><context context-type="linenumber">1358</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1371</context></context-group>
</trans-unit>
- <trans-unit id="_msg179">
+ <trans-unit id="_msg175">
<source xml:space="preserve">HD key generation is &lt;b&gt;disabled&lt;/b&gt;</source>
- <context-group purpose="location"><context context-type="linenumber">1358</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1371</context></context-group>
</trans-unit>
- <trans-unit id="_msg180">
+ <trans-unit id="_msg176">
<source xml:space="preserve">Private key &lt;b&gt;disabled&lt;/b&gt;</source>
- <context-group purpose="location"><context context-type="linenumber">1358</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1371</context></context-group>
</trans-unit>
- <trans-unit id="_msg181">
+ <trans-unit id="_msg177">
<source xml:space="preserve">Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
- <context-group purpose="location"><context context-type="linenumber">1381</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1394</context></context-group>
</trans-unit>
- <trans-unit id="_msg182">
+ <trans-unit id="_msg178">
<source xml:space="preserve">Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
- <context-group purpose="location"><context context-type="linenumber">1389</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1402</context></context-group>
</trans-unit>
- <trans-unit id="_msg183">
+ <trans-unit id="_msg179">
<source xml:space="preserve">Original message:</source>
- <context-group purpose="location"><context context-type="linenumber">1508</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1521</context></context-group>
</trans-unit>
</group>
<group restype="x-trolltech-linguist-context" resname="UnitDisplayStatusBarControl">
- <trans-unit id="_msg184">
+ <trans-unit id="_msg180">
<source xml:space="preserve">Unit to show amounts in. Click to select another unit.</source>
- <context-group purpose="location"><context context-type="linenumber">1547</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1560</context></context-group>
</trans-unit>
</group>
</body></file>
<file original="../forms/coincontroldialog.ui" datatype="x-trolltech-designer-ui" source-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="CoinControlDialog">
- <trans-unit id="_msg185">
+ <trans-unit id="_msg181">
<source xml:space="preserve">Coin Selection</source>
<context-group purpose="location"><context context-type="linenumber">14</context></context-group>
</trans-unit>
- <trans-unit id="_msg186">
+ <trans-unit id="_msg182">
<source xml:space="preserve">Quantity:</source>
<context-group purpose="location"><context context-type="linenumber">48</context></context-group>
</trans-unit>
- <trans-unit id="_msg187">
+ <trans-unit id="_msg183">
<source xml:space="preserve">Bytes:</source>
<context-group purpose="location"><context context-type="linenumber">77</context></context-group>
</trans-unit>
- <trans-unit id="_msg188">
+ <trans-unit id="_msg184">
<source xml:space="preserve">Amount:</source>
<context-group purpose="location"><context context-type="linenumber">122</context></context-group>
</trans-unit>
- <trans-unit id="_msg189">
+ <trans-unit id="_msg185">
<source xml:space="preserve">Fee:</source>
<context-group purpose="location"><context context-type="linenumber">202</context></context-group>
</trans-unit>
- <trans-unit id="_msg190">
+ <trans-unit id="_msg186">
<source xml:space="preserve">Dust:</source>
<context-group purpose="location"><context context-type="linenumber">154</context></context-group>
</trans-unit>
- <trans-unit id="_msg191">
+ <trans-unit id="_msg187">
<source xml:space="preserve">After Fee:</source>
<context-group purpose="location"><context context-type="linenumber">247</context></context-group>
</trans-unit>
- <trans-unit id="_msg192">
+ <trans-unit id="_msg188">
<source xml:space="preserve">Change:</source>
<context-group purpose="location"><context context-type="linenumber">279</context></context-group>
</trans-unit>
- <trans-unit id="_msg193">
+ <trans-unit id="_msg189">
<source xml:space="preserve">(un)select all</source>
<context-group purpose="location"><context context-type="linenumber">335</context></context-group>
</trans-unit>
- <trans-unit id="_msg194">
+ <trans-unit id="_msg190">
<source xml:space="preserve">Tree mode</source>
<context-group purpose="location"><context context-type="linenumber">351</context></context-group>
</trans-unit>
- <trans-unit id="_msg195">
+ <trans-unit id="_msg191">
<source xml:space="preserve">List mode</source>
<context-group purpose="location"><context context-type="linenumber">364</context></context-group>
</trans-unit>
- <trans-unit id="_msg196">
+ <trans-unit id="_msg192">
<source xml:space="preserve">Amount</source>
<context-group purpose="location"><context context-type="linenumber">420</context></context-group>
</trans-unit>
- <trans-unit id="_msg197">
+ <trans-unit id="_msg193">
<source xml:space="preserve">Received with label</source>
<context-group purpose="location"><context context-type="linenumber">425</context></context-group>
</trans-unit>
- <trans-unit id="_msg198">
+ <trans-unit id="_msg194">
<source xml:space="preserve">Received with address</source>
<context-group purpose="location"><context context-type="linenumber">430</context></context-group>
</trans-unit>
- <trans-unit id="_msg199">
+ <trans-unit id="_msg195">
<source xml:space="preserve">Date</source>
<context-group purpose="location"><context context-type="linenumber">435</context></context-group>
</trans-unit>
- <trans-unit id="_msg200">
+ <trans-unit id="_msg196">
<source xml:space="preserve">Confirmations</source>
<context-group purpose="location"><context context-type="linenumber">440</context></context-group>
</trans-unit>
- <trans-unit id="_msg201">
+ <trans-unit id="_msg197">
<source xml:space="preserve">Confirmed</source>
<context-group purpose="location"><context context-type="linenumber">443</context></context-group>
</trans-unit>
@@ -891,88 +873,88 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
</body></file>
<file original="../coincontroldialog.cpp" datatype="cpp" source-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="CoinControlDialog">
- <trans-unit id="_msg202">
+ <trans-unit id="_msg198">
<source xml:space="preserve">Copy amount</source>
<context-group purpose="location"><context context-type="linenumber">69</context></context-group>
</trans-unit>
- <trans-unit id="_msg203">
+ <trans-unit id="_msg199">
<source xml:space="preserve">&amp;Copy address</source>
<context-group purpose="location"><context context-type="linenumber">58</context></context-group>
</trans-unit>
- <trans-unit id="_msg204">
+ <trans-unit id="_msg200">
<source xml:space="preserve">Copy &amp;label</source>
<context-group purpose="location"><context context-type="linenumber">59</context></context-group>
</trans-unit>
- <trans-unit id="_msg205">
+ <trans-unit id="_msg201">
<source xml:space="preserve">Copy &amp;amount</source>
<context-group purpose="location"><context context-type="linenumber">60</context></context-group>
</trans-unit>
- <trans-unit id="_msg206">
+ <trans-unit id="_msg202">
<source xml:space="preserve">Copy transaction &amp;ID and output index</source>
<context-group purpose="location"><context context-type="linenumber">61</context></context-group>
</trans-unit>
- <trans-unit id="_msg207">
+ <trans-unit id="_msg203">
<source xml:space="preserve">L&amp;ock unspent</source>
<context-group purpose="location"><context context-type="linenumber">63</context></context-group>
</trans-unit>
- <trans-unit id="_msg208">
+ <trans-unit id="_msg204">
<source xml:space="preserve">&amp;Unlock unspent</source>
<context-group purpose="location"><context context-type="linenumber">64</context></context-group>
</trans-unit>
- <trans-unit id="_msg209">
+ <trans-unit id="_msg205">
<source xml:space="preserve">Copy quantity</source>
<context-group purpose="location"><context context-type="linenumber">68</context></context-group>
</trans-unit>
- <trans-unit id="_msg210">
+ <trans-unit id="_msg206">
<source xml:space="preserve">Copy fee</source>
<context-group purpose="location"><context context-type="linenumber">70</context></context-group>
</trans-unit>
- <trans-unit id="_msg211">
+ <trans-unit id="_msg207">
<source xml:space="preserve">Copy after fee</source>
<context-group purpose="location"><context context-type="linenumber">71</context></context-group>
</trans-unit>
- <trans-unit id="_msg212">
+ <trans-unit id="_msg208">
<source xml:space="preserve">Copy bytes</source>
<context-group purpose="location"><context context-type="linenumber">72</context></context-group>
</trans-unit>
- <trans-unit id="_msg213">
+ <trans-unit id="_msg209">
<source xml:space="preserve">Copy dust</source>
<context-group purpose="location"><context context-type="linenumber">73</context></context-group>
</trans-unit>
- <trans-unit id="_msg214">
+ <trans-unit id="_msg210">
<source xml:space="preserve">Copy change</source>
<context-group purpose="location"><context context-type="linenumber">74</context></context-group>
</trans-unit>
- <trans-unit id="_msg215">
+ <trans-unit id="_msg211">
<source xml:space="preserve">(%1 locked)</source>
<context-group purpose="location"><context context-type="linenumber">380</context></context-group>
</trans-unit>
- <trans-unit id="_msg216">
+ <trans-unit id="_msg212">
<source xml:space="preserve">yes</source>
<context-group purpose="location"><context context-type="linenumber">534</context></context-group>
</trans-unit>
- <trans-unit id="_msg217">
+ <trans-unit id="_msg213">
<source xml:space="preserve">no</source>
<context-group purpose="location"><context context-type="linenumber">534</context></context-group>
</trans-unit>
- <trans-unit id="_msg218">
+ <trans-unit id="_msg214">
<source xml:space="preserve">This label turns red if any recipient receives an amount smaller than the current dust threshold.</source>
<context-group purpose="location"><context context-type="linenumber">548</context></context-group>
</trans-unit>
- <trans-unit id="_msg219">
+ <trans-unit id="_msg215">
<source xml:space="preserve">Can vary +/- %1 satoshi(s) per input.</source>
<context-group purpose="location"><context context-type="linenumber">553</context></context-group>
</trans-unit>
- <trans-unit id="_msg220">
+ <trans-unit id="_msg216">
<source xml:space="preserve">(no label)</source>
<context-group purpose="location"><context context-type="linenumber">600</context></context-group>
<context-group purpose="location"><context context-type="linenumber">654</context></context-group>
</trans-unit>
- <trans-unit id="_msg221">
+ <trans-unit id="_msg217">
<source xml:space="preserve">change from %1 (%2)</source>
<context-group purpose="location"><context context-type="linenumber">647</context></context-group>
</trans-unit>
- <trans-unit id="_msg222">
+ <trans-unit id="_msg218">
<source xml:space="preserve">(change)</source>
<context-group purpose="location"><context context-type="linenumber">648</context></context-group>
</trans-unit>
@@ -980,114 +962,114 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
</body></file>
<file original="../walletcontroller.cpp" datatype="cpp" source-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="CreateWalletActivity">
- <trans-unit id="_msg223">
+ <trans-unit id="_msg219">
<source xml:space="preserve">Create Wallet</source>
<context-group purpose="location"><context context-type="linenumber">244</context></context-group>
<note annotates="source" from="developer">Title of window indicating the progress of creation of a new wallet.</note>
</trans-unit>
- <trans-unit id="_msg224">
+ <trans-unit id="_msg220">
<source xml:space="preserve">Creating Wallet &lt;b&gt;%1&lt;/b&gt;…</source>
<context-group purpose="location"><context context-type="linenumber">247</context></context-group>
<note annotates="source" from="developer">Descriptive text of the create wallet progress window which indicates to the user which wallet is currently being created.</note>
</trans-unit>
- <trans-unit id="_msg225">
+ <trans-unit id="_msg221">
<source xml:space="preserve">Create wallet failed</source>
<context-group purpose="location"><context context-type="linenumber">280</context></context-group>
</trans-unit>
- <trans-unit id="_msg226">
+ <trans-unit id="_msg222">
<source xml:space="preserve">Create wallet warning</source>
<context-group purpose="location"><context context-type="linenumber">282</context></context-group>
</trans-unit>
- <trans-unit id="_msg227">
+ <trans-unit id="_msg223">
<source xml:space="preserve">Can&apos;t list signers</source>
<context-group purpose="location"><context context-type="linenumber">298</context></context-group>
</trans-unit>
- <trans-unit id="_msg228">
+ <trans-unit id="_msg224">
<source xml:space="preserve">Too many external signers found</source>
<context-group purpose="location"><context context-type="linenumber">301</context></context-group>
</trans-unit>
</group>
<group restype="x-trolltech-linguist-context" resname="LoadWalletsActivity">
- <trans-unit id="_msg229">
+ <trans-unit id="_msg225">
<source xml:space="preserve">Load Wallets</source>
<context-group purpose="location"><context context-type="linenumber">375</context></context-group>
<note annotates="source" from="developer">Title of progress window which is displayed when wallets are being loaded.</note>
</trans-unit>
- <trans-unit id="_msg230">
+ <trans-unit id="_msg226">
<source xml:space="preserve">Loading wallets…</source>
<context-group purpose="location"><context context-type="linenumber">378</context></context-group>
<note annotates="source" from="developer">Descriptive text of the load wallets progress window which indicates to the user that wallets are currently being loaded.</note>
</trans-unit>
</group>
<group restype="x-trolltech-linguist-context" resname="OpenWalletActivity">
- <trans-unit id="_msg231">
+ <trans-unit id="_msg227">
<source xml:space="preserve">Open wallet failed</source>
<context-group purpose="location"><context context-type="linenumber">332</context></context-group>
</trans-unit>
- <trans-unit id="_msg232">
+ <trans-unit id="_msg228">
<source xml:space="preserve">Open wallet warning</source>
<context-group purpose="location"><context context-type="linenumber">334</context></context-group>
</trans-unit>
- <trans-unit id="_msg233">
+ <trans-unit id="_msg229">
<source xml:space="preserve">default wallet</source>
<context-group purpose="location"><context context-type="linenumber">344</context></context-group>
</trans-unit>
- <trans-unit id="_msg234">
+ <trans-unit id="_msg230">
<source xml:space="preserve">Open Wallet</source>
<context-group purpose="location"><context context-type="linenumber">348</context></context-group>
<note annotates="source" from="developer">Title of window indicating the progress of opening of a wallet.</note>
</trans-unit>
- <trans-unit id="_msg235">
+ <trans-unit id="_msg231">
<source xml:space="preserve">Opening Wallet &lt;b&gt;%1&lt;/b&gt;…</source>
<context-group purpose="location"><context context-type="linenumber">351</context></context-group>
<note annotates="source" from="developer">Descriptive text of the open wallet progress window which indicates to the user which wallet is currently being opened.</note>
</trans-unit>
</group>
<group restype="x-trolltech-linguist-context" resname="RestoreWalletActivity">
- <trans-unit id="_msg236">
+ <trans-unit id="_msg232">
<source xml:space="preserve">Restore Wallet</source>
<context-group purpose="location"><context context-type="linenumber">400</context></context-group>
<note annotates="source" from="developer">Title of progress window which is displayed when wallets are being restored.</note>
</trans-unit>
- <trans-unit id="_msg237">
+ <trans-unit id="_msg233">
<source xml:space="preserve">Restoring Wallet &lt;b&gt;%1&lt;/b&gt;…</source>
<context-group purpose="location"><context context-type="linenumber">403</context></context-group>
<note annotates="source" from="developer">Descriptive text of the restore wallets progress window which indicates to the user that wallets are currently being restored.</note>
</trans-unit>
- <trans-unit id="_msg238">
+ <trans-unit id="_msg234">
<source xml:space="preserve">Restore wallet failed</source>
<context-group purpose="location"><context context-type="linenumber">422</context></context-group>
<note annotates="source" from="developer">Title of message box which is displayed when the wallet could not be restored.</note>
</trans-unit>
- <trans-unit id="_msg239">
+ <trans-unit id="_msg235">
<source xml:space="preserve">Restore wallet warning</source>
<context-group purpose="location"><context context-type="linenumber">425</context></context-group>
<note annotates="source" from="developer">Title of message box which is displayed when the wallet is restored with some warning.</note>
</trans-unit>
- <trans-unit id="_msg240">
+ <trans-unit id="_msg236">
<source xml:space="preserve">Restore wallet message</source>
<context-group purpose="location"><context context-type="linenumber">428</context></context-group>
<note annotates="source" from="developer">Title of message box which is displayed when the wallet is successfully restored.</note>
</trans-unit>
</group>
<group restype="x-trolltech-linguist-context" resname="WalletController">
- <trans-unit id="_msg241">
+ <trans-unit id="_msg237">
<source xml:space="preserve">Close wallet</source>
<context-group purpose="location"><context context-type="linenumber">84</context></context-group>
</trans-unit>
- <trans-unit id="_msg242">
+ <trans-unit id="_msg238">
<source xml:space="preserve">Are you sure you wish to close the wallet &lt;i&gt;%1&lt;/i&gt;?</source>
<context-group purpose="location"><context context-type="linenumber">85</context></context-group>
</trans-unit>
- <trans-unit id="_msg243">
+ <trans-unit id="_msg239">
<source xml:space="preserve">Closing the wallet for too long can result in having to resync the entire chain if pruning is enabled.</source>
<context-group purpose="location"><context context-type="linenumber">86</context></context-group>
</trans-unit>
- <trans-unit id="_msg244">
+ <trans-unit id="_msg240">
<source xml:space="preserve">Close all wallets</source>
<context-group purpose="location"><context context-type="linenumber">99</context></context-group>
</trans-unit>
- <trans-unit id="_msg245">
+ <trans-unit id="_msg241">
<source xml:space="preserve">Are you sure you wish to close all wallets?</source>
<context-group purpose="location"><context context-type="linenumber">100</context></context-group>
</trans-unit>
@@ -1095,59 +1077,59 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
</body></file>
<file original="../forms/createwalletdialog.ui" datatype="x-trolltech-designer-ui" source-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="CreateWalletDialog">
- <trans-unit id="_msg246">
+ <trans-unit id="_msg242">
<source xml:space="preserve">Create Wallet</source>
<context-group purpose="location"><context context-type="linenumber">14</context></context-group>
</trans-unit>
- <trans-unit id="_msg247">
+ <trans-unit id="_msg243">
<source xml:space="preserve">Wallet Name</source>
<context-group purpose="location"><context context-type="linenumber">25</context></context-group>
</trans-unit>
- <trans-unit id="_msg248">
+ <trans-unit id="_msg244">
<source xml:space="preserve">Wallet</source>
<context-group purpose="location"><context context-type="linenumber">38</context></context-group>
</trans-unit>
- <trans-unit id="_msg249">
+ <trans-unit id="_msg245">
<source xml:space="preserve">Encrypt the wallet. The wallet will be encrypted with a passphrase of your choice.</source>
<context-group purpose="location"><context context-type="linenumber">47</context></context-group>
</trans-unit>
- <trans-unit id="_msg250">
+ <trans-unit id="_msg246">
<source xml:space="preserve">Encrypt Wallet</source>
<context-group purpose="location"><context context-type="linenumber">50</context></context-group>
</trans-unit>
- <trans-unit id="_msg251">
+ <trans-unit id="_msg247">
<source xml:space="preserve">Advanced Options</source>
<context-group purpose="location"><context context-type="linenumber">76</context></context-group>
</trans-unit>
- <trans-unit id="_msg252">
+ <trans-unit id="_msg248">
<source xml:space="preserve">Disable private keys for this wallet. Wallets with private keys disabled will have no private keys and cannot have an HD seed or imported private keys. This is ideal for watch-only wallets.</source>
<context-group purpose="location"><context context-type="linenumber">85</context></context-group>
</trans-unit>
- <trans-unit id="_msg253">
+ <trans-unit id="_msg249">
<source xml:space="preserve">Disable Private Keys</source>
<context-group purpose="location"><context context-type="linenumber">88</context></context-group>
</trans-unit>
- <trans-unit id="_msg254">
+ <trans-unit id="_msg250">
<source xml:space="preserve">Make a blank wallet. Blank wallets do not initially have private keys or scripts. Private keys and addresses can be imported, or an HD seed can be set, at a later time.</source>
<context-group purpose="location"><context context-type="linenumber">95</context></context-group>
</trans-unit>
- <trans-unit id="_msg255">
+ <trans-unit id="_msg251">
<source xml:space="preserve">Make Blank Wallet</source>
<context-group purpose="location"><context context-type="linenumber">98</context></context-group>
</trans-unit>
- <trans-unit id="_msg256">
+ <trans-unit id="_msg252">
<source xml:space="preserve">Use descriptors for scriptPubKey management</source>
<context-group purpose="location"><context context-type="linenumber">105</context></context-group>
</trans-unit>
- <trans-unit id="_msg257">
+ <trans-unit id="_msg253">
<source xml:space="preserve">Descriptor Wallet</source>
<context-group purpose="location"><context context-type="linenumber">108</context></context-group>
</trans-unit>
- <trans-unit id="_msg258">
+ <trans-unit id="_msg254">
<source xml:space="preserve">Use an external signing device such as a hardware wallet. Configure the external signer script in wallet preferences first.</source>
<context-group purpose="location"><context context-type="linenumber">118</context></context-group>
</trans-unit>
- <trans-unit id="_msg259">
+ <trans-unit id="_msg255">
<source xml:space="preserve">External signer</source>
<context-group purpose="location"><context context-type="linenumber">121</context></context-group>
</trans-unit>
@@ -1155,15 +1137,15 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
</body></file>
<file original="../createwalletdialog.cpp" datatype="cpp" source-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="CreateWalletDialog">
- <trans-unit id="_msg260">
+ <trans-unit id="_msg256">
<source xml:space="preserve">Create</source>
<context-group purpose="location"><context context-type="linenumber">22</context></context-group>
</trans-unit>
- <trans-unit id="_msg261">
+ <trans-unit id="_msg257">
<source xml:space="preserve">Compiled without sqlite support (required for descriptor wallets)</source>
<context-group purpose="location"><context context-type="linenumber">90</context></context-group>
</trans-unit>
- <trans-unit id="_msg262">
+ <trans-unit id="_msg258">
<source xml:space="preserve">Compiled without external signing support (required for external signing)</source>
<context-group purpose="location"><context context-type="linenumber">104</context></context-group>
<note annotates="source" from="developer">&quot;External signing&quot; means using devices such as hardware wallets.</note>
@@ -1172,23 +1154,23 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
</body></file>
<file original="../forms/editaddressdialog.ui" datatype="x-trolltech-designer-ui" source-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="EditAddressDialog">
- <trans-unit id="_msg263">
+ <trans-unit id="_msg259">
<source xml:space="preserve">Edit Address</source>
<context-group purpose="location"><context context-type="linenumber">14</context></context-group>
</trans-unit>
- <trans-unit id="_msg264">
+ <trans-unit id="_msg260">
<source xml:space="preserve">&amp;Label</source>
<context-group purpose="location"><context context-type="linenumber">25</context></context-group>
</trans-unit>
- <trans-unit id="_msg265">
+ <trans-unit id="_msg261">
<source xml:space="preserve">The label associated with this address list entry</source>
<context-group purpose="location"><context context-type="linenumber">35</context></context-group>
</trans-unit>
- <trans-unit id="_msg266">
+ <trans-unit id="_msg262">
<source xml:space="preserve">The address associated with this address list entry. This can only be modified for sending addresses.</source>
<context-group purpose="location"><context context-type="linenumber">52</context></context-group>
</trans-unit>
- <trans-unit id="_msg267">
+ <trans-unit id="_msg263">
<source xml:space="preserve">&amp;Address</source>
<context-group purpose="location"><context context-type="linenumber">42</context></context-group>
</trans-unit>
@@ -1196,35 +1178,35 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
</body></file>
<file original="../editaddressdialog.cpp" datatype="cpp" source-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="EditAddressDialog">
- <trans-unit id="_msg268">
+ <trans-unit id="_msg264">
<source xml:space="preserve">New sending address</source>
<context-group purpose="location"><context context-type="linenumber">27</context></context-group>
</trans-unit>
- <trans-unit id="_msg269">
+ <trans-unit id="_msg265">
<source xml:space="preserve">Edit receiving address</source>
<context-group purpose="location"><context context-type="linenumber">30</context></context-group>
</trans-unit>
- <trans-unit id="_msg270">
+ <trans-unit id="_msg266">
<source xml:space="preserve">Edit sending address</source>
<context-group purpose="location"><context context-type="linenumber">34</context></context-group>
</trans-unit>
- <trans-unit id="_msg271">
+ <trans-unit id="_msg267">
<source xml:space="preserve">The entered address &quot;%1&quot; is not a valid Bitcoin address.</source>
<context-group purpose="location"><context context-type="linenumber">111</context></context-group>
</trans-unit>
- <trans-unit id="_msg272">
+ <trans-unit id="_msg268">
<source xml:space="preserve">Address &quot;%1&quot; already exists as a receiving address with label &quot;%2&quot; and so cannot be added as a sending address.</source>
<context-group purpose="location"><context context-type="linenumber">144</context></context-group>
</trans-unit>
- <trans-unit id="_msg273">
+ <trans-unit id="_msg269">
<source xml:space="preserve">The entered address &quot;%1&quot; is already in the address book with label &quot;%2&quot;.</source>
<context-group purpose="location"><context context-type="linenumber">149</context></context-group>
</trans-unit>
- <trans-unit id="_msg274">
+ <trans-unit id="_msg270">
<source xml:space="preserve">Could not unlock wallet.</source>
<context-group purpose="location"><context context-type="linenumber">121</context></context-group>
</trans-unit>
- <trans-unit id="_msg275">
+ <trans-unit id="_msg271">
<source xml:space="preserve">New key generation failed.</source>
<context-group purpose="location"><context context-type="linenumber">126</context></context-group>
</trans-unit>
@@ -1232,90 +1214,94 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
</body></file>
<file original="../intro.cpp" datatype="cpp" source-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="FreespaceChecker">
- <trans-unit id="_msg276">
+ <trans-unit id="_msg272">
<source xml:space="preserve">A new data directory will be created.</source>
<context-group purpose="location"><context context-type="linenumber">73</context></context-group>
</trans-unit>
- <trans-unit id="_msg277">
+ <trans-unit id="_msg273">
<source xml:space="preserve">name</source>
<context-group purpose="location"><context context-type="linenumber">95</context></context-group>
</trans-unit>
- <trans-unit id="_msg278">
+ <trans-unit id="_msg274">
<source xml:space="preserve">Directory already exists. Add %1 if you intend to create a new directory here.</source>
<context-group purpose="location"><context context-type="linenumber">97</context></context-group>
</trans-unit>
- <trans-unit id="_msg279">
+ <trans-unit id="_msg275">
<source xml:space="preserve">Path already exists, and is not a directory.</source>
<context-group purpose="location"><context context-type="linenumber">100</context></context-group>
</trans-unit>
- <trans-unit id="_msg280">
+ <trans-unit id="_msg276">
<source xml:space="preserve">Cannot create data directory here.</source>
<context-group purpose="location"><context context-type="linenumber">107</context></context-group>
</trans-unit>
</group>
<group restype="x-trolltech-linguist-context" resname="Intro">
- <trans-unit id="_msg281">
+ <trans-unit id="_msg277">
<source xml:space="preserve">Bitcoin</source>
<context-group purpose="location"><context context-type="linenumber">137</context></context-group>
</trans-unit>
<group restype="x-gettext-plurals">
<context-group purpose="location"><context context-type="linenumber">299</context></context-group>
- <trans-unit id="_msg282[0]">
+ <trans-unit id="_msg278[0]">
<source xml:space="preserve">%n GB of space available</source>
</trans-unit>
- <trans-unit id="_msg282[1]">
+ <trans-unit id="_msg278[1]">
<source xml:space="preserve">%n GB of space available</source>
</trans-unit>
</group>
<group restype="x-gettext-plurals">
<context-group purpose="location"><context context-type="linenumber">301</context></context-group>
- <trans-unit id="_msg283[0]">
+ <trans-unit id="_msg279[0]">
<source xml:space="preserve">(of %n GB needed)</source>
</trans-unit>
- <trans-unit id="_msg283[1]">
+ <trans-unit id="_msg279[1]">
<source xml:space="preserve">(of %n GB needed)</source>
</trans-unit>
</group>
<group restype="x-gettext-plurals">
<context-group purpose="location"><context context-type="linenumber">304</context></context-group>
- <trans-unit id="_msg284[0]">
+ <trans-unit id="_msg280[0]">
<source xml:space="preserve">(%n GB needed for full chain)</source>
</trans-unit>
- <trans-unit id="_msg284[1]">
+ <trans-unit id="_msg280[1]">
<source xml:space="preserve">(%n GB needed for full chain)</source>
</trans-unit>
</group>
- <trans-unit id="_msg285">
+ <trans-unit id="_msg281">
+ <source xml:space="preserve">Choose data directory</source>
+ <context-group purpose="location"><context context-type="linenumber">321</context></context-group>
+ </trans-unit>
+ <trans-unit id="_msg282">
<source xml:space="preserve">At least %1 GB of data will be stored in this directory, and it will grow over time.</source>
<context-group purpose="location"><context context-type="linenumber">376</context></context-group>
</trans-unit>
- <trans-unit id="_msg286">
+ <trans-unit id="_msg283">
<source xml:space="preserve">Approximately %1 GB of data will be stored in this directory.</source>
<context-group purpose="location"><context context-type="linenumber">379</context></context-group>
</trans-unit>
<group restype="x-gettext-plurals">
<context-group purpose="location"><context context-type="linenumber">388</context></context-group>
<note annotates="source" from="developer">Explanatory text on the capability of the current prune target.</note>
- <trans-unit id="_msg287[0]">
+ <trans-unit id="_msg284[0]">
<source xml:space="preserve">(sufficient to restore backups %n day(s) old)</source>
</trans-unit>
- <trans-unit id="_msg287[1]">
+ <trans-unit id="_msg284[1]">
<source xml:space="preserve">(sufficient to restore backups %n day(s) old)</source>
</trans-unit>
</group>
- <trans-unit id="_msg288">
+ <trans-unit id="_msg285">
<source xml:space="preserve">%1 will download and store a copy of the Bitcoin block chain.</source>
<context-group purpose="location"><context context-type="linenumber">390</context></context-group>
</trans-unit>
- <trans-unit id="_msg289">
+ <trans-unit id="_msg286">
<source xml:space="preserve">The wallet will also be stored in this directory.</source>
<context-group purpose="location"><context context-type="linenumber">392</context></context-group>
</trans-unit>
- <trans-unit id="_msg290">
+ <trans-unit id="_msg287">
<source xml:space="preserve">Error: Specified data directory &quot;%1&quot; cannot be created.</source>
<context-group purpose="location"><context context-type="linenumber">248</context></context-group>
</trans-unit>
- <trans-unit id="_msg291">
+ <trans-unit id="_msg288">
<source xml:space="preserve">Error</source>
<context-group purpose="location"><context context-type="linenumber">278</context></context-group>
</trans-unit>
@@ -1323,25 +1309,25 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
</body></file>
<file original="../utilitydialog.cpp" datatype="cpp" source-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="HelpMessageDialog">
- <trans-unit id="_msg292">
+ <trans-unit id="_msg289">
<source xml:space="preserve">version</source>
<context-group purpose="location"><context context-type="linenumber">38</context></context-group>
</trans-unit>
- <trans-unit id="_msg293">
+ <trans-unit id="_msg290">
<source xml:space="preserve">About %1</source>
<context-group purpose="location"><context context-type="linenumber">42</context></context-group>
</trans-unit>
- <trans-unit id="_msg294">
+ <trans-unit id="_msg291">
<source xml:space="preserve">Command-line options</source>
<context-group purpose="location"><context context-type="linenumber">60</context></context-group>
</trans-unit>
</group>
<group restype="x-trolltech-linguist-context" resname="ShutdownWindow">
- <trans-unit id="_msg295">
+ <trans-unit id="_msg292">
<source xml:space="preserve">%1 is shutting down…</source>
<context-group purpose="location"><context context-type="linenumber">145</context></context-group>
</trans-unit>
- <trans-unit id="_msg296">
+ <trans-unit id="_msg293">
<source xml:space="preserve">Do not shut down the computer until this window disappears.</source>
<context-group purpose="location"><context context-type="linenumber">146</context></context-group>
</trans-unit>
@@ -1349,47 +1335,47 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
</body></file>
<file original="../forms/intro.ui" datatype="x-trolltech-designer-ui" source-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="Intro">
- <trans-unit id="_msg297">
+ <trans-unit id="_msg294">
<source xml:space="preserve">Welcome</source>
<context-group purpose="location"><context context-type="linenumber">14</context></context-group>
</trans-unit>
- <trans-unit id="_msg298">
+ <trans-unit id="_msg295">
<source xml:space="preserve">Welcome to %1.</source>
<context-group purpose="location"><context context-type="linenumber">23</context></context-group>
</trans-unit>
- <trans-unit id="_msg299">
+ <trans-unit id="_msg296">
<source xml:space="preserve">As this is the first time the program is launched, you can choose where %1 will store its data.</source>
<context-group purpose="location"><context context-type="linenumber">49</context></context-group>
</trans-unit>
- <trans-unit id="_msg300">
+ <trans-unit id="_msg297">
<source xml:space="preserve">Limit block chain storage to</source>
<context-group purpose="location"><context context-type="linenumber">238</context></context-group>
</trans-unit>
- <trans-unit id="_msg301">
+ <trans-unit id="_msg298">
<source xml:space="preserve">Reverting this setting requires re-downloading the entire blockchain. It is faster to download the full chain first and prune it later. Disables some advanced features.</source>
<context-group purpose="location"><context context-type="linenumber">241</context></context-group>
</trans-unit>
- <trans-unit id="_msg302">
+ <trans-unit id="_msg299">
<source xml:space="preserve"> GB</source>
<context-group purpose="location"><context context-type="linenumber">248</context></context-group>
</trans-unit>
- <trans-unit id="_msg303">
+ <trans-unit id="_msg300">
<source xml:space="preserve">This initial synchronisation is very demanding, and may expose hardware problems with your computer that had previously gone unnoticed. Each time you run %1, it will continue downloading where it left off.</source>
<context-group purpose="location"><context context-type="linenumber">216</context></context-group>
</trans-unit>
- <trans-unit id="_msg304">
+ <trans-unit id="_msg301">
<source xml:space="preserve">When you click OK, %1 will begin to download and process the full %4 block chain (%2 GB) starting with the earliest transactions in %3 when %4 initially launched.</source>
<context-group purpose="location"><context context-type="linenumber">206</context></context-group>
</trans-unit>
- <trans-unit id="_msg305">
+ <trans-unit id="_msg302">
<source xml:space="preserve">If you have chosen to limit block chain storage (pruning), the historical data must still be downloaded and processed, but will be deleted afterward to keep your disk usage low.</source>
<context-group purpose="location"><context context-type="linenumber">226</context></context-group>
</trans-unit>
- <trans-unit id="_msg306">
+ <trans-unit id="_msg303">
<source xml:space="preserve">Use the default data directory</source>
<context-group purpose="location"><context context-type="linenumber">66</context></context-group>
</trans-unit>
- <trans-unit id="_msg307">
+ <trans-unit id="_msg304">
<source xml:space="preserve">Use a custom data directory:</source>
<context-group purpose="location"><context context-type="linenumber">73</context></context-group>
</trans-unit>
@@ -1397,54 +1383,54 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
</body></file>
<file original="../forms/modaloverlay.ui" datatype="x-trolltech-designer-ui" source-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="ModalOverlay">
- <trans-unit id="_msg308">
+ <trans-unit id="_msg305">
<source xml:space="preserve">Form</source>
<context-group purpose="location"><context context-type="linenumber">14</context></context-group>
</trans-unit>
- <trans-unit id="_msg309">
+ <trans-unit id="_msg306">
<source xml:space="preserve">Recent transactions may not yet be visible, and therefore your wallet&apos;s balance might be incorrect. This information will be correct once your wallet has finished synchronizing with the bitcoin network, as detailed below.</source>
<context-group purpose="location"><context context-type="linenumber">133</context></context-group>
</trans-unit>
- <trans-unit id="_msg310">
+ <trans-unit id="_msg307">
<source xml:space="preserve">Attempting to spend bitcoins that are affected by not-yet-displayed transactions will not be accepted by the network.</source>
<context-group purpose="location"><context context-type="linenumber">152</context></context-group>
</trans-unit>
- <trans-unit id="_msg311">
+ <trans-unit id="_msg308">
<source xml:space="preserve">Number of blocks left</source>
<context-group purpose="location"><context context-type="linenumber">215</context></context-group>
</trans-unit>
- <trans-unit id="_msg312">
+ <trans-unit id="_msg309">
<source xml:space="preserve">Unknown…</source>
<context-group purpose="location"><context context-type="linenumber">222</context></context-group>
<context-group purpose="location"><context context-type="linenumber">248</context></context-group>
<context-group purpose="location"><context context-type="sourcefile">../modaloverlay.cpp</context><context context-type="linenumber">152</context></context-group>
</trans-unit>
- <trans-unit id="_msg313">
+ <trans-unit id="_msg310">
<source xml:space="preserve">calculating…</source>
<context-group purpose="location"><context context-type="linenumber">292</context></context-group>
<context-group purpose="location"><context context-type="linenumber">312</context></context-group>
</trans-unit>
- <trans-unit id="_msg314">
+ <trans-unit id="_msg311">
<source xml:space="preserve">Last block time</source>
<context-group purpose="location"><context context-type="linenumber">235</context></context-group>
</trans-unit>
- <trans-unit id="_msg315">
+ <trans-unit id="_msg312">
<source xml:space="preserve">Progress</source>
<context-group purpose="location"><context context-type="linenumber">261</context></context-group>
</trans-unit>
- <trans-unit id="_msg316">
+ <trans-unit id="_msg313">
<source xml:space="preserve">Progress increase per hour</source>
<context-group purpose="location"><context context-type="linenumber">285</context></context-group>
</trans-unit>
- <trans-unit id="_msg317">
+ <trans-unit id="_msg314">
<source xml:space="preserve">Estimated time left until synced</source>
<context-group purpose="location"><context context-type="linenumber">305</context></context-group>
</trans-unit>
- <trans-unit id="_msg318">
+ <trans-unit id="_msg315">
<source xml:space="preserve">Hide</source>
<context-group purpose="location"><context context-type="linenumber">342</context></context-group>
</trans-unit>
- <trans-unit id="_msg319">
+ <trans-unit id="_msg316">
<source xml:space="preserve">Esc</source>
<context-group purpose="location"><context context-type="linenumber">345</context></context-group>
</trans-unit>
@@ -1452,21 +1438,21 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
</body></file>
<file original="../modaloverlay.cpp" datatype="cpp" source-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="ModalOverlay">
- <trans-unit id="_msg320">
+ <trans-unit id="_msg317">
<source xml:space="preserve">%1 is currently syncing. It will download headers and blocks from peers and validate them until reaching the tip of the block chain.</source>
<context-group purpose="location"><context context-type="linenumber">31</context></context-group>
</trans-unit>
- <trans-unit id="_msg321">
+ <trans-unit id="_msg318">
<source xml:space="preserve">Unknown. Syncing Headers (%1, %2%)…</source>
<context-group purpose="location"><context context-type="linenumber">158</context></context-group>
</trans-unit>
- <trans-unit id="_msg322">
+ <trans-unit id="_msg319">
<source xml:space="preserve">Unknown. Pre-syncing Headers (%1, %2%)…</source>
<context-group purpose="location"><context context-type="linenumber">163</context></context-group>
</trans-unit>
</group>
<group restype="x-trolltech-linguist-context" resname="QObject">
- <trans-unit id="_msg323">
+ <trans-unit id="_msg320">
<source xml:space="preserve">unknown</source>
<context-group purpose="location"><context context-type="linenumber">123</context></context-group>
</trans-unit>
@@ -1474,15 +1460,15 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
</body></file>
<file original="../forms/openuridialog.ui" datatype="x-trolltech-designer-ui" source-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="OpenURIDialog">
- <trans-unit id="_msg324">
+ <trans-unit id="_msg321">
<source xml:space="preserve">Open bitcoin URI</source>
<context-group purpose="location"><context context-type="linenumber">14</context></context-group>
</trans-unit>
- <trans-unit id="_msg325">
+ <trans-unit id="_msg322">
<source xml:space="preserve">URI:</source>
<context-group purpose="location"><context context-type="linenumber">22</context></context-group>
</trans-unit>
- <trans-unit id="_msg326">
+ <trans-unit id="_msg323">
<source xml:space="preserve">Paste address from clipboard</source>
<context-group purpose="location"><context context-type="linenumber">36</context></context-group>
<note annotates="source" from="developer">Tooltip text for button that allows you to paste an address that is in your clipboard.</note>
@@ -1491,310 +1477,310 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
</body></file>
<file original="../forms/optionsdialog.ui" datatype="x-trolltech-designer-ui" source-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="OptionsDialog">
- <trans-unit id="_msg327">
+ <trans-unit id="_msg324">
<source xml:space="preserve">Options</source>
<context-group purpose="location"><context context-type="linenumber">14</context></context-group>
</trans-unit>
- <trans-unit id="_msg328">
+ <trans-unit id="_msg325">
<source xml:space="preserve">&amp;Main</source>
<context-group purpose="location"><context context-type="linenumber">27</context></context-group>
</trans-unit>
- <trans-unit id="_msg329">
+ <trans-unit id="_msg326">
<source xml:space="preserve">Automatically start %1 after logging in to the system.</source>
<context-group purpose="location"><context context-type="linenumber">33</context></context-group>
</trans-unit>
- <trans-unit id="_msg330">
+ <trans-unit id="_msg327">
<source xml:space="preserve">&amp;Start %1 on system login</source>
<context-group purpose="location"><context context-type="linenumber">36</context></context-group>
</trans-unit>
- <trans-unit id="_msg331">
+ <trans-unit id="_msg328">
<source xml:space="preserve">Enabling pruning significantly reduces the disk space required to store transactions. All blocks are still fully validated. Reverting this setting requires re-downloading the entire blockchain.</source>
<context-group purpose="location"><context context-type="linenumber">58</context></context-group>
</trans-unit>
- <trans-unit id="_msg332">
+ <trans-unit id="_msg329">
<source xml:space="preserve">Size of &amp;database cache</source>
<context-group purpose="location"><context context-type="linenumber">111</context></context-group>
</trans-unit>
- <trans-unit id="_msg333">
+ <trans-unit id="_msg330">
<source xml:space="preserve">Number of script &amp;verification threads</source>
<context-group purpose="location"><context context-type="linenumber">157</context></context-group>
</trans-unit>
- <trans-unit id="_msg334">
+ <trans-unit id="_msg331">
<source xml:space="preserve">Full path to a %1 compatible script (e.g. C:\Downloads\hwi.exe or /Users/you/Downloads/hwi.py). Beware: malware can steal your coins!</source>
<context-group purpose="location"><context context-type="linenumber">289</context></context-group>
</trans-unit>
- <trans-unit id="_msg335">
+ <trans-unit id="_msg332">
<source xml:space="preserve">IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
<context-group purpose="location"><context context-type="linenumber">388</context></context-group>
<context-group purpose="location"><context context-type="linenumber">575</context></context-group>
</trans-unit>
- <trans-unit id="_msg336">
+ <trans-unit id="_msg333">
<source xml:space="preserve">Shows if the supplied default SOCKS5 proxy is used to reach peers via this network type.</source>
<context-group purpose="location"><context context-type="linenumber">457</context></context-group>
<context-group purpose="location"><context context-type="linenumber">480</context></context-group>
<context-group purpose="location"><context context-type="linenumber">503</context></context-group>
</trans-unit>
- <trans-unit id="_msg337">
+ <trans-unit id="_msg334">
<source xml:space="preserve">Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source>
<context-group purpose="location"><context context-type="linenumber">672</context></context-group>
</trans-unit>
- <trans-unit id="_msg338">
+ <trans-unit id="_msg335">
<source xml:space="preserve">Options set in this dialog are overridden by the command line:</source>
<context-group purpose="location"><context context-type="linenumber">899</context></context-group>
</trans-unit>
- <trans-unit id="_msg339">
+ <trans-unit id="_msg336">
<source xml:space="preserve">Open the %1 configuration file from the working directory.</source>
<context-group purpose="location"><context context-type="linenumber">944</context></context-group>
</trans-unit>
- <trans-unit id="_msg340">
+ <trans-unit id="_msg337">
<source xml:space="preserve">Open Configuration File</source>
<context-group purpose="location"><context context-type="linenumber">947</context></context-group>
</trans-unit>
- <trans-unit id="_msg341">
+ <trans-unit id="_msg338">
<source xml:space="preserve">Reset all client options to default.</source>
<context-group purpose="location"><context context-type="linenumber">957</context></context-group>
</trans-unit>
- <trans-unit id="_msg342">
+ <trans-unit id="_msg339">
<source xml:space="preserve">&amp;Reset Options</source>
<context-group purpose="location"><context context-type="linenumber">960</context></context-group>
</trans-unit>
- <trans-unit id="_msg343">
+ <trans-unit id="_msg340">
<source xml:space="preserve">&amp;Network</source>
<context-group purpose="location"><context context-type="linenumber">315</context></context-group>
</trans-unit>
- <trans-unit id="_msg344">
+ <trans-unit id="_msg341">
<source xml:space="preserve">Prune &amp;block storage to</source>
<context-group purpose="location"><context context-type="linenumber">61</context></context-group>
</trans-unit>
- <trans-unit id="_msg345">
+ <trans-unit id="_msg342">
<source xml:space="preserve">GB</source>
<context-group purpose="location"><context context-type="linenumber">71</context></context-group>
</trans-unit>
- <trans-unit id="_msg346">
+ <trans-unit id="_msg343">
<source xml:space="preserve">Reverting this setting requires re-downloading the entire blockchain.</source>
<context-group purpose="location"><context context-type="linenumber">96</context></context-group>
</trans-unit>
- <trans-unit id="_msg347">
+ <trans-unit id="_msg344">
<source xml:space="preserve">Maximum database cache size. A larger cache can contribute to faster sync, after which the benefit is less pronounced for most use cases. Lowering the cache size will reduce memory usage. Unused mempool memory is shared for this cache.</source>
<context-group purpose="location"><context context-type="linenumber">108</context></context-group>
<note annotates="source" from="developer">Tooltip text for Options window setting that sets the size of the database cache. Explains the corresponding effects of increasing/decreasing this value.</note>
</trans-unit>
- <trans-unit id="_msg348">
+ <trans-unit id="_msg345">
<source xml:space="preserve">MiB</source>
<context-group purpose="location"><context context-type="linenumber">127</context></context-group>
</trans-unit>
- <trans-unit id="_msg349">
+ <trans-unit id="_msg346">
<source xml:space="preserve">Set the number of script verification threads. Negative values correspond to the number of cores you want to leave free to the system.</source>
<context-group purpose="location"><context context-type="linenumber">154</context></context-group>
<note annotates="source" from="developer">Tooltip text for Options window setting that sets the number of script verification threads. Explains that negative values mean to leave these many cores free to the system.</note>
</trans-unit>
- <trans-unit id="_msg350">
+ <trans-unit id="_msg347">
<source xml:space="preserve">(0 = auto, &lt;0 = leave that many cores free)</source>
<context-group purpose="location"><context context-type="linenumber">170</context></context-group>
</trans-unit>
- <trans-unit id="_msg351">
+ <trans-unit id="_msg348">
<source xml:space="preserve">This allows you or a third party tool to communicate with the node through command-line and JSON-RPC commands.</source>
<context-group purpose="location"><context context-type="linenumber">192</context></context-group>
<note annotates="source" from="developer">Tooltip text for Options window setting that enables the RPC server.</note>
</trans-unit>
- <trans-unit id="_msg352">
+ <trans-unit id="_msg349">
<source xml:space="preserve">Enable R&amp;PC server</source>
<context-group purpose="location"><context context-type="linenumber">195</context></context-group>
<note annotates="source" from="developer">An Options window setting to enable the RPC server.</note>
</trans-unit>
- <trans-unit id="_msg353">
+ <trans-unit id="_msg350">
<source xml:space="preserve">W&amp;allet</source>
<context-group purpose="location"><context context-type="linenumber">216</context></context-group>
</trans-unit>
- <trans-unit id="_msg354">
+ <trans-unit id="_msg351">
<source xml:space="preserve">Whether to set subtract fee from amount as default or not.</source>
<context-group purpose="location"><context context-type="linenumber">222</context></context-group>
<note annotates="source" from="developer">Tooltip text for Options window setting that sets subtracting the fee from a sending amount as default.</note>
</trans-unit>
- <trans-unit id="_msg355">
+ <trans-unit id="_msg352">
<source xml:space="preserve">Subtract &amp;fee from amount by default</source>
<context-group purpose="location"><context context-type="linenumber">225</context></context-group>
<note annotates="source" from="developer">An Options window setting to set subtracting the fee from a sending amount as default.</note>
</trans-unit>
- <trans-unit id="_msg356">
+ <trans-unit id="_msg353">
<source xml:space="preserve">Expert</source>
<context-group purpose="location"><context context-type="linenumber">232</context></context-group>
</trans-unit>
- <trans-unit id="_msg357">
+ <trans-unit id="_msg354">
<source xml:space="preserve">Enable coin &amp;control features</source>
<context-group purpose="location"><context context-type="linenumber">241</context></context-group>
</trans-unit>
- <trans-unit id="_msg358">
+ <trans-unit id="_msg355">
<source xml:space="preserve">If you disable the spending of unconfirmed change, the change from a transaction cannot be used until that transaction has at least one confirmation. This also affects how your balance is computed.</source>
<context-group purpose="location"><context context-type="linenumber">248</context></context-group>
</trans-unit>
- <trans-unit id="_msg359">
+ <trans-unit id="_msg356">
<source xml:space="preserve">&amp;Spend unconfirmed change</source>
<context-group purpose="location"><context context-type="linenumber">251</context></context-group>
</trans-unit>
- <trans-unit id="_msg360">
+ <trans-unit id="_msg357">
<source xml:space="preserve">Enable &amp;PSBT controls</source>
<context-group purpose="location"><context context-type="linenumber">258</context></context-group>
<note annotates="source" from="developer">An options window setting to enable PSBT controls.</note>
</trans-unit>
- <trans-unit id="_msg361">
+ <trans-unit id="_msg358">
<source xml:space="preserve">Whether to show PSBT controls.</source>
<context-group purpose="location"><context context-type="linenumber">261</context></context-group>
<note annotates="source" from="developer">Tooltip text for options window setting that enables PSBT controls.</note>
</trans-unit>
- <trans-unit id="_msg362">
+ <trans-unit id="_msg359">
<source xml:space="preserve">External Signer (e.g. hardware wallet)</source>
<context-group purpose="location"><context context-type="linenumber">271</context></context-group>
</trans-unit>
- <trans-unit id="_msg363">
+ <trans-unit id="_msg360">
<source xml:space="preserve">&amp;External signer script path</source>
<context-group purpose="location"><context context-type="linenumber">279</context></context-group>
</trans-unit>
- <trans-unit id="_msg364">
+ <trans-unit id="_msg361">
<source xml:space="preserve">Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source>
<context-group purpose="location"><context context-type="linenumber">321</context></context-group>
</trans-unit>
- <trans-unit id="_msg365">
+ <trans-unit id="_msg362">
<source xml:space="preserve">Map port using &amp;UPnP</source>
<context-group purpose="location"><context context-type="linenumber">324</context></context-group>
</trans-unit>
- <trans-unit id="_msg366">
+ <trans-unit id="_msg363">
<source xml:space="preserve">Automatically open the Bitcoin client port on the router. This only works when your router supports NAT-PMP and it is enabled. The external port could be random.</source>
<context-group purpose="location"><context context-type="linenumber">331</context></context-group>
</trans-unit>
- <trans-unit id="_msg367">
+ <trans-unit id="_msg364">
<source xml:space="preserve">Map port using NA&amp;T-PMP</source>
<context-group purpose="location"><context context-type="linenumber">334</context></context-group>
</trans-unit>
- <trans-unit id="_msg368">
+ <trans-unit id="_msg365">
<source xml:space="preserve">Accept connections from outside.</source>
<context-group purpose="location"><context context-type="linenumber">341</context></context-group>
</trans-unit>
- <trans-unit id="_msg369">
+ <trans-unit id="_msg366">
<source xml:space="preserve">Allow incomin&amp;g connections</source>
<context-group purpose="location"><context context-type="linenumber">344</context></context-group>
</trans-unit>
- <trans-unit id="_msg370">
+ <trans-unit id="_msg367">
<source xml:space="preserve">Connect to the Bitcoin network through a SOCKS5 proxy.</source>
<context-group purpose="location"><context context-type="linenumber">351</context></context-group>
</trans-unit>
- <trans-unit id="_msg371">
+ <trans-unit id="_msg368">
<source xml:space="preserve">&amp;Connect through SOCKS5 proxy (default proxy):</source>
<context-group purpose="location"><context context-type="linenumber">354</context></context-group>
</trans-unit>
- <trans-unit id="_msg372">
+ <trans-unit id="_msg369">
<source xml:space="preserve">Proxy &amp;IP:</source>
<context-group purpose="location"><context context-type="linenumber">363</context></context-group>
<context-group purpose="location"><context context-type="linenumber">550</context></context-group>
</trans-unit>
- <trans-unit id="_msg373">
+ <trans-unit id="_msg370">
<source xml:space="preserve">&amp;Port:</source>
<context-group purpose="location"><context context-type="linenumber">395</context></context-group>
<context-group purpose="location"><context context-type="linenumber">582</context></context-group>
</trans-unit>
- <trans-unit id="_msg374">
+ <trans-unit id="_msg371">
<source xml:space="preserve">Port of the proxy (e.g. 9050)</source>
<context-group purpose="location"><context context-type="linenumber">420</context></context-group>
<context-group purpose="location"><context context-type="linenumber">607</context></context-group>
</trans-unit>
- <trans-unit id="_msg375">
+ <trans-unit id="_msg372">
<source xml:space="preserve">Used for reaching peers via:</source>
<context-group purpose="location"><context context-type="linenumber">444</context></context-group>
</trans-unit>
- <trans-unit id="_msg376">
+ <trans-unit id="_msg373">
<source xml:space="preserve">IPv4</source>
<context-group purpose="location"><context context-type="linenumber">467</context></context-group>
</trans-unit>
- <trans-unit id="_msg377">
+ <trans-unit id="_msg374">
<source xml:space="preserve">IPv6</source>
<context-group purpose="location"><context context-type="linenumber">490</context></context-group>
</trans-unit>
- <trans-unit id="_msg378">
+ <trans-unit id="_msg375">
<source xml:space="preserve">Tor</source>
<context-group purpose="location"><context context-type="linenumber">513</context></context-group>
</trans-unit>
- <trans-unit id="_msg379">
+ <trans-unit id="_msg376">
<source xml:space="preserve">&amp;Window</source>
<context-group purpose="location"><context context-type="linenumber">643</context></context-group>
</trans-unit>
- <trans-unit id="_msg380">
+ <trans-unit id="_msg377">
<source xml:space="preserve">Show the icon in the system tray.</source>
<context-group purpose="location"><context context-type="linenumber">649</context></context-group>
</trans-unit>
- <trans-unit id="_msg381">
+ <trans-unit id="_msg378">
<source xml:space="preserve">&amp;Show tray icon</source>
<context-group purpose="location"><context context-type="linenumber">652</context></context-group>
</trans-unit>
- <trans-unit id="_msg382">
+ <trans-unit id="_msg379">
<source xml:space="preserve">Show only a tray icon after minimizing the window.</source>
<context-group purpose="location"><context context-type="linenumber">662</context></context-group>
</trans-unit>
- <trans-unit id="_msg383">
+ <trans-unit id="_msg380">
<source xml:space="preserve">&amp;Minimize to the tray instead of the taskbar</source>
<context-group purpose="location"><context context-type="linenumber">665</context></context-group>
</trans-unit>
- <trans-unit id="_msg384">
+ <trans-unit id="_msg381">
<source xml:space="preserve">M&amp;inimize on close</source>
<context-group purpose="location"><context context-type="linenumber">675</context></context-group>
</trans-unit>
- <trans-unit id="_msg385">
+ <trans-unit id="_msg382">
<source xml:space="preserve">&amp;Display</source>
<context-group purpose="location"><context context-type="linenumber">696</context></context-group>
</trans-unit>
- <trans-unit id="_msg386">
+ <trans-unit id="_msg383">
<source xml:space="preserve">User Interface &amp;language:</source>
<context-group purpose="location"><context context-type="linenumber">704</context></context-group>
</trans-unit>
- <trans-unit id="_msg387">
+ <trans-unit id="_msg384">
<source xml:space="preserve">The user interface language can be set here. This setting will take effect after restarting %1.</source>
<context-group purpose="location"><context context-type="linenumber">717</context></context-group>
</trans-unit>
- <trans-unit id="_msg388">
+ <trans-unit id="_msg385">
<source xml:space="preserve">&amp;Unit to show amounts in:</source>
<context-group purpose="location"><context context-type="linenumber">728</context></context-group>
</trans-unit>
- <trans-unit id="_msg389">
+ <trans-unit id="_msg386">
<source xml:space="preserve">Choose the default subdivision unit to show in the interface and when sending coins.</source>
<context-group purpose="location"><context context-type="linenumber">741</context></context-group>
</trans-unit>
- <trans-unit id="_msg390">
+ <trans-unit id="_msg387">
<source xml:space="preserve">Third-party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source>
<context-group purpose="location"><context context-type="linenumber">752</context></context-group>
<context-group purpose="location"><context context-type="linenumber">765</context></context-group>
</trans-unit>
- <trans-unit id="_msg391">
+ <trans-unit id="_msg388">
<source xml:space="preserve">&amp;Third-party transaction URLs</source>
<context-group purpose="location"><context context-type="linenumber">755</context></context-group>
</trans-unit>
- <trans-unit id="_msg392">
+ <trans-unit id="_msg389">
<source xml:space="preserve">Whether to show coin control features or not.</source>
<context-group purpose="location"><context context-type="linenumber">238</context></context-group>
</trans-unit>
- <trans-unit id="_msg393">
+ <trans-unit id="_msg390">
<source xml:space="preserve">Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor onion services.</source>
<context-group purpose="location"><context context-type="linenumber">538</context></context-group>
</trans-unit>
- <trans-unit id="_msg394">
+ <trans-unit id="_msg391">
<source xml:space="preserve">Use separate SOCKS&amp;5 proxy to reach peers via Tor onion services:</source>
<context-group purpose="location"><context context-type="linenumber">541</context></context-group>
</trans-unit>
- <trans-unit id="_msg395">
+ <trans-unit id="_msg392">
<source xml:space="preserve">Monospaced font in the Overview tab:</source>
<context-group purpose="location"><context context-type="linenumber">777</context></context-group>
</trans-unit>
- <trans-unit id="_msg396">
+ <trans-unit id="_msg393">
<source xml:space="preserve">embedded &quot;%1&quot;</source>
<context-group purpose="location"><context context-type="linenumber">785</context></context-group>
</trans-unit>
- <trans-unit id="_msg397">
+ <trans-unit id="_msg394">
<source xml:space="preserve">closest matching &quot;%1&quot;</source>
<context-group purpose="location"><context context-type="linenumber">834</context></context-group>
</trans-unit>
- <trans-unit id="_msg398">
+ <trans-unit id="_msg395">
<source xml:space="preserve">&amp;OK</source>
<context-group purpose="location"><context context-type="linenumber">1040</context></context-group>
</trans-unit>
- <trans-unit id="_msg399">
+ <trans-unit id="_msg396">
<source xml:space="preserve">&amp;Cancel</source>
<context-group purpose="location"><context context-type="linenumber">1053</context></context-group>
</trans-unit>
@@ -1802,71 +1788,71 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
</body></file>
<file original="../optionsdialog.cpp" datatype="cpp" source-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="OptionsDialog">
- <trans-unit id="_msg400">
+ <trans-unit id="_msg397">
<source xml:space="preserve">Compiled without external signing support (required for external signing)</source>
<context-group purpose="location"><context context-type="linenumber">96</context></context-group>
<note annotates="source" from="developer">&quot;External signing&quot; means using devices such as hardware wallets.</note>
</trans-unit>
- <trans-unit id="_msg401">
+ <trans-unit id="_msg398">
<source xml:space="preserve">default</source>
<context-group purpose="location"><context context-type="linenumber">108</context></context-group>
</trans-unit>
- <trans-unit id="_msg402">
+ <trans-unit id="_msg399">
<source xml:space="preserve">none</source>
<context-group purpose="location"><context context-type="linenumber">194</context></context-group>
</trans-unit>
- <trans-unit id="_msg403">
+ <trans-unit id="_msg400">
<source xml:space="preserve">Confirm options reset</source>
<context-group purpose="location"><context context-type="linenumber">301</context></context-group>
<note annotates="source" from="developer">Window title text of pop-up window shown when the user has chosen to reset options.</note>
</trans-unit>
- <trans-unit id="_msg404">
+ <trans-unit id="_msg401">
<source xml:space="preserve">Client restart required to activate changes.</source>
<context-group purpose="location"><context context-type="linenumber">292</context></context-group>
<context-group purpose="location"><context context-type="linenumber">371</context></context-group>
<note annotates="source" from="developer">Text explaining that the settings changed will not come into effect until the client is restarted.</note>
</trans-unit>
- <trans-unit id="_msg405">
+ <trans-unit id="_msg402">
<source xml:space="preserve">Current settings will be backed up at &quot;%1&quot;.</source>
<context-group purpose="location"><context context-type="linenumber">296</context></context-group>
<note annotates="source" from="developer">Text explaining to the user that the client&apos;s current settings will be backed up at a specific location. %1 is a stand-in argument for the backup location&apos;s path.</note>
</trans-unit>
- <trans-unit id="_msg406">
+ <trans-unit id="_msg403">
<source xml:space="preserve">Client will be shut down. Do you want to proceed?</source>
<context-group purpose="location"><context context-type="linenumber">299</context></context-group>
<note annotates="source" from="developer">Text asking the user to confirm if they would like to proceed with a client shutdown.</note>
</trans-unit>
- <trans-unit id="_msg407">
+ <trans-unit id="_msg404">
<source xml:space="preserve">Configuration options</source>
<context-group purpose="location"><context context-type="linenumber">319</context></context-group>
<note annotates="source" from="developer">Window title text of pop-up box that allows opening up of configuration file.</note>
</trans-unit>
- <trans-unit id="_msg408">
+ <trans-unit id="_msg405">
<source xml:space="preserve">The configuration file is used to specify advanced user options which override GUI settings. Additionally, any command-line options will override this configuration file.</source>
<context-group purpose="location"><context context-type="linenumber">322</context></context-group>
<note annotates="source" from="developer">Explanatory text about the priority order of instructions considered by client. The order from high to low being: command-line, configuration file, GUI settings.</note>
</trans-unit>
- <trans-unit id="_msg409">
+ <trans-unit id="_msg406">
<source xml:space="preserve">Continue</source>
<context-group purpose="location"><context context-type="linenumber">325</context></context-group>
</trans-unit>
- <trans-unit id="_msg410">
+ <trans-unit id="_msg407">
<source xml:space="preserve">Cancel</source>
<context-group purpose="location"><context context-type="linenumber">326</context></context-group>
</trans-unit>
- <trans-unit id="_msg411">
+ <trans-unit id="_msg408">
<source xml:space="preserve">Error</source>
<context-group purpose="location"><context context-type="linenumber">335</context></context-group>
</trans-unit>
- <trans-unit id="_msg412">
+ <trans-unit id="_msg409">
<source xml:space="preserve">The configuration file could not be opened.</source>
<context-group purpose="location"><context context-type="linenumber">335</context></context-group>
</trans-unit>
- <trans-unit id="_msg413">
+ <trans-unit id="_msg410">
<source xml:space="preserve">This change would require a client restart.</source>
<context-group purpose="location"><context context-type="linenumber">375</context></context-group>
</trans-unit>
- <trans-unit id="_msg414">
+ <trans-unit id="_msg411">
<source xml:space="preserve">The supplied proxy address is invalid.</source>
<context-group purpose="location"><context context-type="linenumber">403</context></context-group>
</trans-unit>
@@ -1874,7 +1860,7 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
</body></file>
<file original="../optionsmodel.cpp" datatype="cpp" source-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="OptionsModel">
- <trans-unit id="_msg415">
+ <trans-unit id="_msg412">
<source xml:space="preserve">Could not read setting &quot;%1&quot;, %2.</source>
<context-group purpose="location"><context context-type="linenumber">198</context></context-group>
</trans-unit>
@@ -1882,76 +1868,76 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
</body></file>
<file original="../forms/overviewpage.ui" datatype="x-trolltech-designer-ui" source-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="OverviewPage">
- <trans-unit id="_msg416">
+ <trans-unit id="_msg413">
<source xml:space="preserve">Form</source>
<context-group purpose="location"><context context-type="linenumber">14</context></context-group>
</trans-unit>
- <trans-unit id="_msg417">
+ <trans-unit id="_msg414">
<source xml:space="preserve">The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet.</source>
<context-group purpose="location"><context context-type="linenumber">76</context></context-group>
<context-group purpose="location"><context context-type="linenumber">411</context></context-group>
</trans-unit>
- <trans-unit id="_msg418">
+ <trans-unit id="_msg415">
<source xml:space="preserve">Watch-only:</source>
<context-group purpose="location"><context context-type="linenumber">284</context></context-group>
</trans-unit>
- <trans-unit id="_msg419">
+ <trans-unit id="_msg416">
<source xml:space="preserve">Available:</source>
<context-group purpose="location"><context context-type="linenumber">294</context></context-group>
</trans-unit>
- <trans-unit id="_msg420">
+ <trans-unit id="_msg417">
<source xml:space="preserve">Your current spendable balance</source>
<context-group purpose="location"><context context-type="linenumber">304</context></context-group>
</trans-unit>
- <trans-unit id="_msg421">
+ <trans-unit id="_msg418">
<source xml:space="preserve">Pending:</source>
<context-group purpose="location"><context context-type="linenumber">339</context></context-group>
</trans-unit>
- <trans-unit id="_msg422">
+ <trans-unit id="_msg419">
<source xml:space="preserve">Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</source>
<context-group purpose="location"><context context-type="linenumber">139</context></context-group>
</trans-unit>
- <trans-unit id="_msg423">
+ <trans-unit id="_msg420">
<source xml:space="preserve">Immature:</source>
<context-group purpose="location"><context context-type="linenumber">239</context></context-group>
</trans-unit>
- <trans-unit id="_msg424">
+ <trans-unit id="_msg421">
<source xml:space="preserve">Mined balance that has not yet matured</source>
<context-group purpose="location"><context context-type="linenumber">210</context></context-group>
</trans-unit>
- <trans-unit id="_msg425">
+ <trans-unit id="_msg422">
<source xml:space="preserve">Balances</source>
<context-group purpose="location"><context context-type="linenumber">60</context></context-group>
</trans-unit>
- <trans-unit id="_msg426">
+ <trans-unit id="_msg423">
<source xml:space="preserve">Total:</source>
<context-group purpose="location"><context context-type="linenumber">200</context></context-group>
</trans-unit>
- <trans-unit id="_msg427">
+ <trans-unit id="_msg424">
<source xml:space="preserve">Your current total balance</source>
<context-group purpose="location"><context context-type="linenumber">249</context></context-group>
</trans-unit>
- <trans-unit id="_msg428">
+ <trans-unit id="_msg425">
<source xml:space="preserve">Your current balance in watch-only addresses</source>
<context-group purpose="location"><context context-type="linenumber">323</context></context-group>
</trans-unit>
- <trans-unit id="_msg429">
+ <trans-unit id="_msg426">
<source xml:space="preserve">Spendable:</source>
<context-group purpose="location"><context context-type="linenumber">346</context></context-group>
</trans-unit>
- <trans-unit id="_msg430">
+ <trans-unit id="_msg427">
<source xml:space="preserve">Recent transactions</source>
<context-group purpose="location"><context context-type="linenumber">395</context></context-group>
</trans-unit>
- <trans-unit id="_msg431">
+ <trans-unit id="_msg428">
<source xml:space="preserve">Unconfirmed transactions to watch-only addresses</source>
<context-group purpose="location"><context context-type="linenumber">120</context></context-group>
</trans-unit>
- <trans-unit id="_msg432">
+ <trans-unit id="_msg429">
<source xml:space="preserve">Mined balance in watch-only addresses that has not yet matured</source>
<context-group purpose="location"><context context-type="linenumber">158</context></context-group>
</trans-unit>
- <trans-unit id="_msg433">
+ <trans-unit id="_msg430">
<source xml:space="preserve">Current total balance in watch-only addresses</source>
<context-group purpose="location"><context context-type="linenumber">268</context></context-group>
</trans-unit>
@@ -1959,7 +1945,7 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
</body></file>
<file original="../overviewpage.cpp" datatype="cpp" source-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="OverviewPage">
- <trans-unit id="_msg434">
+ <trans-unit id="_msg431">
<source xml:space="preserve">Privacy mode activated for the Overview tab. To unmask the values, uncheck Settings-&gt;Mask values.</source>
<context-group purpose="location"><context context-type="linenumber">184</context></context-group>
</trans-unit>
@@ -1967,27 +1953,27 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
</body></file>
<file original="../forms/psbtoperationsdialog.ui" datatype="x-trolltech-designer-ui" source-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="PSBTOperationsDialog">
- <trans-unit id="_msg435">
- <source xml:space="preserve">Dialog</source>
+ <trans-unit id="_msg432">
+ <source xml:space="preserve">PSBT Operations</source>
<context-group purpose="location"><context context-type="linenumber">14</context></context-group>
</trans-unit>
- <trans-unit id="_msg436">
+ <trans-unit id="_msg433">
<source xml:space="preserve">Sign Tx</source>
<context-group purpose="location"><context context-type="linenumber">86</context></context-group>
</trans-unit>
- <trans-unit id="_msg437">
+ <trans-unit id="_msg434">
<source xml:space="preserve">Broadcast Tx</source>
<context-group purpose="location"><context context-type="linenumber">102</context></context-group>
</trans-unit>
- <trans-unit id="_msg438">
+ <trans-unit id="_msg435">
<source xml:space="preserve">Copy to Clipboard</source>
<context-group purpose="location"><context context-type="linenumber">122</context></context-group>
</trans-unit>
- <trans-unit id="_msg439">
+ <trans-unit id="_msg436">
<source xml:space="preserve">Save…</source>
<context-group purpose="location"><context context-type="linenumber">129</context></context-group>
</trans-unit>
- <trans-unit id="_msg440">
+ <trans-unit id="_msg437">
<source xml:space="preserve">Close</source>
<context-group purpose="location"><context context-type="linenumber">136</context></context-group>
</trans-unit>
@@ -1995,146 +1981,146 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
</body></file>
<file original="../psbtoperationsdialog.cpp" datatype="cpp" source-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="PSBTOperationsDialog">
- <trans-unit id="_msg441">
+ <trans-unit id="_msg438">
<source xml:space="preserve">Failed to load transaction: %1</source>
- <context-group purpose="location"><context context-type="linenumber">61</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">60</context></context-group>
</trans-unit>
- <trans-unit id="_msg442">
+ <trans-unit id="_msg439">
<source xml:space="preserve">Failed to sign transaction: %1</source>
- <context-group purpose="location"><context context-type="linenumber">86</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">85</context></context-group>
</trans-unit>
- <trans-unit id="_msg443">
+ <trans-unit id="_msg440">
<source xml:space="preserve">Cannot sign inputs while wallet is locked.</source>
- <context-group purpose="location"><context context-type="linenumber">94</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">93</context></context-group>
</trans-unit>
- <trans-unit id="_msg444">
+ <trans-unit id="_msg441">
<source xml:space="preserve">Could not sign any more inputs.</source>
- <context-group purpose="location"><context context-type="linenumber">96</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">95</context></context-group>
</trans-unit>
- <trans-unit id="_msg445">
+ <trans-unit id="_msg442">
<source xml:space="preserve">Signed %1 inputs, but more signatures are still required.</source>
- <context-group purpose="location"><context context-type="linenumber">98</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">97</context></context-group>
</trans-unit>
- <trans-unit id="_msg446">
+ <trans-unit id="_msg443">
<source xml:space="preserve">Signed transaction successfully. Transaction is ready to broadcast.</source>
- <context-group purpose="location"><context context-type="linenumber">101</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">100</context></context-group>
</trans-unit>
- <trans-unit id="_msg447">
+ <trans-unit id="_msg444">
<source xml:space="preserve">Unknown error processing transaction.</source>
- <context-group purpose="location"><context context-type="linenumber">113</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">112</context></context-group>
</trans-unit>
- <trans-unit id="_msg448">
+ <trans-unit id="_msg445">
<source xml:space="preserve">Transaction broadcast successfully! Transaction ID: %1</source>
- <context-group purpose="location"><context context-type="linenumber">123</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">122</context></context-group>
</trans-unit>
- <trans-unit id="_msg449">
+ <trans-unit id="_msg446">
<source xml:space="preserve">Transaction broadcast failed: %1</source>
- <context-group purpose="location"><context context-type="linenumber">126</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">125</context></context-group>
</trans-unit>
- <trans-unit id="_msg450">
+ <trans-unit id="_msg447">
<source xml:space="preserve">PSBT copied to clipboard.</source>
- <context-group purpose="location"><context context-type="linenumber">135</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">134</context></context-group>
</trans-unit>
- <trans-unit id="_msg451">
+ <trans-unit id="_msg448">
<source xml:space="preserve">Save Transaction Data</source>
- <context-group purpose="location"><context context-type="linenumber">158</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">157</context></context-group>
</trans-unit>
- <trans-unit id="_msg452">
+ <trans-unit id="_msg449">
<source xml:space="preserve">Partially Signed Transaction (Binary)</source>
- <context-group purpose="location"><context context-type="linenumber">160</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">159</context></context-group>
<note annotates="source" from="developer">Expanded name of the binary PSBT file format. See: BIP 174.</note>
</trans-unit>
- <trans-unit id="_msg453">
+ <trans-unit id="_msg450">
<source xml:space="preserve">PSBT saved to disk.</source>
- <context-group purpose="location"><context context-type="linenumber">167</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">166</context></context-group>
</trans-unit>
- <trans-unit id="_msg454">
+ <trans-unit id="_msg451">
<source xml:space="preserve"> * Sends %1 to %2</source>
- <context-group purpose="location"><context context-type="linenumber">183</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">182</context></context-group>
</trans-unit>
- <trans-unit id="_msg455">
+ <trans-unit id="_msg452">
<source xml:space="preserve">Unable to calculate transaction fee or total transaction amount.</source>
- <context-group purpose="location"><context context-type="linenumber">193</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">192</context></context-group>
</trans-unit>
- <trans-unit id="_msg456">
+ <trans-unit id="_msg453">
<source xml:space="preserve">Pays transaction fee: </source>
- <context-group purpose="location"><context context-type="linenumber">195</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">194</context></context-group>
</trans-unit>
- <trans-unit id="_msg457">
+ <trans-unit id="_msg454">
<source xml:space="preserve">Total Amount</source>
- <context-group purpose="location"><context context-type="linenumber">207</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">206</context></context-group>
</trans-unit>
- <trans-unit id="_msg458">
+ <trans-unit id="_msg455">
<source xml:space="preserve">or</source>
- <context-group purpose="location"><context context-type="linenumber">210</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">209</context></context-group>
</trans-unit>
- <trans-unit id="_msg459">
+ <trans-unit id="_msg456">
<source xml:space="preserve">Transaction has %1 unsigned inputs.</source>
- <context-group purpose="location"><context context-type="linenumber">216</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">215</context></context-group>
</trans-unit>
- <trans-unit id="_msg460">
+ <trans-unit id="_msg457">
<source xml:space="preserve">Transaction is missing some information about inputs.</source>
- <context-group purpose="location"><context context-type="linenumber">262</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">261</context></context-group>
</trans-unit>
- <trans-unit id="_msg461">
+ <trans-unit id="_msg458">
<source xml:space="preserve">Transaction still needs signature(s).</source>
- <context-group purpose="location"><context context-type="linenumber">266</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">265</context></context-group>
</trans-unit>
- <trans-unit id="_msg462">
+ <trans-unit id="_msg459">
<source xml:space="preserve">(But no wallet is loaded.)</source>
- <context-group purpose="location"><context context-type="linenumber">269</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">268</context></context-group>
</trans-unit>
- <trans-unit id="_msg463">
+ <trans-unit id="_msg460">
<source xml:space="preserve">(But this wallet cannot sign transactions.)</source>
- <context-group purpose="location"><context context-type="linenumber">272</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">271</context></context-group>
</trans-unit>
- <trans-unit id="_msg464">
+ <trans-unit id="_msg461">
<source xml:space="preserve">(But this wallet does not have the right keys.)</source>
- <context-group purpose="location"><context context-type="linenumber">275</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">274</context></context-group>
</trans-unit>
- <trans-unit id="_msg465">
+ <trans-unit id="_msg462">
<source xml:space="preserve">Transaction is fully signed and ready for broadcast.</source>
- <context-group purpose="location"><context context-type="linenumber">283</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">282</context></context-group>
</trans-unit>
- <trans-unit id="_msg466">
+ <trans-unit id="_msg463">
<source xml:space="preserve">Transaction status is unknown.</source>
- <context-group purpose="location"><context context-type="linenumber">287</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">286</context></context-group>
</trans-unit>
</group>
</body></file>
<file original="../paymentserver.cpp" datatype="cpp" source-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="PaymentServer">
- <trans-unit id="_msg467">
+ <trans-unit id="_msg464">
<source xml:space="preserve">Payment request error</source>
<context-group purpose="location"><context context-type="linenumber">149</context></context-group>
</trans-unit>
- <trans-unit id="_msg468">
+ <trans-unit id="_msg465">
<source xml:space="preserve">Cannot start bitcoin: click-to-pay handler</source>
<context-group purpose="location"><context context-type="linenumber">150</context></context-group>
</trans-unit>
- <trans-unit id="_msg469">
+ <trans-unit id="_msg466">
<source xml:space="preserve">URI handling</source>
<context-group purpose="location"><context context-type="linenumber">198</context></context-group>
<context-group purpose="location"><context context-type="linenumber">214</context></context-group>
<context-group purpose="location"><context context-type="linenumber">220</context></context-group>
<context-group purpose="location"><context context-type="linenumber">227</context></context-group>
</trans-unit>
- <trans-unit id="_msg470">
+ <trans-unit id="_msg467">
<source xml:space="preserve">&apos;bitcoin://&apos; is not a valid URI. Use &apos;bitcoin:&apos; instead.</source>
<context-group purpose="location"><context context-type="linenumber">198</context></context-group>
</trans-unit>
- <trans-unit id="_msg471">
+ <trans-unit id="_msg468">
<source xml:space="preserve">Cannot process payment request because BIP70 is not supported.
Due to widespread security flaws in BIP70 it&apos;s strongly recommended that any merchant instructions to switch wallets be ignored.
If you are receiving this error you should request the merchant provide a BIP21 compatible URI.</source>
<context-group purpose="location"><context context-type="linenumber">215</context></context-group>
<context-group purpose="location"><context context-type="linenumber">238</context></context-group>
</trans-unit>
- <trans-unit id="_msg472">
+ <trans-unit id="_msg469">
<source xml:space="preserve">URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters.</source>
<context-group purpose="location"><context context-type="linenumber">228</context></context-group>
</trans-unit>
- <trans-unit id="_msg473">
+ <trans-unit id="_msg470">
<source xml:space="preserve">Payment request file handling</source>
<context-group purpose="location"><context context-type="linenumber">237</context></context-group>
</trans-unit>
@@ -2142,52 +2128,52 @@ If you are receiving this error you should request the merchant provide a BIP21
</body></file>
<file original="../peertablemodel.h" datatype="c" source-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="PeerTableModel">
- <trans-unit id="_msg474">
+ <trans-unit id="_msg471">
<source xml:space="preserve">User Agent</source>
<context-group purpose="location"><context context-type="linenumber">112</context></context-group>
<note annotates="source" from="developer">Title of Peers Table column which contains the peer&apos;s User Agent string.</note>
</trans-unit>
- <trans-unit id="_msg475">
+ <trans-unit id="_msg472">
<source xml:space="preserve">Ping</source>
<context-group purpose="location"><context context-type="linenumber">103</context></context-group>
<note annotates="source" from="developer">Title of Peers Table column which indicates the current latency of the connection with the peer.</note>
</trans-unit>
- <trans-unit id="_msg476">
+ <trans-unit id="_msg473">
<source xml:space="preserve">Peer</source>
<context-group purpose="location"><context context-type="linenumber">85</context></context-group>
<note annotates="source" from="developer">Title of Peers Table column which contains a unique number used to identify a connection.</note>
</trans-unit>
- <trans-unit id="_msg477">
+ <trans-unit id="_msg474">
<source xml:space="preserve">Age</source>
<context-group purpose="location"><context context-type="linenumber">88</context></context-group>
<note annotates="source" from="developer">Title of Peers Table column which indicates the duration (length of time) since the peer connection started.</note>
</trans-unit>
- <trans-unit id="_msg478">
+ <trans-unit id="_msg475">
<source xml:space="preserve">Direction</source>
<context-group purpose="location"><context context-type="linenumber">94</context></context-group>
<note annotates="source" from="developer">Title of Peers Table column which indicates the direction the peer connection was initiated from.</note>
</trans-unit>
- <trans-unit id="_msg479">
+ <trans-unit id="_msg476">
<source xml:space="preserve">Sent</source>
<context-group purpose="location"><context context-type="linenumber">106</context></context-group>
<note annotates="source" from="developer">Title of Peers Table column which indicates the total amount of network information we have sent to the peer.</note>
</trans-unit>
- <trans-unit id="_msg480">
+ <trans-unit id="_msg477">
<source xml:space="preserve">Received</source>
<context-group purpose="location"><context context-type="linenumber">109</context></context-group>
<note annotates="source" from="developer">Title of Peers Table column which indicates the total amount of network information we have received from the peer.</note>
</trans-unit>
- <trans-unit id="_msg481">
+ <trans-unit id="_msg478">
<source xml:space="preserve">Address</source>
<context-group purpose="location"><context context-type="linenumber">91</context></context-group>
<note annotates="source" from="developer">Title of Peers Table column which contains the IP/Onion/I2P address of the connected peer.</note>
</trans-unit>
- <trans-unit id="_msg482">
+ <trans-unit id="_msg479">
<source xml:space="preserve">Type</source>
<context-group purpose="location"><context context-type="linenumber">97</context></context-group>
<note annotates="source" from="developer">Title of Peers Table column which describes the type of peer connection. The &quot;type&quot; describes why the connection exists.</note>
</trans-unit>
- <trans-unit id="_msg483">
+ <trans-unit id="_msg480">
<source xml:space="preserve">Network</source>
<context-group purpose="location"><context context-type="linenumber">100</context></context-group>
<note annotates="source" from="developer">Title of Peers Table column which states the network the peer connected through.</note>
@@ -2196,12 +2182,12 @@ If you are receiving this error you should request the merchant provide a BIP21
</body></file>
<file original="../peertablemodel.cpp" datatype="cpp" source-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="PeerTableModel">
- <trans-unit id="_msg484">
+ <trans-unit id="_msg481">
<source xml:space="preserve">Inbound</source>
<context-group purpose="location"><context context-type="linenumber">77</context></context-group>
<note annotates="source" from="developer">An Inbound Connection from a Peer.</note>
</trans-unit>
- <trans-unit id="_msg485">
+ <trans-unit id="_msg482">
<source xml:space="preserve">Outbound</source>
<context-group purpose="location"><context context-type="linenumber">79</context></context-group>
<note annotates="source" from="developer">An Outbound Connection to a Peer.</note>
@@ -2210,7 +2196,7 @@ If you are receiving this error you should request the merchant provide a BIP21
</body></file>
<file original="../bitcoinunits.cpp" datatype="cpp" source-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="QObject">
- <trans-unit id="_msg486">
+ <trans-unit id="_msg483">
<source xml:space="preserve">Amount</source>
<context-group purpose="location"><context context-type="linenumber">197</context></context-group>
</trans-unit>
@@ -2218,194 +2204,222 @@ If you are receiving this error you should request the merchant provide a BIP21
</body></file>
<file original="../guiutil.cpp" datatype="cpp" source-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="QObject">
- <trans-unit id="_msg487">
+ <trans-unit id="_msg484">
<source xml:space="preserve">Enter a Bitcoin address (e.g. %1)</source>
- <context-group purpose="location"><context context-type="linenumber">129</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">130</context></context-group>
</trans-unit>
- <trans-unit id="_msg488">
+ <trans-unit id="_msg485">
<source xml:space="preserve">Ctrl+W</source>
- <context-group purpose="location"><context context-type="linenumber">417</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">418</context></context-group>
</trans-unit>
- <trans-unit id="_msg489">
+ <trans-unit id="_msg486">
<source xml:space="preserve">Unroutable</source>
- <context-group purpose="location"><context context-type="linenumber">674</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">675</context></context-group>
+ </trans-unit>
+ <trans-unit id="_msg487">
+ <source xml:space="preserve">IPv4</source>
+ <context-group purpose="location"><context context-type="linenumber">677</context></context-group>
+ <context-group><context context-type="x-gettext-msgctxt">network name</context></context-group>
+ <note annotates="source" from="developer">Name of IPv4 network in peer info</note>
+ </trans-unit>
+ <trans-unit id="_msg488">
+ <source xml:space="preserve">IPv6</source>
+ <context-group purpose="location"><context context-type="linenumber">679</context></context-group>
+ <context-group><context context-type="x-gettext-msgctxt">network name</context></context-group>
+ <note annotates="source" from="developer">Name of IPv6 network in peer info</note>
+ </trans-unit>
+ <trans-unit id="_msg489">
+ <source xml:space="preserve">Onion</source>
+ <context-group purpose="location"><context context-type="linenumber">681</context></context-group>
+ <context-group><context context-type="x-gettext-msgctxt">network name</context></context-group>
+ <note annotates="source" from="developer">Name of Tor network in peer info</note>
</trans-unit>
<trans-unit id="_msg490">
- <source xml:space="preserve">Internal</source>
- <context-group purpose="location"><context context-type="linenumber">680</context></context-group>
+ <source xml:space="preserve">I2P</source>
+ <context-group purpose="location"><context context-type="linenumber">683</context></context-group>
+ <context-group><context context-type="x-gettext-msgctxt">network name</context></context-group>
+ <note annotates="source" from="developer">Name of I2P network in peer info</note>
</trans-unit>
<trans-unit id="_msg491">
+ <source xml:space="preserve">CJDNS</source>
+ <context-group purpose="location"><context context-type="linenumber">685</context></context-group>
+ <context-group><context context-type="x-gettext-msgctxt">network name</context></context-group>
+ <note annotates="source" from="developer">Name of CJDNS network in peer info</note>
+ </trans-unit>
+ <trans-unit id="_msg492">
<source xml:space="preserve">Inbound</source>
- <context-group purpose="location"><context context-type="linenumber">693</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">699</context></context-group>
<note annotates="source" from="developer">An inbound connection from a peer. An inbound connection is a connection initiated by a peer.</note>
</trans-unit>
- <trans-unit id="_msg492">
+ <trans-unit id="_msg493">
<source xml:space="preserve">Outbound</source>
- <context-group purpose="location"><context context-type="linenumber">696</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">702</context></context-group>
<note annotates="source" from="developer">An outbound connection to a peer. An outbound connection is a connection initiated by us.</note>
</trans-unit>
- <trans-unit id="_msg493">
+ <trans-unit id="_msg494">
<source xml:space="preserve">Full Relay</source>
- <context-group purpose="location"><context context-type="linenumber">701</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">707</context></context-group>
<note annotates="source" from="developer">Peer connection type that relays all network information.</note>
</trans-unit>
- <trans-unit id="_msg494">
+ <trans-unit id="_msg495">
<source xml:space="preserve">Block Relay</source>
- <context-group purpose="location"><context context-type="linenumber">704</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">710</context></context-group>
<note annotates="source" from="developer">Peer connection type that relays network information about blocks and not transactions or addresses.</note>
</trans-unit>
- <trans-unit id="_msg495">
+ <trans-unit id="_msg496">
<source xml:space="preserve">Manual</source>
- <context-group purpose="location"><context context-type="linenumber">706</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">712</context></context-group>
<note annotates="source" from="developer">Peer connection type established manually through one of several methods.</note>
</trans-unit>
- <trans-unit id="_msg496">
+ <trans-unit id="_msg497">
<source xml:space="preserve">Feeler</source>
- <context-group purpose="location"><context context-type="linenumber">708</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">714</context></context-group>
<note annotates="source" from="developer">Short-lived peer connection type that tests the aliveness of known addresses.</note>
</trans-unit>
- <trans-unit id="_msg497">
+ <trans-unit id="_msg498">
<source xml:space="preserve">Address Fetch</source>
- <context-group purpose="location"><context context-type="linenumber">710</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">716</context></context-group>
<note annotates="source" from="developer">Short-lived peer connection type that solicits known addresses from a peer.</note>
</trans-unit>
- <trans-unit id="_msg498">
- <source xml:space="preserve">%1 d</source>
- <context-group purpose="location"><context context-type="linenumber">723</context></context-group>
- <context-group purpose="location"><context context-type="linenumber">735</context></context-group>
- </trans-unit>
<trans-unit id="_msg499">
- <source xml:space="preserve">%1 h</source>
- <context-group purpose="location"><context context-type="linenumber">724</context></context-group>
- <context-group purpose="location"><context context-type="linenumber">736</context></context-group>
+ <source xml:space="preserve">%1 d</source>
+ <context-group purpose="location"><context context-type="linenumber">729</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">741</context></context-group>
</trans-unit>
<trans-unit id="_msg500">
- <source xml:space="preserve">%1 m</source>
- <context-group purpose="location"><context context-type="linenumber">725</context></context-group>
- <context-group purpose="location"><context context-type="linenumber">737</context></context-group>
+ <source xml:space="preserve">%1 h</source>
+ <context-group purpose="location"><context context-type="linenumber">730</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">742</context></context-group>
</trans-unit>
<trans-unit id="_msg501">
- <source xml:space="preserve">%1 s</source>
- <context-group purpose="location"><context context-type="linenumber">727</context></context-group>
- <context-group purpose="location"><context context-type="linenumber">738</context></context-group>
- <context-group purpose="location"><context context-type="linenumber">764</context></context-group>
+ <source xml:space="preserve">%1 m</source>
+ <context-group purpose="location"><context context-type="linenumber">731</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">743</context></context-group>
</trans-unit>
<trans-unit id="_msg502">
- <source xml:space="preserve">None</source>
- <context-group purpose="location"><context context-type="linenumber">752</context></context-group>
+ <source xml:space="preserve">%1 s</source>
+ <context-group purpose="location"><context context-type="linenumber">733</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">744</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">770</context></context-group>
</trans-unit>
<trans-unit id="_msg503">
- <source xml:space="preserve">N/A</source>
+ <source xml:space="preserve">None</source>
<context-group purpose="location"><context context-type="linenumber">758</context></context-group>
</trans-unit>
<trans-unit id="_msg504">
+ <source xml:space="preserve">N/A</source>
+ <context-group purpose="location"><context context-type="linenumber">764</context></context-group>
+ </trans-unit>
+ <trans-unit id="_msg505">
<source xml:space="preserve">%1 ms</source>
- <context-group purpose="location"><context context-type="linenumber">759</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">765</context></context-group>
</trans-unit>
<group restype="x-gettext-plurals">
- <context-group purpose="location"><context context-type="linenumber">777</context></context-group>
- <trans-unit id="_msg505[0]">
+ <context-group purpose="location"><context context-type="linenumber">783</context></context-group>
+ <trans-unit id="_msg506[0]">
<source xml:space="preserve">%n second(s)</source>
</trans-unit>
- <trans-unit id="_msg505[1]">
+ <trans-unit id="_msg506[1]">
<source xml:space="preserve">%n second(s)</source>
</trans-unit>
</group>
<group restype="x-gettext-plurals">
- <context-group purpose="location"><context context-type="linenumber">781</context></context-group>
- <trans-unit id="_msg506[0]">
+ <context-group purpose="location"><context context-type="linenumber">787</context></context-group>
+ <trans-unit id="_msg507[0]">
<source xml:space="preserve">%n minute(s)</source>
</trans-unit>
- <trans-unit id="_msg506[1]">
+ <trans-unit id="_msg507[1]">
<source xml:space="preserve">%n minute(s)</source>
</trans-unit>
</group>
<group restype="x-gettext-plurals">
- <context-group purpose="location"><context context-type="linenumber">785</context></context-group>
- <trans-unit id="_msg507[0]">
+ <context-group purpose="location"><context context-type="linenumber">791</context></context-group>
+ <trans-unit id="_msg508[0]">
<source xml:space="preserve">%n hour(s)</source>
</trans-unit>
- <trans-unit id="_msg507[1]">
+ <trans-unit id="_msg508[1]">
<source xml:space="preserve">%n hour(s)</source>
</trans-unit>
</group>
<group restype="x-gettext-plurals">
- <context-group purpose="location"><context context-type="linenumber">789</context></context-group>
- <trans-unit id="_msg508[0]">
+ <context-group purpose="location"><context context-type="linenumber">795</context></context-group>
+ <trans-unit id="_msg509[0]">
<source xml:space="preserve">%n day(s)</source>
</trans-unit>
- <trans-unit id="_msg508[1]">
+ <trans-unit id="_msg509[1]">
<source xml:space="preserve">%n day(s)</source>
</trans-unit>
</group>
<group restype="x-gettext-plurals">
- <context-group purpose="location"><context context-type="linenumber">793</context></context-group>
<context-group purpose="location"><context context-type="linenumber">799</context></context-group>
- <trans-unit id="_msg509[0]">
+ <context-group purpose="location"><context context-type="linenumber">805</context></context-group>
+ <trans-unit id="_msg510[0]">
<source xml:space="preserve">%n week(s)</source>
</trans-unit>
- <trans-unit id="_msg509[1]">
+ <trans-unit id="_msg510[1]">
<source xml:space="preserve">%n week(s)</source>
</trans-unit>
</group>
- <trans-unit id="_msg510">
+ <trans-unit id="_msg511">
<source xml:space="preserve">%1 and %2</source>
- <context-group purpose="location"><context context-type="linenumber">799</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">805</context></context-group>
</trans-unit>
<group restype="x-gettext-plurals">
- <context-group purpose="location"><context context-type="linenumber">799</context></context-group>
- <trans-unit id="_msg511[0]">
+ <context-group purpose="location"><context context-type="linenumber">805</context></context-group>
+ <trans-unit id="_msg512[0]">
<source xml:space="preserve">%n year(s)</source>
</trans-unit>
- <trans-unit id="_msg511[1]">
+ <trans-unit id="_msg512[1]">
<source xml:space="preserve">%n year(s)</source>
</trans-unit>
</group>
- <trans-unit id="_msg512">
+ <trans-unit id="_msg513">
<source xml:space="preserve">%1 B</source>
- <context-group purpose="location"><context context-type="linenumber">807</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">813</context></context-group>
</trans-unit>
- <trans-unit id="_msg513">
+ <trans-unit id="_msg514">
<source xml:space="preserve">%1 kB</source>
- <context-group purpose="location"><context context-type="linenumber">809</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">815</context></context-group>
+ <context-group purpose="location"><context context-type="sourcefile">../rpcconsole.cpp</context><context context-type="linenumber">988</context></context-group>
</trans-unit>
- <trans-unit id="_msg514">
+ <trans-unit id="_msg515">
<source xml:space="preserve">%1 MB</source>
- <context-group purpose="location"><context context-type="linenumber">811</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">817</context></context-group>
+ <context-group purpose="location"><context context-type="sourcefile">../rpcconsole.cpp</context><context context-type="linenumber">990</context></context-group>
</trans-unit>
- <trans-unit id="_msg515">
+ <trans-unit id="_msg516">
<source xml:space="preserve">%1 GB</source>
- <context-group purpose="location"><context context-type="linenumber">813</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">819</context></context-group>
</trans-unit>
</group>
</body></file>
<file original="../qrimagewidget.cpp" datatype="cpp" source-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="QRImageWidget">
- <trans-unit id="_msg516">
+ <trans-unit id="_msg517">
<source xml:space="preserve">&amp;Save Image…</source>
<context-group purpose="location"><context context-type="linenumber">30</context></context-group>
</trans-unit>
- <trans-unit id="_msg517">
+ <trans-unit id="_msg518">
<source xml:space="preserve">&amp;Copy Image</source>
<context-group purpose="location"><context context-type="linenumber">31</context></context-group>
</trans-unit>
- <trans-unit id="_msg518">
+ <trans-unit id="_msg519">
<source xml:space="preserve">Resulting URI too long, try to reduce the text for label / message.</source>
<context-group purpose="location"><context context-type="linenumber">42</context></context-group>
</trans-unit>
- <trans-unit id="_msg519">
+ <trans-unit id="_msg520">
<source xml:space="preserve">Error encoding URI into QR Code.</source>
<context-group purpose="location"><context context-type="linenumber">49</context></context-group>
</trans-unit>
- <trans-unit id="_msg520">
+ <trans-unit id="_msg521">
<source xml:space="preserve">QR code support not available.</source>
<context-group purpose="location"><context context-type="linenumber">90</context></context-group>
</trans-unit>
- <trans-unit id="_msg521">
+ <trans-unit id="_msg522">
<source xml:space="preserve">Save QR Code</source>
<context-group purpose="location"><context context-type="linenumber">120</context></context-group>
</trans-unit>
- <trans-unit id="_msg522">
+ <trans-unit id="_msg523">
<source xml:space="preserve">PNG Image</source>
<context-group purpose="location"><context context-type="linenumber">123</context></context-group>
<note annotates="source" from="developer">Expanded name of the PNG file format. See: https://en.wikipedia.org/wiki/Portable_Network_Graphics.</note>
@@ -2414,7 +2428,7 @@ If you are receiving this error you should request the merchant provide a BIP21
</body></file>
<file original="../forms/debugwindow.ui" datatype="x-trolltech-designer-ui" source-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="RPCConsole">
- <trans-unit id="_msg523">
+ <trans-unit id="_msg524">
<source xml:space="preserve">N/A</source>
<context-group purpose="location"><context context-type="linenumber">75</context></context-group>
<context-group purpose="location"><context context-type="linenumber">101</context></context-group>
@@ -2455,291 +2469,291 @@ If you are receiving this error you should request the merchant provide a BIP21
<context-group purpose="location"><context context-type="linenumber">1662</context></context-group>
<context-group purpose="location"><context context-type="sourcefile">../rpcconsole.h</context><context context-type="linenumber">143</context></context-group>
</trans-unit>
- <trans-unit id="_msg524">
+ <trans-unit id="_msg525">
<source xml:space="preserve">Client version</source>
<context-group purpose="location"><context context-type="linenumber">65</context></context-group>
</trans-unit>
- <trans-unit id="_msg525">
+ <trans-unit id="_msg526">
<source xml:space="preserve">&amp;Information</source>
<context-group purpose="location"><context context-type="linenumber">43</context></context-group>
</trans-unit>
- <trans-unit id="_msg526">
+ <trans-unit id="_msg527">
<source xml:space="preserve">General</source>
<context-group purpose="location"><context context-type="linenumber">58</context></context-group>
</trans-unit>
- <trans-unit id="_msg527">
+ <trans-unit id="_msg528">
<source xml:space="preserve">Datadir</source>
<context-group purpose="location"><context context-type="linenumber">114</context></context-group>
</trans-unit>
- <trans-unit id="_msg528">
+ <trans-unit id="_msg529">
<source xml:space="preserve">To specify a non-default location of the data directory use the &apos;%1&apos; option.</source>
<context-group purpose="location"><context context-type="linenumber">124</context></context-group>
</trans-unit>
- <trans-unit id="_msg529">
+ <trans-unit id="_msg530">
<source xml:space="preserve">Blocksdir</source>
<context-group purpose="location"><context context-type="linenumber">143</context></context-group>
</trans-unit>
- <trans-unit id="_msg530">
+ <trans-unit id="_msg531">
<source xml:space="preserve">To specify a non-default location of the blocks directory use the &apos;%1&apos; option.</source>
<context-group purpose="location"><context context-type="linenumber">153</context></context-group>
</trans-unit>
- <trans-unit id="_msg531">
+ <trans-unit id="_msg532">
<source xml:space="preserve">Startup time</source>
<context-group purpose="location"><context context-type="linenumber">172</context></context-group>
</trans-unit>
- <trans-unit id="_msg532">
+ <trans-unit id="_msg533">
<source xml:space="preserve">Network</source>
<context-group purpose="location"><context context-type="linenumber">201</context></context-group>
<context-group purpose="location"><context context-type="linenumber">1093</context></context-group>
</trans-unit>
- <trans-unit id="_msg533">
+ <trans-unit id="_msg534">
<source xml:space="preserve">Name</source>
<context-group purpose="location"><context context-type="linenumber">208</context></context-group>
</trans-unit>
- <trans-unit id="_msg534">
+ <trans-unit id="_msg535">
<source xml:space="preserve">Number of connections</source>
<context-group purpose="location"><context context-type="linenumber">231</context></context-group>
</trans-unit>
- <trans-unit id="_msg535">
+ <trans-unit id="_msg536">
<source xml:space="preserve">Block chain</source>
<context-group purpose="location"><context context-type="linenumber">260</context></context-group>
</trans-unit>
- <trans-unit id="_msg536">
+ <trans-unit id="_msg537">
<source xml:space="preserve">Memory Pool</source>
<context-group purpose="location"><context context-type="linenumber">319</context></context-group>
</trans-unit>
- <trans-unit id="_msg537">
+ <trans-unit id="_msg538">
<source xml:space="preserve">Current number of transactions</source>
<context-group purpose="location"><context context-type="linenumber">326</context></context-group>
</trans-unit>
- <trans-unit id="_msg538">
+ <trans-unit id="_msg539">
<source xml:space="preserve">Memory usage</source>
<context-group purpose="location"><context context-type="linenumber">349</context></context-group>
</trans-unit>
- <trans-unit id="_msg539">
+ <trans-unit id="_msg540">
<source xml:space="preserve">Wallet: </source>
<context-group purpose="location"><context context-type="linenumber">443</context></context-group>
</trans-unit>
- <trans-unit id="_msg540">
+ <trans-unit id="_msg541">
<source xml:space="preserve">(none)</source>
<context-group purpose="location"><context context-type="linenumber">454</context></context-group>
</trans-unit>
- <trans-unit id="_msg541">
+ <trans-unit id="_msg542">
<source xml:space="preserve">&amp;Reset</source>
<context-group purpose="location"><context context-type="linenumber">665</context></context-group>
</trans-unit>
- <trans-unit id="_msg542">
+ <trans-unit id="_msg543">
<source xml:space="preserve">Received</source>
<context-group purpose="location"><context context-type="linenumber">745</context></context-group>
<context-group purpose="location"><context context-type="linenumber">1453</context></context-group>
</trans-unit>
- <trans-unit id="_msg543">
+ <trans-unit id="_msg544">
<source xml:space="preserve">Sent</source>
<context-group purpose="location"><context context-type="linenumber">825</context></context-group>
<context-group purpose="location"><context context-type="linenumber">1430</context></context-group>
</trans-unit>
- <trans-unit id="_msg544">
+ <trans-unit id="_msg545">
<source xml:space="preserve">&amp;Peers</source>
<context-group purpose="location"><context context-type="linenumber">866</context></context-group>
</trans-unit>
- <trans-unit id="_msg545">
+ <trans-unit id="_msg546">
<source xml:space="preserve">Banned peers</source>
<context-group purpose="location"><context context-type="linenumber">942</context></context-group>
</trans-unit>
- <trans-unit id="_msg546">
+ <trans-unit id="_msg547">
<source xml:space="preserve">Select a peer to view detailed information.</source>
<context-group purpose="location"><context context-type="linenumber">1010</context></context-group>
<context-group purpose="location"><context context-type="sourcefile">../rpcconsole.cpp</context><context context-type="linenumber">1155</context></context-group>
</trans-unit>
- <trans-unit id="_msg547">
+ <trans-unit id="_msg548">
<source xml:space="preserve">Version</source>
<context-group purpose="location"><context context-type="linenumber">1116</context></context-group>
</trans-unit>
- <trans-unit id="_msg548">
+ <trans-unit id="_msg549">
<source xml:space="preserve">Whether we relay transactions to this peer.</source>
<context-group purpose="location"><context context-type="linenumber">1188</context></context-group>
</trans-unit>
- <trans-unit id="_msg549">
+ <trans-unit id="_msg550">
<source xml:space="preserve">Transaction Relay</source>
<context-group purpose="location"><context context-type="linenumber">1191</context></context-group>
</trans-unit>
- <trans-unit id="_msg550">
+ <trans-unit id="_msg551">
<source xml:space="preserve">Starting Block</source>
<context-group purpose="location"><context context-type="linenumber">1240</context></context-group>
</trans-unit>
- <trans-unit id="_msg551">
+ <trans-unit id="_msg552">
<source xml:space="preserve">Synced Headers</source>
<context-group purpose="location"><context context-type="linenumber">1263</context></context-group>
</trans-unit>
- <trans-unit id="_msg552">
+ <trans-unit id="_msg553">
<source xml:space="preserve">Synced Blocks</source>
<context-group purpose="location"><context context-type="linenumber">1286</context></context-group>
</trans-unit>
- <trans-unit id="_msg553">
+ <trans-unit id="_msg554">
<source xml:space="preserve">Last Transaction</source>
<context-group purpose="location"><context context-type="linenumber">1361</context></context-group>
</trans-unit>
- <trans-unit id="_msg554">
+ <trans-unit id="_msg555">
<source xml:space="preserve">The mapped Autonomous System used for diversifying peer selection.</source>
<context-group purpose="location"><context context-type="linenumber">1571</context></context-group>
</trans-unit>
- <trans-unit id="_msg555">
+ <trans-unit id="_msg556">
<source xml:space="preserve">Mapped AS</source>
<context-group purpose="location"><context context-type="linenumber">1574</context></context-group>
</trans-unit>
- <trans-unit id="_msg556">
+ <trans-unit id="_msg557">
<source xml:space="preserve">Whether we relay addresses to this peer.</source>
<context-group purpose="location"><context context-type="linenumber">1597</context></context-group>
<note annotates="source" from="developer">Tooltip text for the Address Relay field in the peer details area, which displays whether we relay addresses to this peer (Yes/No).</note>
</trans-unit>
- <trans-unit id="_msg557">
+ <trans-unit id="_msg558">
<source xml:space="preserve">Address Relay</source>
<context-group purpose="location"><context context-type="linenumber">1600</context></context-group>
<note annotates="source" from="developer">Text title for the Address Relay field in the peer details area, which displays whether we relay addresses to this peer (Yes/No).</note>
</trans-unit>
- <trans-unit id="_msg558">
+ <trans-unit id="_msg559">
<source xml:space="preserve">The total number of addresses received from this peer that were processed (excludes addresses that were dropped due to rate-limiting).</source>
<context-group purpose="location"><context context-type="linenumber">1623</context></context-group>
<note annotates="source" from="developer">Tooltip text for the Addresses Processed field in the peer details area, which displays the total number of addresses received from this peer that were processed (excludes addresses that were dropped due to rate-limiting).</note>
</trans-unit>
- <trans-unit id="_msg559">
+ <trans-unit id="_msg560">
<source xml:space="preserve">The total number of addresses received from this peer that were dropped (not processed) due to rate-limiting.</source>
<context-group purpose="location"><context context-type="linenumber">1649</context></context-group>
<note annotates="source" from="developer">Tooltip text for the Addresses Rate-Limited field in the peer details area, which displays the total number of addresses received from this peer that were dropped (not processed) due to rate-limiting.</note>
</trans-unit>
- <trans-unit id="_msg560">
+ <trans-unit id="_msg561">
<source xml:space="preserve">Addresses Processed</source>
<context-group purpose="location"><context context-type="linenumber">1626</context></context-group>
<note annotates="source" from="developer">Text title for the Addresses Processed field in the peer details area, which displays the total number of addresses received from this peer that were processed (excludes addresses that were dropped due to rate-limiting).</note>
</trans-unit>
- <trans-unit id="_msg561">
+ <trans-unit id="_msg562">
<source xml:space="preserve">Addresses Rate-Limited</source>
<context-group purpose="location"><context context-type="linenumber">1652</context></context-group>
<note annotates="source" from="developer">Text title for the Addresses Rate-Limited field in the peer details area, which displays the total number of addresses received from this peer that were dropped (not processed) due to rate-limiting.</note>
</trans-unit>
- <trans-unit id="_msg562">
+ <trans-unit id="_msg563">
<source xml:space="preserve">User Agent</source>
<context-group purpose="location"><context context-type="linenumber">88</context></context-group>
<context-group purpose="location"><context context-type="linenumber">1139</context></context-group>
</trans-unit>
- <trans-unit id="_msg563">
+ <trans-unit id="_msg564">
<source xml:space="preserve">Node window</source>
<context-group purpose="location"><context context-type="linenumber">14</context></context-group>
</trans-unit>
- <trans-unit id="_msg564">
+ <trans-unit id="_msg565">
<source xml:space="preserve">Current block height</source>
<context-group purpose="location"><context context-type="linenumber">267</context></context-group>
</trans-unit>
- <trans-unit id="_msg565">
+ <trans-unit id="_msg566">
<source xml:space="preserve">Open the %1 debug log file from the current data directory. This can take a few seconds for large log files.</source>
<context-group purpose="location"><context context-type="linenumber">397</context></context-group>
</trans-unit>
- <trans-unit id="_msg566">
+ <trans-unit id="_msg567">
<source xml:space="preserve">Decrease font size</source>
<context-group purpose="location"><context context-type="linenumber">475</context></context-group>
</trans-unit>
- <trans-unit id="_msg567">
+ <trans-unit id="_msg568">
<source xml:space="preserve">Increase font size</source>
<context-group purpose="location"><context context-type="linenumber">495</context></context-group>
</trans-unit>
- <trans-unit id="_msg568">
+ <trans-unit id="_msg569">
<source xml:space="preserve">Permissions</source>
<context-group purpose="location"><context context-type="linenumber">1041</context></context-group>
</trans-unit>
- <trans-unit id="_msg569">
+ <trans-unit id="_msg570">
<source xml:space="preserve">The direction and type of peer connection: %1</source>
<context-group purpose="location"><context context-type="linenumber">1064</context></context-group>
</trans-unit>
- <trans-unit id="_msg570">
+ <trans-unit id="_msg571">
<source xml:space="preserve">Direction/Type</source>
<context-group purpose="location"><context context-type="linenumber">1067</context></context-group>
</trans-unit>
- <trans-unit id="_msg571">
+ <trans-unit id="_msg572">
<source xml:space="preserve">The network protocol this peer is connected through: IPv4, IPv6, Onion, I2P, or CJDNS.</source>
<context-group purpose="location"><context context-type="linenumber">1090</context></context-group>
</trans-unit>
- <trans-unit id="_msg572">
+ <trans-unit id="_msg573">
<source xml:space="preserve">Services</source>
<context-group purpose="location"><context context-type="linenumber">1162</context></context-group>
</trans-unit>
- <trans-unit id="_msg573">
+ <trans-unit id="_msg574">
<source xml:space="preserve">High bandwidth BIP152 compact block relay: %1</source>
<context-group purpose="location"><context context-type="linenumber">1214</context></context-group>
</trans-unit>
- <trans-unit id="_msg574">
+ <trans-unit id="_msg575">
<source xml:space="preserve">High Bandwidth</source>
<context-group purpose="location"><context context-type="linenumber">1217</context></context-group>
</trans-unit>
- <trans-unit id="_msg575">
+ <trans-unit id="_msg576">
<source xml:space="preserve">Connection Time</source>
<context-group purpose="location"><context context-type="linenumber">1309</context></context-group>
</trans-unit>
- <trans-unit id="_msg576">
+ <trans-unit id="_msg577">
<source xml:space="preserve">Elapsed time since a novel block passing initial validity checks was received from this peer.</source>
<context-group purpose="location"><context context-type="linenumber">1332</context></context-group>
</trans-unit>
- <trans-unit id="_msg577">
+ <trans-unit id="_msg578">
<source xml:space="preserve">Last Block</source>
<context-group purpose="location"><context context-type="linenumber">1335</context></context-group>
</trans-unit>
- <trans-unit id="_msg578">
+ <trans-unit id="_msg579">
<source xml:space="preserve">Elapsed time since a novel transaction accepted into our mempool was received from this peer.</source>
<context-group purpose="location"><context context-type="linenumber">1358</context></context-group>
<note annotates="source" from="developer">Tooltip text for the Last Transaction field in the peer details area.</note>
</trans-unit>
- <trans-unit id="_msg579">
+ <trans-unit id="_msg580">
<source xml:space="preserve">Last Send</source>
<context-group purpose="location"><context context-type="linenumber">1384</context></context-group>
</trans-unit>
- <trans-unit id="_msg580">
+ <trans-unit id="_msg581">
<source xml:space="preserve">Last Receive</source>
<context-group purpose="location"><context context-type="linenumber">1407</context></context-group>
</trans-unit>
- <trans-unit id="_msg581">
+ <trans-unit id="_msg582">
<source xml:space="preserve">Ping Time</source>
<context-group purpose="location"><context context-type="linenumber">1476</context></context-group>
</trans-unit>
- <trans-unit id="_msg582">
+ <trans-unit id="_msg583">
<source xml:space="preserve">The duration of a currently outstanding ping.</source>
<context-group purpose="location"><context context-type="linenumber">1499</context></context-group>
</trans-unit>
- <trans-unit id="_msg583">
+ <trans-unit id="_msg584">
<source xml:space="preserve">Ping Wait</source>
<context-group purpose="location"><context context-type="linenumber">1502</context></context-group>
</trans-unit>
- <trans-unit id="_msg584">
+ <trans-unit id="_msg585">
<source xml:space="preserve">Min Ping</source>
<context-group purpose="location"><context context-type="linenumber">1525</context></context-group>
</trans-unit>
- <trans-unit id="_msg585">
+ <trans-unit id="_msg586">
<source xml:space="preserve">Time Offset</source>
<context-group purpose="location"><context context-type="linenumber">1548</context></context-group>
</trans-unit>
- <trans-unit id="_msg586">
+ <trans-unit id="_msg587">
<source xml:space="preserve">Last block time</source>
<context-group purpose="location"><context context-type="linenumber">290</context></context-group>
</trans-unit>
- <trans-unit id="_msg587">
+ <trans-unit id="_msg588">
<source xml:space="preserve">&amp;Open</source>
<context-group purpose="location"><context context-type="linenumber">400</context></context-group>
</trans-unit>
- <trans-unit id="_msg588">
+ <trans-unit id="_msg589">
<source xml:space="preserve">&amp;Console</source>
<context-group purpose="location"><context context-type="linenumber">426</context></context-group>
</trans-unit>
- <trans-unit id="_msg589">
+ <trans-unit id="_msg590">
<source xml:space="preserve">&amp;Network Traffic</source>
<context-group purpose="location"><context context-type="linenumber">613</context></context-group>
</trans-unit>
- <trans-unit id="_msg590">
+ <trans-unit id="_msg591">
<source xml:space="preserve">Totals</source>
<context-group purpose="location"><context context-type="linenumber">681</context></context-group>
</trans-unit>
- <trans-unit id="_msg591">
+ <trans-unit id="_msg592">
<source xml:space="preserve">Debug log file</source>
<context-group purpose="location"><context context-type="linenumber">390</context></context-group>
</trans-unit>
- <trans-unit id="_msg592">
+ <trans-unit id="_msg593">
<source xml:space="preserve">Clear console</source>
<context-group purpose="location"><context context-type="linenumber">515</context></context-group>
</trans-unit>
@@ -2747,139 +2761,139 @@ If you are receiving this error you should request the merchant provide a BIP21
</body></file>
<file original="../rpcconsole.cpp" datatype="cpp" source-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="RPCConsole">
- <trans-unit id="_msg593">
+ <trans-unit id="_msg594">
<source xml:space="preserve">In:</source>
- <context-group purpose="location"><context context-type="linenumber">953</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">952</context></context-group>
</trans-unit>
- <trans-unit id="_msg594">
+ <trans-unit id="_msg595">
<source xml:space="preserve">Out:</source>
- <context-group purpose="location"><context context-type="linenumber">954</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">953</context></context-group>
</trans-unit>
- <trans-unit id="_msg595">
+ <trans-unit id="_msg596">
<source xml:space="preserve">Inbound: initiated by peer</source>
- <context-group purpose="location"><context context-type="linenumber">496</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">495</context></context-group>
<note annotates="source" from="developer">Explanatory text for an inbound peer connection.</note>
</trans-unit>
- <trans-unit id="_msg596">
+ <trans-unit id="_msg597">
<source xml:space="preserve">Outbound Full Relay: default</source>
- <context-group purpose="location"><context context-type="linenumber">500</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">499</context></context-group>
<note annotates="source" from="developer">Explanatory text for an outbound peer connection that relays all network information. This is the default behavior for outbound connections.</note>
</trans-unit>
- <trans-unit id="_msg597">
+ <trans-unit id="_msg598">
<source xml:space="preserve">Outbound Block Relay: does not relay transactions or addresses</source>
- <context-group purpose="location"><context context-type="linenumber">503</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">502</context></context-group>
<note annotates="source" from="developer">Explanatory text for an outbound peer connection that relays network information about blocks and not transactions or addresses.</note>
</trans-unit>
- <trans-unit id="_msg598">
+ <trans-unit id="_msg599">
<source xml:space="preserve">Outbound Manual: added using RPC %1 or %2/%3 configuration options</source>
- <context-group purpose="location"><context context-type="linenumber">508</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">507</context></context-group>
<note annotates="source" from="developer">Explanatory text for an outbound peer connection that was established manually through one of several methods. The numbered arguments are stand-ins for the methods available to establish manual connections.</note>
</trans-unit>
- <trans-unit id="_msg599">
+ <trans-unit id="_msg600">
<source xml:space="preserve">Outbound Feeler: short-lived, for testing addresses</source>
- <context-group purpose="location"><context context-type="linenumber">514</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">513</context></context-group>
<note annotates="source" from="developer">Explanatory text for a short-lived outbound peer connection that is used to test the aliveness of known addresses.</note>
</trans-unit>
- <trans-unit id="_msg600">
+ <trans-unit id="_msg601">
<source xml:space="preserve">Outbound Address Fetch: short-lived, for soliciting addresses</source>
- <context-group purpose="location"><context context-type="linenumber">517</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">516</context></context-group>
<note annotates="source" from="developer">Explanatory text for a short-lived outbound peer connection that is used to request addresses from a peer.</note>
</trans-unit>
- <trans-unit id="_msg601">
+ <trans-unit id="_msg602">
<source xml:space="preserve">we selected the peer for high bandwidth relay</source>
- <context-group purpose="location"><context context-type="linenumber">521</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">520</context></context-group>
</trans-unit>
- <trans-unit id="_msg602">
+ <trans-unit id="_msg603">
<source xml:space="preserve">the peer selected us for high bandwidth relay</source>
- <context-group purpose="location"><context context-type="linenumber">522</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">521</context></context-group>
</trans-unit>
- <trans-unit id="_msg603">
+ <trans-unit id="_msg604">
<source xml:space="preserve">no high bandwidth relay selected</source>
- <context-group purpose="location"><context context-type="linenumber">523</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">522</context></context-group>
</trans-unit>
- <trans-unit id="_msg604">
+ <trans-unit id="_msg605">
<source xml:space="preserve">Ctrl++</source>
- <context-group purpose="location"><context context-type="linenumber">536</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">535</context></context-group>
<note annotates="source" from="developer">Main shortcut to increase the RPC console font size.</note>
</trans-unit>
- <trans-unit id="_msg605">
+ <trans-unit id="_msg606">
<source xml:space="preserve">Ctrl+=</source>
- <context-group purpose="location"><context context-type="linenumber">538</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">537</context></context-group>
<note annotates="source" from="developer">Secondary shortcut to increase the RPC console font size.</note>
</trans-unit>
- <trans-unit id="_msg606">
+ <trans-unit id="_msg607">
<source xml:space="preserve">Ctrl+-</source>
- <context-group purpose="location"><context context-type="linenumber">542</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">541</context></context-group>
<note annotates="source" from="developer">Main shortcut to decrease the RPC console font size.</note>
</trans-unit>
- <trans-unit id="_msg607">
+ <trans-unit id="_msg608">
<source xml:space="preserve">Ctrl+_</source>
- <context-group purpose="location"><context context-type="linenumber">544</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">543</context></context-group>
<note annotates="source" from="developer">Secondary shortcut to decrease the RPC console font size.</note>
</trans-unit>
- <trans-unit id="_msg608">
+ <trans-unit id="_msg609">
<source xml:space="preserve">&amp;Copy address</source>
- <context-group purpose="location"><context context-type="linenumber">695</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">694</context></context-group>
<note annotates="source" from="developer">Context menu action to copy the address of a peer.</note>
</trans-unit>
- <trans-unit id="_msg609">
+ <trans-unit id="_msg610">
<source xml:space="preserve">&amp;Disconnect</source>
- <context-group purpose="location"><context context-type="linenumber">699</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">698</context></context-group>
</trans-unit>
- <trans-unit id="_msg610">
+ <trans-unit id="_msg611">
<source xml:space="preserve">1 &amp;hour</source>
- <context-group purpose="location"><context context-type="linenumber">700</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">699</context></context-group>
</trans-unit>
- <trans-unit id="_msg611">
+ <trans-unit id="_msg612">
<source xml:space="preserve">1 d&amp;ay</source>
- <context-group purpose="location"><context context-type="linenumber">701</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">700</context></context-group>
</trans-unit>
- <trans-unit id="_msg612">
+ <trans-unit id="_msg613">
<source xml:space="preserve">1 &amp;week</source>
- <context-group purpose="location"><context context-type="linenumber">702</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">701</context></context-group>
</trans-unit>
- <trans-unit id="_msg613">
+ <trans-unit id="_msg614">
<source xml:space="preserve">1 &amp;year</source>
- <context-group purpose="location"><context context-type="linenumber">703</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">702</context></context-group>
</trans-unit>
- <trans-unit id="_msg614">
+ <trans-unit id="_msg615">
<source xml:space="preserve">&amp;Copy IP/Netmask</source>
- <context-group purpose="location"><context context-type="linenumber">729</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">728</context></context-group>
<note annotates="source" from="developer">Context menu action to copy the IP/Netmask of a banned peer. IP/Netmask is the combination of a peer&apos;s IP address and its Netmask. For IP address, see: https://en.wikipedia.org/wiki/IP_address.</note>
</trans-unit>
- <trans-unit id="_msg615">
+ <trans-unit id="_msg616">
<source xml:space="preserve">&amp;Unban</source>
- <context-group purpose="location"><context context-type="linenumber">733</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">732</context></context-group>
</trans-unit>
- <trans-unit id="_msg616">
+ <trans-unit id="_msg617">
<source xml:space="preserve">Network activity disabled</source>
- <context-group purpose="location"><context context-type="linenumber">957</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">956</context></context-group>
</trans-unit>
- <trans-unit id="_msg617">
+ <trans-unit id="_msg618">
<source xml:space="preserve">Executing command without any wallet</source>
<context-group purpose="location"><context context-type="linenumber">1035</context></context-group>
</trans-unit>
- <trans-unit id="_msg618">
+ <trans-unit id="_msg619">
<source xml:space="preserve">Ctrl+I</source>
- <context-group purpose="location"><context context-type="linenumber">1355</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1351</context></context-group>
</trans-unit>
- <trans-unit id="_msg619">
+ <trans-unit id="_msg620">
<source xml:space="preserve">Ctrl+T</source>
- <context-group purpose="location"><context context-type="linenumber">1356</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1352</context></context-group>
</trans-unit>
- <trans-unit id="_msg620">
+ <trans-unit id="_msg621">
<source xml:space="preserve">Ctrl+N</source>
- <context-group purpose="location"><context context-type="linenumber">1357</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1353</context></context-group>
</trans-unit>
- <trans-unit id="_msg621">
+ <trans-unit id="_msg622">
<source xml:space="preserve">Ctrl+P</source>
- <context-group purpose="location"><context context-type="linenumber">1358</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1354</context></context-group>
</trans-unit>
- <trans-unit id="_msg622">
+ <trans-unit id="_msg623">
<source xml:space="preserve">Executing command using &quot;%1&quot; wallet</source>
<context-group purpose="location"><context context-type="linenumber">1033</context></context-group>
</trans-unit>
- <trans-unit id="_msg623">
+ <trans-unit id="_msg624">
<source xml:space="preserve">Welcome to the %1 RPC console.
Use up and down arrows to navigate history, and %2 to clear screen.
Use %3 and %4 to increase or decrease the font size.
@@ -2887,19 +2901,19 @@ Type %5 for an overview of available commands.
For more information on using this console, type %6.
%7WARNING: Scammers have been active, telling users to type commands here, stealing their wallet contents. Do not use this console without fully understanding the ramifications of a command.%8</source>
- <context-group purpose="location"><context context-type="linenumber">887</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">886</context></context-group>
<note annotates="source" from="developer">RPC console welcome message. Placeholders %7 and %8 are style tags for the warning content, and they are not space separated from the rest of the text intentionally.</note>
</trans-unit>
- <trans-unit id="_msg624">
+ <trans-unit id="_msg625">
<source xml:space="preserve">Executing…</source>
<context-group purpose="location"><context context-type="linenumber">1043</context></context-group>
<note annotates="source" from="developer">A console message indicating an entered command is currently being executed.</note>
</trans-unit>
- <trans-unit id="_msg625">
+ <trans-unit id="_msg626">
<source xml:space="preserve">(peer: %1)</source>
<context-group purpose="location"><context context-type="linenumber">1161</context></context-group>
</trans-unit>
- <trans-unit id="_msg626">
+ <trans-unit id="_msg627">
<source xml:space="preserve">via %1</source>
<context-group purpose="location"><context context-type="linenumber">1163</context></context-group>
</trans-unit>
@@ -2907,31 +2921,31 @@ For more information on using this console, type %6.
</body></file>
<file original="../rpcconsole.h" datatype="c" source-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="RPCConsole">
- <trans-unit id="_msg627">
+ <trans-unit id="_msg628">
<source xml:space="preserve">Yes</source>
<context-group purpose="location"><context context-type="linenumber">142</context></context-group>
</trans-unit>
- <trans-unit id="_msg628">
+ <trans-unit id="_msg629">
<source xml:space="preserve">No</source>
<context-group purpose="location"><context context-type="linenumber">142</context></context-group>
</trans-unit>
- <trans-unit id="_msg629">
+ <trans-unit id="_msg630">
<source xml:space="preserve">To</source>
<context-group purpose="location"><context context-type="linenumber">142</context></context-group>
</trans-unit>
- <trans-unit id="_msg630">
+ <trans-unit id="_msg631">
<source xml:space="preserve">From</source>
<context-group purpose="location"><context context-type="linenumber">142</context></context-group>
</trans-unit>
- <trans-unit id="_msg631">
+ <trans-unit id="_msg632">
<source xml:space="preserve">Ban for</source>
<context-group purpose="location"><context context-type="linenumber">143</context></context-group>
</trans-unit>
- <trans-unit id="_msg632">
+ <trans-unit id="_msg633">
<source xml:space="preserve">Never</source>
<context-group purpose="location"><context context-type="linenumber">185</context></context-group>
</trans-unit>
- <trans-unit id="_msg633">
+ <trans-unit id="_msg634">
<source xml:space="preserve">Unknown</source>
<context-group purpose="location"><context context-type="linenumber">143</context></context-group>
</trans-unit>
@@ -2939,72 +2953,72 @@ For more information on using this console, type %6.
</body></file>
<file original="../forms/receivecoinsdialog.ui" datatype="x-trolltech-designer-ui" source-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="ReceiveCoinsDialog">
- <trans-unit id="_msg634">
+ <trans-unit id="_msg635">
<source xml:space="preserve">&amp;Amount:</source>
<context-group purpose="location"><context context-type="linenumber">37</context></context-group>
</trans-unit>
- <trans-unit id="_msg635">
+ <trans-unit id="_msg636">
<source xml:space="preserve">&amp;Label:</source>
<context-group purpose="location"><context context-type="linenumber">83</context></context-group>
</trans-unit>
- <trans-unit id="_msg636">
+ <trans-unit id="_msg637">
<source xml:space="preserve">&amp;Message:</source>
<context-group purpose="location"><context context-type="linenumber">53</context></context-group>
</trans-unit>
- <trans-unit id="_msg637">
+ <trans-unit id="_msg638">
<source xml:space="preserve">An optional message to attach to the payment request, which will be displayed when the request is opened. Note: The message will not be sent with the payment over the Bitcoin network.</source>
<context-group purpose="location"><context context-type="linenumber">50</context></context-group>
</trans-unit>
- <trans-unit id="_msg638">
+ <trans-unit id="_msg639">
<source xml:space="preserve">An optional label to associate with the new receiving address.</source>
<context-group purpose="location"><context context-type="linenumber">80</context></context-group>
</trans-unit>
- <trans-unit id="_msg639">
+ <trans-unit id="_msg640">
<source xml:space="preserve">Use this form to request payments. All fields are &lt;b&gt;optional&lt;/b&gt;.</source>
<context-group purpose="location"><context context-type="linenumber">73</context></context-group>
</trans-unit>
- <trans-unit id="_msg640">
+ <trans-unit id="_msg641">
<source xml:space="preserve">An optional amount to request. Leave this empty or zero to not request a specific amount.</source>
<context-group purpose="location"><context context-type="linenumber">34</context></context-group>
<context-group purpose="location"><context context-type="linenumber">193</context></context-group>
</trans-unit>
- <trans-unit id="_msg641">
+ <trans-unit id="_msg642">
<source xml:space="preserve">An optional label to associate with the new receiving address (used by you to identify an invoice). It is also attached to the payment request.</source>
<context-group purpose="location"><context context-type="linenumber">66</context></context-group>
</trans-unit>
- <trans-unit id="_msg642">
+ <trans-unit id="_msg643">
<source xml:space="preserve">An optional message that is attached to the payment request and may be displayed to the sender.</source>
<context-group purpose="location"><context context-type="linenumber">96</context></context-group>
</trans-unit>
- <trans-unit id="_msg643">
+ <trans-unit id="_msg644">
<source xml:space="preserve">&amp;Create new receiving address</source>
<context-group purpose="location"><context context-type="linenumber">111</context></context-group>
</trans-unit>
- <trans-unit id="_msg644">
+ <trans-unit id="_msg645">
<source xml:space="preserve">Clear all fields of the form.</source>
<context-group purpose="location"><context context-type="linenumber">134</context></context-group>
</trans-unit>
- <trans-unit id="_msg645">
+ <trans-unit id="_msg646">
<source xml:space="preserve">Clear</source>
<context-group purpose="location"><context context-type="linenumber">137</context></context-group>
</trans-unit>
- <trans-unit id="_msg646">
+ <trans-unit id="_msg647">
<source xml:space="preserve">Requested payments history</source>
<context-group purpose="location"><context context-type="linenumber">273</context></context-group>
</trans-unit>
- <trans-unit id="_msg647">
+ <trans-unit id="_msg648">
<source xml:space="preserve">Show the selected request (does the same as double clicking an entry)</source>
<context-group purpose="location"><context context-type="linenumber">298</context></context-group>
</trans-unit>
- <trans-unit id="_msg648">
+ <trans-unit id="_msg649">
<source xml:space="preserve">Show</source>
<context-group purpose="location"><context context-type="linenumber">301</context></context-group>
</trans-unit>
- <trans-unit id="_msg649">
+ <trans-unit id="_msg650">
<source xml:space="preserve">Remove the selected entries from the list</source>
<context-group purpose="location"><context context-type="linenumber">318</context></context-group>
</trans-unit>
- <trans-unit id="_msg650">
+ <trans-unit id="_msg651">
<source xml:space="preserve">Remove</source>
<context-group purpose="location"><context context-type="linenumber">321</context></context-group>
</trans-unit>
@@ -3012,31 +3026,63 @@ For more information on using this console, type %6.
</body></file>
<file original="../receivecoinsdialog.cpp" datatype="cpp" source-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="ReceiveCoinsDialog">
- <trans-unit id="_msg651">
+ <trans-unit id="_msg652">
<source xml:space="preserve">Copy &amp;URI</source>
<context-group purpose="location"><context context-type="linenumber">46</context></context-group>
</trans-unit>
- <trans-unit id="_msg652">
+ <trans-unit id="_msg653">
<source xml:space="preserve">&amp;Copy address</source>
<context-group purpose="location"><context context-type="linenumber">47</context></context-group>
</trans-unit>
- <trans-unit id="_msg653">
+ <trans-unit id="_msg654">
<source xml:space="preserve">Copy &amp;label</source>
<context-group purpose="location"><context context-type="linenumber">48</context></context-group>
</trans-unit>
- <trans-unit id="_msg654">
+ <trans-unit id="_msg655">
<source xml:space="preserve">Copy &amp;message</source>
<context-group purpose="location"><context context-type="linenumber">49</context></context-group>
</trans-unit>
- <trans-unit id="_msg655">
+ <trans-unit id="_msg656">
<source xml:space="preserve">Copy &amp;amount</source>
<context-group purpose="location"><context context-type="linenumber">50</context></context-group>
</trans-unit>
- <trans-unit id="_msg656">
+ <trans-unit id="_msg657">
+ <source xml:space="preserve">Base58 (Legacy)</source>
+ <context-group purpose="location"><context context-type="linenumber">96</context></context-group>
+ </trans-unit>
+ <trans-unit id="_msg658">
+ <source xml:space="preserve">Not recommended due to higher fees and less protection against typos.</source>
+ <context-group purpose="location"><context context-type="linenumber">96</context></context-group>
+ </trans-unit>
+ <trans-unit id="_msg659">
+ <source xml:space="preserve">Base58 (P2SH-SegWit)</source>
+ <context-group purpose="location"><context context-type="linenumber">97</context></context-group>
+ </trans-unit>
+ <trans-unit id="_msg660">
+ <source xml:space="preserve">Generates an address compatible with older wallets.</source>
+ <context-group purpose="location"><context context-type="linenumber">97</context></context-group>
+ </trans-unit>
+ <trans-unit id="_msg661">
+ <source xml:space="preserve">Bech32 (SegWit)</source>
+ <context-group purpose="location"><context context-type="linenumber">98</context></context-group>
+ </trans-unit>
+ <trans-unit id="_msg662">
+ <source xml:space="preserve">Generates a native segwit address (BIP-173). Some old wallets don&apos;t support it.</source>
+ <context-group purpose="location"><context context-type="linenumber">98</context></context-group>
+ </trans-unit>
+ <trans-unit id="_msg663">
+ <source xml:space="preserve">Bech32m (Taproot)</source>
+ <context-group purpose="location"><context context-type="linenumber">100</context></context-group>
+ </trans-unit>
+ <trans-unit id="_msg664">
+ <source xml:space="preserve">Bech32m (BIP-350) is an upgrade to Bech32, wallet support is still limited.</source>
+ <context-group purpose="location"><context context-type="linenumber">100</context></context-group>
+ </trans-unit>
+ <trans-unit id="_msg665">
<source xml:space="preserve">Could not unlock wallet.</source>
<context-group purpose="location"><context context-type="linenumber">175</context></context-group>
</trans-unit>
- <trans-unit id="_msg657">
+ <trans-unit id="_msg666">
<source xml:space="preserve">Could not generate new %1 address</source>
<context-group purpose="location"><context context-type="linenumber">180</context></context-group>
</trans-unit>
@@ -3044,51 +3090,51 @@ For more information on using this console, type %6.
</body></file>
<file original="../forms/receiverequestdialog.ui" datatype="x-trolltech-designer-ui" source-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="ReceiveRequestDialog">
- <trans-unit id="_msg658">
+ <trans-unit id="_msg667">
<source xml:space="preserve">Request payment to …</source>
<context-group purpose="location"><context context-type="linenumber">14</context></context-group>
</trans-unit>
- <trans-unit id="_msg659">
+ <trans-unit id="_msg668">
<source xml:space="preserve">Address:</source>
<context-group purpose="location"><context context-type="linenumber">90</context></context-group>
</trans-unit>
- <trans-unit id="_msg660">
+ <trans-unit id="_msg669">
<source xml:space="preserve">Amount:</source>
<context-group purpose="location"><context context-type="linenumber">119</context></context-group>
</trans-unit>
- <trans-unit id="_msg661">
+ <trans-unit id="_msg670">
<source xml:space="preserve">Label:</source>
<context-group purpose="location"><context context-type="linenumber">148</context></context-group>
</trans-unit>
- <trans-unit id="_msg662">
+ <trans-unit id="_msg671">
<source xml:space="preserve">Message:</source>
<context-group purpose="location"><context context-type="linenumber">180</context></context-group>
</trans-unit>
- <trans-unit id="_msg663">
+ <trans-unit id="_msg672">
<source xml:space="preserve">Wallet:</source>
<context-group purpose="location"><context context-type="linenumber">212</context></context-group>
</trans-unit>
- <trans-unit id="_msg664">
+ <trans-unit id="_msg673">
<source xml:space="preserve">Copy &amp;URI</source>
<context-group purpose="location"><context context-type="linenumber">240</context></context-group>
</trans-unit>
- <trans-unit id="_msg665">
+ <trans-unit id="_msg674">
<source xml:space="preserve">Copy &amp;Address</source>
<context-group purpose="location"><context context-type="linenumber">250</context></context-group>
</trans-unit>
- <trans-unit id="_msg666">
+ <trans-unit id="_msg675">
<source xml:space="preserve">&amp;Verify</source>
<context-group purpose="location"><context context-type="linenumber">260</context></context-group>
</trans-unit>
- <trans-unit id="_msg667">
+ <trans-unit id="_msg676">
<source xml:space="preserve">Verify this address on e.g. a hardware wallet screen</source>
<context-group purpose="location"><context context-type="linenumber">263</context></context-group>
</trans-unit>
- <trans-unit id="_msg668">
+ <trans-unit id="_msg677">
<source xml:space="preserve">&amp;Save Image…</source>
<context-group purpose="location"><context context-type="linenumber">273</context></context-group>
</trans-unit>
- <trans-unit id="_msg669">
+ <trans-unit id="_msg678">
<source xml:space="preserve">Payment information</source>
<context-group purpose="location"><context context-type="linenumber">39</context></context-group>
</trans-unit>
@@ -3096,7 +3142,7 @@ For more information on using this console, type %6.
</body></file>
<file original="../receiverequestdialog.cpp" datatype="cpp" source-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="ReceiveRequestDialog">
- <trans-unit id="_msg670">
+ <trans-unit id="_msg679">
<source xml:space="preserve">Request payment to %1</source>
<context-group purpose="location"><context context-type="linenumber">48</context></context-group>
</trans-unit>
@@ -3104,31 +3150,31 @@ For more information on using this console, type %6.
</body></file>
<file original="../recentrequeststablemodel.cpp" datatype="cpp" source-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="RecentRequestsTableModel">
- <trans-unit id="_msg671">
+ <trans-unit id="_msg680">
<source xml:space="preserve">Date</source>
<context-group purpose="location"><context context-type="linenumber">32</context></context-group>
</trans-unit>
- <trans-unit id="_msg672">
+ <trans-unit id="_msg681">
<source xml:space="preserve">Label</source>
<context-group purpose="location"><context context-type="linenumber">32</context></context-group>
</trans-unit>
- <trans-unit id="_msg673">
+ <trans-unit id="_msg682">
<source xml:space="preserve">Message</source>
<context-group purpose="location"><context context-type="linenumber">32</context></context-group>
</trans-unit>
- <trans-unit id="_msg674">
+ <trans-unit id="_msg683">
<source xml:space="preserve">(no label)</source>
<context-group purpose="location"><context context-type="linenumber">70</context></context-group>
</trans-unit>
- <trans-unit id="_msg675">
+ <trans-unit id="_msg684">
<source xml:space="preserve">(no message)</source>
<context-group purpose="location"><context context-type="linenumber">79</context></context-group>
</trans-unit>
- <trans-unit id="_msg676">
+ <trans-unit id="_msg685">
<source xml:space="preserve">(no amount requested)</source>
<context-group purpose="location"><context context-type="linenumber">87</context></context-group>
</trans-unit>
- <trans-unit id="_msg677">
+ <trans-unit id="_msg686">
<source xml:space="preserve">Requested</source>
<context-group purpose="location"><context context-type="linenumber">130</context></context-group>
</trans-unit>
@@ -3136,154 +3182,154 @@ For more information on using this console, type %6.
</body></file>
<file original="../forms/sendcoinsdialog.ui" datatype="x-trolltech-designer-ui" source-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="SendCoinsDialog">
- <trans-unit id="_msg678">
+ <trans-unit id="_msg687">
<source xml:space="preserve">Send Coins</source>
<context-group purpose="location"><context context-type="linenumber">14</context></context-group>
- <context-group purpose="location"><context context-type="sourcefile">../sendcoinsdialog.cpp</context><context context-type="linenumber">755</context></context-group>
+ <context-group purpose="location"><context context-type="sourcefile">../sendcoinsdialog.cpp</context><context context-type="linenumber">765</context></context-group>
</trans-unit>
- <trans-unit id="_msg679">
+ <trans-unit id="_msg688">
<source xml:space="preserve">Coin Control Features</source>
<context-group purpose="location"><context context-type="linenumber">90</context></context-group>
</trans-unit>
- <trans-unit id="_msg680">
+ <trans-unit id="_msg689">
<source xml:space="preserve">automatically selected</source>
<context-group purpose="location"><context context-type="linenumber">120</context></context-group>
</trans-unit>
- <trans-unit id="_msg681">
+ <trans-unit id="_msg690">
<source xml:space="preserve">Insufficient funds!</source>
<context-group purpose="location"><context context-type="linenumber">139</context></context-group>
</trans-unit>
- <trans-unit id="_msg682">
+ <trans-unit id="_msg691">
<source xml:space="preserve">Quantity:</source>
<context-group purpose="location"><context context-type="linenumber">228</context></context-group>
</trans-unit>
- <trans-unit id="_msg683">
+ <trans-unit id="_msg692">
<source xml:space="preserve">Bytes:</source>
<context-group purpose="location"><context context-type="linenumber">263</context></context-group>
</trans-unit>
- <trans-unit id="_msg684">
+ <trans-unit id="_msg693">
<source xml:space="preserve">Amount:</source>
<context-group purpose="location"><context context-type="linenumber">311</context></context-group>
</trans-unit>
- <trans-unit id="_msg685">
+ <trans-unit id="_msg694">
<source xml:space="preserve">Fee:</source>
<context-group purpose="location"><context context-type="linenumber">391</context></context-group>
</trans-unit>
- <trans-unit id="_msg686">
+ <trans-unit id="_msg695">
<source xml:space="preserve">After Fee:</source>
<context-group purpose="location"><context context-type="linenumber">442</context></context-group>
</trans-unit>
- <trans-unit id="_msg687">
+ <trans-unit id="_msg696">
<source xml:space="preserve">Change:</source>
<context-group purpose="location"><context context-type="linenumber">474</context></context-group>
</trans-unit>
- <trans-unit id="_msg688">
+ <trans-unit id="_msg697">
<source xml:space="preserve">If this is activated, but the change address is empty or invalid, change will be sent to a newly generated address.</source>
<context-group purpose="location"><context context-type="linenumber">518</context></context-group>
</trans-unit>
- <trans-unit id="_msg689">
+ <trans-unit id="_msg698">
<source xml:space="preserve">Custom change address</source>
<context-group purpose="location"><context context-type="linenumber">521</context></context-group>
</trans-unit>
- <trans-unit id="_msg690">
+ <trans-unit id="_msg699">
<source xml:space="preserve">Transaction Fee:</source>
<context-group purpose="location"><context context-type="linenumber">727</context></context-group>
</trans-unit>
- <trans-unit id="_msg691">
+ <trans-unit id="_msg700">
<source xml:space="preserve">Using the fallbackfee can result in sending a transaction that will take several hours or days (or never) to confirm. Consider choosing your fee manually or wait until you have validated the complete chain.</source>
<context-group purpose="location"><context context-type="linenumber">765</context></context-group>
</trans-unit>
- <trans-unit id="_msg692">
+ <trans-unit id="_msg701">
<source xml:space="preserve">Warning: Fee estimation is currently not possible.</source>
<context-group purpose="location"><context context-type="linenumber">774</context></context-group>
</trans-unit>
- <trans-unit id="_msg693">
+ <trans-unit id="_msg702">
<source xml:space="preserve">per kilobyte</source>
<context-group purpose="location"><context context-type="linenumber">856</context></context-group>
</trans-unit>
- <trans-unit id="_msg694">
+ <trans-unit id="_msg703">
<source xml:space="preserve">Hide</source>
<context-group purpose="location"><context context-type="linenumber">803</context></context-group>
</trans-unit>
- <trans-unit id="_msg695">
+ <trans-unit id="_msg704">
<source xml:space="preserve">Recommended:</source>
<context-group purpose="location"><context context-type="linenumber">915</context></context-group>
</trans-unit>
- <trans-unit id="_msg696">
+ <trans-unit id="_msg705">
<source xml:space="preserve">Custom:</source>
<context-group purpose="location"><context context-type="linenumber">945</context></context-group>
</trans-unit>
- <trans-unit id="_msg697">
+ <trans-unit id="_msg706">
<source xml:space="preserve">Send to multiple recipients at once</source>
<context-group purpose="location"><context context-type="linenumber">1160</context></context-group>
</trans-unit>
- <trans-unit id="_msg698">
+ <trans-unit id="_msg707">
<source xml:space="preserve">Add &amp;Recipient</source>
<context-group purpose="location"><context context-type="linenumber">1163</context></context-group>
</trans-unit>
- <trans-unit id="_msg699">
+ <trans-unit id="_msg708">
<source xml:space="preserve">Clear all fields of the form.</source>
<context-group purpose="location"><context context-type="linenumber">1143</context></context-group>
</trans-unit>
- <trans-unit id="_msg700">
+ <trans-unit id="_msg709">
<source xml:space="preserve">Inputs…</source>
<context-group purpose="location"><context context-type="linenumber">110</context></context-group>
</trans-unit>
- <trans-unit id="_msg701">
+ <trans-unit id="_msg710">
<source xml:space="preserve">Dust:</source>
<context-group purpose="location"><context context-type="linenumber">343</context></context-group>
</trans-unit>
- <trans-unit id="_msg702">
+ <trans-unit id="_msg711">
<source xml:space="preserve">Choose…</source>
<context-group purpose="location"><context context-type="linenumber">741</context></context-group>
</trans-unit>
- <trans-unit id="_msg703">
+ <trans-unit id="_msg712">
<source xml:space="preserve">Hide transaction fee settings</source>
<context-group purpose="location"><context context-type="linenumber">800</context></context-group>
</trans-unit>
- <trans-unit id="_msg704">
+ <trans-unit id="_msg713">
<source xml:space="preserve">Specify a custom fee per kB (1,000 bytes) of the transaction&apos;s virtual size.
Note: Since the fee is calculated on a per-byte basis, a fee rate of &quot;100 satoshis per kvB&quot; for a transaction size of 500 virtual bytes (half of 1 kvB) would ultimately yield a fee of only 50 satoshis.</source>
<context-group purpose="location"><context context-type="linenumber">851</context></context-group>
</trans-unit>
- <trans-unit id="_msg705">
+ <trans-unit id="_msg714">
<source xml:space="preserve">When there is less transaction volume than space in the blocks, miners as well as relaying nodes may enforce a minimum fee. Paying only this minimum fee is just fine, but be aware that this can result in a never confirming transaction once there is more demand for bitcoin transactions than the network can process.</source>
<context-group purpose="location"><context context-type="linenumber">886</context></context-group>
</trans-unit>
- <trans-unit id="_msg706">
+ <trans-unit id="_msg715">
<source xml:space="preserve">A too low fee might result in a never confirming transaction (read the tooltip)</source>
<context-group purpose="location"><context context-type="linenumber">889</context></context-group>
</trans-unit>
- <trans-unit id="_msg707">
+ <trans-unit id="_msg716">
<source xml:space="preserve">(Smart fee not initialized yet. This usually takes a few blocks…)</source>
<context-group purpose="location"><context context-type="linenumber">994</context></context-group>
</trans-unit>
- <trans-unit id="_msg708">
+ <trans-unit id="_msg717">
<source xml:space="preserve">Confirmation time target:</source>
<context-group purpose="location"><context context-type="linenumber">1020</context></context-group>
</trans-unit>
- <trans-unit id="_msg709">
+ <trans-unit id="_msg718">
<source xml:space="preserve">Enable Replace-By-Fee</source>
<context-group purpose="location"><context context-type="linenumber">1078</context></context-group>
</trans-unit>
- <trans-unit id="_msg710">
+ <trans-unit id="_msg719">
<source xml:space="preserve">With Replace-By-Fee (BIP-125) you can increase a transaction&apos;s fee after it is sent. Without this, a higher fee may be recommended to compensate for increased transaction delay risk.</source>
<context-group purpose="location"><context context-type="linenumber">1081</context></context-group>
</trans-unit>
- <trans-unit id="_msg711">
+ <trans-unit id="_msg720">
<source xml:space="preserve">Clear &amp;All</source>
<context-group purpose="location"><context context-type="linenumber">1146</context></context-group>
</trans-unit>
- <trans-unit id="_msg712">
+ <trans-unit id="_msg721">
<source xml:space="preserve">Balance:</source>
<context-group purpose="location"><context context-type="linenumber">1201</context></context-group>
</trans-unit>
- <trans-unit id="_msg713">
+ <trans-unit id="_msg722">
<source xml:space="preserve">Confirm the send action</source>
<context-group purpose="location"><context context-type="linenumber">1117</context></context-group>
</trans-unit>
- <trans-unit id="_msg714">
+ <trans-unit id="_msg723">
<source xml:space="preserve">S&amp;end</source>
<context-group purpose="location"><context context-type="linenumber">1120</context></context-group>
</trans-unit>
@@ -3291,278 +3337,304 @@ Note: Since the fee is calculated on a per-byte basis, a fee rate of &quot;100
</body></file>
<file original="../sendcoinsdialog.cpp" datatype="cpp" source-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="SendCoinsDialog">
- <trans-unit id="_msg715">
+ <trans-unit id="_msg724">
<source xml:space="preserve">Copy quantity</source>
<context-group purpose="location"><context context-type="linenumber">95</context></context-group>
</trans-unit>
- <trans-unit id="_msg716">
+ <trans-unit id="_msg725">
<source xml:space="preserve">Copy amount</source>
<context-group purpose="location"><context context-type="linenumber">96</context></context-group>
</trans-unit>
- <trans-unit id="_msg717">
+ <trans-unit id="_msg726">
<source xml:space="preserve">Copy fee</source>
<context-group purpose="location"><context context-type="linenumber">97</context></context-group>
</trans-unit>
- <trans-unit id="_msg718">
+ <trans-unit id="_msg727">
<source xml:space="preserve">Copy after fee</source>
<context-group purpose="location"><context context-type="linenumber">98</context></context-group>
</trans-unit>
- <trans-unit id="_msg719">
+ <trans-unit id="_msg728">
<source xml:space="preserve">Copy bytes</source>
<context-group purpose="location"><context context-type="linenumber">99</context></context-group>
</trans-unit>
- <trans-unit id="_msg720">
+ <trans-unit id="_msg729">
<source xml:space="preserve">Copy dust</source>
<context-group purpose="location"><context context-type="linenumber">100</context></context-group>
</trans-unit>
- <trans-unit id="_msg721">
+ <trans-unit id="_msg730">
<source xml:space="preserve">Copy change</source>
<context-group purpose="location"><context context-type="linenumber">101</context></context-group>
</trans-unit>
- <trans-unit id="_msg722">
+ <trans-unit id="_msg731">
<source xml:space="preserve">%1 (%2 blocks)</source>
<context-group purpose="location"><context context-type="linenumber">175</context></context-group>
</trans-unit>
- <trans-unit id="_msg723">
+ <trans-unit id="_msg732">
<source xml:space="preserve">Sign on device</source>
<context-group purpose="location"><context context-type="linenumber">205</context></context-group>
<note annotates="source" from="developer">&quot;device&quot; usually means a hardware wallet.</note>
</trans-unit>
- <trans-unit id="_msg724">
+ <trans-unit id="_msg733">
<source xml:space="preserve">Connect your hardware wallet first.</source>
<context-group purpose="location"><context context-type="linenumber">208</context></context-group>
</trans-unit>
- <trans-unit id="_msg725">
+ <trans-unit id="_msg734">
<source xml:space="preserve">Set external signer script path in Options -&gt; Wallet</source>
<context-group purpose="location"><context context-type="linenumber">212</context></context-group>
<note annotates="source" from="developer">&quot;External signer&quot; means using devices such as hardware wallets.</note>
</trans-unit>
- <trans-unit id="_msg726">
+ <trans-unit id="_msg735">
<source xml:space="preserve">Cr&amp;eate Unsigned</source>
<context-group purpose="location"><context context-type="linenumber">215</context></context-group>
</trans-unit>
- <trans-unit id="_msg727">
+ <trans-unit id="_msg736">
<source xml:space="preserve">Creates a Partially Signed Bitcoin Transaction (PSBT) for use with e.g. an offline %1 wallet, or a PSBT-compatible hardware wallet.</source>
<context-group purpose="location"><context context-type="linenumber">216</context></context-group>
</trans-unit>
- <trans-unit id="_msg728">
+ <trans-unit id="_msg737">
<source xml:space="preserve"> from wallet &apos;%1&apos;</source>
<context-group purpose="location"><context context-type="linenumber">308</context></context-group>
</trans-unit>
- <trans-unit id="_msg729">
+ <trans-unit id="_msg738">
<source xml:space="preserve">%1 to &apos;%2&apos;</source>
<context-group purpose="location"><context context-type="linenumber">319</context></context-group>
</trans-unit>
- <trans-unit id="_msg730">
+ <trans-unit id="_msg739">
<source xml:space="preserve">%1 to %2</source>
<context-group purpose="location"><context context-type="linenumber">324</context></context-group>
</trans-unit>
- <trans-unit id="_msg731">
+ <trans-unit id="_msg740">
<source xml:space="preserve">To review recipient list click &quot;Show Details…&quot;</source>
- <context-group purpose="location"><context context-type="linenumber">390</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">391</context></context-group>
</trans-unit>
- <trans-unit id="_msg732">
+ <trans-unit id="_msg741">
<source xml:space="preserve">Sign failed</source>
- <context-group purpose="location"><context context-type="linenumber">450</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">453</context></context-group>
</trans-unit>
- <trans-unit id="_msg733">
+ <trans-unit id="_msg742">
<source xml:space="preserve">External signer not found</source>
- <context-group purpose="location"><context context-type="linenumber">455</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">458</context></context-group>
<note annotates="source" from="developer">&quot;External signer&quot; means using devices such as hardware wallets.</note>
</trans-unit>
- <trans-unit id="_msg734">
+ <trans-unit id="_msg743">
<source xml:space="preserve">External signer failure</source>
- <context-group purpose="location"><context context-type="linenumber">460</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">464</context></context-group>
<note annotates="source" from="developer">&quot;External signer&quot; means using devices such as hardware wallets.</note>
</trans-unit>
- <trans-unit id="_msg735">
+ <trans-unit id="_msg744">
<source xml:space="preserve">Save Transaction Data</source>
- <context-group purpose="location"><context context-type="linenumber">426</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">428</context></context-group>
</trans-unit>
- <trans-unit id="_msg736">
+ <trans-unit id="_msg745">
<source xml:space="preserve">Partially Signed Transaction (Binary)</source>
- <context-group purpose="location"><context context-type="linenumber">428</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">430</context></context-group>
<note annotates="source" from="developer">Expanded name of the binary PSBT file format. See: BIP 174.</note>
</trans-unit>
- <trans-unit id="_msg737">
+ <trans-unit id="_msg746">
<source xml:space="preserve">PSBT saved</source>
- <context-group purpose="location"><context context-type="linenumber">435</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">438</context></context-group>
+ <note annotates="source" from="developer">Popup message when a PSBT has been saved to a file</note>
</trans-unit>
- <trans-unit id="_msg738">
+ <trans-unit id="_msg747">
<source xml:space="preserve">External balance:</source>
- <context-group purpose="location"><context context-type="linenumber">701</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">711</context></context-group>
</trans-unit>
- <trans-unit id="_msg739">
+ <trans-unit id="_msg748">
<source xml:space="preserve">or</source>
- <context-group purpose="location"><context context-type="linenumber">386</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">387</context></context-group>
</trans-unit>
- <trans-unit id="_msg740">
+ <trans-unit id="_msg749">
<source xml:space="preserve">You can increase the fee later (signals Replace-By-Fee, BIP-125).</source>
- <context-group purpose="location"><context context-type="linenumber">368</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">369</context></context-group>
</trans-unit>
- <trans-unit id="_msg741">
+ <trans-unit id="_msg750">
<source xml:space="preserve">Please, review your transaction proposal. This will produce a Partially Signed Bitcoin Transaction (PSBT) which you can save or copy and then sign with e.g. an offline %1 wallet, or a PSBT-compatible hardware wallet.</source>
<context-group purpose="location"><context context-type="linenumber">338</context></context-group>
<note annotates="source" from="developer">Text to inform a user attempting to create a transaction of their current options. At this stage, a user can only create a PSBT. This string is displayed when private keys are disabled and an external signer is not available.</note>
</trans-unit>
- <trans-unit id="_msg742">
+ <trans-unit id="_msg751">
<source xml:space="preserve">Do you want to create this transaction?</source>
<context-group purpose="location"><context context-type="linenumber">332</context></context-group>
<note annotates="source" from="developer">Message displayed when attempting to create a transaction. Cautionary text to prompt the user to verify that the displayed transaction details represent the transaction the user intends to create.</note>
</trans-unit>
- <trans-unit id="_msg743">
+ <trans-unit id="_msg752">
<source xml:space="preserve">Please, review your transaction. You can create and send this transaction or create a Partially Signed Bitcoin Transaction (PSBT), which you can save or copy and then sign with, e.g., an offline %1 wallet, or a PSBT-compatible hardware wallet.</source>
<context-group purpose="location"><context context-type="linenumber">343</context></context-group>
<note annotates="source" from="developer">Text to inform a user attempting to create a transaction of their current options. At this stage, a user can send their transaction or create a PSBT. This string is displayed when both private keys and PSBT controls are enabled.</note>
</trans-unit>
- <trans-unit id="_msg744">
+ <trans-unit id="_msg753">
<source xml:space="preserve">Please, review your transaction.</source>
<context-group purpose="location"><context context-type="linenumber">346</context></context-group>
<note annotates="source" from="developer">Text to prompt a user to review the details of the transaction they are attempting to send.</note>
</trans-unit>
- <trans-unit id="_msg745">
+ <trans-unit id="_msg754">
<source xml:space="preserve">Transaction fee</source>
<context-group purpose="location"><context context-type="linenumber">354</context></context-group>
</trans-unit>
- <trans-unit id="_msg746">
+ <trans-unit id="_msg755">
+ <source xml:space="preserve">%1 kvB</source>
+ <context-group purpose="location"><context context-type="linenumber">359</context></context-group>
+ <context-group><context context-type="x-gettext-msgctxt">PSBT transaction creation</context></context-group>
+ <note annotates="source" from="developer">When reviewing a newly created PSBT (via Send flow), the transaction fee is shown, with &quot;virtual size&quot; of the transaction displayed for context</note>
+ </trans-unit>
+ <trans-unit id="_msg756">
<source xml:space="preserve">Not signalling Replace-By-Fee, BIP-125.</source>
- <context-group purpose="location"><context context-type="linenumber">370</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">371</context></context-group>
</trans-unit>
- <trans-unit id="_msg747">
+ <trans-unit id="_msg757">
<source xml:space="preserve">Total Amount</source>
- <context-group purpose="location"><context context-type="linenumber">383</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">384</context></context-group>
</trans-unit>
- <trans-unit id="_msg748">
+ <trans-unit id="_msg758">
+ <source xml:space="preserve">Unsigned Transaction</source>
+ <context-group purpose="location"><context context-type="linenumber">408</context></context-group>
+ <context-group><context context-type="x-gettext-msgctxt">PSBT copied</context></context-group>
+ <note annotates="source" from="developer">Caption of &quot;PSBT has been copied&quot; messagebox</note>
+ </trans-unit>
+ <trans-unit id="_msg759">
+ <source xml:space="preserve">The PSBT has been copied to the clipboard. You can also save it.</source>
+ <context-group purpose="location"><context context-type="linenumber">409</context></context-group>
+ </trans-unit>
+ <trans-unit id="_msg760">
+ <source xml:space="preserve">PSBT saved to disk</source>
+ <context-group purpose="location"><context context-type="linenumber">438</context></context-group>
+ </trans-unit>
+ <trans-unit id="_msg761">
<source xml:space="preserve">Confirm send coins</source>
- <context-group purpose="location"><context context-type="linenumber">482</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">487</context></context-group>
</trans-unit>
- <trans-unit id="_msg749">
+ <trans-unit id="_msg762">
<source xml:space="preserve">Watch-only balance:</source>
- <context-group purpose="location"><context context-type="linenumber">704</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">714</context></context-group>
</trans-unit>
- <trans-unit id="_msg750">
+ <trans-unit id="_msg763">
<source xml:space="preserve">The recipient address is not valid. Please recheck.</source>
- <context-group purpose="location"><context context-type="linenumber">728</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">738</context></context-group>
</trans-unit>
- <trans-unit id="_msg751">
+ <trans-unit id="_msg764">
<source xml:space="preserve">The amount to pay must be larger than 0.</source>
- <context-group purpose="location"><context context-type="linenumber">731</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">741</context></context-group>
</trans-unit>
- <trans-unit id="_msg752">
+ <trans-unit id="_msg765">
<source xml:space="preserve">The amount exceeds your balance.</source>
- <context-group purpose="location"><context context-type="linenumber">734</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">744</context></context-group>
</trans-unit>
- <trans-unit id="_msg753">
+ <trans-unit id="_msg766">
<source xml:space="preserve">The total exceeds your balance when the %1 transaction fee is included.</source>
- <context-group purpose="location"><context context-type="linenumber">737</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">747</context></context-group>
</trans-unit>
- <trans-unit id="_msg754">
+ <trans-unit id="_msg767">
<source xml:space="preserve">Duplicate address found: addresses should only be used once each.</source>
- <context-group purpose="location"><context context-type="linenumber">740</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">750</context></context-group>
</trans-unit>
- <trans-unit id="_msg755">
+ <trans-unit id="_msg768">
<source xml:space="preserve">Transaction creation failed!</source>
- <context-group purpose="location"><context context-type="linenumber">743</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">753</context></context-group>
</trans-unit>
- <trans-unit id="_msg756">
+ <trans-unit id="_msg769">
<source xml:space="preserve">A fee higher than %1 is considered an absurdly high fee.</source>
- <context-group purpose="location"><context context-type="linenumber">747</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">757</context></context-group>
+ </trans-unit>
+ <trans-unit id="_msg770">
+ <source xml:space="preserve">%1/kvB</source>
+ <context-group purpose="location"><context context-type="linenumber">831</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">866</context></context-group>
</trans-unit>
<group restype="x-gettext-plurals">
- <context-group purpose="location"><context context-type="linenumber">870</context></context-group>
- <trans-unit id="_msg757[0]">
+ <context-group purpose="location"><context context-type="linenumber">880</context></context-group>
+ <trans-unit id="_msg771[0]">
<source xml:space="preserve">Estimated to begin confirmation within %n block(s).</source>
</trans-unit>
- <trans-unit id="_msg757[1]">
+ <trans-unit id="_msg771[1]">
<source xml:space="preserve">Estimated to begin confirmation within %n block(s).</source>
</trans-unit>
</group>
- <trans-unit id="_msg758">
+ <trans-unit id="_msg772">
<source xml:space="preserve">Warning: Invalid Bitcoin address</source>
- <context-group purpose="location"><context context-type="linenumber">971</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">981</context></context-group>
</trans-unit>
- <trans-unit id="_msg759">
+ <trans-unit id="_msg773">
<source xml:space="preserve">Warning: Unknown change address</source>
- <context-group purpose="location"><context context-type="linenumber">976</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">986</context></context-group>
</trans-unit>
- <trans-unit id="_msg760">
+ <trans-unit id="_msg774">
<source xml:space="preserve">Confirm custom change address</source>
- <context-group purpose="location"><context context-type="linenumber">979</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">989</context></context-group>
</trans-unit>
- <trans-unit id="_msg761">
+ <trans-unit id="_msg775">
<source xml:space="preserve">The address you selected for change is not part of this wallet. Any or all funds in your wallet may be sent to this address. Are you sure?</source>
- <context-group purpose="location"><context context-type="linenumber">979</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">989</context></context-group>
</trans-unit>
- <trans-unit id="_msg762">
+ <trans-unit id="_msg776">
<source xml:space="preserve">(no label)</source>
- <context-group purpose="location"><context context-type="linenumber">1000</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1010</context></context-group>
</trans-unit>
</group>
</body></file>
<file original="../forms/sendcoinsentry.ui" datatype="x-trolltech-designer-ui" source-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="SendCoinsEntry">
- <trans-unit id="_msg763">
+ <trans-unit id="_msg777">
<source xml:space="preserve">A&amp;mount:</source>
<context-group purpose="location"><context context-type="linenumber">151</context></context-group>
</trans-unit>
- <trans-unit id="_msg764">
+ <trans-unit id="_msg778">
<source xml:space="preserve">Pay &amp;To:</source>
<context-group purpose="location"><context context-type="linenumber">35</context></context-group>
</trans-unit>
- <trans-unit id="_msg765">
+ <trans-unit id="_msg779">
<source xml:space="preserve">&amp;Label:</source>
<context-group purpose="location"><context context-type="linenumber">128</context></context-group>
</trans-unit>
- <trans-unit id="_msg766">
+ <trans-unit id="_msg780">
<source xml:space="preserve">Choose previously used address</source>
<context-group purpose="location"><context context-type="linenumber">60</context></context-group>
</trans-unit>
- <trans-unit id="_msg767">
+ <trans-unit id="_msg781">
<source xml:space="preserve">The Bitcoin address to send the payment to</source>
<context-group purpose="location"><context context-type="linenumber">53</context></context-group>
</trans-unit>
- <trans-unit id="_msg768">
+ <trans-unit id="_msg782">
<source xml:space="preserve">Alt+A</source>
<context-group purpose="location"><context context-type="linenumber">76</context></context-group>
</trans-unit>
- <trans-unit id="_msg769">
+ <trans-unit id="_msg783">
<source xml:space="preserve">Paste address from clipboard</source>
<context-group purpose="location"><context context-type="linenumber">83</context></context-group>
</trans-unit>
- <trans-unit id="_msg770">
+ <trans-unit id="_msg784">
<source xml:space="preserve">Alt+P</source>
<context-group purpose="location"><context context-type="linenumber">99</context></context-group>
</trans-unit>
- <trans-unit id="_msg771">
+ <trans-unit id="_msg785">
<source xml:space="preserve">Remove this entry</source>
<context-group purpose="location"><context context-type="linenumber">106</context></context-group>
</trans-unit>
- <trans-unit id="_msg772">
+ <trans-unit id="_msg786">
<source xml:space="preserve">The amount to send in the selected unit</source>
<context-group purpose="location"><context context-type="linenumber">166</context></context-group>
</trans-unit>
- <trans-unit id="_msg773">
+ <trans-unit id="_msg787">
<source xml:space="preserve">The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source>
<context-group purpose="location"><context context-type="linenumber">173</context></context-group>
</trans-unit>
- <trans-unit id="_msg774">
+ <trans-unit id="_msg788">
<source xml:space="preserve">S&amp;ubtract fee from amount</source>
<context-group purpose="location"><context context-type="linenumber">176</context></context-group>
</trans-unit>
- <trans-unit id="_msg775">
+ <trans-unit id="_msg789">
<source xml:space="preserve">Use available balance</source>
<context-group purpose="location"><context context-type="linenumber">183</context></context-group>
</trans-unit>
- <trans-unit id="_msg776">
+ <trans-unit id="_msg790">
<source xml:space="preserve">Message:</source>
<context-group purpose="location"><context context-type="linenumber">192</context></context-group>
</trans-unit>
- <trans-unit id="_msg777">
+ <trans-unit id="_msg791">
<source xml:space="preserve">Enter a label for this address to add it to the list of used addresses</source>
<context-group purpose="location"><context context-type="linenumber">141</context></context-group>
<context-group purpose="location"><context context-type="linenumber">144</context></context-group>
</trans-unit>
- <trans-unit id="_msg778">
+ <trans-unit id="_msg792">
<source xml:space="preserve">A message that was attached to the bitcoin: URI which will be stored with the transaction for your reference. Note: This message will not be sent over the Bitcoin network.</source>
<context-group purpose="location"><context context-type="linenumber">202</context></context-group>
</trans-unit>
@@ -3570,11 +3642,11 @@ Note: Since the fee is calculated on a per-byte basis, a fee rate of &quot;100
</body></file>
<file original="../sendcoinsdialog.h" datatype="c" source-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="SendConfirmationDialog">
- <trans-unit id="_msg779">
+ <trans-unit id="_msg793">
<source xml:space="preserve">Send</source>
<context-group purpose="location"><context context-type="linenumber">144</context></context-group>
</trans-unit>
- <trans-unit id="_msg780">
+ <trans-unit id="_msg794">
<source xml:space="preserve">Create Unsigned</source>
<context-group purpose="location"><context context-type="linenumber">146</context></context-group>
</trans-unit>
@@ -3582,105 +3654,105 @@ Note: Since the fee is calculated on a per-byte basis, a fee rate of &quot;100
</body></file>
<file original="../forms/signverifymessagedialog.ui" datatype="x-trolltech-designer-ui" source-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="SignVerifyMessageDialog">
- <trans-unit id="_msg781">
+ <trans-unit id="_msg795">
<source xml:space="preserve">Signatures - Sign / Verify a Message</source>
<context-group purpose="location"><context context-type="linenumber">14</context></context-group>
</trans-unit>
- <trans-unit id="_msg782">
+ <trans-unit id="_msg796">
<source xml:space="preserve">&amp;Sign Message</source>
<context-group purpose="location"><context context-type="linenumber">27</context></context-group>
</trans-unit>
- <trans-unit id="_msg783">
+ <trans-unit id="_msg797">
<source xml:space="preserve">You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source>
<context-group purpose="location"><context context-type="linenumber">33</context></context-group>
</trans-unit>
- <trans-unit id="_msg784">
+ <trans-unit id="_msg798">
<source xml:space="preserve">The Bitcoin address to sign the message with</source>
<context-group purpose="location"><context context-type="linenumber">51</context></context-group>
</trans-unit>
- <trans-unit id="_msg785">
+ <trans-unit id="_msg799">
<source xml:space="preserve">Choose previously used address</source>
<context-group purpose="location"><context context-type="linenumber">58</context></context-group>
<context-group purpose="location"><context context-type="linenumber">274</context></context-group>
</trans-unit>
- <trans-unit id="_msg786">
+ <trans-unit id="_msg800">
<source xml:space="preserve">Alt+A</source>
<context-group purpose="location"><context context-type="linenumber">68</context></context-group>
<context-group purpose="location"><context context-type="linenumber">284</context></context-group>
</trans-unit>
- <trans-unit id="_msg787">
+ <trans-unit id="_msg801">
<source xml:space="preserve">Paste address from clipboard</source>
<context-group purpose="location"><context context-type="linenumber">78</context></context-group>
</trans-unit>
- <trans-unit id="_msg788">
+ <trans-unit id="_msg802">
<source xml:space="preserve">Alt+P</source>
<context-group purpose="location"><context context-type="linenumber">88</context></context-group>
</trans-unit>
- <trans-unit id="_msg789">
+ <trans-unit id="_msg803">
<source xml:space="preserve">Enter the message you want to sign here</source>
<context-group purpose="location"><context context-type="linenumber">100</context></context-group>
<context-group purpose="location"><context context-type="linenumber">103</context></context-group>
</trans-unit>
- <trans-unit id="_msg790">
+ <trans-unit id="_msg804">
<source xml:space="preserve">Signature</source>
<context-group purpose="location"><context context-type="linenumber">110</context></context-group>
</trans-unit>
- <trans-unit id="_msg791">
+ <trans-unit id="_msg805">
<source xml:space="preserve">Copy the current signature to the system clipboard</source>
<context-group purpose="location"><context context-type="linenumber">140</context></context-group>
</trans-unit>
- <trans-unit id="_msg792">
+ <trans-unit id="_msg806">
<source xml:space="preserve">Sign the message to prove you own this Bitcoin address</source>
<context-group purpose="location"><context context-type="linenumber">161</context></context-group>
</trans-unit>
- <trans-unit id="_msg793">
+ <trans-unit id="_msg807">
<source xml:space="preserve">Sign &amp;Message</source>
<context-group purpose="location"><context context-type="linenumber">164</context></context-group>
</trans-unit>
- <trans-unit id="_msg794">
+ <trans-unit id="_msg808">
<source xml:space="preserve">Reset all sign message fields</source>
<context-group purpose="location"><context context-type="linenumber">178</context></context-group>
</trans-unit>
- <trans-unit id="_msg795">
+ <trans-unit id="_msg809">
<source xml:space="preserve">Clear &amp;All</source>
<context-group purpose="location"><context context-type="linenumber">181</context></context-group>
<context-group purpose="location"><context context-type="linenumber">338</context></context-group>
</trans-unit>
- <trans-unit id="_msg796">
+ <trans-unit id="_msg810">
<source xml:space="preserve">&amp;Verify Message</source>
<context-group purpose="location"><context context-type="linenumber">240</context></context-group>
</trans-unit>
- <trans-unit id="_msg797">
+ <trans-unit id="_msg811">
<source xml:space="preserve">Enter the receiver&apos;s address, message (ensure you copy line breaks, spaces, tabs, etc. exactly) and signature below to verify the message. Be careful not to read more into the signature than what is in the signed message itself, to avoid being tricked by a man-in-the-middle attack. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction!</source>
<context-group purpose="location"><context context-type="linenumber">246</context></context-group>
</trans-unit>
- <trans-unit id="_msg798">
+ <trans-unit id="_msg812">
<source xml:space="preserve">The Bitcoin address the message was signed with</source>
<context-group purpose="location"><context context-type="linenumber">267</context></context-group>
</trans-unit>
- <trans-unit id="_msg799">
+ <trans-unit id="_msg813">
<source xml:space="preserve">The signed message to verify</source>
<context-group purpose="location"><context context-type="linenumber">296</context></context-group>
<context-group purpose="location"><context context-type="linenumber">299</context></context-group>
</trans-unit>
- <trans-unit id="_msg800">
+ <trans-unit id="_msg814">
<source xml:space="preserve">The signature given when the message was signed</source>
<context-group purpose="location"><context context-type="linenumber">306</context></context-group>
<context-group purpose="location"><context context-type="linenumber">309</context></context-group>
</trans-unit>
- <trans-unit id="_msg801">
+ <trans-unit id="_msg815">
<source xml:space="preserve">Verify the message to ensure it was signed with the specified Bitcoin address</source>
<context-group purpose="location"><context context-type="linenumber">318</context></context-group>
</trans-unit>
- <trans-unit id="_msg802">
+ <trans-unit id="_msg816">
<source xml:space="preserve">Verify &amp;Message</source>
<context-group purpose="location"><context context-type="linenumber">321</context></context-group>
</trans-unit>
- <trans-unit id="_msg803">
+ <trans-unit id="_msg817">
<source xml:space="preserve">Reset all verify message fields</source>
<context-group purpose="location"><context context-type="linenumber">335</context></context-group>
</trans-unit>
- <trans-unit id="_msg804">
+ <trans-unit id="_msg818">
<source xml:space="preserve">Click &quot;Sign Message&quot; to generate signature</source>
<context-group purpose="location"><context context-type="linenumber">125</context></context-group>
</trans-unit>
@@ -3688,61 +3760,61 @@ Note: Since the fee is calculated on a per-byte basis, a fee rate of &quot;100
</body></file>
<file original="../signverifymessagedialog.cpp" datatype="cpp" source-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="SignVerifyMessageDialog">
- <trans-unit id="_msg805">
+ <trans-unit id="_msg819">
<source xml:space="preserve">The entered address is invalid.</source>
<context-group purpose="location"><context context-type="linenumber">119</context></context-group>
<context-group purpose="location"><context context-type="linenumber">218</context></context-group>
</trans-unit>
- <trans-unit id="_msg806">
+ <trans-unit id="_msg820">
<source xml:space="preserve">Please check the address and try again.</source>
<context-group purpose="location"><context context-type="linenumber">119</context></context-group>
<context-group purpose="location"><context context-type="linenumber">126</context></context-group>
<context-group purpose="location"><context context-type="linenumber">219</context></context-group>
<context-group purpose="location"><context context-type="linenumber">226</context></context-group>
</trans-unit>
- <trans-unit id="_msg807">
+ <trans-unit id="_msg821">
<source xml:space="preserve">The entered address does not refer to a key.</source>
<context-group purpose="location"><context context-type="linenumber">126</context></context-group>
<context-group purpose="location"><context context-type="linenumber">225</context></context-group>
</trans-unit>
- <trans-unit id="_msg808">
+ <trans-unit id="_msg822">
<source xml:space="preserve">Wallet unlock was cancelled.</source>
<context-group purpose="location"><context context-type="linenumber">134</context></context-group>
</trans-unit>
- <trans-unit id="_msg809">
+ <trans-unit id="_msg823">
<source xml:space="preserve">No error</source>
<context-group purpose="location"><context context-type="linenumber">145</context></context-group>
</trans-unit>
- <trans-unit id="_msg810">
+ <trans-unit id="_msg824">
<source xml:space="preserve">Private key for the entered address is not available.</source>
<context-group purpose="location"><context context-type="linenumber">148</context></context-group>
</trans-unit>
- <trans-unit id="_msg811">
+ <trans-unit id="_msg825">
<source xml:space="preserve">Message signing failed.</source>
<context-group purpose="location"><context context-type="linenumber">151</context></context-group>
</trans-unit>
- <trans-unit id="_msg812">
+ <trans-unit id="_msg826">
<source xml:space="preserve">Message signed.</source>
<context-group purpose="location"><context context-type="linenumber">163</context></context-group>
</trans-unit>
- <trans-unit id="_msg813">
+ <trans-unit id="_msg827">
<source xml:space="preserve">The signature could not be decoded.</source>
<context-group purpose="location"><context context-type="linenumber">232</context></context-group>
</trans-unit>
- <trans-unit id="_msg814">
+ <trans-unit id="_msg828">
<source xml:space="preserve">Please check the signature and try again.</source>
<context-group purpose="location"><context context-type="linenumber">233</context></context-group>
<context-group purpose="location"><context context-type="linenumber">240</context></context-group>
</trans-unit>
- <trans-unit id="_msg815">
+ <trans-unit id="_msg829">
<source xml:space="preserve">The signature did not match the message digest.</source>
<context-group purpose="location"><context context-type="linenumber">239</context></context-group>
</trans-unit>
- <trans-unit id="_msg816">
+ <trans-unit id="_msg830">
<source xml:space="preserve">Message verification failed.</source>
<context-group purpose="location"><context context-type="linenumber">245</context></context-group>
</trans-unit>
- <trans-unit id="_msg817">
+ <trans-unit id="_msg831">
<source xml:space="preserve">Message verified.</source>
<context-group purpose="location"><context context-type="linenumber">213</context></context-group>
</trans-unit>
@@ -3750,11 +3822,11 @@ Note: Since the fee is calculated on a per-byte basis, a fee rate of &quot;100
</body></file>
<file original="../splashscreen.cpp" datatype="cpp" source-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="SplashScreen">
- <trans-unit id="_msg818">
+ <trans-unit id="_msg832">
<source xml:space="preserve">(press q to shutdown and continue later)</source>
<context-group purpose="location"><context context-type="linenumber">177</context></context-group>
</trans-unit>
- <trans-unit id="_msg819">
+ <trans-unit id="_msg833">
<source xml:space="preserve">press q to shutdown</source>
<context-group purpose="location"><context context-type="linenumber">178</context></context-group>
</trans-unit>
@@ -3762,7 +3834,7 @@ Note: Since the fee is calculated on a per-byte basis, a fee rate of &quot;100
</body></file>
<file original="../trafficgraphwidget.cpp" datatype="cpp" source-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="TrafficGraphWidget">
- <trans-unit id="_msg820">
+ <trans-unit id="_msg834">
<source xml:space="preserve">kB/s</source>
<context-group purpose="location"><context context-type="linenumber">74</context></context-group>
</trans-unit>
@@ -3770,82 +3842,84 @@ Note: Since the fee is calculated on a per-byte basis, a fee rate of &quot;100
</body></file>
<file original="../transactiondesc.cpp" datatype="cpp" source-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="TransactionDesc">
- <trans-unit id="_msg821">
+ <trans-unit id="_msg835">
<source xml:space="preserve">conflicted with a transaction with %1 confirmations</source>
<context-group purpose="location"><context context-type="linenumber">43</context></context-group>
<note annotates="source" from="developer">Text explaining the current status of a transaction, shown in the status field of the details window for this transaction. This status represents an unconfirmed transaction that conflicts with a confirmed transaction.</note>
</trans-unit>
- <trans-unit id="_msg822">
+ <trans-unit id="_msg836">
<source xml:space="preserve">0/unconfirmed, in memory pool</source>
<context-group purpose="location"><context context-type="linenumber">50</context></context-group>
<note annotates="source" from="developer">Text explaining the current status of a transaction, shown in the status field of the details window for this transaction. This status represents an unconfirmed transaction that is in the memory pool.</note>
</trans-unit>
- <trans-unit id="_msg823">
+ <trans-unit id="_msg837">
<source xml:space="preserve">0/unconfirmed, not in memory pool</source>
<context-group purpose="location"><context context-type="linenumber">55</context></context-group>
<note annotates="source" from="developer">Text explaining the current status of a transaction, shown in the status field of the details window for this transaction. This status represents an unconfirmed transaction that is not in the memory pool.</note>
</trans-unit>
- <trans-unit id="_msg824">
+ <trans-unit id="_msg838">
<source xml:space="preserve">abandoned</source>
<context-group purpose="location"><context context-type="linenumber">61</context></context-group>
<note annotates="source" from="developer">Text explaining the current status of a transaction, shown in the status field of the details window for this transaction. This status represents an abandoned transaction.</note>
</trans-unit>
- <trans-unit id="_msg825">
+ <trans-unit id="_msg839">
<source xml:space="preserve">%1/unconfirmed</source>
<context-group purpose="location"><context context-type="linenumber">69</context></context-group>
<note annotates="source" from="developer">Text explaining the current status of a transaction, shown in the status field of the details window for this transaction. This status represents a transaction confirmed in at least one block, but less than 6 blocks.</note>
</trans-unit>
- <trans-unit id="_msg826">
+ <trans-unit id="_msg840">
<source xml:space="preserve">%1 confirmations</source>
<context-group purpose="location"><context context-type="linenumber">74</context></context-group>
<note annotates="source" from="developer">Text explaining the current status of a transaction, shown in the status field of the details window for this transaction. This status represents a transaction confirmed in 6 or more blocks.</note>
</trans-unit>
- <trans-unit id="_msg827">
+ <trans-unit id="_msg841">
<source xml:space="preserve">Status</source>
<context-group purpose="location"><context context-type="linenumber">124</context></context-group>
</trans-unit>
- <trans-unit id="_msg828">
+ <trans-unit id="_msg842">
<source xml:space="preserve">Date</source>
<context-group purpose="location"><context context-type="linenumber">127</context></context-group>
</trans-unit>
- <trans-unit id="_msg829">
+ <trans-unit id="_msg843">
<source xml:space="preserve">Source</source>
<context-group purpose="location"><context context-type="linenumber">134</context></context-group>
</trans-unit>
- <trans-unit id="_msg830">
+ <trans-unit id="_msg844">
<source xml:space="preserve">Generated</source>
<context-group purpose="location"><context context-type="linenumber">134</context></context-group>
</trans-unit>
- <trans-unit id="_msg831">
+ <trans-unit id="_msg845">
<source xml:space="preserve">From</source>
<context-group purpose="location"><context context-type="linenumber">139</context></context-group>
<context-group purpose="location"><context context-type="linenumber">153</context></context-group>
<context-group purpose="location"><context context-type="linenumber">225</context></context-group>
</trans-unit>
- <trans-unit id="_msg832">
+ <trans-unit id="_msg846">
<source xml:space="preserve">unknown</source>
<context-group purpose="location"><context context-type="linenumber">153</context></context-group>
</trans-unit>
- <trans-unit id="_msg833">
+ <trans-unit id="_msg847">
<source xml:space="preserve">To</source>
<context-group purpose="location"><context context-type="linenumber">154</context></context-group>
<context-group purpose="location"><context context-type="linenumber">174</context></context-group>
<context-group purpose="location"><context context-type="linenumber">244</context></context-group>
</trans-unit>
- <trans-unit id="_msg834">
+ <trans-unit id="_msg848">
<source xml:space="preserve">own address</source>
<context-group purpose="location"><context context-type="linenumber">156</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">251</context></context-group>
</trans-unit>
- <trans-unit id="_msg835">
+ <trans-unit id="_msg849">
<source xml:space="preserve">watch-only</source>
<context-group purpose="location"><context context-type="linenumber">156</context></context-group>
<context-group purpose="location"><context context-type="linenumber">225</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">253</context></context-group>
</trans-unit>
- <trans-unit id="_msg836">
+ <trans-unit id="_msg850">
<source xml:space="preserve">label</source>
<context-group purpose="location"><context context-type="linenumber">158</context></context-group>
</trans-unit>
- <trans-unit id="_msg837">
+ <trans-unit id="_msg851">
<source xml:space="preserve">Credit</source>
<context-group purpose="location"><context context-type="linenumber">194</context></context-group>
<context-group purpose="location"><context context-type="linenumber">206</context></context-group>
@@ -3855,98 +3929,98 @@ Note: Since the fee is calculated on a per-byte basis, a fee rate of &quot;100
</trans-unit>
<group restype="x-gettext-plurals">
<context-group purpose="location"><context context-type="linenumber">196</context></context-group>
- <trans-unit id="_msg838[0]">
+ <trans-unit id="_msg852[0]">
<source xml:space="preserve">matures in %n more block(s)</source>
</trans-unit>
- <trans-unit id="_msg838[1]">
+ <trans-unit id="_msg852[1]">
<source xml:space="preserve">matures in %n more block(s)</source>
</trans-unit>
</group>
- <trans-unit id="_msg839">
+ <trans-unit id="_msg853">
<source xml:space="preserve">not accepted</source>
<context-group purpose="location"><context context-type="linenumber">198</context></context-group>
</trans-unit>
- <trans-unit id="_msg840">
+ <trans-unit id="_msg854">
<source xml:space="preserve">Debit</source>
<context-group purpose="location"><context context-type="linenumber">258</context></context-group>
<context-group purpose="location"><context context-type="linenumber">284</context></context-group>
<context-group purpose="location"><context context-type="linenumber">347</context></context-group>
</trans-unit>
- <trans-unit id="_msg841">
+ <trans-unit id="_msg855">
<source xml:space="preserve">Total debit</source>
<context-group purpose="location"><context context-type="linenumber">268</context></context-group>
</trans-unit>
- <trans-unit id="_msg842">
+ <trans-unit id="_msg856">
<source xml:space="preserve">Total credit</source>
<context-group purpose="location"><context context-type="linenumber">269</context></context-group>
</trans-unit>
- <trans-unit id="_msg843">
+ <trans-unit id="_msg857">
<source xml:space="preserve">Transaction fee</source>
<context-group purpose="location"><context context-type="linenumber">274</context></context-group>
</trans-unit>
- <trans-unit id="_msg844">
+ <trans-unit id="_msg858">
<source xml:space="preserve">Net amount</source>
<context-group purpose="location"><context context-type="linenumber">296</context></context-group>
</trans-unit>
- <trans-unit id="_msg845">
+ <trans-unit id="_msg859">
<source xml:space="preserve">Message</source>
<context-group purpose="location"><context context-type="linenumber">302</context></context-group>
<context-group purpose="location"><context context-type="linenumber">314</context></context-group>
</trans-unit>
- <trans-unit id="_msg846">
+ <trans-unit id="_msg860">
<source xml:space="preserve">Comment</source>
<context-group purpose="location"><context context-type="linenumber">304</context></context-group>
</trans-unit>
- <trans-unit id="_msg847">
+ <trans-unit id="_msg861">
<source xml:space="preserve">Transaction ID</source>
<context-group purpose="location"><context context-type="linenumber">306</context></context-group>
</trans-unit>
- <trans-unit id="_msg848">
+ <trans-unit id="_msg862">
<source xml:space="preserve">Transaction total size</source>
<context-group purpose="location"><context context-type="linenumber">307</context></context-group>
</trans-unit>
- <trans-unit id="_msg849">
+ <trans-unit id="_msg863">
<source xml:space="preserve">Transaction virtual size</source>
<context-group purpose="location"><context context-type="linenumber">308</context></context-group>
</trans-unit>
- <trans-unit id="_msg850">
+ <trans-unit id="_msg864">
<source xml:space="preserve">Output index</source>
<context-group purpose="location"><context context-type="linenumber">309</context></context-group>
</trans-unit>
- <trans-unit id="_msg851">
+ <trans-unit id="_msg865">
<source xml:space="preserve"> (Certificate was not verified)</source>
<context-group purpose="location"><context context-type="linenumber">325</context></context-group>
</trans-unit>
- <trans-unit id="_msg852">
+ <trans-unit id="_msg866">
<source xml:space="preserve">Merchant</source>
<context-group purpose="location"><context context-type="linenumber">328</context></context-group>
</trans-unit>
- <trans-unit id="_msg853">
+ <trans-unit id="_msg867">
<source xml:space="preserve">Generated coins must mature %1 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, its state will change to &quot;not accepted&quot; and it won&apos;t be spendable. This may occasionally happen if another node generates a block within a few seconds of yours.</source>
<context-group purpose="location"><context context-type="linenumber">336</context></context-group>
</trans-unit>
- <trans-unit id="_msg854">
+ <trans-unit id="_msg868">
<source xml:space="preserve">Debug information</source>
<context-group purpose="location"><context context-type="linenumber">344</context></context-group>
</trans-unit>
- <trans-unit id="_msg855">
+ <trans-unit id="_msg869">
<source xml:space="preserve">Transaction</source>
<context-group purpose="location"><context context-type="linenumber">352</context></context-group>
</trans-unit>
- <trans-unit id="_msg856">
+ <trans-unit id="_msg870">
<source xml:space="preserve">Inputs</source>
<context-group purpose="location"><context context-type="linenumber">355</context></context-group>
</trans-unit>
- <trans-unit id="_msg857">
+ <trans-unit id="_msg871">
<source xml:space="preserve">Amount</source>
<context-group purpose="location"><context context-type="linenumber">376</context></context-group>
</trans-unit>
- <trans-unit id="_msg858">
+ <trans-unit id="_msg872">
<source xml:space="preserve">true</source>
<context-group purpose="location"><context context-type="linenumber">377</context></context-group>
<context-group purpose="location"><context context-type="linenumber">378</context></context-group>
</trans-unit>
- <trans-unit id="_msg859">
+ <trans-unit id="_msg873">
<source xml:space="preserve">false</source>
<context-group purpose="location"><context context-type="linenumber">377</context></context-group>
<context-group purpose="location"><context context-type="linenumber">378</context></context-group>
@@ -3955,7 +4029,7 @@ Note: Since the fee is calculated on a per-byte basis, a fee rate of &quot;100
</body></file>
<file original="../forms/transactiondescdialog.ui" datatype="x-trolltech-designer-ui" source-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="TransactionDescDialog">
- <trans-unit id="_msg860">
+ <trans-unit id="_msg874">
<source xml:space="preserve">This pane shows a detailed description of the transaction</source>
<context-group purpose="location"><context context-type="linenumber">20</context></context-group>
</trans-unit>
@@ -3963,7 +4037,7 @@ Note: Since the fee is calculated on a per-byte basis, a fee rate of &quot;100
</body></file>
<file original="../transactiondescdialog.cpp" datatype="cpp" source-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="TransactionDescDialog">
- <trans-unit id="_msg861">
+ <trans-unit id="_msg875">
<source xml:space="preserve">Details for %1</source>
<context-group purpose="location"><context context-type="linenumber">18</context></context-group>
</trans-unit>
@@ -3971,99 +4045,99 @@ Note: Since the fee is calculated on a per-byte basis, a fee rate of &quot;100
</body></file>
<file original="../transactiontablemodel.cpp" datatype="cpp" source-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="TransactionTableModel">
- <trans-unit id="_msg862">
+ <trans-unit id="_msg876">
<source xml:space="preserve">Date</source>
<context-group purpose="location"><context context-type="linenumber">257</context></context-group>
</trans-unit>
- <trans-unit id="_msg863">
+ <trans-unit id="_msg877">
<source xml:space="preserve">Type</source>
<context-group purpose="location"><context context-type="linenumber">257</context></context-group>
</trans-unit>
- <trans-unit id="_msg864">
+ <trans-unit id="_msg878">
<source xml:space="preserve">Label</source>
<context-group purpose="location"><context context-type="linenumber">257</context></context-group>
</trans-unit>
- <trans-unit id="_msg865">
+ <trans-unit id="_msg879">
<source xml:space="preserve">Unconfirmed</source>
<context-group purpose="location"><context context-type="linenumber">317</context></context-group>
</trans-unit>
- <trans-unit id="_msg866">
+ <trans-unit id="_msg880">
<source xml:space="preserve">Abandoned</source>
<context-group purpose="location"><context context-type="linenumber">320</context></context-group>
</trans-unit>
- <trans-unit id="_msg867">
+ <trans-unit id="_msg881">
<source xml:space="preserve">Confirming (%1 of %2 recommended confirmations)</source>
<context-group purpose="location"><context context-type="linenumber">323</context></context-group>
</trans-unit>
- <trans-unit id="_msg868">
+ <trans-unit id="_msg882">
<source xml:space="preserve">Confirmed (%1 confirmations)</source>
<context-group purpose="location"><context context-type="linenumber">326</context></context-group>
</trans-unit>
- <trans-unit id="_msg869">
+ <trans-unit id="_msg883">
<source xml:space="preserve">Conflicted</source>
<context-group purpose="location"><context context-type="linenumber">329</context></context-group>
</trans-unit>
- <trans-unit id="_msg870">
+ <trans-unit id="_msg884">
<source xml:space="preserve">Immature (%1 confirmations, will be available after %2)</source>
<context-group purpose="location"><context context-type="linenumber">332</context></context-group>
</trans-unit>
- <trans-unit id="_msg871">
+ <trans-unit id="_msg885">
<source xml:space="preserve">Generated but not accepted</source>
<context-group purpose="location"><context context-type="linenumber">335</context></context-group>
</trans-unit>
- <trans-unit id="_msg872">
+ <trans-unit id="_msg886">
<source xml:space="preserve">Received with</source>
<context-group purpose="location"><context context-type="linenumber">374</context></context-group>
</trans-unit>
- <trans-unit id="_msg873">
+ <trans-unit id="_msg887">
<source xml:space="preserve">Received from</source>
<context-group purpose="location"><context context-type="linenumber">376</context></context-group>
</trans-unit>
- <trans-unit id="_msg874">
+ <trans-unit id="_msg888">
<source xml:space="preserve">Sent to</source>
<context-group purpose="location"><context context-type="linenumber">379</context></context-group>
</trans-unit>
- <trans-unit id="_msg875">
+ <trans-unit id="_msg889">
<source xml:space="preserve">Payment to yourself</source>
<context-group purpose="location"><context context-type="linenumber">381</context></context-group>
</trans-unit>
- <trans-unit id="_msg876">
+ <trans-unit id="_msg890">
<source xml:space="preserve">Mined</source>
<context-group purpose="location"><context context-type="linenumber">383</context></context-group>
</trans-unit>
- <trans-unit id="_msg877">
+ <trans-unit id="_msg891">
<source xml:space="preserve">watch-only</source>
<context-group purpose="location"><context context-type="linenumber">411</context></context-group>
</trans-unit>
- <trans-unit id="_msg878">
+ <trans-unit id="_msg892">
<source xml:space="preserve">(n/a)</source>
<context-group purpose="location"><context context-type="linenumber">427</context></context-group>
</trans-unit>
- <trans-unit id="_msg879">
+ <trans-unit id="_msg893">
<source xml:space="preserve">(no label)</source>
<context-group purpose="location"><context context-type="linenumber">634</context></context-group>
</trans-unit>
- <trans-unit id="_msg880">
+ <trans-unit id="_msg894">
<source xml:space="preserve">Transaction status. Hover over this field to show number of confirmations.</source>
<context-group purpose="location"><context context-type="linenumber">673</context></context-group>
</trans-unit>
- <trans-unit id="_msg881">
+ <trans-unit id="_msg895">
<source xml:space="preserve">Date and time that the transaction was received.</source>
<context-group purpose="location"><context context-type="linenumber">675</context></context-group>
</trans-unit>
- <trans-unit id="_msg882">
+ <trans-unit id="_msg896">
<source xml:space="preserve">Type of transaction.</source>
<context-group purpose="location"><context context-type="linenumber">677</context></context-group>
</trans-unit>
- <trans-unit id="_msg883">
+ <trans-unit id="_msg897">
<source xml:space="preserve">Whether or not a watch-only address is involved in this transaction.</source>
<context-group purpose="location"><context context-type="linenumber">679</context></context-group>
</trans-unit>
- <trans-unit id="_msg884">
+ <trans-unit id="_msg898">
<source xml:space="preserve">User-defined intent/purpose of the transaction.</source>
<context-group purpose="location"><context context-type="linenumber">681</context></context-group>
</trans-unit>
- <trans-unit id="_msg885">
+ <trans-unit id="_msg899">
<source xml:space="preserve">Amount removed from or added to balance.</source>
<context-group purpose="location"><context context-type="linenumber">683</context></context-group>
</trans-unit>
@@ -4071,206 +4145,206 @@ Note: Since the fee is calculated on a per-byte basis, a fee rate of &quot;100
</body></file>
<file original="../transactionview.cpp" datatype="cpp" source-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="TransactionView">
- <trans-unit id="_msg886">
+ <trans-unit id="_msg900">
<source xml:space="preserve">All</source>
<context-group purpose="location"><context context-type="linenumber">73</context></context-group>
<context-group purpose="location"><context context-type="linenumber">89</context></context-group>
</trans-unit>
- <trans-unit id="_msg887">
+ <trans-unit id="_msg901">
<source xml:space="preserve">Today</source>
<context-group purpose="location"><context context-type="linenumber">74</context></context-group>
</trans-unit>
- <trans-unit id="_msg888">
+ <trans-unit id="_msg902">
<source xml:space="preserve">This week</source>
<context-group purpose="location"><context context-type="linenumber">75</context></context-group>
</trans-unit>
- <trans-unit id="_msg889">
+ <trans-unit id="_msg903">
<source xml:space="preserve">This month</source>
<context-group purpose="location"><context context-type="linenumber">76</context></context-group>
</trans-unit>
- <trans-unit id="_msg890">
+ <trans-unit id="_msg904">
<source xml:space="preserve">Last month</source>
<context-group purpose="location"><context context-type="linenumber">77</context></context-group>
</trans-unit>
- <trans-unit id="_msg891">
+ <trans-unit id="_msg905">
<source xml:space="preserve">This year</source>
<context-group purpose="location"><context context-type="linenumber">78</context></context-group>
</trans-unit>
- <trans-unit id="_msg892">
+ <trans-unit id="_msg906">
<source xml:space="preserve">Received with</source>
<context-group purpose="location"><context context-type="linenumber">90</context></context-group>
</trans-unit>
- <trans-unit id="_msg893">
+ <trans-unit id="_msg907">
<source xml:space="preserve">Sent to</source>
<context-group purpose="location"><context context-type="linenumber">92</context></context-group>
</trans-unit>
- <trans-unit id="_msg894">
+ <trans-unit id="_msg908">
<source xml:space="preserve">To yourself</source>
<context-group purpose="location"><context context-type="linenumber">94</context></context-group>
</trans-unit>
- <trans-unit id="_msg895">
+ <trans-unit id="_msg909">
<source xml:space="preserve">Mined</source>
<context-group purpose="location"><context context-type="linenumber">95</context></context-group>
</trans-unit>
- <trans-unit id="_msg896">
+ <trans-unit id="_msg910">
<source xml:space="preserve">Other</source>
<context-group purpose="location"><context context-type="linenumber">96</context></context-group>
</trans-unit>
- <trans-unit id="_msg897">
+ <trans-unit id="_msg911">
<source xml:space="preserve">Enter address, transaction id, or label to search</source>
<context-group purpose="location"><context context-type="linenumber">101</context></context-group>
</trans-unit>
- <trans-unit id="_msg898">
+ <trans-unit id="_msg912">
<source xml:space="preserve">Min amount</source>
<context-group purpose="location"><context context-type="linenumber">105</context></context-group>
</trans-unit>
- <trans-unit id="_msg899">
+ <trans-unit id="_msg913">
<source xml:space="preserve">Range…</source>
<context-group purpose="location"><context context-type="linenumber">79</context></context-group>
</trans-unit>
- <trans-unit id="_msg900">
+ <trans-unit id="_msg914">
<source xml:space="preserve">&amp;Copy address</source>
<context-group purpose="location"><context context-type="linenumber">169</context></context-group>
</trans-unit>
- <trans-unit id="_msg901">
+ <trans-unit id="_msg915">
<source xml:space="preserve">Copy &amp;label</source>
<context-group purpose="location"><context context-type="linenumber">170</context></context-group>
</trans-unit>
- <trans-unit id="_msg902">
+ <trans-unit id="_msg916">
<source xml:space="preserve">Copy &amp;amount</source>
<context-group purpose="location"><context context-type="linenumber">171</context></context-group>
</trans-unit>
- <trans-unit id="_msg903">
+ <trans-unit id="_msg917">
<source xml:space="preserve">Copy transaction &amp;ID</source>
<context-group purpose="location"><context context-type="linenumber">172</context></context-group>
</trans-unit>
- <trans-unit id="_msg904">
+ <trans-unit id="_msg918">
<source xml:space="preserve">Copy &amp;raw transaction</source>
<context-group purpose="location"><context context-type="linenumber">173</context></context-group>
</trans-unit>
- <trans-unit id="_msg905">
+ <trans-unit id="_msg919">
<source xml:space="preserve">Copy full transaction &amp;details</source>
<context-group purpose="location"><context context-type="linenumber">174</context></context-group>
</trans-unit>
- <trans-unit id="_msg906">
+ <trans-unit id="_msg920">
<source xml:space="preserve">&amp;Show transaction details</source>
<context-group purpose="location"><context context-type="linenumber">175</context></context-group>
</trans-unit>
- <trans-unit id="_msg907">
+ <trans-unit id="_msg921">
<source xml:space="preserve">Increase transaction &amp;fee</source>
<context-group purpose="location"><context context-type="linenumber">177</context></context-group>
</trans-unit>
- <trans-unit id="_msg908">
+ <trans-unit id="_msg922">
<source xml:space="preserve">A&amp;bandon transaction</source>
<context-group purpose="location"><context context-type="linenumber">180</context></context-group>
</trans-unit>
- <trans-unit id="_msg909">
+ <trans-unit id="_msg923">
<source xml:space="preserve">&amp;Edit address label</source>
<context-group purpose="location"><context context-type="linenumber">181</context></context-group>
</trans-unit>
- <trans-unit id="_msg910">
+ <trans-unit id="_msg924">
<source xml:space="preserve">Show in %1</source>
<context-group purpose="location"><context context-type="linenumber">240</context></context-group>
<note annotates="source" from="developer">Transactions table context menu action to show the selected transaction in a third-party block explorer. %1 is a stand-in argument for the URL of the explorer.</note>
</trans-unit>
- <trans-unit id="_msg911">
+ <trans-unit id="_msg925">
<source xml:space="preserve">Export Transaction History</source>
<context-group purpose="location"><context context-type="linenumber">359</context></context-group>
</trans-unit>
- <trans-unit id="_msg912">
+ <trans-unit id="_msg926">
<source xml:space="preserve">Comma separated file</source>
<context-group purpose="location"><context context-type="linenumber">362</context></context-group>
<note annotates="source" from="developer">Expanded name of the CSV file format. See: https://en.wikipedia.org/wiki/Comma-separated_values.</note>
</trans-unit>
- <trans-unit id="_msg913">
+ <trans-unit id="_msg927">
<source xml:space="preserve">Confirmed</source>
<context-group purpose="location"><context context-type="linenumber">371</context></context-group>
</trans-unit>
- <trans-unit id="_msg914">
+ <trans-unit id="_msg928">
<source xml:space="preserve">Watch-only</source>
<context-group purpose="location"><context context-type="linenumber">373</context></context-group>
</trans-unit>
- <trans-unit id="_msg915">
+ <trans-unit id="_msg929">
<source xml:space="preserve">Date</source>
<context-group purpose="location"><context context-type="linenumber">374</context></context-group>
</trans-unit>
- <trans-unit id="_msg916">
+ <trans-unit id="_msg930">
<source xml:space="preserve">Type</source>
<context-group purpose="location"><context context-type="linenumber">375</context></context-group>
</trans-unit>
- <trans-unit id="_msg917">
+ <trans-unit id="_msg931">
<source xml:space="preserve">Label</source>
<context-group purpose="location"><context context-type="linenumber">376</context></context-group>
</trans-unit>
- <trans-unit id="_msg918">
+ <trans-unit id="_msg932">
<source xml:space="preserve">Address</source>
<context-group purpose="location"><context context-type="linenumber">377</context></context-group>
</trans-unit>
- <trans-unit id="_msg919">
+ <trans-unit id="_msg933">
<source xml:space="preserve">ID</source>
<context-group purpose="location"><context context-type="linenumber">379</context></context-group>
</trans-unit>
- <trans-unit id="_msg920">
+ <trans-unit id="_msg934">
<source xml:space="preserve">Exporting Failed</source>
<context-group purpose="location"><context context-type="linenumber">382</context></context-group>
</trans-unit>
- <trans-unit id="_msg921">
+ <trans-unit id="_msg935">
<source xml:space="preserve">There was an error trying to save the transaction history to %1.</source>
<context-group purpose="location"><context context-type="linenumber">382</context></context-group>
</trans-unit>
- <trans-unit id="_msg922">
+ <trans-unit id="_msg936">
<source xml:space="preserve">Exporting Successful</source>
<context-group purpose="location"><context context-type="linenumber">386</context></context-group>
</trans-unit>
- <trans-unit id="_msg923">
+ <trans-unit id="_msg937">
<source xml:space="preserve">The transaction history was successfully saved to %1.</source>
<context-group purpose="location"><context context-type="linenumber">386</context></context-group>
</trans-unit>
- <trans-unit id="_msg924">
+ <trans-unit id="_msg938">
<source xml:space="preserve">Range:</source>
- <context-group purpose="location"><context context-type="linenumber">555</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">556</context></context-group>
</trans-unit>
- <trans-unit id="_msg925">
+ <trans-unit id="_msg939">
<source xml:space="preserve">to</source>
- <context-group purpose="location"><context context-type="linenumber">563</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">564</context></context-group>
</trans-unit>
</group>
</body></file>
<file original="../walletframe.cpp" datatype="cpp" source-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="WalletFrame">
- <trans-unit id="_msg926">
+ <trans-unit id="_msg940">
<source xml:space="preserve">No wallet has been loaded.
Go to File &gt; Open Wallet to load a wallet.
- OR -</source>
<context-group purpose="location"><context context-type="linenumber">45</context></context-group>
</trans-unit>
- <trans-unit id="_msg927">
+ <trans-unit id="_msg941">
<source xml:space="preserve">Create a new wallet</source>
<context-group purpose="location"><context context-type="linenumber">50</context></context-group>
</trans-unit>
- <trans-unit id="_msg928">
+ <trans-unit id="_msg942">
<source xml:space="preserve">Error</source>
<context-group purpose="location"><context context-type="linenumber">201</context></context-group>
<context-group purpose="location"><context context-type="linenumber">211</context></context-group>
<context-group purpose="location"><context context-type="linenumber">229</context></context-group>
</trans-unit>
- <trans-unit id="_msg929">
+ <trans-unit id="_msg943">
<source xml:space="preserve">Unable to decode PSBT from clipboard (invalid base64)</source>
<context-group purpose="location"><context context-type="linenumber">201</context></context-group>
</trans-unit>
- <trans-unit id="_msg930">
+ <trans-unit id="_msg944">
<source xml:space="preserve">Load Transaction Data</source>
<context-group purpose="location"><context context-type="linenumber">207</context></context-group>
</trans-unit>
- <trans-unit id="_msg931">
+ <trans-unit id="_msg945">
<source xml:space="preserve">Partially Signed Transaction (*.psbt)</source>
<context-group purpose="location"><context context-type="linenumber">208</context></context-group>
</trans-unit>
- <trans-unit id="_msg932">
+ <trans-unit id="_msg946">
<source xml:space="preserve">PSBT file must be smaller than 100 MiB</source>
<context-group purpose="location"><context context-type="linenumber">211</context></context-group>
</trans-unit>
- <trans-unit id="_msg933">
+ <trans-unit id="_msg947">
<source xml:space="preserve">Unable to decode PSBT</source>
<context-group purpose="location"><context context-type="linenumber">229</context></context-group>
</trans-unit>
@@ -4278,68 +4352,73 @@ Go to File &gt; Open Wallet to load a wallet.
</body></file>
<file original="../walletmodel.cpp" datatype="cpp" source-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="WalletModel">
- <trans-unit id="_msg934">
+ <trans-unit id="_msg948">
<source xml:space="preserve">Send Coins</source>
<context-group purpose="location"><context context-type="linenumber">228</context></context-group>
<context-group purpose="location"><context context-type="linenumber">241</context></context-group>
</trans-unit>
- <trans-unit id="_msg935">
+ <trans-unit id="_msg949">
<source xml:space="preserve">Fee bump error</source>
<context-group purpose="location"><context context-type="linenumber">489</context></context-group>
<context-group purpose="location"><context context-type="linenumber">544</context></context-group>
<context-group purpose="location"><context context-type="linenumber">559</context></context-group>
<context-group purpose="location"><context context-type="linenumber">564</context></context-group>
</trans-unit>
- <trans-unit id="_msg936">
+ <trans-unit id="_msg950">
<source xml:space="preserve">Increasing transaction fee failed</source>
<context-group purpose="location"><context context-type="linenumber">489</context></context-group>
</trans-unit>
- <trans-unit id="_msg937">
+ <trans-unit id="_msg951">
<source xml:space="preserve">Do you want to increase the fee?</source>
<context-group purpose="location"><context context-type="linenumber">496</context></context-group>
<note annotates="source" from="developer">Asks a user if they would like to manually increase the fee of a transaction that has already been created.</note>
</trans-unit>
- <trans-unit id="_msg938">
+ <trans-unit id="_msg952">
<source xml:space="preserve">Current fee:</source>
<context-group purpose="location"><context context-type="linenumber">500</context></context-group>
</trans-unit>
- <trans-unit id="_msg939">
+ <trans-unit id="_msg953">
<source xml:space="preserve">Increase:</source>
<context-group purpose="location"><context context-type="linenumber">504</context></context-group>
</trans-unit>
- <trans-unit id="_msg940">
+ <trans-unit id="_msg954">
<source xml:space="preserve">New fee:</source>
<context-group purpose="location"><context context-type="linenumber">508</context></context-group>
</trans-unit>
- <trans-unit id="_msg941">
+ <trans-unit id="_msg955">
<source xml:space="preserve">Warning: This may pay the additional fee by reducing change outputs or adding inputs, when necessary. It may add a new change output if one does not already exist. These changes may potentially leak privacy.</source>
<context-group purpose="location"><context context-type="linenumber">516</context></context-group>
</trans-unit>
- <trans-unit id="_msg942">
+ <trans-unit id="_msg956">
<source xml:space="preserve">Confirm fee bump</source>
<context-group purpose="location"><context context-type="linenumber">521</context></context-group>
</trans-unit>
- <trans-unit id="_msg943">
+ <trans-unit id="_msg957">
<source xml:space="preserve">Can&apos;t draft transaction.</source>
<context-group purpose="location"><context context-type="linenumber">544</context></context-group>
</trans-unit>
- <trans-unit id="_msg944">
+ <trans-unit id="_msg958">
<source xml:space="preserve">PSBT copied</source>
<context-group purpose="location"><context context-type="linenumber">551</context></context-group>
</trans-unit>
- <trans-unit id="_msg945">
+ <trans-unit id="_msg959">
+ <source xml:space="preserve">Copied to clipboard</source>
+ <context-group purpose="location"><context context-type="linenumber">551</context></context-group>
+ <context-group><context context-type="x-gettext-msgctxt">Fee-bump PSBT saved</context></context-group>
+ </trans-unit>
+ <trans-unit id="_msg960">
<source xml:space="preserve">Can&apos;t sign transaction.</source>
<context-group purpose="location"><context context-type="linenumber">559</context></context-group>
</trans-unit>
- <trans-unit id="_msg946">
+ <trans-unit id="_msg961">
<source xml:space="preserve">Could not commit transaction</source>
<context-group purpose="location"><context context-type="linenumber">564</context></context-group>
</trans-unit>
- <trans-unit id="_msg947">
+ <trans-unit id="_msg962">
<source xml:space="preserve">Can&apos;t display address</source>
<context-group purpose="location"><context context-type="linenumber">578</context></context-group>
</trans-unit>
- <trans-unit id="_msg948">
+ <trans-unit id="_msg963">
<source xml:space="preserve">default wallet</source>
<context-group purpose="location"><context context-type="linenumber">596</context></context-group>
</trans-unit>
@@ -4347,879 +4426,911 @@ Go to File &gt; Open Wallet to load a wallet.
</body></file>
<file original="../walletview.cpp" datatype="cpp" source-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="WalletView">
- <trans-unit id="_msg949">
+ <trans-unit id="_msg964">
<source xml:space="preserve">&amp;Export</source>
<context-group purpose="location"><context context-type="linenumber">50</context></context-group>
</trans-unit>
- <trans-unit id="_msg950">
+ <trans-unit id="_msg965">
<source xml:space="preserve">Export the data in the current tab to a file</source>
<context-group purpose="location"><context context-type="linenumber">51</context></context-group>
</trans-unit>
- <trans-unit id="_msg951">
+ <trans-unit id="_msg966">
<source xml:space="preserve">Backup Wallet</source>
- <context-group purpose="location"><context context-type="linenumber">213</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">214</context></context-group>
</trans-unit>
- <trans-unit id="_msg952">
+ <trans-unit id="_msg967">
<source xml:space="preserve">Wallet Data</source>
- <context-group purpose="location"><context context-type="linenumber">215</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">216</context></context-group>
<note annotates="source" from="developer">Name of the wallet data file format.</note>
</trans-unit>
- <trans-unit id="_msg953">
+ <trans-unit id="_msg968">
<source xml:space="preserve">Backup Failed</source>
- <context-group purpose="location"><context context-type="linenumber">221</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">222</context></context-group>
</trans-unit>
- <trans-unit id="_msg954">
+ <trans-unit id="_msg969">
<source xml:space="preserve">There was an error trying to save the wallet data to %1.</source>
- <context-group purpose="location"><context context-type="linenumber">221</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">222</context></context-group>
</trans-unit>
- <trans-unit id="_msg955">
+ <trans-unit id="_msg970">
<source xml:space="preserve">Backup Successful</source>
- <context-group purpose="location"><context context-type="linenumber">225</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">226</context></context-group>
</trans-unit>
- <trans-unit id="_msg956">
+ <trans-unit id="_msg971">
<source xml:space="preserve">The wallet data was successfully saved to %1.</source>
- <context-group purpose="location"><context context-type="linenumber">225</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">226</context></context-group>
</trans-unit>
- <trans-unit id="_msg957">
+ <trans-unit id="_msg972">
<source xml:space="preserve">Cancel</source>
- <context-group purpose="location"><context context-type="linenumber">262</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">263</context></context-group>
</trans-unit>
</group>
</body></file>
<file original="../bitcoinstrings.cpp" datatype="cpp" source-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="bitcoin-core">
- <trans-unit id="_msg958">
+ <trans-unit id="_msg973">
<source xml:space="preserve">The %s developers</source>
<context-group purpose="location"><context context-type="linenumber">12</context></context-group>
</trans-unit>
- <trans-unit id="_msg959">
+ <trans-unit id="_msg974">
<source xml:space="preserve">%s corrupt. Try using the wallet tool bitcoin-wallet to salvage or restoring a backup.</source>
<context-group purpose="location"><context context-type="linenumber">13</context></context-group>
</trans-unit>
- <trans-unit id="_msg960">
+ <trans-unit id="_msg975">
<source xml:space="preserve">%s request to listen on port %u. This port is considered &quot;bad&quot; and thus it is unlikely that any peer will connect to it. See doc/p2p-bad-ports.md for details and a full list.</source>
- <context-group purpose="location"><context context-type="linenumber">16</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">28</context></context-group>
</trans-unit>
- <trans-unit id="_msg961">
- <source xml:space="preserve">-maxtxfee is set very high! Fees this large could be paid on a single transaction.</source>
- <context-group purpose="location"><context context-type="linenumber">20</context></context-group>
- </trans-unit>
- <trans-unit id="_msg962">
+ <trans-unit id="_msg976">
<source xml:space="preserve">Cannot downgrade wallet from version %i to version %i. Wallet version unchanged.</source>
- <context-group purpose="location"><context context-type="linenumber">35</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">44</context></context-group>
</trans-unit>
- <trans-unit id="_msg963">
+ <trans-unit id="_msg977">
<source xml:space="preserve">Cannot obtain a lock on data directory %s. %s is probably already running.</source>
- <context-group purpose="location"><context context-type="linenumber">38</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">47</context></context-group>
</trans-unit>
- <trans-unit id="_msg964">
+ <trans-unit id="_msg978">
<source xml:space="preserve">Cannot upgrade a non HD split wallet from version %i to version %i without upgrading to support pre-split keypool. Please use version %i or no version specified.</source>
- <context-group purpose="location"><context context-type="linenumber">43</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">52</context></context-group>
</trans-unit>
- <trans-unit id="_msg965">
+ <trans-unit id="_msg979">
<source xml:space="preserve">Disk space for %s may not accommodate the block files. Approximately %u GB of data will be stored in this directory.</source>
- <context-group purpose="location"><context context-type="linenumber">47</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">56</context></context-group>
</trans-unit>
- <trans-unit id="_msg966">
+ <trans-unit id="_msg980">
<source xml:space="preserve">Distributed under the MIT software license, see the accompanying file %s or %s</source>
- <context-group purpose="location"><context context-type="linenumber">50</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">59</context></context-group>
</trans-unit>
- <trans-unit id="_msg967">
+ <trans-unit id="_msg981">
<source xml:space="preserve">Error loading wallet. Wallet requires blocks to be downloaded, and software does not currently support loading wallets while blocks are being downloaded out of order when using assumeutxo snapshots. Wallet should be able to load successfully after node sync reaches height %s</source>
- <context-group purpose="location"><context context-type="linenumber">56</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">65</context></context-group>
</trans-unit>
- <trans-unit id="_msg968">
+ <trans-unit id="_msg982">
<source xml:space="preserve">Error reading %s! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source>
- <context-group purpose="location"><context context-type="linenumber">61</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">70</context></context-group>
</trans-unit>
- <trans-unit id="_msg969">
+ <trans-unit id="_msg983">
<source xml:space="preserve">Error reading %s! Transaction data may be missing or incorrect. Rescanning wallet.</source>
- <context-group purpose="location"><context context-type="linenumber">64</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">73</context></context-group>
</trans-unit>
- <trans-unit id="_msg970">
+ <trans-unit id="_msg984">
<source xml:space="preserve">Error: Dumpfile format record is incorrect. Got &quot;%s&quot;, expected &quot;format&quot;.</source>
- <context-group purpose="location"><context context-type="linenumber">70</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">79</context></context-group>
</trans-unit>
- <trans-unit id="_msg971">
+ <trans-unit id="_msg985">
<source xml:space="preserve">Error: Dumpfile identifier record is incorrect. Got &quot;%s&quot;, expected &quot;%s&quot;.</source>
- <context-group purpose="location"><context context-type="linenumber">72</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">81</context></context-group>
</trans-unit>
- <trans-unit id="_msg972">
+ <trans-unit id="_msg986">
<source xml:space="preserve">Error: Dumpfile version is not supported. This version of bitcoin-wallet only supports version 1 dumpfiles. Got dumpfile with version %s</source>
- <context-group purpose="location"><context context-type="linenumber">74</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">83</context></context-group>
</trans-unit>
- <trans-unit id="_msg973">
+ <trans-unit id="_msg987">
<source xml:space="preserve">Error: Legacy wallets only support the &quot;legacy&quot;, &quot;p2sh-segwit&quot;, and &quot;bech32&quot; address types</source>
- <context-group purpose="location"><context context-type="linenumber">80</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">89</context></context-group>
</trans-unit>
- <trans-unit id="_msg974">
+ <trans-unit id="_msg988">
<source xml:space="preserve">Error: Unable to produce descriptors for this legacy wallet. Make sure to provide the wallet&apos;s passphrase if it is encrypted.</source>
- <context-group purpose="location"><context context-type="linenumber">86</context></context-group>
- </trans-unit>
- <trans-unit id="_msg975">
- <source xml:space="preserve">Fee estimation failed. Fallbackfee is disabled. Wait a few blocks or enable -fallbackfee.</source>
- <context-group purpose="location"><context context-type="linenumber">92</context></context-group>
- </trans-unit>
- <trans-unit id="_msg976">
- <source xml:space="preserve">File %s already exists. If you are sure this is what you want, move it out of the way first.</source>
<context-group purpose="location"><context context-type="linenumber">95</context></context-group>
</trans-unit>
- <trans-unit id="_msg977">
- <source xml:space="preserve">Invalid amount for -maxtxfee=&lt;amount&gt;: &apos;%s&apos; (must be at least the minrelay fee of %s to prevent stuck transactions)</source>
- <context-group purpose="location"><context context-type="linenumber">101</context></context-group>
+ <trans-unit id="_msg989">
+ <source xml:space="preserve">File %s already exists. If you are sure this is what you want, move it out of the way first.</source>
+ <context-group purpose="location"><context context-type="linenumber">104</context></context-group>
</trans-unit>
- <trans-unit id="_msg978">
+ <trans-unit id="_msg990">
<source xml:space="preserve">Invalid or corrupt peers.dat (%s). If you believe this is a bug, please report it to %s. As a workaround, you can move the file (%s) out of the way (rename, move, or delete) to have a new one created on the next start.</source>
- <context-group purpose="location"><context context-type="linenumber">104</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">113</context></context-group>
</trans-unit>
- <trans-unit id="_msg979">
+ <trans-unit id="_msg991">
<source xml:space="preserve">More than one onion bind address is provided. Using %s for the automatically created Tor onion service.</source>
- <context-group purpose="location"><context context-type="linenumber">108</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">117</context></context-group>
</trans-unit>
- <trans-unit id="_msg980">
+ <trans-unit id="_msg992">
<source xml:space="preserve">No dump file provided. To use createfromdump, -dumpfile=&lt;filename&gt; must be provided.</source>
- <context-group purpose="location"><context context-type="linenumber">111</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">120</context></context-group>
</trans-unit>
- <trans-unit id="_msg981">
+ <trans-unit id="_msg993">
<source xml:space="preserve">No dump file provided. To use dump, -dumpfile=&lt;filename&gt; must be provided.</source>
- <context-group purpose="location"><context context-type="linenumber">114</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">123</context></context-group>
</trans-unit>
- <trans-unit id="_msg982">
+ <trans-unit id="_msg994">
<source xml:space="preserve">No wallet file format provided. To use createfromdump, -format=&lt;format&gt; must be provided.</source>
- <context-group purpose="location"><context context-type="linenumber">116</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">125</context></context-group>
</trans-unit>
- <trans-unit id="_msg983">
+ <trans-unit id="_msg995">
<source xml:space="preserve">Please check that your computer&apos;s date and time are correct! If your clock is wrong, %s will not work properly.</source>
- <context-group purpose="location"><context context-type="linenumber">132</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">141</context></context-group>
</trans-unit>
- <trans-unit id="_msg984">
+ <trans-unit id="_msg996">
<source xml:space="preserve">Please contribute if you find %s useful. Visit %s for further information about the software.</source>
- <context-group purpose="location"><context context-type="linenumber">135</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">144</context></context-group>
</trans-unit>
- <trans-unit id="_msg985">
+ <trans-unit id="_msg997">
<source xml:space="preserve">Prune configured below the minimum of %d MiB. Please use a higher number.</source>
- <context-group purpose="location"><context context-type="linenumber">138</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">147</context></context-group>
</trans-unit>
- <trans-unit id="_msg986">
+ <trans-unit id="_msg998">
<source xml:space="preserve">Prune mode is incompatible with -reindex-chainstate. Use full -reindex instead.</source>
- <context-group purpose="location"><context context-type="linenumber">140</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">149</context></context-group>
</trans-unit>
- <trans-unit id="_msg987">
+ <trans-unit id="_msg999">
<source xml:space="preserve">Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node)</source>
- <context-group purpose="location"><context context-type="linenumber">143</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">152</context></context-group>
</trans-unit>
- <trans-unit id="_msg988">
+ <trans-unit id="_msg1000">
<source xml:space="preserve">SQLiteDatabase: Unknown sqlite wallet schema version %d. Only version %d is supported</source>
- <context-group purpose="location"><context context-type="linenumber">146</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">155</context></context-group>
</trans-unit>
- <trans-unit id="_msg989">
+ <trans-unit id="_msg1001">
<source xml:space="preserve">The block database contains a block which appears to be from the future. This may be due to your computer&apos;s date and time being set incorrectly. Only rebuild the block database if you are sure that your computer&apos;s date and time are correct</source>
- <context-group purpose="location"><context context-type="linenumber">152</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">161</context></context-group>
</trans-unit>
- <trans-unit id="_msg990">
+ <trans-unit id="_msg1002">
<source xml:space="preserve">The block index db contains a legacy &apos;txindex&apos;. To clear the occupied disk space, run a full -reindex, otherwise ignore this error. This error message will not be displayed again.</source>
- <context-group purpose="location"><context context-type="linenumber">157</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">166</context></context-group>
</trans-unit>
- <trans-unit id="_msg991">
+ <trans-unit id="_msg1003">
<source xml:space="preserve">The transaction amount is too small to send after the fee has been deducted</source>
- <context-group purpose="location"><context context-type="linenumber">168</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">177</context></context-group>
</trans-unit>
- <trans-unit id="_msg992">
+ <trans-unit id="_msg1004">
<source xml:space="preserve">This error could occur if this wallet was not shutdown cleanly and was last loaded using a build with a newer version of Berkeley DB. If so, please use the software that last loaded this wallet</source>
- <context-group purpose="location"><context context-type="linenumber">170</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">179</context></context-group>
</trans-unit>
- <trans-unit id="_msg993">
+ <trans-unit id="_msg1005">
<source xml:space="preserve">This is a pre-release test build - use at your own risk - do not use for mining or merchant applications</source>
- <context-group purpose="location"><context context-type="linenumber">174</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">183</context></context-group>
</trans-unit>
- <trans-unit id="_msg994">
+ <trans-unit id="_msg1006">
<source xml:space="preserve">This is the maximum transaction fee you pay (in addition to the normal fee) to prioritize partial spend avoidance over regular coin selection.</source>
- <context-group purpose="location"><context context-type="linenumber">177</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">186</context></context-group>
</trans-unit>
- <trans-unit id="_msg995">
+ <trans-unit id="_msg1007">
<source xml:space="preserve">This is the transaction fee you may discard if change is smaller than dust at this level</source>
- <context-group purpose="location"><context context-type="linenumber">180</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">189</context></context-group>
</trans-unit>
- <trans-unit id="_msg996">
+ <trans-unit id="_msg1008">
<source xml:space="preserve">This is the transaction fee you may pay when fee estimates are not available.</source>
- <context-group purpose="location"><context context-type="linenumber">183</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">192</context></context-group>
</trans-unit>
- <trans-unit id="_msg997">
+ <trans-unit id="_msg1009">
<source xml:space="preserve">Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments.</source>
- <context-group purpose="location"><context context-type="linenumber">185</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">194</context></context-group>
</trans-unit>
- <trans-unit id="_msg998">
+ <trans-unit id="_msg1010">
<source xml:space="preserve">Unable to replay blocks. You will need to rebuild the database using -reindex-chainstate.</source>
- <context-group purpose="location"><context context-type="linenumber">188</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">203</context></context-group>
</trans-unit>
- <trans-unit id="_msg999">
+ <trans-unit id="_msg1011">
<source xml:space="preserve">Unknown wallet file format &quot;%s&quot; provided. Please provide one of &quot;bdb&quot; or &quot;sqlite&quot;.</source>
- <context-group purpose="location"><context context-type="linenumber">195</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">213</context></context-group>
</trans-unit>
- <trans-unit id="_msg1000">
+ <trans-unit id="_msg1012">
<source xml:space="preserve">Unsupported chainstate database format found. Please restart with -reindex-chainstate. This will rebuild the chainstate database.</source>
- <context-group purpose="location"><context context-type="linenumber">206</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">224</context></context-group>
</trans-unit>
- <trans-unit id="_msg1001">
+ <trans-unit id="_msg1013">
<source xml:space="preserve">Wallet created successfully. The legacy wallet type is being deprecated and support for creating and opening legacy wallets will be removed in the future.</source>
- <context-group purpose="location"><context context-type="linenumber">209</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">227</context></context-group>
</trans-unit>
- <trans-unit id="_msg1002">
+ <trans-unit id="_msg1014">
<source xml:space="preserve">Warning: Dumpfile wallet format &quot;%s&quot; does not match command line specified format &quot;%s&quot;.</source>
- <context-group purpose="location"><context context-type="linenumber">213</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">231</context></context-group>
</trans-unit>
- <trans-unit id="_msg1003">
+ <trans-unit id="_msg1015">
<source xml:space="preserve">Warning: Private keys detected in wallet {%s} with disabled private keys</source>
- <context-group purpose="location"><context context-type="linenumber">216</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">234</context></context-group>
</trans-unit>
- <trans-unit id="_msg1004">
+ <trans-unit id="_msg1016">
<source xml:space="preserve">Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade.</source>
- <context-group purpose="location"><context context-type="linenumber">218</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">236</context></context-group>
</trans-unit>
- <trans-unit id="_msg1005">
+ <trans-unit id="_msg1017">
<source xml:space="preserve">Witness data for blocks after height %d requires validation. Please restart with -reindex.</source>
- <context-group purpose="location"><context context-type="linenumber">221</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">239</context></context-group>
</trans-unit>
- <trans-unit id="_msg1006">
+ <trans-unit id="_msg1018">
<source xml:space="preserve">You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source>
- <context-group purpose="location"><context context-type="linenumber">224</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">242</context></context-group>
</trans-unit>
- <trans-unit id="_msg1007">
+ <trans-unit id="_msg1019">
<source xml:space="preserve">%s is set very high!</source>
- <context-group purpose="location"><context context-type="linenumber">233</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">251</context></context-group>
</trans-unit>
- <trans-unit id="_msg1008">
+ <trans-unit id="_msg1020">
<source xml:space="preserve">-maxmempool must be at least %d MB</source>
- <context-group purpose="location"><context context-type="linenumber">234</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">252</context></context-group>
</trans-unit>
- <trans-unit id="_msg1009">
+ <trans-unit id="_msg1021">
<source xml:space="preserve">A fatal internal error occurred, see debug.log for details</source>
- <context-group purpose="location"><context context-type="linenumber">235</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">253</context></context-group>
</trans-unit>
- <trans-unit id="_msg1010">
+ <trans-unit id="_msg1022">
<source xml:space="preserve">Cannot resolve -%s address: &apos;%s&apos;</source>
- <context-group purpose="location"><context context-type="linenumber">236</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">255</context></context-group>
</trans-unit>
- <trans-unit id="_msg1011">
+ <trans-unit id="_msg1023">
<source xml:space="preserve">Cannot set -forcednsseed to true when setting -dnsseed to false.</source>
- <context-group purpose="location"><context context-type="linenumber">237</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">256</context></context-group>
</trans-unit>
- <trans-unit id="_msg1012">
+ <trans-unit id="_msg1024">
<source xml:space="preserve">Cannot set -peerblockfilters without -blockfilterindex.</source>
- <context-group purpose="location"><context context-type="linenumber">238</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">257</context></context-group>
</trans-unit>
- <trans-unit id="_msg1013">
+ <trans-unit id="_msg1025">
<source xml:space="preserve">Cannot write to data directory &apos;%s&apos;; check permissions.</source>
- <context-group purpose="location"><context context-type="linenumber">239</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">258</context></context-group>
</trans-unit>
- <trans-unit id="_msg1014">
+ <trans-unit id="_msg1026">
<source xml:space="preserve">The -txindex upgrade started by a previous version cannot be completed. Restart with the previous version or run a full -reindex.</source>
- <context-group purpose="location"><context context-type="linenumber">149</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">158</context></context-group>
</trans-unit>
- <trans-unit id="_msg1015">
+ <trans-unit id="_msg1027">
+ <source xml:space="preserve">%s failed to validate the -assumeutxo snapshot state. This indicates a hardware problem, or a bug in the software, or a bad software modification that allowed an invalid snapshot to be loaded. As a result of this, the node will shut down and stop using any state that was built on the snapshot, resetting the chain height from %d to %d. On the next restart, the node will resume syncing from %d without using any snapshot data. Please report this incident to %s, including how you obtained the snapshot. The invalid snapshot chainstate has been left on disk in case it is helpful in diagnosing the issue that caused this error.</source>
+ <context-group purpose="location"><context context-type="linenumber">16</context></context-group>
+ </trans-unit>
+ <trans-unit id="_msg1028">
+ <source xml:space="preserve">%s is set very high! Fees this large could be paid on a single transaction.</source>
+ <context-group purpose="location"><context context-type="linenumber">26</context></context-group>
+ </trans-unit>
+ <trans-unit id="_msg1029">
<source xml:space="preserve">-reindex-chainstate option is not compatible with -blockfilterindex. Please temporarily disable blockfilterindex while using -reindex-chainstate, or replace -reindex-chainstate with -reindex to fully rebuild all indexes.</source>
- <context-group purpose="location"><context context-type="linenumber">23</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">32</context></context-group>
</trans-unit>
- <trans-unit id="_msg1016">
+ <trans-unit id="_msg1030">
<source xml:space="preserve">-reindex-chainstate option is not compatible with -coinstatsindex. Please temporarily disable coinstatsindex while using -reindex-chainstate, or replace -reindex-chainstate with -reindex to fully rebuild all indexes.</source>
- <context-group purpose="location"><context context-type="linenumber">27</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">36</context></context-group>
</trans-unit>
- <trans-unit id="_msg1017">
+ <trans-unit id="_msg1031">
<source xml:space="preserve">-reindex-chainstate option is not compatible with -txindex. Please temporarily disable txindex while using -reindex-chainstate, or replace -reindex-chainstate with -reindex to fully rebuild all indexes.</source>
- <context-group purpose="location"><context context-type="linenumber">31</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">40</context></context-group>
</trans-unit>
- <trans-unit id="_msg1018">
+ <trans-unit id="_msg1032">
<source xml:space="preserve">Cannot provide specific connections and have addrman find outgoing connections at the same time.</source>
- <context-group purpose="location"><context context-type="linenumber">40</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">49</context></context-group>
</trans-unit>
- <trans-unit id="_msg1019">
+ <trans-unit id="_msg1033">
<source xml:space="preserve">Error loading %s: External signer wallet being loaded without external signer support compiled</source>
- <context-group purpose="location"><context context-type="linenumber">53</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">62</context></context-group>
</trans-unit>
- <trans-unit id="_msg1020">
+ <trans-unit id="_msg1034">
<source xml:space="preserve">Error: Address book data in wallet cannot be identified to belong to migrated wallets</source>
- <context-group purpose="location"><context context-type="linenumber">67</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">76</context></context-group>
</trans-unit>
- <trans-unit id="_msg1021">
+ <trans-unit id="_msg1035">
<source xml:space="preserve">Error: Duplicate descriptors created during migration. Your wallet may be corrupted.</source>
- <context-group purpose="location"><context context-type="linenumber">77</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">86</context></context-group>
</trans-unit>
- <trans-unit id="_msg1022">
+ <trans-unit id="_msg1036">
<source xml:space="preserve">Error: Transaction %s in wallet cannot be identified to belong to migrated wallets</source>
- <context-group purpose="location"><context context-type="linenumber">83</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">92</context></context-group>
</trans-unit>
- <trans-unit id="_msg1023">
+ <trans-unit id="_msg1037">
<source xml:space="preserve">Failed to rename invalid peers.dat file. Please move or delete it and try again.</source>
- <context-group purpose="location"><context context-type="linenumber">89</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">98</context></context-group>
</trans-unit>
- <trans-unit id="_msg1024">
+ <trans-unit id="_msg1038">
+ <source xml:space="preserve">Fee estimation failed. Fallbackfee is disabled. Wait a few blocks or enable %s.</source>
+ <context-group purpose="location"><context context-type="linenumber">101</context></context-group>
+ </trans-unit>
+ <trans-unit id="_msg1039">
<source xml:space="preserve">Incompatible options: -dnsseed=1 was explicitly specified, but -onlynet forbids connections to IPv4/IPv6</source>
- <context-group purpose="location"><context context-type="linenumber">98</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">107</context></context-group>
</trans-unit>
- <trans-unit id="_msg1025">
+ <trans-unit id="_msg1040">
+ <source xml:space="preserve">Invalid amount for %s=&lt;amount&gt;: &apos;%s&apos; (must be at least the minrelay fee of %s to prevent stuck transactions)</source>
+ <context-group purpose="location"><context context-type="linenumber">110</context></context-group>
+ </trans-unit>
+ <trans-unit id="_msg1041">
<source xml:space="preserve">Outbound connections restricted to CJDNS (-onlynet=cjdns) but -cjdnsreachable is not provided</source>
- <context-group purpose="location"><context context-type="linenumber">119</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">128</context></context-group>
</trans-unit>
- <trans-unit id="_msg1026">
+ <trans-unit id="_msg1042">
<source xml:space="preserve">Outbound connections restricted to Tor (-onlynet=onion) but the proxy for reaching the Tor network is explicitly forbidden: -onion=0</source>
- <context-group purpose="location"><context context-type="linenumber">122</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">131</context></context-group>
</trans-unit>
- <trans-unit id="_msg1027">
+ <trans-unit id="_msg1043">
<source xml:space="preserve">Outbound connections restricted to Tor (-onlynet=onion) but the proxy for reaching the Tor network is not provided: none of -proxy, -onion or -listenonion is given</source>
- <context-group purpose="location"><context context-type="linenumber">125</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">134</context></context-group>
</trans-unit>
- <trans-unit id="_msg1028">
+ <trans-unit id="_msg1044">
<source xml:space="preserve">Outbound connections restricted to i2p (-onlynet=i2p) but -i2psam is not provided</source>
- <context-group purpose="location"><context context-type="linenumber">129</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">138</context></context-group>
</trans-unit>
- <trans-unit id="_msg1029">
+ <trans-unit id="_msg1045">
<source xml:space="preserve">The inputs size exceeds the maximum weight. Please try sending a smaller amount or manually consolidating your wallet&apos;s UTXOs</source>
- <context-group purpose="location"><context context-type="linenumber">161</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">170</context></context-group>
</trans-unit>
- <trans-unit id="_msg1030">
+ <trans-unit id="_msg1046">
<source xml:space="preserve">The preselected coins total amount does not cover the transaction target. Please allow other inputs to be automatically selected or include more coins manually</source>
- <context-group purpose="location"><context context-type="linenumber">164</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">173</context></context-group>
</trans-unit>
- <trans-unit id="_msg1031">
+ <trans-unit id="_msg1047">
+ <source xml:space="preserve">Transaction requires one destination of non-0 value, a non-0 feerate, or a pre-selected input</source>
+ <context-group purpose="location"><context context-type="linenumber">197</context></context-group>
+ </trans-unit>
+ <trans-unit id="_msg1048">
+ <source xml:space="preserve">UTXO snapshot failed to validate. Restart to resume normal initial block download, or try loading a different snapshot.</source>
+ <context-group purpose="location"><context context-type="linenumber">200</context></context-group>
+ </trans-unit>
+ <trans-unit id="_msg1049">
+ <source xml:space="preserve">Unconfirmed UTXOs are available, but spending them creates a chain of transactions that will be rejected by the mempool</source>
+ <context-group purpose="location"><context context-type="linenumber">206</context></context-group>
+ </trans-unit>
+ <trans-unit id="_msg1050">
<source xml:space="preserve">Unexpected legacy entry in descriptor wallet found. Loading wallet %s
The wallet might have been tampered with or created with malicious intent.
</source>
- <context-group purpose="location"><context context-type="linenumber">191</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">209</context></context-group>
</trans-unit>
- <trans-unit id="_msg1032">
+ <trans-unit id="_msg1051">
<source xml:space="preserve">Unrecognized descriptor found. Loading wallet %s
The wallet might had been created on a newer version.
Please try running the latest software version.
</source>
- <context-group purpose="location"><context context-type="linenumber">198</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">216</context></context-group>
</trans-unit>
- <trans-unit id="_msg1033">
+ <trans-unit id="_msg1052">
<source xml:space="preserve">Unsupported category-specific logging level -loglevel=%s. Expected -loglevel=&lt;category&gt;:&lt;loglevel&gt;. Valid categories: %s. Valid loglevels: %s.</source>
- <context-group purpose="location"><context context-type="linenumber">203</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">221</context></context-group>
</trans-unit>
- <trans-unit id="_msg1034">
+ <trans-unit id="_msg1053">
<source xml:space="preserve">
Unable to cleanup failed migration</source>
- <context-group purpose="location"><context context-type="linenumber">227</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">245</context></context-group>
</trans-unit>
- <trans-unit id="_msg1035">
+ <trans-unit id="_msg1054">
<source xml:space="preserve">
Unable to restore backup of wallet.</source>
- <context-group purpose="location"><context context-type="linenumber">230</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">248</context></context-group>
</trans-unit>
- <trans-unit id="_msg1036">
+ <trans-unit id="_msg1055">
+ <source xml:space="preserve">Block verification was interrupted</source>
+ <context-group purpose="location"><context context-type="linenumber">254</context></context-group>
+ </trans-unit>
+ <trans-unit id="_msg1056">
<source xml:space="preserve">Config setting for %s only applied on %s network when in [%s] section.</source>
- <context-group purpose="location"><context context-type="linenumber">240</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">259</context></context-group>
</trans-unit>
- <trans-unit id="_msg1037">
+ <trans-unit id="_msg1057">
<source xml:space="preserve">Copyright (C) %i-%i</source>
- <context-group purpose="location"><context context-type="linenumber">241</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">260</context></context-group>
</trans-unit>
- <trans-unit id="_msg1038">
+ <trans-unit id="_msg1058">
<source xml:space="preserve">Corrupted block database detected</source>
- <context-group purpose="location"><context context-type="linenumber">242</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">261</context></context-group>
</trans-unit>
- <trans-unit id="_msg1039">
+ <trans-unit id="_msg1059">
<source xml:space="preserve">Could not find asmap file %s</source>
- <context-group purpose="location"><context context-type="linenumber">243</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">262</context></context-group>
</trans-unit>
- <trans-unit id="_msg1040">
+ <trans-unit id="_msg1060">
<source xml:space="preserve">Could not parse asmap file %s</source>
- <context-group purpose="location"><context context-type="linenumber">244</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">263</context></context-group>
</trans-unit>
- <trans-unit id="_msg1041">
+ <trans-unit id="_msg1061">
<source xml:space="preserve">Disk space is too low!</source>
- <context-group purpose="location"><context context-type="linenumber">245</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">264</context></context-group>
</trans-unit>
- <trans-unit id="_msg1042">
+ <trans-unit id="_msg1062">
<source xml:space="preserve">Do you want to rebuild the block database now?</source>
- <context-group purpose="location"><context context-type="linenumber">246</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">265</context></context-group>
</trans-unit>
- <trans-unit id="_msg1043">
+ <trans-unit id="_msg1063">
<source xml:space="preserve">Done loading</source>
- <context-group purpose="location"><context context-type="linenumber">247</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">266</context></context-group>
</trans-unit>
- <trans-unit id="_msg1044">
+ <trans-unit id="_msg1064">
<source xml:space="preserve">Dump file %s does not exist.</source>
- <context-group purpose="location"><context context-type="linenumber">248</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">267</context></context-group>
</trans-unit>
- <trans-unit id="_msg1045">
+ <trans-unit id="_msg1065">
<source xml:space="preserve">Error creating %s</source>
- <context-group purpose="location"><context context-type="linenumber">249</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">268</context></context-group>
</trans-unit>
- <trans-unit id="_msg1046">
+ <trans-unit id="_msg1066">
<source xml:space="preserve">Error initializing block database</source>
- <context-group purpose="location"><context context-type="linenumber">250</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">269</context></context-group>
</trans-unit>
- <trans-unit id="_msg1047">
+ <trans-unit id="_msg1067">
<source xml:space="preserve">Error initializing wallet database environment %s!</source>
- <context-group purpose="location"><context context-type="linenumber">251</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">270</context></context-group>
</trans-unit>
- <trans-unit id="_msg1048">
+ <trans-unit id="_msg1068">
<source xml:space="preserve">Error loading %s</source>
- <context-group purpose="location"><context context-type="linenumber">252</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">271</context></context-group>
</trans-unit>
- <trans-unit id="_msg1049">
+ <trans-unit id="_msg1069">
<source xml:space="preserve">Error loading %s: Private keys can only be disabled during creation</source>
- <context-group purpose="location"><context context-type="linenumber">253</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">272</context></context-group>
</trans-unit>
- <trans-unit id="_msg1050">
+ <trans-unit id="_msg1070">
<source xml:space="preserve">Error loading %s: Wallet corrupted</source>
- <context-group purpose="location"><context context-type="linenumber">254</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">273</context></context-group>
</trans-unit>
- <trans-unit id="_msg1051">
+ <trans-unit id="_msg1071">
<source xml:space="preserve">Error loading %s: Wallet requires newer version of %s</source>
- <context-group purpose="location"><context context-type="linenumber">255</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">274</context></context-group>
</trans-unit>
- <trans-unit id="_msg1052">
+ <trans-unit id="_msg1072">
<source xml:space="preserve">Error loading block database</source>
- <context-group purpose="location"><context context-type="linenumber">256</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">275</context></context-group>
</trans-unit>
- <trans-unit id="_msg1053">
+ <trans-unit id="_msg1073">
<source xml:space="preserve">Error opening block database</source>
- <context-group purpose="location"><context context-type="linenumber">257</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">276</context></context-group>
</trans-unit>
- <trans-unit id="_msg1054">
+ <trans-unit id="_msg1074">
+ <source xml:space="preserve">Error reading configuration file: %s</source>
+ <context-group purpose="location"><context context-type="linenumber">277</context></context-group>
+ </trans-unit>
+ <trans-unit id="_msg1075">
<source xml:space="preserve">Error reading from database, shutting down.</source>
- <context-group purpose="location"><context context-type="linenumber">258</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">278</context></context-group>
</trans-unit>
- <trans-unit id="_msg1055">
+ <trans-unit id="_msg1076">
<source xml:space="preserve">Error reading next record from wallet database</source>
- <context-group purpose="location"><context context-type="linenumber">259</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">279</context></context-group>
</trans-unit>
- <trans-unit id="_msg1056">
+ <trans-unit id="_msg1077">
<source xml:space="preserve">Error: Cannot extract destination from the generated scriptpubkey</source>
- <context-group purpose="location"><context context-type="linenumber">260</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">280</context></context-group>
</trans-unit>
- <trans-unit id="_msg1057">
+ <trans-unit id="_msg1078">
<source xml:space="preserve">Error: Could not add watchonly tx to watchonly wallet</source>
- <context-group purpose="location"><context context-type="linenumber">261</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">281</context></context-group>
</trans-unit>
- <trans-unit id="_msg1058">
+ <trans-unit id="_msg1079">
<source xml:space="preserve">Error: Could not delete watchonly transactions</source>
- <context-group purpose="location"><context context-type="linenumber">262</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">282</context></context-group>
</trans-unit>
- <trans-unit id="_msg1059">
+ <trans-unit id="_msg1080">
<source xml:space="preserve">Error: Couldn&apos;t create cursor into database</source>
- <context-group purpose="location"><context context-type="linenumber">263</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">283</context></context-group>
</trans-unit>
- <trans-unit id="_msg1060">
+ <trans-unit id="_msg1081">
<source xml:space="preserve">Error: Disk space is low for %s</source>
- <context-group purpose="location"><context context-type="linenumber">264</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">284</context></context-group>
</trans-unit>
- <trans-unit id="_msg1061">
+ <trans-unit id="_msg1082">
<source xml:space="preserve">Error: Dumpfile checksum does not match. Computed %s, expected %s</source>
- <context-group purpose="location"><context context-type="linenumber">265</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">285</context></context-group>
</trans-unit>
- <trans-unit id="_msg1062">
+ <trans-unit id="_msg1083">
<source xml:space="preserve">Error: Failed to create new watchonly wallet</source>
- <context-group purpose="location"><context context-type="linenumber">266</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">286</context></context-group>
</trans-unit>
- <trans-unit id="_msg1063">
+ <trans-unit id="_msg1084">
<source xml:space="preserve">Error: Got key that was not hex: %s</source>
- <context-group purpose="location"><context context-type="linenumber">267</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">287</context></context-group>
</trans-unit>
- <trans-unit id="_msg1064">
+ <trans-unit id="_msg1085">
<source xml:space="preserve">Error: Got value that was not hex: %s</source>
- <context-group purpose="location"><context context-type="linenumber">268</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">288</context></context-group>
</trans-unit>
- <trans-unit id="_msg1065">
+ <trans-unit id="_msg1086">
<source xml:space="preserve">Error: Keypool ran out, please call keypoolrefill first</source>
- <context-group purpose="location"><context context-type="linenumber">269</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">289</context></context-group>
</trans-unit>
- <trans-unit id="_msg1066">
+ <trans-unit id="_msg1087">
<source xml:space="preserve">Error: Missing checksum</source>
- <context-group purpose="location"><context context-type="linenumber">270</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">290</context></context-group>
</trans-unit>
- <trans-unit id="_msg1067">
+ <trans-unit id="_msg1088">
<source xml:space="preserve">Error: No %s addresses available.</source>
- <context-group purpose="location"><context context-type="linenumber">271</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">291</context></context-group>
</trans-unit>
- <trans-unit id="_msg1068">
+ <trans-unit id="_msg1089">
<source xml:space="preserve">Error: Not all watchonly txs could be deleted</source>
- <context-group purpose="location"><context context-type="linenumber">272</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">292</context></context-group>
</trans-unit>
- <trans-unit id="_msg1069">
+ <trans-unit id="_msg1090">
<source xml:space="preserve">Error: This wallet already uses SQLite</source>
- <context-group purpose="location"><context context-type="linenumber">273</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">293</context></context-group>
</trans-unit>
- <trans-unit id="_msg1070">
+ <trans-unit id="_msg1091">
<source xml:space="preserve">Error: This wallet is already a descriptor wallet</source>
- <context-group purpose="location"><context context-type="linenumber">274</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">294</context></context-group>
</trans-unit>
- <trans-unit id="_msg1071">
+ <trans-unit id="_msg1092">
<source xml:space="preserve">Error: Unable to begin reading all records in the database</source>
- <context-group purpose="location"><context context-type="linenumber">275</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">295</context></context-group>
</trans-unit>
- <trans-unit id="_msg1072">
+ <trans-unit id="_msg1093">
<source xml:space="preserve">Error: Unable to make a backup of your wallet</source>
- <context-group purpose="location"><context context-type="linenumber">276</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">296</context></context-group>
</trans-unit>
- <trans-unit id="_msg1073">
+ <trans-unit id="_msg1094">
<source xml:space="preserve">Error: Unable to parse version %u as a uint32_t</source>
- <context-group purpose="location"><context context-type="linenumber">277</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">297</context></context-group>
</trans-unit>
- <trans-unit id="_msg1074">
+ <trans-unit id="_msg1095">
<source xml:space="preserve">Error: Unable to read all records in the database</source>
- <context-group purpose="location"><context context-type="linenumber">278</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">298</context></context-group>
</trans-unit>
- <trans-unit id="_msg1075">
+ <trans-unit id="_msg1096">
<source xml:space="preserve">Error: Unable to remove watchonly address book data</source>
- <context-group purpose="location"><context context-type="linenumber">279</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">299</context></context-group>
</trans-unit>
- <trans-unit id="_msg1076">
+ <trans-unit id="_msg1097">
<source xml:space="preserve">Error: Unable to write record to new wallet</source>
- <context-group purpose="location"><context context-type="linenumber">280</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">300</context></context-group>
</trans-unit>
- <trans-unit id="_msg1077">
+ <trans-unit id="_msg1098">
<source xml:space="preserve">Failed to listen on any port. Use -listen=0 if you want this.</source>
- <context-group purpose="location"><context context-type="linenumber">281</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">301</context></context-group>
</trans-unit>
- <trans-unit id="_msg1078">
+ <trans-unit id="_msg1099">
<source xml:space="preserve">Failed to rescan the wallet during initialization</source>
- <context-group purpose="location"><context context-type="linenumber">282</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">302</context></context-group>
</trans-unit>
- <trans-unit id="_msg1079">
+ <trans-unit id="_msg1100">
<source xml:space="preserve">Failed to verify database</source>
- <context-group purpose="location"><context context-type="linenumber">283</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">303</context></context-group>
</trans-unit>
- <trans-unit id="_msg1080">
+ <trans-unit id="_msg1101">
<source xml:space="preserve">Fee rate (%s) is lower than the minimum fee rate setting (%s)</source>
- <context-group purpose="location"><context context-type="linenumber">284</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">304</context></context-group>
</trans-unit>
- <trans-unit id="_msg1081">
+ <trans-unit id="_msg1102">
<source xml:space="preserve">Ignoring duplicate -wallet %s.</source>
- <context-group purpose="location"><context context-type="linenumber">285</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">305</context></context-group>
</trans-unit>
- <trans-unit id="_msg1082">
+ <trans-unit id="_msg1103">
<source xml:space="preserve">Importing…</source>
- <context-group purpose="location"><context context-type="linenumber">286</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">306</context></context-group>
</trans-unit>
- <trans-unit id="_msg1083">
+ <trans-unit id="_msg1104">
<source xml:space="preserve">Incorrect or no genesis block found. Wrong datadir for network?</source>
- <context-group purpose="location"><context context-type="linenumber">287</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">307</context></context-group>
</trans-unit>
- <trans-unit id="_msg1084">
+ <trans-unit id="_msg1105">
<source xml:space="preserve">Initialization sanity check failed. %s is shutting down.</source>
- <context-group purpose="location"><context context-type="linenumber">288</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">308</context></context-group>
</trans-unit>
- <trans-unit id="_msg1085">
+ <trans-unit id="_msg1106">
<source xml:space="preserve">Input not found or already spent</source>
- <context-group purpose="location"><context context-type="linenumber">289</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">309</context></context-group>
</trans-unit>
- <trans-unit id="_msg1086">
+ <trans-unit id="_msg1107">
<source xml:space="preserve">Insufficient dbcache for block verification</source>
- <context-group purpose="location"><context context-type="linenumber">290</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">310</context></context-group>
</trans-unit>
- <trans-unit id="_msg1087">
+ <trans-unit id="_msg1108">
<source xml:space="preserve">Insufficient funds</source>
- <context-group purpose="location"><context context-type="linenumber">291</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">311</context></context-group>
</trans-unit>
- <trans-unit id="_msg1088">
+ <trans-unit id="_msg1109">
<source xml:space="preserve">Invalid -i2psam address or hostname: &apos;%s&apos;</source>
- <context-group purpose="location"><context context-type="linenumber">292</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">312</context></context-group>
</trans-unit>
- <trans-unit id="_msg1089">
+ <trans-unit id="_msg1110">
<source xml:space="preserve">Invalid -onion address or hostname: &apos;%s&apos;</source>
- <context-group purpose="location"><context context-type="linenumber">293</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">313</context></context-group>
</trans-unit>
- <trans-unit id="_msg1090">
+ <trans-unit id="_msg1111">
<source xml:space="preserve">Invalid -proxy address or hostname: &apos;%s&apos;</source>
- <context-group purpose="location"><context context-type="linenumber">294</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">314</context></context-group>
</trans-unit>
- <trans-unit id="_msg1091">
+ <trans-unit id="_msg1112">
<source xml:space="preserve">Invalid P2P permission: &apos;%s&apos;</source>
- <context-group purpose="location"><context context-type="linenumber">295</context></context-group>
- </trans-unit>
- <trans-unit id="_msg1092">
- <source xml:space="preserve">Invalid amount for -%s=&lt;amount&gt;: &apos;%s&apos;</source>
- <context-group purpose="location"><context context-type="linenumber">296</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">315</context></context-group>
</trans-unit>
- <trans-unit id="_msg1093">
- <source xml:space="preserve">Invalid amount for -discardfee=&lt;amount&gt;: &apos;%s&apos;</source>
- <context-group purpose="location"><context context-type="linenumber">297</context></context-group>
+ <trans-unit id="_msg1113">
+ <source xml:space="preserve">Invalid amount for %s=&lt;amount&gt;: &apos;%s&apos; (must be at least %s)</source>
+ <context-group purpose="location"><context context-type="linenumber">316</context></context-group>
</trans-unit>
- <trans-unit id="_msg1094">
- <source xml:space="preserve">Invalid amount for -fallbackfee=&lt;amount&gt;: &apos;%s&apos;</source>
- <context-group purpose="location"><context context-type="linenumber">298</context></context-group>
+ <trans-unit id="_msg1114">
+ <source xml:space="preserve">Invalid amount for %s=&lt;amount&gt;: &apos;%s&apos;</source>
+ <context-group purpose="location"><context context-type="linenumber">317</context></context-group>
</trans-unit>
- <trans-unit id="_msg1095">
- <source xml:space="preserve">Invalid amount for -paytxfee=&lt;amount&gt;: &apos;%s&apos; (must be at least %s)</source>
- <context-group purpose="location"><context context-type="linenumber">299</context></context-group>
+ <trans-unit id="_msg1115">
+ <source xml:space="preserve">Invalid amount for -%s=&lt;amount&gt;: &apos;%s&apos;</source>
+ <context-group purpose="location"><context context-type="linenumber">318</context></context-group>
</trans-unit>
- <trans-unit id="_msg1096">
+ <trans-unit id="_msg1116">
<source xml:space="preserve">Invalid netmask specified in -whitelist: &apos;%s&apos;</source>
- <context-group purpose="location"><context context-type="linenumber">300</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">319</context></context-group>
</trans-unit>
- <trans-unit id="_msg1097">
+ <trans-unit id="_msg1117">
<source xml:space="preserve">Invalid port specified in %s: &apos;%s&apos;</source>
- <context-group purpose="location"><context context-type="linenumber">301</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">320</context></context-group>
</trans-unit>
- <trans-unit id="_msg1098">
+ <trans-unit id="_msg1118">
<source xml:space="preserve">Invalid pre-selected input %s</source>
- <context-group purpose="location"><context context-type="linenumber">302</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">321</context></context-group>
</trans-unit>
- <trans-unit id="_msg1099">
+ <trans-unit id="_msg1119">
<source xml:space="preserve">Listening for incoming connections failed (listen returned error %s)</source>
- <context-group purpose="location"><context context-type="linenumber">303</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">322</context></context-group>
</trans-unit>
- <trans-unit id="_msg1100">
+ <trans-unit id="_msg1120">
<source xml:space="preserve">Loading P2P addresses…</source>
- <context-group purpose="location"><context context-type="linenumber">304</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">323</context></context-group>
</trans-unit>
- <trans-unit id="_msg1101">
+ <trans-unit id="_msg1121">
<source xml:space="preserve">Loading banlist…</source>
- <context-group purpose="location"><context context-type="linenumber">305</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">324</context></context-group>
</trans-unit>
- <trans-unit id="_msg1102">
+ <trans-unit id="_msg1122">
<source xml:space="preserve">Loading block index…</source>
- <context-group purpose="location"><context context-type="linenumber">306</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">325</context></context-group>
</trans-unit>
- <trans-unit id="_msg1103">
+ <trans-unit id="_msg1123">
<source xml:space="preserve">Loading wallet…</source>
- <context-group purpose="location"><context context-type="linenumber">307</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">326</context></context-group>
</trans-unit>
- <trans-unit id="_msg1104">
+ <trans-unit id="_msg1124">
<source xml:space="preserve">Missing amount</source>
- <context-group purpose="location"><context context-type="linenumber">308</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">327</context></context-group>
</trans-unit>
- <trans-unit id="_msg1105">
+ <trans-unit id="_msg1125">
<source xml:space="preserve">Missing solving data for estimating transaction size</source>
- <context-group purpose="location"><context context-type="linenumber">309</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">328</context></context-group>
</trans-unit>
- <trans-unit id="_msg1106">
+ <trans-unit id="_msg1126">
<source xml:space="preserve">Need to specify a port with -whitebind: &apos;%s&apos;</source>
- <context-group purpose="location"><context context-type="linenumber">310</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">329</context></context-group>
</trans-unit>
- <trans-unit id="_msg1107">
+ <trans-unit id="_msg1127">
<source xml:space="preserve">No addresses available</source>
- <context-group purpose="location"><context context-type="linenumber">311</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">330</context></context-group>
</trans-unit>
- <trans-unit id="_msg1108">
+ <trans-unit id="_msg1128">
<source xml:space="preserve">Not enough file descriptors available.</source>
- <context-group purpose="location"><context context-type="linenumber">312</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">331</context></context-group>
</trans-unit>
- <trans-unit id="_msg1109">
+ <trans-unit id="_msg1129">
<source xml:space="preserve">Not found pre-selected input %s</source>
- <context-group purpose="location"><context context-type="linenumber">313</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">332</context></context-group>
</trans-unit>
- <trans-unit id="_msg1110">
+ <trans-unit id="_msg1130">
<source xml:space="preserve">Not solvable pre-selected input %s</source>
- <context-group purpose="location"><context context-type="linenumber">314</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">333</context></context-group>
</trans-unit>
- <trans-unit id="_msg1111">
+ <trans-unit id="_msg1131">
<source xml:space="preserve">Prune cannot be configured with a negative value.</source>
- <context-group purpose="location"><context context-type="linenumber">315</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">334</context></context-group>
</trans-unit>
- <trans-unit id="_msg1112">
+ <trans-unit id="_msg1132">
<source xml:space="preserve">Prune mode is incompatible with -txindex.</source>
- <context-group purpose="location"><context context-type="linenumber">316</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">335</context></context-group>
</trans-unit>
- <trans-unit id="_msg1113">
+ <trans-unit id="_msg1133">
<source xml:space="preserve">Pruning blockstore…</source>
- <context-group purpose="location"><context context-type="linenumber">317</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">336</context></context-group>
</trans-unit>
- <trans-unit id="_msg1114">
+ <trans-unit id="_msg1134">
<source xml:space="preserve">Reducing -maxconnections from %d to %d, because of system limitations.</source>
- <context-group purpose="location"><context context-type="linenumber">318</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">337</context></context-group>
</trans-unit>
- <trans-unit id="_msg1115">
+ <trans-unit id="_msg1135">
<source xml:space="preserve">Replaying blocks…</source>
- <context-group purpose="location"><context context-type="linenumber">319</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">338</context></context-group>
</trans-unit>
- <trans-unit id="_msg1116">
+ <trans-unit id="_msg1136">
<source xml:space="preserve">Rescanning…</source>
- <context-group purpose="location"><context context-type="linenumber">320</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">339</context></context-group>
</trans-unit>
- <trans-unit id="_msg1117">
+ <trans-unit id="_msg1137">
<source xml:space="preserve">SQLiteDatabase: Failed to execute statement to verify database: %s</source>
- <context-group purpose="location"><context context-type="linenumber">321</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">340</context></context-group>
</trans-unit>
- <trans-unit id="_msg1118">
+ <trans-unit id="_msg1138">
<source xml:space="preserve">SQLiteDatabase: Failed to prepare statement to verify database: %s</source>
- <context-group purpose="location"><context context-type="linenumber">322</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">341</context></context-group>
</trans-unit>
- <trans-unit id="_msg1119">
+ <trans-unit id="_msg1139">
<source xml:space="preserve">SQLiteDatabase: Failed to read database verification error: %s</source>
- <context-group purpose="location"><context context-type="linenumber">323</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">342</context></context-group>
</trans-unit>
- <trans-unit id="_msg1120">
+ <trans-unit id="_msg1140">
<source xml:space="preserve">SQLiteDatabase: Unexpected application id. Expected %u, got %u</source>
- <context-group purpose="location"><context context-type="linenumber">324</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">343</context></context-group>
</trans-unit>
- <trans-unit id="_msg1121">
+ <trans-unit id="_msg1141">
<source xml:space="preserve">Section [%s] is not recognized.</source>
- <context-group purpose="location"><context context-type="linenumber">325</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">344</context></context-group>
</trans-unit>
- <trans-unit id="_msg1122">
+ <trans-unit id="_msg1142">
<source xml:space="preserve">Signing transaction failed</source>
- <context-group purpose="location"><context context-type="linenumber">326</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">347</context></context-group>
</trans-unit>
- <trans-unit id="_msg1123">
+ <trans-unit id="_msg1143">
<source xml:space="preserve">Specified -walletdir &quot;%s&quot; does not exist</source>
- <context-group purpose="location"><context context-type="linenumber">327</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">348</context></context-group>
</trans-unit>
- <trans-unit id="_msg1124">
+ <trans-unit id="_msg1144">
<source xml:space="preserve">Specified -walletdir &quot;%s&quot; is a relative path</source>
- <context-group purpose="location"><context context-type="linenumber">328</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">349</context></context-group>
</trans-unit>
- <trans-unit id="_msg1125">
+ <trans-unit id="_msg1145">
<source xml:space="preserve">Specified -walletdir &quot;%s&quot; is not a directory</source>
- <context-group purpose="location"><context context-type="linenumber">329</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">350</context></context-group>
</trans-unit>
- <trans-unit id="_msg1126">
+ <trans-unit id="_msg1146">
<source xml:space="preserve">Specified blocks directory &quot;%s&quot; does not exist.</source>
- <context-group purpose="location"><context context-type="linenumber">330</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">351</context></context-group>
</trans-unit>
- <trans-unit id="_msg1127">
+ <trans-unit id="_msg1147">
+ <source xml:space="preserve">Specified data directory &quot;%s&quot; does not exist.</source>
+ <context-group purpose="location"><context context-type="linenumber">352</context></context-group>
+ </trans-unit>
+ <trans-unit id="_msg1148">
<source xml:space="preserve">Starting network threads…</source>
- <context-group purpose="location"><context context-type="linenumber">331</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">353</context></context-group>
</trans-unit>
- <trans-unit id="_msg1128">
+ <trans-unit id="_msg1149">
<source xml:space="preserve">The source code is available from %s.</source>
- <context-group purpose="location"><context context-type="linenumber">332</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">354</context></context-group>
</trans-unit>
- <trans-unit id="_msg1129">
+ <trans-unit id="_msg1150">
<source xml:space="preserve">The specified config file %s does not exist</source>
- <context-group purpose="location"><context context-type="linenumber">333</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">355</context></context-group>
</trans-unit>
- <trans-unit id="_msg1130">
+ <trans-unit id="_msg1151">
<source xml:space="preserve">The transaction amount is too small to pay the fee</source>
- <context-group purpose="location"><context context-type="linenumber">334</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">356</context></context-group>
</trans-unit>
- <trans-unit id="_msg1131">
+ <trans-unit id="_msg1152">
<source xml:space="preserve">The wallet will avoid paying less than the minimum relay fee.</source>
- <context-group purpose="location"><context context-type="linenumber">335</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">357</context></context-group>
</trans-unit>
- <trans-unit id="_msg1132">
+ <trans-unit id="_msg1153">
<source xml:space="preserve">This is experimental software.</source>
- <context-group purpose="location"><context context-type="linenumber">336</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">358</context></context-group>
</trans-unit>
- <trans-unit id="_msg1133">
+ <trans-unit id="_msg1154">
<source xml:space="preserve">This is the minimum transaction fee you pay on every transaction.</source>
- <context-group purpose="location"><context context-type="linenumber">337</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">359</context></context-group>
</trans-unit>
- <trans-unit id="_msg1134">
+ <trans-unit id="_msg1155">
<source xml:space="preserve">This is the transaction fee you will pay if you send a transaction.</source>
- <context-group purpose="location"><context context-type="linenumber">338</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">360</context></context-group>
</trans-unit>
- <trans-unit id="_msg1135">
+ <trans-unit id="_msg1156">
<source xml:space="preserve">Transaction amount too small</source>
- <context-group purpose="location"><context context-type="linenumber">339</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">361</context></context-group>
</trans-unit>
- <trans-unit id="_msg1136">
+ <trans-unit id="_msg1157">
<source xml:space="preserve">Transaction amounts must not be negative</source>
- <context-group purpose="location"><context context-type="linenumber">340</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">362</context></context-group>
</trans-unit>
- <trans-unit id="_msg1137">
+ <trans-unit id="_msg1158">
<source xml:space="preserve">Transaction change output index out of range</source>
- <context-group purpose="location"><context context-type="linenumber">341</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">363</context></context-group>
</trans-unit>
- <trans-unit id="_msg1138">
+ <trans-unit id="_msg1159">
<source xml:space="preserve">Transaction has too long of a mempool chain</source>
- <context-group purpose="location"><context context-type="linenumber">342</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">364</context></context-group>
</trans-unit>
- <trans-unit id="_msg1139">
+ <trans-unit id="_msg1160">
<source xml:space="preserve">Transaction must have at least one recipient</source>
- <context-group purpose="location"><context context-type="linenumber">343</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">365</context></context-group>
</trans-unit>
- <trans-unit id="_msg1140">
+ <trans-unit id="_msg1161">
<source xml:space="preserve">Transaction needs a change address, but we can&apos;t generate it.</source>
- <context-group purpose="location"><context context-type="linenumber">344</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">366</context></context-group>
</trans-unit>
- <trans-unit id="_msg1141">
+ <trans-unit id="_msg1162">
<source xml:space="preserve">Transaction too large</source>
- <context-group purpose="location"><context context-type="linenumber">345</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">367</context></context-group>
</trans-unit>
- <trans-unit id="_msg1142">
+ <trans-unit id="_msg1163">
<source xml:space="preserve">Unable to allocate memory for -maxsigcachesize: &apos;%s&apos; MiB</source>
- <context-group purpose="location"><context context-type="linenumber">346</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">368</context></context-group>
</trans-unit>
- <trans-unit id="_msg1143">
+ <trans-unit id="_msg1164">
<source xml:space="preserve">Unable to bind to %s on this computer (bind returned error %s)</source>
- <context-group purpose="location"><context context-type="linenumber">347</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">369</context></context-group>
</trans-unit>
- <trans-unit id="_msg1144">
+ <trans-unit id="_msg1165">
<source xml:space="preserve">Unable to bind to %s on this computer. %s is probably already running.</source>
- <context-group purpose="location"><context context-type="linenumber">348</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">370</context></context-group>
</trans-unit>
- <trans-unit id="_msg1145">
+ <trans-unit id="_msg1166">
<source xml:space="preserve">Unable to create the PID file &apos;%s&apos;: %s</source>
- <context-group purpose="location"><context context-type="linenumber">349</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">371</context></context-group>
</trans-unit>
- <trans-unit id="_msg1146">
+ <trans-unit id="_msg1167">
<source xml:space="preserve">Unable to find UTXO for external input</source>
- <context-group purpose="location"><context context-type="linenumber">350</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">372</context></context-group>
</trans-unit>
- <trans-unit id="_msg1147">
+ <trans-unit id="_msg1168">
<source xml:space="preserve">Unable to generate initial keys</source>
- <context-group purpose="location"><context context-type="linenumber">351</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">373</context></context-group>
</trans-unit>
- <trans-unit id="_msg1148">
+ <trans-unit id="_msg1169">
<source xml:space="preserve">Unable to generate keys</source>
- <context-group purpose="location"><context context-type="linenumber">352</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">374</context></context-group>
</trans-unit>
- <trans-unit id="_msg1149">
+ <trans-unit id="_msg1170">
<source xml:space="preserve">Unable to open %s for writing</source>
- <context-group purpose="location"><context context-type="linenumber">353</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">375</context></context-group>
</trans-unit>
- <trans-unit id="_msg1150">
+ <trans-unit id="_msg1171">
<source xml:space="preserve">Unable to parse -maxuploadtarget: &apos;%s&apos;</source>
- <context-group purpose="location"><context context-type="linenumber">354</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">376</context></context-group>
</trans-unit>
- <trans-unit id="_msg1151">
+ <trans-unit id="_msg1172">
<source xml:space="preserve">Unable to start HTTP server. See debug log for details.</source>
- <context-group purpose="location"><context context-type="linenumber">355</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">377</context></context-group>
</trans-unit>
- <trans-unit id="_msg1152">
+ <trans-unit id="_msg1173">
<source xml:space="preserve">Unable to unload the wallet before migrating</source>
- <context-group purpose="location"><context context-type="linenumber">356</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">378</context></context-group>
</trans-unit>
- <trans-unit id="_msg1153">
+ <trans-unit id="_msg1174">
<source xml:space="preserve">Unknown -blockfilterindex value %s.</source>
- <context-group purpose="location"><context context-type="linenumber">357</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">379</context></context-group>
</trans-unit>
- <trans-unit id="_msg1154">
+ <trans-unit id="_msg1175">
<source xml:space="preserve">Unknown address type &apos;%s&apos;</source>
- <context-group purpose="location"><context context-type="linenumber">358</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">380</context></context-group>
</trans-unit>
- <trans-unit id="_msg1155">
+ <trans-unit id="_msg1176">
<source xml:space="preserve">Unknown change type &apos;%s&apos;</source>
- <context-group purpose="location"><context context-type="linenumber">359</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">381</context></context-group>
</trans-unit>
- <trans-unit id="_msg1156">
+ <trans-unit id="_msg1177">
<source xml:space="preserve">Unknown network specified in -onlynet: &apos;%s&apos;</source>
- <context-group purpose="location"><context context-type="linenumber">360</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">382</context></context-group>
</trans-unit>
- <trans-unit id="_msg1157">
+ <trans-unit id="_msg1178">
<source xml:space="preserve">Unknown new rules activated (versionbit %i)</source>
- <context-group purpose="location"><context context-type="linenumber">361</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">383</context></context-group>
</trans-unit>
- <trans-unit id="_msg1158">
+ <trans-unit id="_msg1179">
<source xml:space="preserve">Unsupported global logging level -loglevel=%s. Valid values: %s.</source>
- <context-group purpose="location"><context context-type="linenumber">362</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">384</context></context-group>
</trans-unit>
- <trans-unit id="_msg1159">
+ <trans-unit id="_msg1180">
<source xml:space="preserve">Unsupported logging category %s=%s.</source>
- <context-group purpose="location"><context context-type="linenumber">363</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">385</context></context-group>
</trans-unit>
- <trans-unit id="_msg1160">
+ <trans-unit id="_msg1181">
<source xml:space="preserve">User Agent comment (%s) contains unsafe characters.</source>
- <context-group purpose="location"><context context-type="linenumber">364</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">386</context></context-group>
</trans-unit>
- <trans-unit id="_msg1161">
+ <trans-unit id="_msg1182">
<source xml:space="preserve">Verifying blocks…</source>
- <context-group purpose="location"><context context-type="linenumber">365</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">387</context></context-group>
</trans-unit>
- <trans-unit id="_msg1162">
+ <trans-unit id="_msg1183">
<source xml:space="preserve">Verifying wallet(s)…</source>
- <context-group purpose="location"><context context-type="linenumber">366</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">388</context></context-group>
</trans-unit>
- <trans-unit id="_msg1163">
+ <trans-unit id="_msg1184">
<source xml:space="preserve">Wallet needed to be rewritten: restart %s to complete</source>
- <context-group purpose="location"><context context-type="linenumber">367</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">389</context></context-group>
+ </trans-unit>
+ <trans-unit id="_msg1185">
+ <source xml:space="preserve">Settings file could not be read</source>
+ <context-group purpose="location"><context context-type="linenumber">345</context></context-group>
+ </trans-unit>
+ <trans-unit id="_msg1186">
+ <source xml:space="preserve">Settings file could not be written</source>
+ <context-group purpose="location"><context context-type="linenumber">346</context></context-group>
</trans-unit>
</group>
</body></file>
diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp
index bee8fafddc..87a7e703b8 100644
--- a/src/qt/optionsmodel.cpp
+++ b/src/qt/optionsmodel.cpp
@@ -12,14 +12,14 @@
#include <qt/guiconstants.h>
#include <qt/guiutil.h>
+#include <common/args.h>
#include <interfaces/node.h>
#include <mapport.h>
#include <net.h>
#include <netbase.h>
-#include <txdb.h> // for -dbcache defaults
+#include <txdb.h> // for -dbcache defaults
#include <util/string.h>
-#include <util/system.h>
-#include <validation.h> // For DEFAULT_SCRIPTCHECK_THREADS
+#include <validation.h> // For DEFAULT_SCRIPTCHECK_THREADS
#include <wallet/wallet.h> // For DEFAULT_SPEND_ZEROCONF_CHANGE
#include <QDebug>
diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp
index 3f9d1b040b..592e591edb 100644
--- a/src/qt/paymentserver.cpp
+++ b/src/qt/paymentserver.cpp
@@ -13,11 +13,11 @@
#include <qt/optionsmodel.h>
#include <chainparams.h>
+#include <common/args.h>
#include <interfaces/node.h>
#include <key_io.h>
#include <node/interface_ui.h>
#include <policy/policy.h>
-#include <util/system.h>
#include <wallet/wallet.h>
#include <cstdlib>
diff --git a/src/qt/psbtoperationsdialog.cpp b/src/qt/psbtoperationsdialog.cpp
index 17a65be0fe..fe52e11157 100644
--- a/src/qt/psbtoperationsdialog.cpp
+++ b/src/qt/psbtoperationsdialog.cpp
@@ -5,7 +5,6 @@
#include <qt/psbtoperationsdialog.h>
#include <core_io.h>
-#include <fs.h>
#include <interfaces/node.h>
#include <key_io.h>
#include <node/psbt.h>
@@ -14,6 +13,7 @@
#include <qt/forms/ui_psbtoperationsdialog.h>
#include <qt/guiutil.h>
#include <qt/optionsmodel.h>
+#include <util/fs.h>
#include <util/strencodings.h>
#include <fstream>
@@ -31,7 +31,6 @@ PSBTOperationsDialog::PSBTOperationsDialog(
m_client_model(client_model)
{
m_ui->setupUi(this);
- setWindowTitle("PSBT Operations");
connect(m_ui->signTransactionButton, &QPushButton::clicked, this, &PSBTOperationsDialog::signTransaction);
connect(m_ui->broadcastTransactionButton, &QPushButton::clicked, this, &PSBTOperationsDialog::broadcastTransaction);
diff --git a/src/qt/receivecoinsdialog.cpp b/src/qt/receivecoinsdialog.cpp
index 22eb642ecd..be7741e8a8 100644
--- a/src/qt/receivecoinsdialog.cpp
+++ b/src/qt/receivecoinsdialog.cpp
@@ -93,11 +93,11 @@ void ReceiveCoinsDialog::setModel(WalletModel *_model)
ui->addressType->setItemData(index, tooltip, Qt::ToolTipRole);
if (model->wallet().getDefaultAddressType() == type) ui->addressType->setCurrentIndex(index);
};
- add_address_type(OutputType::LEGACY, "Base58 (Legacy)", "Not recommended due to higher fees and less protection against typos.");
- add_address_type(OutputType::P2SH_SEGWIT, "Base58 (P2SH-SegWit)", "Generates an address compatible with older wallets.");
- add_address_type(OutputType::BECH32, "Bech32 (SegWit)", "Generates a native segwit address (BIP-173). Some old wallets don't support it.");
+ add_address_type(OutputType::LEGACY, tr("Base58 (Legacy)"), tr("Not recommended due to higher fees and less protection against typos."));
+ add_address_type(OutputType::P2SH_SEGWIT, tr("Base58 (P2SH-SegWit)"), tr("Generates an address compatible with older wallets."));
+ add_address_type(OutputType::BECH32, tr("Bech32 (SegWit)"), tr("Generates a native segwit address (BIP-173). Some old wallets don't support it."));
if (model->wallet().taprootEnabled()) {
- add_address_type(OutputType::BECH32M, "Bech32m (Taproot)", "Bech32m (BIP-350) is an upgrade to Bech32, wallet support is still limited.");
+ add_address_type(OutputType::BECH32M, tr("Bech32m (Taproot)"), tr("Bech32m (BIP-350) is an upgrade to Bech32, wallet support is still limited."));
}
// Set the button to be enabled or disabled based on whether the wallet can give out new addresses.
diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp
index 0e712062af..76500a4a36 100644
--- a/src/qt/rpcconsole.cpp
+++ b/src/qt/rpcconsole.cpp
@@ -984,10 +984,11 @@ void RPCConsole::setMempoolSize(long numberOfTxs, size_t dynUsage)
{
ui->mempoolNumberTxs->setText(QString::number(numberOfTxs));
- if (dynUsage < 1000000)
- ui->mempoolSize->setText(QString::number(dynUsage/1000.0, 'f', 2) + " KB");
- else
- ui->mempoolSize->setText(QString::number(dynUsage/1000000.0, 'f', 2) + " MB");
+ if (dynUsage < 1000000) {
+ ui->mempoolSize->setText(QObject::tr("%1 kB").arg(dynUsage / 1000.0, 0, 'f', 2));
+ } else {
+ ui->mempoolSize->setText(QObject::tr("%1 MB").arg(dynUsage / 1000000.0, 0, 'f', 2));
+ }
}
void RPCConsole::on_lineEdit_returnPressed()
diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp
index 89dd0ada62..48f7fb6ad1 100644
--- a/src/qt/sendcoinsdialog.cpp
+++ b/src/qt/sendcoinsdialog.cpp
@@ -355,7 +355,8 @@ bool SendCoinsDialog::PrepareSendText(QString& question_string, QString& informa
question_string.append("</b>");
// append transaction size
- question_string.append(" (" + QString::number((double)m_current_transaction->getTransactionSize() / 1000) + " kB): ");
+ //: When reviewing a newly created PSBT (via Send flow), the transaction fee is shown, with "virtual size" of the transaction displayed for context
+ question_string.append(" (" + tr("%1 kvB", "PSBT transaction creation").arg((double)m_current_transaction->getTransactionSize() / 1000, 0, 'g', 3) + "): ");
// append transaction fee value
question_string.append("<span style='color:#aa0000; font-weight:bold;'>");
@@ -402,9 +403,10 @@ void SendCoinsDialog::presentPSBT(PartiallySignedTransaction& psbtx)
CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
ssTx << psbtx;
GUIUtil::setClipboard(EncodeBase64(ssTx.str()).c_str());
- QMessageBox msgBox;
- msgBox.setText("Unsigned Transaction");
- msgBox.setInformativeText("The PSBT has been copied to the clipboard. You can also save it.");
+ QMessageBox msgBox(this);
+ //: Caption of "PSBT has been copied" messagebox
+ msgBox.setText(tr("Unsigned Transaction", "PSBT copied"));
+ msgBox.setInformativeText(tr("The PSBT has been copied to the clipboard. You can also save it."));
msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Discard);
msgBox.setDefaultButton(QMessageBox::Discard);
switch (msgBox.exec()) {
@@ -432,7 +434,8 @@ void SendCoinsDialog::presentPSBT(PartiallySignedTransaction& psbtx)
std::ofstream out{filename.toLocal8Bit().data(), std::ofstream::out | std::ofstream::binary};
out << ssTx.str();
out.close();
- Q_EMIT message(tr("PSBT saved"), "PSBT saved to disk", CClientUIInterface::MSG_INFORMATION);
+ //: Popup message when a PSBT has been saved to a file
+ Q_EMIT message(tr("PSBT saved"), tr("PSBT saved to disk"), CClientUIInterface::MSG_INFORMATION);
break;
}
case QMessageBox::Discard:
@@ -452,12 +455,14 @@ bool SendCoinsDialog::signWithExternalSigner(PartiallySignedTransaction& psbtx,
}
if (err == TransactionError::EXTERNAL_SIGNER_NOT_FOUND) {
//: "External signer" means using devices such as hardware wallets.
- QMessageBox::critical(nullptr, tr("External signer not found"), "External signer not found");
+ const QString msg = tr("External signer not found");
+ QMessageBox::critical(nullptr, msg, msg);
return false;
}
if (err == TransactionError::EXTERNAL_SIGNER_FAILED) {
//: "External signer" means using devices such as hardware wallets.
- QMessageBox::critical(nullptr, tr("External signer failure"), "External signer failure");
+ const QString msg = tr("External signer failure");
+ QMessageBox::critical(nullptr, msg, msg);
return false;
}
if (err != TransactionError::OK) {
@@ -596,10 +601,15 @@ SendCoinsEntry *SendCoinsDialog::addEntry()
entry->clear();
entry->setFocus();
ui->scrollAreaWidgetContents->resize(ui->scrollAreaWidgetContents->sizeHint());
- qApp->processEvents();
- QScrollBar* bar = ui->scrollArea->verticalScrollBar();
- if(bar)
- bar->setSliderPosition(bar->maximum());
+
+ // Scroll to the newly added entry on a QueuedConnection because Qt doesn't
+ // adjust the scroll area and scrollbar immediately when the widget is added.
+ // Invoking on a DirectConnection will only scroll to the second-to-last entry.
+ QMetaObject::invokeMethod(ui->scrollArea, [this] {
+ if (ui->scrollArea->verticalScrollBar()) {
+ ui->scrollArea->verticalScrollBar()->setValue(ui->scrollArea->verticalScrollBar()->maximum());
+ }
+ }, Qt::QueuedConnection);
updateTabsAndLabels();
return entry;
@@ -781,8 +791,13 @@ void SendCoinsDialog::useAvailableBalance(SendCoinsEntry* entry)
// Include watch-only for wallets without private key
m_coin_control->fAllowWatchOnly = model->wallet().privateKeysDisabled() && !model->wallet().hasExternalSigner();
+ // Same behavior as send: if we have selected coins, only obtain their available balance.
+ // Copy to avoid modifying the member's data.
+ CCoinControl coin_control = *m_coin_control;
+ coin_control.m_allow_other_inputs = !coin_control.HasSelected();
+
// Calculate available amount to send.
- CAmount amount = model->getAvailableBalance(m_coin_control.get());
+ CAmount amount = model->getAvailableBalance(&coin_control);
for (int i = 0; i < ui->entries->count(); ++i) {
SendCoinsEntry* e = qobject_cast<SendCoinsEntry*>(ui->entries->itemAt(i)->widget());
if (e && !e->isHidden() && e != entry) {
@@ -818,7 +833,7 @@ void SendCoinsDialog::updateFeeMinimizedLabel()
if (ui->radioSmartFee->isChecked())
ui->labelFeeMinimized->setText(ui->labelSmartFee->text());
else {
- ui->labelFeeMinimized->setText(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), ui->customFee->value()) + "/kvB");
+ ui->labelFeeMinimized->setText(tr("%1/kvB").arg(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), ui->customFee->value())));
}
}
@@ -853,7 +868,7 @@ void SendCoinsDialog::updateSmartFeeLabel()
FeeReason reason;
CFeeRate feeRate = CFeeRate(model->wallet().getMinimumFee(1000, *m_coin_control, &returned_target, &reason));
- ui->labelSmartFee->setText(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), feeRate.GetFeePerK()) + "/kvB");
+ ui->labelSmartFee->setText(tr("%1/kvB").arg(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), feeRate.GetFeePerK())));
if (reason == FeeReason::FALLBACK) {
ui->labelSmartFee2->show(); // (Smart fee not initialized yet. This usually takes a few blocks...)
diff --git a/src/qt/sendcoinsdialog.h b/src/qt/sendcoinsdialog.h
index 2fcdf5b32a..ac05cd98e5 100644
--- a/src/qt/sendcoinsdialog.h
+++ b/src/qt/sendcoinsdialog.h
@@ -49,6 +49,9 @@ public:
void pasteEntry(const SendCoinsRecipient &rv);
bool handlePaymentRequest(const SendCoinsRecipient &recipient);
+ // Only used for testing-purposes
+ wallet::CCoinControl* getCoinControl() { return m_coin_control.get(); }
+
public Q_SLOTS:
void clear();
void reject() override;
diff --git a/src/qt/test/addressbooktests.cpp b/src/qt/test/addressbooktests.cpp
index d005e08d14..5706964cc9 100644
--- a/src/qt/test/addressbooktests.cpp
+++ b/src/qt/test/addressbooktests.cpp
@@ -113,8 +113,8 @@ void TestAddAddressesToSendBook(interfaces::Node& node)
{
LOCK(wallet->cs_wallet);
- wallet->SetAddressBook(r_key_dest, r_label.toStdString(), "receive");
- wallet->SetAddressBook(s_key_dest, s_label.toStdString(), "send");
+ wallet->SetAddressBook(r_key_dest, r_label.toStdString(), wallet::AddressPurpose::RECEIVE);
+ wallet->SetAddressBook(s_key_dest, s_label.toStdString(), wallet::AddressPurpose::SEND);
}
auto check_addbook_size = [&wallet](int expected_size) {
diff --git a/src/qt/test/optiontests.cpp b/src/qt/test/optiontests.cpp
index dc7c8928c5..0838e21678 100644
--- a/src/qt/test/optiontests.cpp
+++ b/src/qt/test/optiontests.cpp
@@ -2,12 +2,12 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#include <common/args.h>
#include <init.h>
#include <qt/bitcoin.h>
#include <qt/guiutil.h>
#include <qt/test/optiontests.h>
#include <test/util/setup_common.h>
-#include <util/system.h>
#include <QSettings>
#include <QTest>
diff --git a/src/qt/test/wallettests.cpp b/src/qt/test/wallettests.cpp
index 62f2019438..072718fe15 100644
--- a/src/qt/test/wallettests.cpp
+++ b/src/qt/test/wallettests.cpp
@@ -5,6 +5,7 @@
#include <qt/test/wallettests.h>
#include <qt/test/util.h>
+#include <wallet/coincontrol.h>
#include <interfaces/chain.h>
#include <interfaces/node.h>
#include <key_io.h>
@@ -34,6 +35,8 @@
#include <QAction>
#include <QApplication>
#include <QCheckBox>
+#include <QClipboard>
+#include <QObject>
#include <QPushButton>
#include <QTimer>
#include <QVBoxLayout>
@@ -46,6 +49,7 @@ using wallet::CWallet;
using wallet::CreateMockWalletDatabase;
using wallet::RemoveWallet;
using wallet::WALLET_FLAG_DESCRIPTORS;
+using wallet::WALLET_FLAG_DISABLE_PRIVATE_KEYS;
using wallet::WalletContext;
using wallet::WalletDescriptor;
using wallet::WalletRescanReserver;
@@ -53,14 +57,14 @@ using wallet::WalletRescanReserver;
namespace
{
//! Press "Yes" or "Cancel" buttons in modal send confirmation dialog.
-void ConfirmSend(QString* text = nullptr, bool cancel = false)
+void ConfirmSend(QString* text = nullptr, QMessageBox::StandardButton confirm_type = QMessageBox::Yes)
{
- QTimer::singleShot(0, [text, cancel]() {
+ QTimer::singleShot(0, [text, confirm_type]() {
for (QWidget* widget : QApplication::topLevelWidgets()) {
if (widget->inherits("SendConfirmationDialog")) {
SendConfirmationDialog* dialog = qobject_cast<SendConfirmationDialog*>(widget);
if (text) *text = dialog->text();
- QAbstractButton* button = dialog->button(cancel ? QMessageBox::Cancel : QMessageBox::Yes);
+ QAbstractButton* button = dialog->button(confirm_type);
button->setEnabled(true);
button->click();
}
@@ -69,7 +73,8 @@ void ConfirmSend(QString* text = nullptr, bool cancel = false)
}
//! Send coins to address and return txid.
-uint256 SendCoins(CWallet& wallet, SendCoinsDialog& sendCoinsDialog, const CTxDestination& address, CAmount amount, bool rbf)
+uint256 SendCoins(CWallet& wallet, SendCoinsDialog& sendCoinsDialog, const CTxDestination& address, CAmount amount, bool rbf,
+ QMessageBox::StandardButton confirm_type = QMessageBox::Yes)
{
QVBoxLayout* entries = sendCoinsDialog.findChild<QVBoxLayout*>("entries");
SendCoinsEntry* entry = qobject_cast<SendCoinsEntry*>(entries->itemAt(0)->widget());
@@ -83,7 +88,7 @@ uint256 SendCoins(CWallet& wallet, SendCoinsDialog& sendCoinsDialog, const CTxDe
boost::signals2::scoped_connection c(wallet.NotifyTransactionChanged.connect([&txid](const uint256& hash, ChangeType status) {
if (status == CT_NEW) txid = hash;
}));
- ConfirmSend();
+ ConfirmSend(/*text=*/nullptr, confirm_type);
bool invoked = QMetaObject::invokeMethod(&sendCoinsDialog, "sendButtonClicked", Q_ARG(bool, false));
assert(invoked);
return txid;
@@ -121,7 +126,7 @@ void BumpFee(TransactionView& view, const uint256& txid, bool expectDisabled, st
action->setEnabled(true);
QString text;
if (expectError.empty()) {
- ConfirmSend(&text, cancel);
+ ConfirmSend(&text, cancel ? QMessageBox::Cancel : QMessageBox::Yes);
} else {
ConfirmMessage(&text, 0ms);
}
@@ -136,6 +141,119 @@ void CompareBalance(WalletModel& walletModel, CAmount expected_balance, QLabel*
QCOMPARE(balance_label_to_check->text().trimmed(), balanceComparison);
}
+// Verify the 'useAvailableBalance' functionality. With and without manually selected coins.
+// Case 1: No coin control selected coins.
+// 'useAvailableBalance' should fill the amount edit box with the total available balance
+// Case 2: With coin control selected coins.
+// 'useAvailableBalance' should fill the amount edit box with the sum of the selected coins values.
+void VerifyUseAvailableBalance(SendCoinsDialog& sendCoinsDialog, const WalletModel& walletModel)
+{
+ // Verify first entry amount and "useAvailableBalance" button
+ QVBoxLayout* entries = sendCoinsDialog.findChild<QVBoxLayout*>("entries");
+ QVERIFY(entries->count() == 1); // only one entry
+ SendCoinsEntry* send_entry = qobject_cast<SendCoinsEntry*>(entries->itemAt(0)->widget());
+ QVERIFY(send_entry->getValue().amount == 0);
+ // Now click "useAvailableBalance", check updated balance (the entire wallet balance should be set)
+ Q_EMIT send_entry->useAvailableBalance(send_entry);
+ QVERIFY(send_entry->getValue().amount == walletModel.getCachedBalance().balance);
+
+ // Now manually select two coins and click on "useAvailableBalance". Then check updated balance
+ // (only the sum of the selected coins should be set).
+ int COINS_TO_SELECT = 2;
+ auto coins = walletModel.wallet().listCoins();
+ CAmount sum_selected_coins = 0;
+ int selected = 0;
+ QVERIFY(coins.size() == 1); // context check, coins received only on one destination
+ for (const auto& [outpoint, tx_out] : coins.begin()->second) {
+ sendCoinsDialog.getCoinControl()->Select(outpoint);
+ sum_selected_coins += tx_out.txout.nValue;
+ if (++selected == COINS_TO_SELECT) break;
+ }
+ QVERIFY(selected == COINS_TO_SELECT);
+
+ // Now that we have 2 coins selected, "useAvailableBalance" should update the balance label only with
+ // the sum of them.
+ Q_EMIT send_entry->useAvailableBalance(send_entry);
+ QVERIFY(send_entry->getValue().amount == sum_selected_coins);
+}
+
+void SyncUpWallet(const std::shared_ptr<CWallet>& wallet, interfaces::Node& node)
+{
+ WalletRescanReserver reserver(*wallet);
+ reserver.reserve();
+ CWallet::ScanResult result = wallet->ScanForWalletTransactions(Params().GetConsensus().hashGenesisBlock, /*start_height=*/0, /*max_height=*/{}, reserver, /*fUpdate=*/true, /*save_progress=*/false);
+ QCOMPARE(result.status, CWallet::ScanResult::SUCCESS);
+ QCOMPARE(result.last_scanned_block, WITH_LOCK(node.context()->chainman->GetMutex(), return node.context()->chainman->ActiveChain().Tip()->GetBlockHash()));
+ QVERIFY(result.last_failed_block.IsNull());
+}
+
+std::shared_ptr<CWallet> SetupLegacyWatchOnlyWallet(interfaces::Node& node, TestChain100Setup& test)
+{
+ std::shared_ptr<CWallet> wallet = std::make_shared<CWallet>(node.context()->chain.get(), "", CreateMockWalletDatabase());
+ wallet->LoadWallet();
+ {
+ LOCK(wallet->cs_wallet);
+ wallet->SetWalletFlag(WALLET_FLAG_DISABLE_PRIVATE_KEYS);
+ wallet->SetupLegacyScriptPubKeyMan();
+ // Add watched key
+ CPubKey pubKey = test.coinbaseKey.GetPubKey();
+ bool import_keys = wallet->ImportPubKeys({pubKey.GetID()}, {{pubKey.GetID(), pubKey}} , /*key_origins=*/{}, /*add_keypool=*/false, /*internal=*/false, /*timestamp=*/1);
+ assert(import_keys);
+ wallet->SetLastBlockProcessed(105, WITH_LOCK(node.context()->chainman->GetMutex(), return node.context()->chainman->ActiveChain().Tip()->GetBlockHash()));
+ }
+ SyncUpWallet(wallet, node);
+ return wallet;
+}
+
+std::shared_ptr<CWallet> SetupDescriptorsWallet(interfaces::Node& node, TestChain100Setup& test)
+{
+ std::shared_ptr<CWallet> wallet = std::make_shared<CWallet>(node.context()->chain.get(), "", CreateMockWalletDatabase());
+ wallet->LoadWallet();
+ LOCK(wallet->cs_wallet);
+ wallet->SetWalletFlag(WALLET_FLAG_DESCRIPTORS);
+ wallet->SetupDescriptorScriptPubKeyMans();
+
+ // Add the coinbase key
+ FlatSigningProvider provider;
+ std::string error;
+ std::unique_ptr<Descriptor> desc = Parse("combo(" + EncodeSecret(test.coinbaseKey) + ")", provider, error, /* require_checksum=*/ false);
+ assert(desc);
+ WalletDescriptor w_desc(std::move(desc), 0, 0, 1, 1);
+ if (!wallet->AddWalletDescriptor(w_desc, provider, "", false)) assert(false);
+ CTxDestination dest = GetDestinationForKey(test.coinbaseKey.GetPubKey(), wallet->m_default_address_type);
+ wallet->SetAddressBook(dest, "", wallet::AddressPurpose::RECEIVE);
+ wallet->SetLastBlockProcessed(105, WITH_LOCK(node.context()->chainman->GetMutex(), return node.context()->chainman->ActiveChain().Tip()->GetBlockHash()));
+ SyncUpWallet(wallet, node);
+ wallet->SetBroadcastTransactions(true);
+ return wallet;
+}
+
+struct MiniGUI {
+public:
+ SendCoinsDialog sendCoinsDialog;
+ TransactionView transactionView;
+ OptionsModel optionsModel;
+ std::unique_ptr<ClientModel> clientModel;
+ std::unique_ptr<WalletModel> walletModel;
+
+ MiniGUI(interfaces::Node& node, const PlatformStyle* platformStyle) : sendCoinsDialog(platformStyle), transactionView(platformStyle), optionsModel(node) {
+ bilingual_str error;
+ QVERIFY(optionsModel.Init(error));
+ clientModel = std::make_unique<ClientModel>(node, &optionsModel);
+ }
+
+ void initModelForWallet(interfaces::Node& node, const std::shared_ptr<CWallet>& wallet, const PlatformStyle* platformStyle)
+ {
+ WalletContext& context = *node.walletLoader().context();
+ AddWallet(context, wallet);
+ walletModel = std::make_unique<WalletModel>(interfaces::MakeWallet(context, wallet), *clientModel, platformStyle);
+ RemoveWallet(context, wallet, /* load_on_start= */ std::nullopt);
+ sendCoinsDialog.setModel(walletModel.get());
+ transactionView.setModel(walletModel.get());
+ }
+
+};
+
//! Simple qt wallet tests.
//
// Test widgets can be debugged interactively calling show() on them and
@@ -149,69 +267,31 @@ void CompareBalance(WalletModel& walletModel, CAmount expected_balance, QLabel*
// QT_QPA_PLATFORM=xcb src/qt/test/test_bitcoin-qt # Linux
// QT_QPA_PLATFORM=windows src/qt/test/test_bitcoin-qt # Windows
// QT_QPA_PLATFORM=cocoa src/qt/test/test_bitcoin-qt # macOS
-void TestGUI(interfaces::Node& node)
+void TestGUI(interfaces::Node& node, const std::shared_ptr<CWallet>& wallet)
{
- // Set up wallet and chain with 105 blocks (5 mature blocks for spending).
- TestChain100Setup test;
- for (int i = 0; i < 5; ++i) {
- test.CreateAndProcessBlock({}, GetScriptForRawPubKey(test.coinbaseKey.GetPubKey()));
- }
- auto wallet_loader = interfaces::MakeWalletLoader(*test.m_node.chain, *Assert(test.m_node.args));
- test.m_node.wallet_loader = wallet_loader.get();
- node.setContext(&test.m_node);
- const std::shared_ptr<CWallet> wallet = std::make_shared<CWallet>(node.context()->chain.get(), "", CreateMockWalletDatabase());
- wallet->LoadWallet();
- wallet->SetWalletFlag(WALLET_FLAG_DESCRIPTORS);
- {
- LOCK(wallet->cs_wallet);
- wallet->SetupDescriptorScriptPubKeyMans();
-
- // Add the coinbase key
- FlatSigningProvider provider;
- std::string error;
- std::unique_ptr<Descriptor> desc = Parse("combo(" + EncodeSecret(test.coinbaseKey) + ")", provider, error, /* require_checksum=*/ false);
- assert(desc);
- WalletDescriptor w_desc(std::move(desc), 0, 0, 1, 1);
- if (!wallet->AddWalletDescriptor(w_desc, provider, "", false)) assert(false);
- CTxDestination dest = GetDestinationForKey(test.coinbaseKey.GetPubKey(), wallet->m_default_address_type);
- wallet->SetAddressBook(dest, "", "receive");
- wallet->SetLastBlockProcessed(105, WITH_LOCK(node.context()->chainman->GetMutex(), return node.context()->chainman->ActiveChain().Tip()->GetBlockHash()));
- }
- {
- WalletRescanReserver reserver(*wallet);
- reserver.reserve();
- CWallet::ScanResult result = wallet->ScanForWalletTransactions(Params().GetConsensus().hashGenesisBlock, /*start_height=*/0, /*max_height=*/{}, reserver, /*fUpdate=*/true, /*save_progress=*/false);
- QCOMPARE(result.status, CWallet::ScanResult::SUCCESS);
- QCOMPARE(result.last_scanned_block, WITH_LOCK(node.context()->chainman->GetMutex(), return node.context()->chainman->ActiveChain().Tip()->GetBlockHash()));
- QVERIFY(result.last_failed_block.IsNull());
- }
- wallet->SetBroadcastTransactions(true);
-
// Create widgets for sending coins and listing transactions.
std::unique_ptr<const PlatformStyle> platformStyle(PlatformStyle::instantiate("other"));
- SendCoinsDialog sendCoinsDialog(platformStyle.get());
- TransactionView transactionView(platformStyle.get());
- OptionsModel optionsModel(node);
- bilingual_str error;
- QVERIFY(optionsModel.Init(error));
- ClientModel clientModel(node, &optionsModel);
- WalletContext& context = *node.walletLoader().context();
- AddWallet(context, wallet);
- WalletModel walletModel(interfaces::MakeWallet(context, wallet), clientModel, platformStyle.get());
- RemoveWallet(context, wallet, /* load_on_start= */ std::nullopt);
- sendCoinsDialog.setModel(&walletModel);
- transactionView.setModel(&walletModel);
+ MiniGUI mini_gui(node, platformStyle.get());
+ mini_gui.initModelForWallet(node, wallet, platformStyle.get());
+ WalletModel& walletModel = *mini_gui.walletModel;
+ SendCoinsDialog& sendCoinsDialog = mini_gui.sendCoinsDialog;
+ TransactionView& transactionView = mini_gui.transactionView;
// Update walletModel cached balance which will trigger an update for the 'labelBalance' QLabel.
walletModel.pollBalanceChanged();
// Check balance in send dialog
CompareBalance(walletModel, walletModel.wallet().getBalance(), sendCoinsDialog.findChild<QLabel*>("labelBalance"));
+ // Check 'UseAvailableBalance' functionality
+ VerifyUseAvailableBalance(sendCoinsDialog, walletModel);
+
// Send two transactions, and verify they are added to transaction list.
TransactionTableModel* transactionTableModel = walletModel.getTransactionTableModel();
QCOMPARE(transactionTableModel->rowCount({}), 105);
uint256 txid1 = SendCoins(*wallet.get(), sendCoinsDialog, PKHash(), 5 * COIN, /*rbf=*/false);
uint256 txid2 = SendCoins(*wallet.get(), sendCoinsDialog, PKHash(), 10 * COIN, /*rbf=*/true);
+ // Transaction table model updates on a QueuedConnection, so process events to ensure it's updated.
+ qApp->processEvents();
QCOMPARE(transactionTableModel->rowCount({}), 107);
QVERIFY(FindTx(*transactionTableModel, txid1).isValid());
QVERIFY(FindTx(*transactionTableModel, txid2).isValid());
@@ -311,6 +391,76 @@ void TestGUI(interfaces::Node& node)
QCOMPARE(walletModel.wallet().getAddressReceiveRequests().size(), size_t{0});
}
+void TestGUIWatchOnly(interfaces::Node& node, TestChain100Setup& test)
+{
+ const std::shared_ptr<CWallet>& wallet = SetupLegacyWatchOnlyWallet(node, test);
+
+ // Create widgets and init models
+ std::unique_ptr<const PlatformStyle> platformStyle(PlatformStyle::instantiate("other"));
+ MiniGUI mini_gui(node, platformStyle.get());
+ mini_gui.initModelForWallet(node, wallet, platformStyle.get());
+ WalletModel& walletModel = *mini_gui.walletModel;
+ SendCoinsDialog& sendCoinsDialog = mini_gui.sendCoinsDialog;
+
+ // Update walletModel cached balance which will trigger an update for the 'labelBalance' QLabel.
+ walletModel.pollBalanceChanged();
+ // Check balance in send dialog
+ CompareBalance(walletModel, walletModel.wallet().getBalances().watch_only_balance,
+ sendCoinsDialog.findChild<QLabel*>("labelBalance"));
+
+ // Set change address
+ sendCoinsDialog.getCoinControl()->destChange = GetDestinationForKey(test.coinbaseKey.GetPubKey(), OutputType::LEGACY);
+
+ // Time to reject "save" PSBT dialog ('SendCoins' locks the main thread until the dialog receives the event).
+ QTimer timer;
+ timer.setInterval(500);
+ QObject::connect(&timer, &QTimer::timeout, [&](){
+ for (QWidget* widget : QApplication::topLevelWidgets()) {
+ if (widget->inherits("QMessageBox")) {
+ QMessageBox* dialog = qobject_cast<QMessageBox*>(widget);
+ QAbstractButton* button = dialog->button(QMessageBox::Discard);
+ button->setEnabled(true);
+ button->click();
+ timer.stop();
+ break;
+ }
+ }
+ });
+ timer.start(500);
+
+ // Send tx and verify PSBT copied to the clipboard.
+ SendCoins(*wallet.get(), sendCoinsDialog, PKHash(), 5 * COIN, /*rbf=*/false, QMessageBox::Save);
+ const std::string& psbt_string = QApplication::clipboard()->text().toStdString();
+ QVERIFY(!psbt_string.empty());
+
+ // Decode psbt
+ std::optional<std::vector<unsigned char>> decoded_psbt = DecodeBase64(psbt_string);
+ QVERIFY(decoded_psbt);
+ PartiallySignedTransaction psbt;
+ std::string err;
+ QVERIFY(DecodeRawPSBT(psbt, MakeByteSpan(*decoded_psbt), err));
+}
+
+void TestGUI(interfaces::Node& node)
+{
+ // Set up wallet and chain with 105 blocks (5 mature blocks for spending).
+ TestChain100Setup test;
+ for (int i = 0; i < 5; ++i) {
+ test.CreateAndProcessBlock({}, GetScriptForRawPubKey(test.coinbaseKey.GetPubKey()));
+ }
+ auto wallet_loader = interfaces::MakeWalletLoader(*test.m_node.chain, *Assert(test.m_node.args));
+ test.m_node.wallet_loader = wallet_loader.get();
+ node.setContext(&test.m_node);
+
+ // "Full" GUI tests, use descriptor wallet
+ const std::shared_ptr<CWallet>& desc_wallet = SetupDescriptorsWallet(node, test);
+ TestGUI(node, desc_wallet);
+
+ // Legacy watch-only wallet test
+ // Verify PSBT creation.
+ TestGUIWatchOnly(node, test);
+}
+
} // namespace
void WalletTests::walletTests()
diff --git a/src/qt/trafficgraphwidget.cpp b/src/qt/trafficgraphwidget.cpp
index 08789c1048..fb6f2cb464 100644
--- a/src/qt/trafficgraphwidget.cpp
+++ b/src/qt/trafficgraphwidget.cpp
@@ -68,8 +68,8 @@ void TrafficGraphWidget::paintEvent(QPaintEvent *)
painter.drawLine(XMARGIN, YMARGIN + h, width() - XMARGIN, YMARGIN + h);
// decide what order of magnitude we are
- int base = floor(log10(fMax));
- float val = pow(10.0f, base);
+ int base = std::floor(std::log10(fMax));
+ float val = std::pow(10.0f, base);
const QString units = tr("kB/s");
const float yMarginText = 2.0;
diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp
index 2ced44241f..2461a06930 100644
--- a/src/qt/transactiondesc.cpp
+++ b/src/qt/transactiondesc.cpp
@@ -20,7 +20,7 @@
#include <policy/policy.h>
#include <util/system.h>
#include <validation.h>
-#include <wallet/ismine.h>
+#include <wallet/types.h>
#include <stdint.h>
#include <string>
@@ -248,9 +248,9 @@ QString TransactionDesc::toHTML(interfaces::Node& node, interfaces::Wallet& wall
strHTML += GUIUtil::HtmlEscape(name) + " ";
strHTML += GUIUtil::HtmlEscape(EncodeDestination(address));
if(toSelf == ISMINE_SPENDABLE)
- strHTML += " (own address)";
+ strHTML += " (" + tr("own address") + ")";
else if(toSelf & ISMINE_WATCH_ONLY)
- strHTML += " (watch-only)";
+ strHTML += " (" + tr("watch-only") + ")";
strHTML += "<br>";
}
}
diff --git a/src/qt/transactionrecord.cpp b/src/qt/transactionrecord.cpp
index 5f981ea250..1d2f6484fb 100644
--- a/src/qt/transactionrecord.cpp
+++ b/src/qt/transactionrecord.cpp
@@ -7,7 +7,7 @@
#include <chain.h>
#include <interfaces/wallet.h>
#include <key_io.h>
-#include <wallet/ismine.h>
+#include <wallet/types.h>
#include <stdint.h>
diff --git a/src/qt/utilitydialog.cpp b/src/qt/utilitydialog.cpp
index eb2ab12a66..f43b993628 100644
--- a/src/qt/utilitydialog.cpp
+++ b/src/qt/utilitydialog.cpp
@@ -13,8 +13,8 @@
#include <qt/guiutil.h>
#include <clientversion.h>
+#include <common/args.h>
#include <init.h>
-#include <util/system.h>
#include <util/strencodings.h>
#include <cstdio>
diff --git a/src/qt/walletframe.cpp b/src/qt/walletframe.cpp
index 43411370a2..7a8a053900 100644
--- a/src/qt/walletframe.cpp
+++ b/src/qt/walletframe.cpp
@@ -4,7 +4,6 @@
#include <qt/walletframe.h>
-#include <fs.h>
#include <node/interface_ui.h>
#include <psbt.h>
#include <qt/guiutil.h>
@@ -12,7 +11,8 @@
#include <qt/psbtoperationsdialog.h>
#include <qt/walletmodel.h>
#include <qt/walletview.h>
-#include <util/system.h>
+#include <util/fs.h>
+#include <util/fs_helpers.h>
#include <cassert>
#include <fstream>
diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp
index 3c69d46b7e..ee3327530c 100644
--- a/src/qt/walletmodel.cpp
+++ b/src/qt/walletmodel.cpp
@@ -18,12 +18,12 @@
#include <qt/sendcoinsdialog.h>
#include <qt/transactiontablemodel.h>
+#include <common/args.h> // for GetBoolArg
#include <interfaces/handler.h>
#include <interfaces/node.h>
#include <key_io.h>
#include <node/interface_ui.h>
#include <psbt.h>
-#include <util/system.h> // for GetBoolArg
#include <util/translation.h>
#include <wallet/coincontrol.h>
#include <wallet/wallet.h> // for CRecipient
@@ -138,7 +138,7 @@ void WalletModel::updateTransaction()
}
void WalletModel::updateAddressBook(const QString &address, const QString &label,
- bool isMine, const QString &purpose, int status)
+ bool isMine, wallet::AddressPurpose purpose, int status)
{
if(addressTableModel)
addressTableModel->updateEntry(address, label, isMine, purpose, status);
@@ -280,11 +280,11 @@ void WalletModel::sendCoins(WalletModelTransaction& transaction)
if (!m_wallet->getAddress(
dest, &name, /* is_mine= */ nullptr, /* purpose= */ nullptr))
{
- m_wallet->setAddressBook(dest, strLabel, "send");
+ m_wallet->setAddressBook(dest, strLabel, wallet::AddressPurpose::SEND);
}
else if (name != strLabel)
{
- m_wallet->setAddressBook(dest, strLabel, ""); // "" means don't change purpose
+ m_wallet->setAddressBook(dest, strLabel, {}); // {} means don't change purpose
}
}
}
@@ -377,18 +377,17 @@ static void NotifyKeyStoreStatusChanged(WalletModel *walletmodel)
static void NotifyAddressBookChanged(WalletModel *walletmodel,
const CTxDestination &address, const std::string &label, bool isMine,
- const std::string &purpose, ChangeType status)
+ wallet::AddressPurpose purpose, ChangeType status)
{
QString strAddress = QString::fromStdString(EncodeDestination(address));
QString strLabel = QString::fromStdString(label);
- QString strPurpose = QString::fromStdString(purpose);
- qDebug() << "NotifyAddressBookChanged: " + strAddress + " " + strLabel + " isMine=" + QString::number(isMine) + " purpose=" + strPurpose + " status=" + QString::number(status);
+ qDebug() << "NotifyAddressBookChanged: " + strAddress + " " + strLabel + " isMine=" + QString::number(isMine) + " purpose=" + QString::number(static_cast<uint8_t>(purpose)) + " status=" + QString::number(status);
bool invoked = QMetaObject::invokeMethod(walletmodel, "updateAddressBook",
Q_ARG(QString, strAddress),
Q_ARG(QString, strLabel),
Q_ARG(bool, isMine),
- Q_ARG(QString, strPurpose),
+ Q_ARG(wallet::AddressPurpose, purpose),
Q_ARG(int, status));
assert(invoked);
}
@@ -548,7 +547,7 @@ bool WalletModel::bumpFee(uint256 hash, uint256& new_hash)
CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
ssTx << psbtx;
GUIUtil::setClipboard(EncodeBase64(ssTx.str()).c_str());
- Q_EMIT message(tr("PSBT copied"), "Copied to clipboard", CClientUIInterface::MSG_INFORMATION);
+ Q_EMIT message(tr("PSBT copied"), tr("Copied to clipboard", "Fee-bump PSBT saved"), CClientUIInterface::MSG_INFORMATION);
return true;
}
@@ -613,5 +612,17 @@ uint256 WalletModel::getLastBlockProcessed() const
CAmount WalletModel::getAvailableBalance(const CCoinControl* control)
{
- return control && control->HasSelected() ? wallet().getAvailableBalance(*control) : getCachedBalance().balance;
+ // No selected coins, return the cached balance
+ if (!control || !control->HasSelected()) {
+ const interfaces::WalletBalances& balances = getCachedBalance();
+ CAmount available_balance = balances.balance;
+ // if wallet private keys are disabled, this is a watch-only wallet
+ // so, let's include the watch-only balance.
+ if (balances.have_watch_only && m_wallet->privateKeysDisabled()) {
+ available_balance += balances.watch_only_balance;
+ }
+ return available_balance;
+ }
+ // Fetch balance from the wallet, taking into account the selected coins
+ return wallet().getAvailableBalance(*control);
}
diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h
index 17a39349f3..4f75d41404 100644
--- a/src/qt/walletmodel.h
+++ b/src/qt/walletmodel.h
@@ -236,7 +236,7 @@ public Q_SLOTS:
/* New transaction, or transaction changed status */
void updateTransaction();
/* New, updated or removed address book entry */
- void updateAddressBook(const QString &address, const QString &label, bool isMine, const QString &purpose, int status);
+ void updateAddressBook(const QString &address, const QString &label, bool isMine, wallet::AddressPurpose purpose, int status);
/* Watch-only added */
void updateWatchOnlyFlag(bool fHaveWatchonly);
/* Current, immature or unconfirmed balance might have changed - emit 'balanceChanged' if so */
diff --git a/src/randomenv.cpp b/src/randomenv.cpp
index 3e4d5a587d..581612bccf 100644
--- a/src/randomenv.cpp
+++ b/src/randomenv.cpp
@@ -24,11 +24,12 @@
#include <thread>
#include <vector>
+#include <sys/types.h> // must go before a number of other headers
+
#ifdef WIN32
#include <windows.h>
#include <winreg.h>
#else
-#include <sys/types.h> // must go before a number of other headers
#include <fcntl.h>
#include <netinet/in.h>
#include <sys/resource.h>
diff --git a/src/rest.cpp b/src/rest.cpp
index fa119ddfb7..e46406f1ad 100644
--- a/src/rest.cpp
+++ b/src/rest.cpp
@@ -200,7 +200,11 @@ static bool rest_headers(const std::any& context,
} else if (path.size() == 1) {
// new path with query parameter: /rest/headers/<hash>?count=<count>
hashStr = path[0];
- raw_count = req->GetQueryParameter("count").value_or("5");
+ try {
+ raw_count = req->GetQueryParameter("count").value_or("5");
+ } catch (const std::runtime_error& e) {
+ return RESTERR(req, HTTP_BAD_REQUEST, e.what());
+ }
} else {
return RESTERR(req, HTTP_BAD_REQUEST, "Invalid URI format. Expected /rest/headers/<hash>.<ext>?count=<count>");
}
@@ -371,7 +375,11 @@ static bool rest_filter_header(const std::any& context, HTTPRequest* req, const
} else if (uri_parts.size() == 2) {
// new path with query parameter: /rest/blockfilterheaders/<filtertype>/<blockhash>?count=<count>
raw_blockhash = uri_parts[1];
- raw_count = req->GetQueryParameter("count").value_or("5");
+ try {
+ raw_count = req->GetQueryParameter("count").value_or("5");
+ } catch (const std::runtime_error& e) {
+ return RESTERR(req, HTTP_BAD_REQUEST, e.what());
+ }
} else {
return RESTERR(req, HTTP_BAD_REQUEST, "Invalid URI format. Expected /rest/blockfilterheaders/<filtertype>/<blockhash>.<ext>?count=<count>");
}
@@ -652,11 +660,21 @@ static bool rest_mempool(const std::any& context, HTTPRequest* req, const std::s
case RESTResponseFormat::JSON: {
std::string str_json;
if (param == "contents") {
- const std::string raw_verbose{req->GetQueryParameter("verbose").value_or("true")};
+ std::string raw_verbose;
+ try {
+ raw_verbose = req->GetQueryParameter("verbose").value_or("true");
+ } catch (const std::runtime_error& e) {
+ return RESTERR(req, HTTP_BAD_REQUEST, e.what());
+ }
if (raw_verbose != "true" && raw_verbose != "false") {
return RESTERR(req, HTTP_BAD_REQUEST, "The \"verbose\" query parameter must be either \"true\" or \"false\".");
}
- const std::string raw_mempool_sequence{req->GetQueryParameter("mempool_sequence").value_or("false")};
+ std::string raw_mempool_sequence;
+ try {
+ raw_mempool_sequence = req->GetQueryParameter("mempool_sequence").value_or("false");
+ } catch (const std::runtime_error& e) {
+ return RESTERR(req, HTTP_BAD_REQUEST, e.what());
+ }
if (raw_mempool_sequence != "true" && raw_mempool_sequence != "false") {
return RESTERR(req, HTTP_BAD_REQUEST, "The \"mempool_sequence\" query parameter must be either \"true\" or \"false\".");
}
diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp
index 1a9b265fbe..11484a9d8d 100644
--- a/src/rpc/blockchain.cpp
+++ b/src/rpc/blockchain.cpp
@@ -9,13 +9,13 @@
#include <chain.h>
#include <chainparams.h>
#include <coins.h>
+#include <common/args.h>
#include <consensus/amount.h>
#include <consensus/params.h>
#include <consensus/validation.h>
#include <core_io.h>
#include <deploymentinfo.h>
#include <deploymentstatus.h>
-#include <fs.h>
#include <hash.h>
#include <index/blockfilterindex.h>
#include <index/coinstatsindex.h>
@@ -39,8 +39,8 @@
#include <undo.h>
#include <univalue.h>
#include <util/check.h>
+#include <util/fs.h>
#include <util/strencodings.h>
-#include <util/system.h>
#include <util/translation.h>
#include <validation.h>
#include <validationinterface.h>
@@ -2325,6 +2325,7 @@ static RPCHelpMan scanblocks()
{RPCResult::Type::ARR, "relevant_blocks", "Blocks that may have matched a scanobject.", {
{RPCResult::Type::STR_HEX, "blockhash", "A relevant blockhash"},
}},
+ {RPCResult::Type::BOOL, "completed", "true if the scan process was not aborted"}
}},
RPCResult{"when action=='status' and a scan is currently in progress", RPCResult::Type::OBJ, "", "", {
{RPCResult::Type::NUM, "progress", "Approximate percent complete"},
@@ -2362,8 +2363,7 @@ static RPCHelpMan scanblocks()
// set the abort flag
g_scanfilter_should_abort_scan = true;
return true;
- }
- else if (request.params[0].get_str() == "start") {
+ } else if (request.params[0].get_str() == "start") {
BlockFiltersScanReserver reserver;
if (!reserver.reserve()) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Scan already in progress, use action \"abort\" or \"status\"");
@@ -2387,27 +2387,28 @@ static RPCHelpMan scanblocks()
ChainstateManager& chainman = EnsureChainman(node);
// set the start-height
- const CBlockIndex* block = nullptr;
+ const CBlockIndex* start_index = nullptr;
const CBlockIndex* stop_block = nullptr;
{
LOCK(cs_main);
CChain& active_chain = chainman.ActiveChain();
- block = active_chain.Genesis();
- stop_block = active_chain.Tip();
+ start_index = active_chain.Genesis();
+ stop_block = active_chain.Tip(); // If no stop block is provided, stop at the chain tip.
if (!request.params[2].isNull()) {
- block = active_chain[request.params[2].getInt<int>()];
- if (!block) {
+ start_index = active_chain[request.params[2].getInt<int>()];
+ if (!start_index) {
throw JSONRPCError(RPC_MISC_ERROR, "Invalid start_height");
}
}
if (!request.params[3].isNull()) {
stop_block = active_chain[request.params[3].getInt<int>()];
- if (!stop_block || stop_block->nHeight < block->nHeight) {
+ if (!stop_block || stop_block->nHeight < start_index->nHeight) {
throw JSONRPCError(RPC_MISC_ERROR, "Invalid stop_height");
}
}
}
- CHECK_NONFATAL(block);
+ CHECK_NONFATAL(start_index);
+ CHECK_NONFATAL(stop_block);
// loop through the scan objects, add scripts to the needle_set
GCSFilter::ElementSet needle_set;
@@ -2420,64 +2421,64 @@ static RPCHelpMan scanblocks()
}
UniValue blocks(UniValue::VARR);
const int amount_per_chunk = 10000;
- const CBlockIndex* start_index = block; // for remembering the start of a blockfilter range
std::vector<BlockFilter> filters;
- const CBlockIndex* start_block = block; // for progress reporting
- const int total_blocks_to_process = stop_block->nHeight - start_block->nHeight;
+ int start_block_height = start_index->nHeight; // for progress reporting
+ const int total_blocks_to_process = stop_block->nHeight - start_block_height;
g_scanfilter_should_abort_scan = false;
g_scanfilter_progress = 0;
- g_scanfilter_progress_height = start_block->nHeight;
+ g_scanfilter_progress_height = start_block_height;
+ bool completed = true;
- while (block) {
+ const CBlockIndex* end_range = nullptr;
+ do {
node.rpc_interruption_point(); // allow a clean shutdown
if (g_scanfilter_should_abort_scan) {
- LogPrintf("scanblocks RPC aborted at height %d.\n", block->nHeight);
+ completed = false;
break;
}
- const CBlockIndex* next = nullptr;
- {
- LOCK(cs_main);
- CChain& active_chain = chainman.ActiveChain();
- next = active_chain.Next(block);
- if (block == stop_block) next = nullptr;
- }
- if (start_index->nHeight + amount_per_chunk == block->nHeight || next == nullptr) {
- LogPrint(BCLog::RPC, "Fetching blockfilters from height %d to height %d.\n", start_index->nHeight, block->nHeight);
- if (index->LookupFilterRange(start_index->nHeight, block, filters)) {
- for (const BlockFilter& filter : filters) {
- // compare the elements-set with each filter
- if (filter.GetFilter().MatchAny(needle_set)) {
- if (filter_false_positives) {
- // Double check the filter matches by scanning the block
- const CBlockIndex& blockindex = *CHECK_NONFATAL(WITH_LOCK(cs_main, return chainman.m_blockman.LookupBlockIndex(filter.GetBlockHash())));
-
- if (!CheckBlockFilterMatches(chainman.m_blockman, blockindex, needle_set)) {
- continue;
- }
- }
- blocks.push_back(filter.GetBlockHash().GetHex());
- LogPrint(BCLog::RPC, "scanblocks: found match in %s\n", filter.GetBlockHash().GetHex());
+ // split the lookup range in chunks if we are deeper than 'amount_per_chunk' blocks from the stopping block
+ int start_block = !end_range ? start_index->nHeight : start_index->nHeight + 1; // to not include the previous round 'end_range' block
+ end_range = (start_block + amount_per_chunk < stop_block->nHeight) ?
+ WITH_LOCK(::cs_main, return chainman.ActiveChain()[start_block + amount_per_chunk]) :
+ stop_block;
+
+ if (index->LookupFilterRange(start_block, end_range, filters)) {
+ for (const BlockFilter& filter : filters) {
+ // compare the elements-set with each filter
+ if (filter.GetFilter().MatchAny(needle_set)) {
+ if (filter_false_positives) {
+ // Double check the filter matches by scanning the block
+ const CBlockIndex& blockindex = *CHECK_NONFATAL(WITH_LOCK(cs_main, return chainman.m_blockman.LookupBlockIndex(filter.GetBlockHash())));
+
+ if (!CheckBlockFilterMatches(chainman.m_blockman, blockindex, needle_set)) {
+ continue;
+ }
}
+
+ blocks.push_back(filter.GetBlockHash().GetHex());
}
}
- start_index = block;
-
- // update progress
- int blocks_processed = block->nHeight - start_block->nHeight;
- if (total_blocks_to_process > 0) { // avoid division by zero
- g_scanfilter_progress = (int)(100.0 / total_blocks_to_process * blocks_processed);
- } else {
- g_scanfilter_progress = 100;
- }
- g_scanfilter_progress_height = block->nHeight;
}
- block = next;
- }
- ret.pushKV("from_height", start_block->nHeight);
- ret.pushKV("to_height", g_scanfilter_progress_height.load());
+ start_index = end_range;
+
+ // update progress
+ int blocks_processed = end_range->nHeight - start_block_height;
+ if (total_blocks_to_process > 0) { // avoid division by zero
+ g_scanfilter_progress = (int)(100.0 / total_blocks_to_process * blocks_processed);
+ } else {
+ g_scanfilter_progress = 100;
+ }
+ g_scanfilter_progress_height = end_range->nHeight;
+
+ // Finish if we reached the stop block
+ } while (start_index != stop_block);
+
+ ret.pushKV("from_height", start_block_height);
+ ret.pushKV("to_height", start_index->nHeight); // start_index is always the last scanned block here
ret.pushKV("relevant_blocks", blocks);
+ ret.pushKV("completed", completed);
}
else {
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid action '%s'", request.params[0].get_str()));
diff --git a/src/rpc/blockchain.h b/src/rpc/blockchain.h
index 9ccb87b78a..0a86085db0 100644
--- a/src/rpc/blockchain.h
+++ b/src/rpc/blockchain.h
@@ -7,9 +7,9 @@
#include <consensus/amount.h>
#include <core_io.h>
-#include <fs.h>
#include <streams.h>
#include <sync.h>
+#include <util/fs.h>
#include <validation.h>
#include <any>
diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp
index 4459dd71aa..f3c19003ff 100644
--- a/src/rpc/client.cpp
+++ b/src/rpc/client.cpp
@@ -3,9 +3,9 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#include <common/args.h>
#include <rpc/client.h>
#include <tinyformat.h>
-#include <util/system.h>
#include <set>
#include <stdint.h>
diff --git a/src/rpc/external_signer.cpp b/src/rpc/external_signer.cpp
index f5a6913572..1e139c9990 100644
--- a/src/rpc/external_signer.cpp
+++ b/src/rpc/external_signer.cpp
@@ -3,11 +3,13 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <chainparamsbase.h>
+#include <common/args.h>
#include <external_signer.h>
+#include <rpc/protocol.h>
#include <rpc/server.h>
#include <rpc/util.h>
#include <util/strencodings.h>
-#include <rpc/protocol.h>
+#include <util/system.h>
#include <string>
#include <vector>
diff --git a/src/rpc/mempool.cpp b/src/rpc/mempool.cpp
index 3a69e2d8a2..927b4ce1fc 100644
--- a/src/rpc/mempool.cpp
+++ b/src/rpc/mempool.cpp
@@ -9,7 +9,6 @@
#include <chainparams.h>
#include <core_io.h>
-#include <fs.h>
#include <kernel/mempool_entry.h>
#include <node/mempool_persist_args.h>
#include <policy/rbf.h>
@@ -21,6 +20,7 @@
#include <script/standard.h>
#include <txmempool.h>
#include <univalue.h>
+#include <util/fs.h>
#include <util/moneystr.h>
#include <util/time.h>
diff --git a/src/rpc/output_script.cpp b/src/rpc/output_script.cpp
index bb04f58424..990ec3ab0c 100644
--- a/src/rpc/output_script.cpp
+++ b/src/rpc/output_script.cpp
@@ -162,7 +162,7 @@ static RPCHelpMan createmultisig()
// Only warns if the user has explicitly chosen an address type we cannot generate
warnings.push_back("Unable to make chosen address type, please ensure no uncompressed public keys are present.");
}
- if (!warnings.empty()) result.pushKV("warnings", warnings);
+ PushWarnings(warnings, result);
return result;
},
diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp
index 21d49fda9d..4a918cbd42 100644
--- a/src/rpc/rawtransaction.cpp
+++ b/src/rpc/rawtransaction.cpp
@@ -172,6 +172,91 @@ static std::vector<RPCArg> CreateTxDoc()
};
}
+// Update PSBT with information from the mempool, the UTXO set, the txindex, and the provided descriptors
+PartiallySignedTransaction ProcessPSBT(const std::string& psbt_string, const std::any& context, const HidingSigningProvider& provider)
+{
+ // Unserialize the transactions
+ PartiallySignedTransaction psbtx;
+ std::string error;
+ if (!DecodeBase64PSBT(psbtx, psbt_string, error)) {
+ throw JSONRPCError(RPC_DESERIALIZATION_ERROR, strprintf("TX decode failed %s", error));
+ }
+
+ if (g_txindex) g_txindex->BlockUntilSyncedToCurrentChain();
+ const NodeContext& node = EnsureAnyNodeContext(context);
+
+ // If we can't find the corresponding full transaction for all of our inputs,
+ // this will be used to find just the utxos for the segwit inputs for which
+ // the full transaction isn't found
+ std::map<COutPoint, Coin> coins;
+
+ // Fetch previous transactions:
+ // First, look in the txindex and the mempool
+ for (unsigned int i = 0; i < psbtx.tx->vin.size(); ++i) {
+ PSBTInput& psbt_input = psbtx.inputs.at(i);
+ const CTxIn& tx_in = psbtx.tx->vin.at(i);
+
+ // The `non_witness_utxo` is the whole previous transaction
+ if (psbt_input.non_witness_utxo) continue;
+
+ CTransactionRef tx;
+
+ // Look in the txindex
+ if (g_txindex) {
+ uint256 block_hash;
+ g_txindex->FindTx(tx_in.prevout.hash, block_hash, tx);
+ }
+ // If we still don't have it look in the mempool
+ if (!tx) {
+ tx = node.mempool->get(tx_in.prevout.hash);
+ }
+ if (tx) {
+ psbt_input.non_witness_utxo = tx;
+ } else {
+ coins[tx_in.prevout]; // Create empty map entry keyed by prevout
+ }
+ }
+
+ // If we still haven't found all of the inputs, look for the missing ones in the utxo set
+ if (!coins.empty()) {
+ FindCoins(node, coins);
+ for (unsigned int i = 0; i < psbtx.tx->vin.size(); ++i) {
+ PSBTInput& input = psbtx.inputs.at(i);
+
+ // If there are still missing utxos, add them if they were found in the utxo set
+ if (!input.non_witness_utxo) {
+ const CTxIn& tx_in = psbtx.tx->vin.at(i);
+ const Coin& coin = coins.at(tx_in.prevout);
+ if (!coin.out.IsNull() && IsSegWitOutput(provider, coin.out.scriptPubKey)) {
+ input.witness_utxo = coin.out;
+ }
+ }
+ }
+ }
+
+ const PrecomputedTransactionData& txdata = PrecomputePSBTData(psbtx);
+
+ for (unsigned int i = 0; i < psbtx.tx->vin.size(); ++i) {
+ if (PSBTInputSigned(psbtx.inputs.at(i))) {
+ continue;
+ }
+
+ // Update script/keypath information using descriptor data.
+ // Note that SignPSBTInput does a lot more than just constructing ECDSA signatures
+ // we don't actually care about those here, in fact.
+ SignPSBTInput(provider, psbtx, /*index=*/i, &txdata, /*sighash=*/1);
+ }
+
+ // Update script/keypath information using descriptor data.
+ for (unsigned int i = 0; i < psbtx.tx->vout.size(); ++i) {
+ UpdatePSBTOutput(provider, psbtx, i);
+ }
+
+ RemoveUnnecessaryTransactions(psbtx, /*sighash_type=*/1);
+
+ return psbtx;
+}
+
static RPCHelpMan getrawtransaction()
{
return RPCHelpMan{
@@ -1580,7 +1665,7 @@ static RPCHelpMan converttopsbt()
static RPCHelpMan utxoupdatepsbt()
{
return RPCHelpMan{"utxoupdatepsbt",
- "\nUpdates all segwit inputs and outputs in a PSBT with data from output descriptors, the UTXO set or the mempool.\n",
+ "\nUpdates all segwit inputs and outputs in a PSBT with data from output descriptors, the UTXO set, txindex, or the mempool.\n",
{
{"psbt", RPCArg::Type::STR, RPCArg::Optional::NO, "A base64 string of a PSBT"},
{"descriptors", RPCArg::Type::ARR, RPCArg::Optional::OMITTED, "An array of either strings or objects", {
@@ -1599,13 +1684,6 @@ static RPCHelpMan utxoupdatepsbt()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- // Unserialize the transactions
- PartiallySignedTransaction psbtx;
- std::string error;
- if (!DecodeBase64PSBT(psbtx, request.params[0].get_str(), error)) {
- throw JSONRPCError(RPC_DESERIALIZATION_ERROR, strprintf("TX decode failed %s", error));
- }
-
// Parse descriptors, if any.
FlatSigningProvider provider;
if (!request.params[1].isNull()) {
@@ -1614,53 +1692,12 @@ static RPCHelpMan utxoupdatepsbt()
EvalDescriptorStringOrObject(descs[i], provider);
}
}
- // We don't actually need private keys further on; hide them as a precaution.
- HidingSigningProvider public_provider(&provider, /*hide_secret=*/true, /*hide_origin=*/false);
-
- // Fetch previous transactions (inputs):
- CCoinsView viewDummy;
- CCoinsViewCache view(&viewDummy);
- {
- NodeContext& node = EnsureAnyNodeContext(request.context);
- const CTxMemPool& mempool = EnsureMemPool(node);
- ChainstateManager& chainman = EnsureChainman(node);
- LOCK2(cs_main, mempool.cs);
- CCoinsViewCache &viewChain = chainman.ActiveChainstate().CoinsTip();
- CCoinsViewMemPool viewMempool(&viewChain, mempool);
- view.SetBackend(viewMempool); // temporarily switch cache backend to db+mempool view
-
- for (const CTxIn& txin : psbtx.tx->vin) {
- view.AccessCoin(txin.prevout); // Load entries from viewChain into view; can fail.
- }
-
- view.SetBackend(viewDummy); // switch back to avoid locking mempool for too long
- }
-
- // Fill the inputs
- const PrecomputedTransactionData txdata = PrecomputePSBTData(psbtx);
- for (unsigned int i = 0; i < psbtx.tx->vin.size(); ++i) {
- PSBTInput& input = psbtx.inputs.at(i);
- if (input.non_witness_utxo || !input.witness_utxo.IsNull()) {
- continue;
- }
-
- const Coin& coin = view.AccessCoin(psbtx.tx->vin[i].prevout);
-
- if (IsSegWitOutput(provider, coin.out.scriptPubKey)) {
- input.witness_utxo = coin.out;
- }
-
- // Update script/keypath information using descriptor data.
- // Note that SignPSBTInput does a lot more than just constructing ECDSA signatures
- // we don't actually care about those here, in fact.
- SignPSBTInput(public_provider, psbtx, i, &txdata, /*sighash=*/1);
- }
-
- // Update script/keypath information using descriptor data.
- for (unsigned int i = 0; i < psbtx.tx->vout.size(); ++i) {
- UpdatePSBTOutput(public_provider, psbtx, i);
- }
+ // We don't actually need private keys further on; hide them as a precaution.
+ const PartiallySignedTransaction& psbtx = ProcessPSBT(
+ request.params[0].get_str(),
+ request.context,
+ HidingSigningProvider(&provider, /*hide_secret=*/true, /*hide_origin=*/false));
CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
ssTx << psbtx;
diff --git a/src/rpc/request.cpp b/src/rpc/request.cpp
index b6ef1909c9..ad91ed0f23 100644
--- a/src/rpc/request.cpp
+++ b/src/rpc/request.cpp
@@ -5,11 +5,13 @@
#include <rpc/request.h>
-#include <fs.h>
+#include <util/fs.h>
+#include <common/args.h>
+#include <logging.h>
#include <random.h>
#include <rpc/protocol.h>
-#include <util/system.h>
+#include <util/fs_helpers.h>
#include <util/strencodings.h>
#include <fstream>
diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp
index 44d7e2676b..354f949002 100644
--- a/src/rpc/server.cpp
+++ b/src/rpc/server.cpp
@@ -5,6 +5,8 @@
#include <rpc/server.h>
+#include <common/args.h>
+#include <logging.h>
#include <rpc/util.h>
#include <shutdown.h>
#include <sync.h>
@@ -83,6 +85,7 @@ std::string CRPCTable::help(const std::string& strCommand, const JSONRPCRequest&
std::string category;
std::set<intptr_t> setDone;
std::vector<std::pair<std::string, const CRPCCommand*> > vCommands;
+ vCommands.reserve(mapCommands.size());
for (const auto& entry : mapCommands)
vCommands.push_back(make_pair(entry.second.front()->category + entry.first, entry.second.front()));
@@ -513,6 +516,7 @@ static bool ExecuteCommand(const CRPCCommand& command, const JSONRPCRequest& req
std::vector<std::string> CRPCTable::listCommands() const
{
std::vector<std::string> commandList;
+ commandList.reserve(mapCommands.size());
for (const auto& i : mapCommands) commandList.emplace_back(i.first);
return commandList;
}
diff --git a/src/rpc/server_util.cpp b/src/rpc/server_util.cpp
index 7a708ec813..13d007b496 100644
--- a/src/rpc/server_util.cpp
+++ b/src/rpc/server_util.cpp
@@ -4,6 +4,7 @@
#include <rpc/server_util.h>
+#include <common/args.h>
#include <net_processing.h>
#include <node/context.h>
#include <policy/fees.h>
diff --git a/src/rpc/util.cpp b/src/rpc/util.cpp
index a1020c3b2b..1f3f37d0a0 100644
--- a/src/rpc/util.cpp
+++ b/src/rpc/util.cpp
@@ -3,6 +3,7 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <clientversion.h>
+#include <common/args.h>
#include <consensus/amount.h>
#include <key_io.h>
#include <outputtype.h>
@@ -13,7 +14,6 @@
#include <util/check.h>
#include <util/strencodings.h>
#include <util/string.h>
-#include <util/system.h>
#include <util/translation.h>
#include <tuple>
@@ -608,6 +608,7 @@ bool RPCHelpMan::IsValidNumArgs(size_t num_args) const
std::vector<std::string> RPCHelpMan::GetArgNames() const
{
std::vector<std::string> ret;
+ ret.reserve(m_args.size());
for (const auto& arg : m_args) {
ret.emplace_back(arg.m_names);
}
@@ -732,12 +733,12 @@ UniValue RPCArg::MatchesType(const UniValue& request) const
std::string RPCArg::GetFirstName() const
{
- return m_names.substr(0, m_names.find("|"));
+ return m_names.substr(0, m_names.find('|'));
}
std::string RPCArg::GetName() const
{
- CHECK_NONFATAL(std::string::npos == m_names.find("|"));
+ CHECK_NONFATAL(std::string::npos == m_names.find('|'));
return m_names;
}
@@ -1173,3 +1174,26 @@ UniValue GetServicesNames(ServiceFlags services)
return servicesNames;
}
+
+/** Convert a vector of bilingual strings to a UniValue::VARR containing their original untranslated values. */
+[[nodiscard]] static UniValue BilingualStringsToUniValue(const std::vector<bilingual_str>& bilingual_strings)
+{
+ CHECK_NONFATAL(!bilingual_strings.empty());
+ UniValue result{UniValue::VARR};
+ for (const auto& s : bilingual_strings) {
+ result.push_back(s.original);
+ }
+ return result;
+}
+
+void PushWarnings(const UniValue& warnings, UniValue& obj)
+{
+ if (warnings.empty()) return;
+ obj.pushKV("warnings", warnings);
+}
+
+void PushWarnings(const std::vector<bilingual_str>& warnings, UniValue& obj)
+{
+ if (warnings.empty()) return;
+ obj.pushKV("warnings", BilingualStringsToUniValue(warnings));
+}
diff --git a/src/rpc/util.h b/src/rpc/util.h
index e3783c8f76..bb5c30a2f4 100644
--- a/src/rpc/util.h
+++ b/src/rpc/util.h
@@ -381,4 +381,13 @@ private:
const RPCExamples m_examples;
};
+/**
+ * Push warning messages to an RPC "warnings" field as a JSON array of strings.
+ *
+ * @param[in] warnings Warning messages to push.
+ * @param[out] obj UniValue object to push the warnings array object to.
+ */
+void PushWarnings(const UniValue& warnings, UniValue& obj);
+void PushWarnings(const std::vector<bilingual_str>& warnings, UniValue& obj);
+
#endif // BITCOIN_RPC_UTIL_H
diff --git a/src/script/descriptor.cpp b/src/script/descriptor.cpp
index 857fee1818..0951504ee0 100644
--- a/src/script/descriptor.cpp
+++ b/src/script/descriptor.cpp
@@ -12,10 +12,10 @@
#include <script/standard.h>
#include <uint256.h>
+#include <common/args.h>
#include <span.h>
#include <util/bip32.h>
#include <util/spanparsing.h>
-#include <util/system.h>
#include <util/strencodings.h>
#include <util/vector.h>
@@ -830,6 +830,7 @@ protected:
std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, Span<const CScript>, FlatSigningProvider&) const override {
CScript ret;
std::vector<XOnlyPubKey> xkeys;
+ xkeys.reserve(keys.size());
for (const auto& key : keys) xkeys.emplace_back(key);
if (m_sorted) std::sort(xkeys.begin(), xkeys.end());
ret << ToByteVector(xkeys[0]) << OP_CHECKSIG;
diff --git a/src/script/miniscript.h b/src/script/miniscript.h
index bb42bf3c92..7c1a87a7dc 100644
--- a/src/script/miniscript.h
+++ b/src/script/miniscript.h
@@ -1194,7 +1194,7 @@ public:
case Fragment::OR_I:
return subs[0] || subs[1];
case Fragment::THRESH:
- return std::count(subs.begin(), subs.end(), true) >= node.k;
+ return static_cast<uint32_t>(std::count(subs.begin(), subs.end(), true)) >= node.k;
default: // wrappers
assert(subs.size() == 1);
return subs[0];
diff --git a/src/script/sigcache.cpp b/src/script/sigcache.cpp
index fef3601887..e52e8cd309 100644
--- a/src/script/sigcache.cpp
+++ b/src/script/sigcache.cpp
@@ -5,6 +5,7 @@
#include <script/sigcache.h>
+#include <logging.h>
#include <pubkey.h>
#include <random.h>
#include <uint256.h>
diff --git a/src/secp256k1/CHANGELOG.md b/src/secp256k1/CHANGELOG.md
index 7f43843641..6d23662a93 100644
--- a/src/secp256k1/CHANGELOG.md
+++ b/src/secp256k1/CHANGELOG.md
@@ -7,6 +7,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
+## [0.3.1] - 2023-04-10
+We strongly recommend updating to 0.3.1 if you use or plan to use Clang >=14 to compile libsecp256k1, e.g., Xcode >=14 on macOS has Clang >=14. When in doubt, check the Clang version using `clang -v`.
+
+#### Security
+ - Fix "constant-timeness" issue with Clang >=14 that could leave applications using libsecp256k1 vulnerable to a timing side-channel attack. The fix avoids secret-dependent control flow and secret-dependent memory accesses in conditional moves of memory objects when libsecp256k1 is compiled with Clang >=14.
+
+#### Added
+ - Added tests against [Project Wycheproof's](https://github.com/google/wycheproof/) set of ECDSA test vectors (Bitcoin "low-S" variant), a fixed set of test cases designed to trigger various edge cases.
+
+#### Changed
+ - Increased minimum required CMake version to 3.13. CMake builds remain experimental.
+
+#### ABI Compatibility
+The ABI is compatible with version 0.3.0.
+
## [0.3.0] - 2023-03-08
#### Added
@@ -25,7 +40,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Removed the configuration header `src/libsecp256k1-config.h`. We recommend passing flags to `./configure` or `cmake` to set configuration options (see `./configure --help` or `cmake -LH`). If you cannot or do not want to use one of the supported build systems, pass configuration flags such as `-DSECP256K1_ENABLE_MODULE_SCHNORRSIG` manually to the compiler (see the file `configure.ac` for supported flags).
#### ABI Compatibility
-
Due to changes in the API regarding `secp256k1_context_static` described above, the ABI is *not* compatible with previous versions.
## [0.2.0] - 2022-12-12
@@ -45,7 +59,6 @@ Due to changes in the API regarding `secp256k1_context_static` described above,
- Module `schnorrsig`: renamed `secp256k1_schnorrsig_sign` to `secp256k1_schnorrsig_sign32`.
#### ABI Compatibility
-
Since this is the first release, we do not compare application binary interfaces.
However, there are earlier unreleased versions of libsecp256k1 that are *not* ABI compatible with this version.
@@ -55,7 +68,8 @@ This version was in fact never released.
The number was given by the build system since the introduction of autotools in Jan 2014 (ea0fe5a5bf0c04f9cc955b2966b614f5f378c6f6).
Therefore, this version number does not uniquely identify a set of source files.
-[unreleased]: https://github.com/bitcoin-core/secp256k1/compare/v0.3.0...HEAD
+[unreleased]: https://github.com/bitcoin-core/secp256k1/compare/v0.3.1...HEAD
+[0.3.1]: https://github.com/bitcoin-core/secp256k1/compare/v0.3.0...v0.3.1
[0.3.0]: https://github.com/bitcoin-core/secp256k1/compare/v0.2.0...v0.3.0
[0.2.0]: https://github.com/bitcoin-core/secp256k1/compare/423b6d19d373f1224fd671a982584d7e7900bc93..v0.2.0
[0.1.0]: https://github.com/bitcoin-core/secp256k1/commit/423b6d19d373f1224fd671a982584d7e7900bc93
diff --git a/src/secp256k1/CMakeLists.txt b/src/secp256k1/CMakeLists.txt
index 5c8aad6fcc..a70165e356 100644
--- a/src/secp256k1/CMakeLists.txt
+++ b/src/secp256k1/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 3.1)
+cmake_minimum_required(VERSION 3.13)
if(CMAKE_VERSION VERSION_GREATER 3.14)
# MSVC runtime library flags are selected by the CMAKE_MSVC_RUNTIME_LIBRARY abstraction.
@@ -10,7 +10,7 @@ endif()
# The package (a.k.a. release) version is based on semantic versioning 2.0.0 of
# the API. All changes in experimental modules are treated as
# backwards-compatible and therefore at most increase the minor version.
-project(libsecp256k1 VERSION 0.3.0 LANGUAGES C)
+project(libsecp256k1 VERSION 0.3.2 LANGUAGES C)
# The library version is based on libtool versioning of the ABI. The set of
# rules for updating the version can be found here:
@@ -18,7 +18,7 @@ project(libsecp256k1 VERSION 0.3.0 LANGUAGES C)
# All changes in experimental modules are treated as if they don't affect the
# interface and therefore only increase the revision.
set(${PROJECT_NAME}_LIB_VERSION_CURRENT 2)
-set(${PROJECT_NAME}_LIB_VERSION_REVISION 0)
+set(${PROJECT_NAME}_LIB_VERSION_REVISION 2)
set(${PROJECT_NAME}_LIB_VERSION_AGE 0)
set(CMAKE_C_STANDARD 90)
@@ -147,7 +147,7 @@ else()
endif()
# Define custom "Coverage" build type.
-set(CMAKE_C_FLAGS_COVERAGE "${CMAKE_C_FLAGS_RELWITHDEBINFO} -O0 -DCOVERAGE=1 --coverage -Wno-unused-parameter" CACHE STRING
+set(CMAKE_C_FLAGS_COVERAGE "${CMAKE_C_FLAGS_RELWITHDEBINFO} -O0 -DCOVERAGE=1 --coverage" CACHE STRING
"Flags used by the C compiler during \"Coverage\" builds."
FORCE
)
@@ -203,11 +203,6 @@ else()
try_add_compile_option(-Wundef)
endif()
-if(CMAKE_VERSION VERSION_GREATER 3.2)
- # Honor visibility properties for all target types.
- # See: https://cmake.org/cmake/help/latest/policy/CMP0063.html
- cmake_policy(SET CMP0063 NEW)
-endif()
set(CMAKE_C_VISIBILITY_PRESET hidden)
# Ask CTest to create a "check" target (e.g., make check) as alias for the "test" target.
diff --git a/src/secp256k1/Makefile.am b/src/secp256k1/Makefile.am
index e3fdf4da27..36e26e3e8a 100644
--- a/src/secp256k1/Makefile.am
+++ b/src/secp256k1/Makefile.am
@@ -247,3 +247,20 @@ endif
if ENABLE_MODULE_SCHNORRSIG
include src/modules/schnorrsig/Makefile.am.include
endif
+
+EXTRA_DIST += src/wycheproof/WYCHEPROOF_COPYING
+EXTRA_DIST += src/wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.h
+EXTRA_DIST += src/wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.json
+EXTRA_DIST += tools/tests_wycheproof_generate.py
+
+TESTVECTORS = src/wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.h
+
+src/wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.h:
+ python3 tools/tests_wycheproof_generate.py src/wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.json > $@
+
+testvectors: $(TESTVECTORS)
+
+maintainer-clean-testvectors: clean-testvectors
+
+clean-testvectors:
+ rm -f $(TESTVECTORS)
diff --git a/src/secp256k1/ci/cirrus.sh b/src/secp256k1/ci/cirrus.sh
index 8495c39203..b2af03bb5d 100755
--- a/src/secp256k1/ci/cirrus.sh
+++ b/src/secp256k1/ci/cirrus.sh
@@ -109,8 +109,8 @@ fi
# Rebuild precomputed files (if not cross-compiling).
if [ -z "$HOST" ]
then
- make clean-precomp
- make precomp
+ make clean-precomp clean-testvectors
+ make precomp testvectors
fi
# Check that no repo files have been modified by the build.
diff --git a/src/secp256k1/configure.ac b/src/secp256k1/configure.ac
index a46a0a7be3..0b555eac67 100644
--- a/src/secp256k1/configure.ac
+++ b/src/secp256k1/configure.ac
@@ -5,8 +5,8 @@ AC_PREREQ([2.60])
# backwards-compatible and therefore at most increase the minor version.
define(_PKG_VERSION_MAJOR, 0)
define(_PKG_VERSION_MINOR, 3)
-define(_PKG_VERSION_PATCH, 0)
-define(_PKG_VERSION_IS_RELEASE, true)
+define(_PKG_VERSION_PATCH, 2)
+define(_PKG_VERSION_IS_RELEASE, false)
# The library version is based on libtool versioning of the ABI. The set of
# rules for updating the version can be found here:
@@ -14,7 +14,7 @@ define(_PKG_VERSION_IS_RELEASE, true)
# All changes in experimental modules are treated as if they don't affect the
# interface and therefore only increase the revision.
define(_LIB_VERSION_CURRENT, 2)
-define(_LIB_VERSION_REVISION, 0)
+define(_LIB_VERSION_REVISION, 2)
define(_LIB_VERSION_AGE, 0)
AC_INIT([libsecp256k1],m4_join([.], _PKG_VERSION_MAJOR, _PKG_VERSION_MINOR, _PKG_VERSION_PATCH)m4_if(_PKG_VERSION_IS_RELEASE, [true], [], [-dev]),[https://github.com/bitcoin-core/secp256k1/issues],[libsecp256k1],[https://github.com/bitcoin-core/secp256k1])
@@ -29,6 +29,11 @@ AM_INIT_AUTOMAKE([1.11.2 foreign subdir-objects])
# Make the compilation flags quiet unless V=1 is used.
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
+if test "${CFLAGS+set}" = "set"; then
+ CFLAGS_overridden=yes
+else
+ CFLAGS_overridden=no
+fi
AC_PROG_CC
AM_PROG_AS
AM_PROG_AR
@@ -88,11 +93,14 @@ esac
AC_DEFUN([SECP_TRY_APPEND_DEFAULT_CFLAGS], [
# GCC and compatible (incl. clang)
if test "x$GCC" = "xyes"; then
- # Try to append -Werror=unknown-warning-option to CFLAGS temporarily. Otherwise clang will
- # not error out if it gets unknown warning flags and the checks here will always succeed
- # no matter if clang knows the flag or not.
+ # Try to append -Werror to CFLAGS temporarily. Otherwise checks for some unsupported
+ # flags will succeed.
+ # Note that failure to append -Werror does not necessarily mean that -Werror is not
+ # supported. The compiler may already be warning about something unrelated, for example
+ # about some path issue. If that is the case, -Werror cannot be used because all
+ # of those warnings would be turned into errors.
SECP_TRY_APPEND_DEFAULT_CFLAGS_saved_CFLAGS="$CFLAGS"
- SECP_TRY_APPEND_CFLAGS([-Werror=unknown-warning-option], CFLAGS)
+ SECP_TRY_APPEND_CFLAGS([-Werror], CFLAGS)
SECP_TRY_APPEND_CFLAGS([-std=c89 -pedantic -Wno-long-long -Wnested-externs -Wshadow -Wstrict-prototypes -Wundef], $1) # GCC >= 3.0, -Wlong-long is implied by -pedantic.
SECP_TRY_APPEND_CFLAGS([-Wno-overlength-strings], $1) # GCC >= 4.2, -Woverlength-strings is implied by -pedantic.
@@ -241,6 +249,12 @@ fi
if test x"$enable_coverage" = x"yes"; then
SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DCOVERAGE=1"
SECP_CFLAGS="-O0 --coverage $SECP_CFLAGS"
+ # If coverage is enabled, and the user has not overridden CFLAGS,
+ # override Autoconf's value "-g -O2" with "-g". Otherwise we'd end up
+ # with "-O0 --coverage -g -O2".
+ if test "$CFLAGS_overridden" = "no"; then
+ CFLAGS="-g"
+ fi
LDFLAGS="--coverage $LDFLAGS"
else
# Most likely the CFLAGS already contain -O2 because that is autoconf's default.
diff --git a/src/secp256k1/doc/release-process.md b/src/secp256k1/doc/release-process.md
index b522f89657..70a35f0910 100644
--- a/src/secp256k1/doc/release-process.md
+++ b/src/secp256k1/doc/release-process.md
@@ -15,15 +15,20 @@ This process also assumes that there will be no minor releases for old major rel
## Regular release
1. Open a PR to the master branch with a commit (using message `"release: prepare for $MAJOR.$MINOR.$PATCH"`, for example) that
- * finalizes the release notes in [CHANGELOG.md](../CHANGELOG.md) (make sure to include an entry for `### ABI Compatibility`) and
- * updates `_PKG_VERSION_*`, `_LIB_VERSION_*`, and sets `_PKG_VERSION_IS_RELEASE` to `true` in `configure.ac`.
+ * finalizes the release notes in [CHANGELOG.md](../CHANGELOG.md) (make sure to include an entry for `### ABI Compatibility`),
+ * updates `_PKG_VERSION_*` and `_LIB_VERSION_*` and sets `_PKG_VERSION_IS_RELEASE` to `true` in `configure.ac`, and
+ * updates `project(libsecp256k1 VERSION ...)` and `${PROJECT_NAME}_LIB_VERSION_*` in `CMakeLists.txt`.
2. After the PR is merged, tag the commit and push it:
```
RELEASE_COMMIT=<merge commit of step 1>
git tag -s v$MAJOR.$MINOR.$PATCH -m "libsecp256k1 $MAJOR.$MINOR.$PATCH" $RELEASE_COMMIT
git push git@github.com:bitcoin-core/secp256k1.git v$MAJOR.$MINOR.$PATCH
```
-3. Open a PR to the master branch with a commit (using message `"release cleanup: bump version after $MAJOR.$MINOR.$PATCH"`, for example) that sets `_PKG_VERSION_IS_RELEASE` to `false` and `_PKG_VERSION_PATCH` to `$PATCH + 1` and increases `_LIB_VERSION_REVISION`. If other maintainers are not present to approve the PR, it can be merged without ACKs.
+3. Open a PR to the master branch with a commit (using message `"release cleanup: bump version after $MAJOR.$MINOR.$PATCH"`, for example) that
+ * sets `_PKG_VERSION_IS_RELEASE` to `false` and increments `_PKG_VERSION_PATCH` and `_LIB_VERSION_REVISION` in `configure.ac`, and
+ * increments the `$PATCH` component of `project(libsecp256k1 VERSION ...)` and `${PROJECT_NAME}_LIB_VERSION_REVISION` in `CMakeLists.txt`.
+
+ If other maintainers are not present to approve the PR, it can be merged without ACKs.
4. Create a new GitHub release with a link to the corresponding entry in [CHANGELOG.md](../CHANGELOG.md).
## Maintenance release
@@ -38,7 +43,9 @@ Note that bugfixes only need to be backported to releases for which no compatibl
2. Open a pull request to the `$MAJOR.$MINOR` branch that
* includes the bugfixes,
* finalizes the release notes,
- * bumps `_PKG_VERSION_PATCH` and `_LIB_VERSION_REVISION` in `configure.ac` (with commit message `"release: update PKG_ and LIB_VERSION for $MAJOR.$MINOR.$PATCH"`, for example).
+ * increments `_PKG_VERSION_PATCH` and `_LIB_VERSION_REVISION` in `configure.ac`
+ and the `$PATCH` component of `project(libsecp256k1 VERSION ...)` and `${PROJECT_NAME}_LIB_VERSION_REVISION` in `CMakeLists.txt`
+ (with commit message `"release: bump versions for $MAJOR.$MINOR.$PATCH"`, for example).
3. After the PRs are merged, update the release branch and tag the commit:
```
git checkout $MAJOR.$MINOR && git pull
diff --git a/src/secp256k1/include/secp256k1.h b/src/secp256k1/include/secp256k1.h
index 325f35eb04..4ce3e500ba 100644
--- a/src/secp256k1/include/secp256k1.h
+++ b/src/secp256k1/include/secp256k1.h
@@ -288,7 +288,7 @@ SECP256K1_API void secp256k1_selftest(void);
* Do not create a new context object for each operation, as construction and
* randomization can take non-negligible time.
*/
-SECP256K1_API secp256k1_context* secp256k1_context_create(
+SECP256K1_API secp256k1_context *secp256k1_context_create(
unsigned int flags
) SECP256K1_WARN_UNUSED_RESULT;
@@ -304,8 +304,8 @@ SECP256K1_API secp256k1_context* secp256k1_context_create(
* Returns: a newly created context object.
* Args: ctx: an existing context to copy (not secp256k1_context_static)
*/
-SECP256K1_API secp256k1_context* secp256k1_context_clone(
- const secp256k1_context* ctx
+SECP256K1_API secp256k1_context *secp256k1_context_clone(
+ const secp256k1_context *ctx
) SECP256K1_ARG_NONNULL(1) SECP256K1_WARN_UNUSED_RESULT;
/** Destroy a secp256k1 context object (created in dynamically allocated memory).
@@ -323,7 +323,7 @@ SECP256K1_API secp256k1_context* secp256k1_context_clone(
* (i.e., not secp256k1_context_static).
*/
SECP256K1_API void secp256k1_context_destroy(
- secp256k1_context* ctx
+ secp256k1_context *ctx
) SECP256K1_ARG_NONNULL(1);
/** Set a callback function to be called when an illegal argument is passed to
@@ -347,8 +347,8 @@ SECP256K1_API void secp256k1_context_destroy(
* USE_EXTERNAL_DEFAULT_CALLBACKS is defined, which is the case if the build
* has been configured with --enable-external-default-callbacks. Then the
* following two symbols must be provided to link against:
- * - void secp256k1_default_illegal_callback_fn(const char* message, void* data);
- * - void secp256k1_default_error_callback_fn(const char* message, void* data);
+ * - void secp256k1_default_illegal_callback_fn(const char *message, void *data);
+ * - void secp256k1_default_error_callback_fn(const char *message, void *data);
* The library can call these default handlers even before a proper callback data
* pointer could have been set using secp256k1_context_set_illegal_callback or
* secp256k1_context_set_error_callback, e.g., when the creation of a context
@@ -364,9 +364,9 @@ SECP256K1_API void secp256k1_context_destroy(
* See also secp256k1_context_set_error_callback.
*/
SECP256K1_API void secp256k1_context_set_illegal_callback(
- secp256k1_context* ctx,
- void (*fun)(const char* message, void* data),
- const void* data
+ secp256k1_context *ctx,
+ void (*fun)(const char *message, void *data),
+ const void *data
) SECP256K1_ARG_NONNULL(1);
/** Set a callback function to be called when an internal consistency check
@@ -392,9 +392,9 @@ SECP256K1_API void secp256k1_context_set_illegal_callback(
* See also secp256k1_context_set_illegal_callback.
*/
SECP256K1_API void secp256k1_context_set_error_callback(
- secp256k1_context* ctx,
- void (*fun)(const char* message, void* data),
- const void* data
+ secp256k1_context *ctx,
+ void (*fun)(const char *message, void *data),
+ const void *data
) SECP256K1_ARG_NONNULL(1);
/** Create a secp256k1 scratch space object.
@@ -404,8 +404,8 @@ SECP256K1_API void secp256k1_context_set_error_callback(
* In: size: amount of memory to be available as scratch space. Some extra
* (<100 bytes) will be allocated for extra accounting.
*/
-SECP256K1_API SECP256K1_WARN_UNUSED_RESULT secp256k1_scratch_space* secp256k1_scratch_space_create(
- const secp256k1_context* ctx,
+SECP256K1_API SECP256K1_WARN_UNUSED_RESULT secp256k1_scratch_space *secp256k1_scratch_space_create(
+ const secp256k1_context *ctx,
size_t size
) SECP256K1_ARG_NONNULL(1);
@@ -416,8 +416,8 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT secp256k1_scratch_space* secp256k1_sc
* scratch: space to destroy
*/
SECP256K1_API void secp256k1_scratch_space_destroy(
- const secp256k1_context* ctx,
- secp256k1_scratch_space* scratch
+ const secp256k1_context *ctx,
+ secp256k1_scratch_space *scratch
) SECP256K1_ARG_NONNULL(1);
/** Parse a variable-length public key into the pubkey object.
@@ -435,8 +435,8 @@ SECP256K1_API void secp256k1_scratch_space_destroy(
* byte 0x06 or 0x07) format public keys.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_parse(
- const secp256k1_context* ctx,
- secp256k1_pubkey* pubkey,
+ const secp256k1_context *ctx,
+ secp256k1_pubkey *pubkey,
const unsigned char *input,
size_t inputlen
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
@@ -457,10 +457,10 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_parse(
* compressed format, otherwise SECP256K1_EC_UNCOMPRESSED.
*/
SECP256K1_API int secp256k1_ec_pubkey_serialize(
- const secp256k1_context* ctx,
+ const secp256k1_context *ctx,
unsigned char *output,
size_t *outputlen,
- const secp256k1_pubkey* pubkey,
+ const secp256k1_pubkey *pubkey,
unsigned int flags
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
@@ -474,9 +474,9 @@ SECP256K1_API int secp256k1_ec_pubkey_serialize(
* pubkey2: second public key to compare
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_cmp(
- const secp256k1_context* ctx,
- const secp256k1_pubkey* pubkey1,
- const secp256k1_pubkey* pubkey2
+ const secp256k1_context *ctx,
+ const secp256k1_pubkey *pubkey1,
+ const secp256k1_pubkey *pubkey2
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Parse an ECDSA signature in compact (64 bytes) format.
@@ -495,8 +495,8 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_cmp(
* any message and public key.
*/
SECP256K1_API int secp256k1_ecdsa_signature_parse_compact(
- const secp256k1_context* ctx,
- secp256k1_ecdsa_signature* sig,
+ const secp256k1_context *ctx,
+ secp256k1_ecdsa_signature *sig,
const unsigned char *input64
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
@@ -516,8 +516,8 @@ SECP256K1_API int secp256k1_ecdsa_signature_parse_compact(
* guaranteed to fail for every message and public key.
*/
SECP256K1_API int secp256k1_ecdsa_signature_parse_der(
- const secp256k1_context* ctx,
- secp256k1_ecdsa_signature* sig,
+ const secp256k1_context *ctx,
+ secp256k1_ecdsa_signature *sig,
const unsigned char *input,
size_t inputlen
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
@@ -534,10 +534,10 @@ SECP256K1_API int secp256k1_ecdsa_signature_parse_der(
* In: sig: a pointer to an initialized signature object
*/
SECP256K1_API int secp256k1_ecdsa_signature_serialize_der(
- const secp256k1_context* ctx,
+ const secp256k1_context *ctx,
unsigned char *output,
size_t *outputlen,
- const secp256k1_ecdsa_signature* sig
+ const secp256k1_ecdsa_signature *sig
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
/** Serialize an ECDSA signature in compact (64 byte) format.
@@ -550,9 +550,9 @@ SECP256K1_API int secp256k1_ecdsa_signature_serialize_der(
* See secp256k1_ecdsa_signature_parse_compact for details about the encoding.
*/
SECP256K1_API int secp256k1_ecdsa_signature_serialize_compact(
- const secp256k1_context* ctx,
+ const secp256k1_context *ctx,
unsigned char *output64,
- const secp256k1_ecdsa_signature* sig
+ const secp256k1_ecdsa_signature *sig
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Verify an ECDSA signature.
@@ -581,7 +581,7 @@ SECP256K1_API int secp256k1_ecdsa_signature_serialize_compact(
* For details, see the comments for that function.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_verify(
- const secp256k1_context* ctx,
+ const secp256k1_context *ctx,
const secp256k1_ecdsa_signature *sig,
const unsigned char *msghash32,
const secp256k1_pubkey *pubkey
@@ -629,7 +629,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_verify(
* secp256k1_ecdsa_signature_normalize must be called before verification.
*/
SECP256K1_API int secp256k1_ecdsa_signature_normalize(
- const secp256k1_context* ctx,
+ const secp256k1_context *ctx,
secp256k1_ecdsa_signature *sigout,
const secp256k1_ecdsa_signature *sigin
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(3);
@@ -662,7 +662,7 @@ SECP256K1_API_VAR const secp256k1_nonce_function secp256k1_nonce_function_defaul
* secp256k1_ecdsa_signature_normalize for more details.
*/
SECP256K1_API int secp256k1_ecdsa_sign(
- const secp256k1_context* ctx,
+ const secp256k1_context *ctx,
secp256k1_ecdsa_signature *sig,
const unsigned char *msghash32,
const unsigned char *seckey,
@@ -683,7 +683,7 @@ SECP256K1_API int secp256k1_ecdsa_sign(
* In: seckey: pointer to a 32-byte secret key.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_verify(
- const secp256k1_context* ctx,
+ const secp256k1_context *ctx,
const unsigned char *seckey
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);
@@ -696,7 +696,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_verify(
* In: seckey: pointer to a 32-byte secret key.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_create(
- const secp256k1_context* ctx,
+ const secp256k1_context *ctx,
secp256k1_pubkey *pubkey,
const unsigned char *seckey
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
@@ -712,14 +712,14 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_create(
* seckey will be set to some unspecified value.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_negate(
- const secp256k1_context* ctx,
+ const secp256k1_context *ctx,
unsigned char *seckey
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);
/** Same as secp256k1_ec_seckey_negate, but DEPRECATED. Will be removed in
* future versions. */
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_negate(
- const secp256k1_context* ctx,
+ const secp256k1_context *ctx,
unsigned char *seckey
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2)
SECP256K1_DEPRECATED("Use secp256k1_ec_seckey_negate instead");
@@ -731,7 +731,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_negate(
* In/Out: pubkey: pointer to the public key to be negated.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_negate(
- const secp256k1_context* ctx,
+ const secp256k1_context *ctx,
secp256k1_pubkey *pubkey
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);
@@ -751,7 +751,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_negate(
* is negligible (around 1 in 2^128).
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_tweak_add(
- const secp256k1_context* ctx,
+ const secp256k1_context *ctx,
unsigned char *seckey,
const unsigned char *tweak32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
@@ -759,7 +759,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_tweak_add(
/** Same as secp256k1_ec_seckey_tweak_add, but DEPRECATED. Will be removed in
* future versions. */
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_add(
- const secp256k1_context* ctx,
+ const secp256k1_context *ctx,
unsigned char *seckey,
const unsigned char *tweak32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
@@ -779,7 +779,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_add(
* is negligible (around 1 in 2^128).
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_add(
- const secp256k1_context* ctx,
+ const secp256k1_context *ctx,
secp256k1_pubkey *pubkey,
const unsigned char *tweak32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
@@ -798,7 +798,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_add(
* is negligible (around 1 in 2^128).
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_tweak_mul(
- const secp256k1_context* ctx,
+ const secp256k1_context *ctx,
unsigned char *seckey,
const unsigned char *tweak32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
@@ -806,7 +806,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_tweak_mul(
/** Same as secp256k1_ec_seckey_tweak_mul, but DEPRECATED. Will be removed in
* future versions. */
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_mul(
- const secp256k1_context* ctx,
+ const secp256k1_context *ctx,
unsigned char *seckey,
const unsigned char *tweak32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
@@ -824,7 +824,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_mul(
* is negligible (around 1 in 2^128).
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_mul(
- const secp256k1_context* ctx,
+ const secp256k1_context *ctx,
secp256k1_pubkey *pubkey,
const unsigned char *tweak32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
@@ -862,7 +862,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_mul(
* enhanced protection against side-channel leakage currently.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_context_randomize(
- secp256k1_context* ctx,
+ secp256k1_context *ctx,
const unsigned char *seed32
) SECP256K1_ARG_NONNULL(1);
@@ -876,9 +876,9 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_context_randomize(
* n: the number of public keys to add together (must be at least 1).
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_combine(
- const secp256k1_context* ctx,
+ const secp256k1_context *ctx,
secp256k1_pubkey *out,
- const secp256k1_pubkey * const * ins,
+ const secp256k1_pubkey * const *ins,
size_t n
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
@@ -899,7 +899,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_combine(
* msglen: length of the message array
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_tagged_sha256(
- const secp256k1_context* ctx,
+ const secp256k1_context *ctx,
unsigned char *hash32,
const unsigned char *tag,
size_t taglen,
diff --git a/src/secp256k1/include/secp256k1_ecdh.h b/src/secp256k1/include/secp256k1_ecdh.h
index 625061b282..837ae2abe5 100644
--- a/src/secp256k1/include/secp256k1_ecdh.h
+++ b/src/secp256k1/include/secp256k1_ecdh.h
@@ -48,7 +48,7 @@ SECP256K1_API_VAR const secp256k1_ecdh_hash_function secp256k1_ecdh_hash_functio
* (can be NULL for secp256k1_ecdh_hash_function_sha256).
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdh(
- const secp256k1_context* ctx,
+ const secp256k1_context *ctx,
unsigned char *output,
const secp256k1_pubkey *pubkey,
const unsigned char *seckey,
diff --git a/src/secp256k1/include/secp256k1_extrakeys.h b/src/secp256k1/include/secp256k1_extrakeys.h
index 3591bc0012..52bba240b4 100644
--- a/src/secp256k1/include/secp256k1_extrakeys.h
+++ b/src/secp256k1/include/secp256k1_extrakeys.h
@@ -45,8 +45,8 @@ typedef struct {
* In: input32: pointer to a serialized xonly_pubkey.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_xonly_pubkey_parse(
- const secp256k1_context* ctx,
- secp256k1_xonly_pubkey* pubkey,
+ const secp256k1_context *ctx,
+ secp256k1_xonly_pubkey *pubkey,
const unsigned char *input32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
@@ -59,9 +59,9 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_xonly_pubkey_parse(
* In: pubkey: a pointer to a secp256k1_xonly_pubkey containing an initialized public key.
*/
SECP256K1_API int secp256k1_xonly_pubkey_serialize(
- const secp256k1_context* ctx,
+ const secp256k1_context *ctx,
unsigned char *output32,
- const secp256k1_xonly_pubkey* pubkey
+ const secp256k1_xonly_pubkey *pubkey
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Compare two x-only public keys using lexicographic order
@@ -74,9 +74,9 @@ SECP256K1_API int secp256k1_xonly_pubkey_serialize(
* pubkey2: second public key to compare
*/
SECP256K1_API int secp256k1_xonly_pubkey_cmp(
- const secp256k1_context* ctx,
- const secp256k1_xonly_pubkey* pk1,
- const secp256k1_xonly_pubkey* pk2
+ const secp256k1_context *ctx,
+ const secp256k1_xonly_pubkey *pk1,
+ const secp256k1_xonly_pubkey *pk2
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Converts a secp256k1_pubkey into a secp256k1_xonly_pubkey.
@@ -91,7 +91,7 @@ SECP256K1_API int secp256k1_xonly_pubkey_cmp(
* In: pubkey: pointer to a public key that is converted.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_xonly_pubkey_from_pubkey(
- const secp256k1_context* ctx,
+ const secp256k1_context *ctx,
secp256k1_xonly_pubkey *xonly_pubkey,
int *pk_parity,
const secp256k1_pubkey *pubkey
@@ -118,7 +118,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_xonly_pubkey_from_pubke
* chance of being invalid is negligible (around 1 in 2^128).
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_xonly_pubkey_tweak_add(
- const secp256k1_context* ctx,
+ const secp256k1_context *ctx,
secp256k1_pubkey *output_pubkey,
const secp256k1_xonly_pubkey *internal_pubkey,
const unsigned char *tweak32
@@ -148,7 +148,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_xonly_pubkey_tweak_add(
* tweak32: pointer to a 32-byte tweak.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_xonly_pubkey_tweak_add_check(
- const secp256k1_context* ctx,
+ const secp256k1_context *ctx,
const unsigned char *tweaked_pubkey32,
int tweaked_pk_parity,
const secp256k1_xonly_pubkey *internal_pubkey,
@@ -164,7 +164,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_xonly_pubkey_tweak_add_
* In: seckey: pointer to a 32-byte secret key.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_create(
- const secp256k1_context* ctx,
+ const secp256k1_context *ctx,
secp256k1_keypair *keypair,
const unsigned char *seckey
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
@@ -177,7 +177,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_create(
* In: keypair: pointer to a keypair.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_sec(
- const secp256k1_context* ctx,
+ const secp256k1_context *ctx,
unsigned char *seckey,
const secp256k1_keypair *keypair
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
@@ -191,7 +191,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_sec(
* In: keypair: pointer to a keypair.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_pub(
- const secp256k1_context* ctx,
+ const secp256k1_context *ctx,
secp256k1_pubkey *pubkey,
const secp256k1_keypair *keypair
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
@@ -211,7 +211,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_pub(
* In: keypair: pointer to a keypair.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_xonly_pub(
- const secp256k1_context* ctx,
+ const secp256k1_context *ctx,
secp256k1_xonly_pubkey *pubkey,
int *pk_parity,
const secp256k1_keypair *keypair
@@ -237,7 +237,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_xonly_pub(
* is negligible (around 1 in 2^128).
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_xonly_tweak_add(
- const secp256k1_context* ctx,
+ const secp256k1_context *ctx,
secp256k1_keypair *keypair,
const unsigned char *tweak32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
diff --git a/src/secp256k1/include/secp256k1_preallocated.h b/src/secp256k1/include/secp256k1_preallocated.h
index ffa96dd339..f37744777b 100644
--- a/src/secp256k1/include/secp256k1_preallocated.h
+++ b/src/secp256k1/include/secp256k1_preallocated.h
@@ -63,8 +63,8 @@ SECP256K1_API size_t secp256k1_context_preallocated_size(
* See also secp256k1_context_randomize (in secp256k1.h)
* and secp256k1_context_preallocated_destroy.
*/
-SECP256K1_API secp256k1_context* secp256k1_context_preallocated_create(
- void* prealloc,
+SECP256K1_API secp256k1_context *secp256k1_context_preallocated_create(
+ void *prealloc,
unsigned int flags
) SECP256K1_ARG_NONNULL(1) SECP256K1_WARN_UNUSED_RESULT;
@@ -75,7 +75,7 @@ SECP256K1_API secp256k1_context* secp256k1_context_preallocated_create(
* In: ctx: an existing context to copy.
*/
SECP256K1_API size_t secp256k1_context_preallocated_clone_size(
- const secp256k1_context* ctx
+ const secp256k1_context *ctx
) SECP256K1_ARG_NONNULL(1) SECP256K1_WARN_UNUSED_RESULT;
/** Copy a secp256k1 context object into caller-provided memory.
@@ -97,9 +97,9 @@ SECP256K1_API size_t secp256k1_context_preallocated_clone_size(
* size at least secp256k1_context_preallocated_size(flags)
* bytes, as detailed above.
*/
-SECP256K1_API secp256k1_context* secp256k1_context_preallocated_clone(
- const secp256k1_context* ctx,
- void* prealloc
+SECP256K1_API secp256k1_context *secp256k1_context_preallocated_clone(
+ const secp256k1_context *ctx,
+ void *prealloc
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_WARN_UNUSED_RESULT;
/** Destroy a secp256k1 context object that has been created in
@@ -124,7 +124,7 @@ SECP256K1_API secp256k1_context* secp256k1_context_preallocated_clone(
* (i.e., not secp256k1_context_static).
*/
SECP256K1_API void secp256k1_context_preallocated_destroy(
- secp256k1_context* ctx
+ secp256k1_context *ctx
) SECP256K1_ARG_NONNULL(1);
#ifdef __cplusplus
diff --git a/src/secp256k1/include/secp256k1_recovery.h b/src/secp256k1/include/secp256k1_recovery.h
index 824c604025..b12ca4d972 100644
--- a/src/secp256k1/include/secp256k1_recovery.h
+++ b/src/secp256k1/include/secp256k1_recovery.h
@@ -34,8 +34,8 @@ typedef struct {
* recid: the recovery id (0, 1, 2 or 3)
*/
SECP256K1_API int secp256k1_ecdsa_recoverable_signature_parse_compact(
- const secp256k1_context* ctx,
- secp256k1_ecdsa_recoverable_signature* sig,
+ const secp256k1_context *ctx,
+ secp256k1_ecdsa_recoverable_signature *sig,
const unsigned char *input64,
int recid
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
@@ -48,9 +48,9 @@ SECP256K1_API int secp256k1_ecdsa_recoverable_signature_parse_compact(
* In: sigin: a pointer to a recoverable signature.
*/
SECP256K1_API int secp256k1_ecdsa_recoverable_signature_convert(
- const secp256k1_context* ctx,
- secp256k1_ecdsa_signature* sig,
- const secp256k1_ecdsa_recoverable_signature* sigin
+ const secp256k1_context *ctx,
+ secp256k1_ecdsa_signature *sig,
+ const secp256k1_ecdsa_recoverable_signature *sigin
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Serialize an ECDSA signature in compact format (64 bytes + recovery id).
@@ -62,10 +62,10 @@ SECP256K1_API int secp256k1_ecdsa_recoverable_signature_convert(
* In: sig: a pointer to an initialized signature object.
*/
SECP256K1_API int secp256k1_ecdsa_recoverable_signature_serialize_compact(
- const secp256k1_context* ctx,
+ const secp256k1_context *ctx,
unsigned char *output64,
int *recid,
- const secp256k1_ecdsa_recoverable_signature* sig
+ const secp256k1_ecdsa_recoverable_signature *sig
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
/** Create a recoverable ECDSA signature.
@@ -82,7 +82,7 @@ SECP256K1_API int secp256k1_ecdsa_recoverable_signature_serialize_compact(
* (can be NULL for secp256k1_nonce_function_default).
*/
SECP256K1_API int secp256k1_ecdsa_sign_recoverable(
- const secp256k1_context* ctx,
+ const secp256k1_context *ctx,
secp256k1_ecdsa_recoverable_signature *sig,
const unsigned char *msghash32,
const unsigned char *seckey,
@@ -100,7 +100,7 @@ SECP256K1_API int secp256k1_ecdsa_sign_recoverable(
* msghash32: the 32-byte message hash assumed to be signed.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_recover(
- const secp256k1_context* ctx,
+ const secp256k1_context *ctx,
secp256k1_pubkey *pubkey,
const secp256k1_ecdsa_recoverable_signature *sig,
const unsigned char *msghash32
diff --git a/src/secp256k1/include/secp256k1_schnorrsig.h b/src/secp256k1/include/secp256k1_schnorrsig.h
index 4cd2d98256..733fee5282 100644
--- a/src/secp256k1/include/secp256k1_schnorrsig.h
+++ b/src/secp256k1/include/secp256k1_schnorrsig.h
@@ -82,7 +82,7 @@ SECP256K1_API_VAR const secp256k1_nonce_function_hardened secp256k1_nonce_functi
typedef struct {
unsigned char magic[4];
secp256k1_nonce_function_hardened noncefp;
- void* ndata;
+ void *ndata;
} secp256k1_schnorrsig_extraparams;
#define SECP256K1_SCHNORRSIG_EXTRAPARAMS_MAGIC { 0xda, 0x6f, 0xb3, 0x8c }
@@ -117,7 +117,7 @@ typedef struct {
* argument and for guidance if randomness is expensive.
*/
SECP256K1_API int secp256k1_schnorrsig_sign32(
- const secp256k1_context* ctx,
+ const secp256k1_context *ctx,
unsigned char *sig64,
const unsigned char *msg32,
const secp256k1_keypair *keypair,
@@ -127,7 +127,7 @@ SECP256K1_API int secp256k1_schnorrsig_sign32(
/** Same as secp256k1_schnorrsig_sign32, but DEPRECATED. Will be removed in
* future versions. */
SECP256K1_API int secp256k1_schnorrsig_sign(
- const secp256k1_context* ctx,
+ const secp256k1_context *ctx,
unsigned char *sig64,
const unsigned char *msg32,
const secp256k1_keypair *keypair,
@@ -149,7 +149,7 @@ SECP256K1_API int secp256k1_schnorrsig_sign(
* extraparams: pointer to a extraparams object (can be NULL)
*/
SECP256K1_API int secp256k1_schnorrsig_sign_custom(
- const secp256k1_context* ctx,
+ const secp256k1_context *ctx,
unsigned char *sig64,
const unsigned char *msg,
size_t msglen,
@@ -168,7 +168,7 @@ SECP256K1_API int secp256k1_schnorrsig_sign_custom(
* pubkey: pointer to an x-only public key to verify with (cannot be NULL)
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_schnorrsig_verify(
- const secp256k1_context* ctx,
+ const secp256k1_context *ctx,
const unsigned char *sig64,
const unsigned char *msg,
size_t msglen,
diff --git a/src/secp256k1/src/asm/field_10x26_arm.s b/src/secp256k1/src/asm/field_10x26_arm.s
index 5f68cefc46..42cbf879ef 100644
--- a/src/secp256k1/src/asm/field_10x26_arm.s
+++ b/src/secp256k1/src/asm/field_10x26_arm.s
@@ -29,6 +29,7 @@ Note:
.align 2
.global secp256k1_fe_mul_inner
.type secp256k1_fe_mul_inner, %function
+ .hidden secp256k1_fe_mul_inner
@ Arguments:
@ r0 r Restrict: can overlap with a, not with b
@ r1 a
@@ -516,6 +517,7 @@ secp256k1_fe_mul_inner:
.align 2
.global secp256k1_fe_sqr_inner
.type secp256k1_fe_sqr_inner, %function
+ .hidden secp256k1_fe_sqr_inner
@ Arguments:
@ r0 r Can overlap with a
@ r1 a
diff --git a/src/secp256k1/src/ecmult_const.h b/src/secp256k1/src/ecmult_const.h
index f891f3f306..417f328535 100644
--- a/src/secp256k1/src/ecmult_const.h
+++ b/src/secp256k1/src/ecmult_const.h
@@ -18,4 +18,25 @@
*/
static void secp256k1_ecmult_const(secp256k1_gej *r, const secp256k1_ge *a, const secp256k1_scalar *q, int bits);
+/**
+ * Same as secp256k1_ecmult_const, but takes in an x coordinate of the base point
+ * only, specified as fraction n/d (numerator/denominator). Only the x coordinate of the result is
+ * returned.
+ *
+ * If known_on_curve is 0, a verification is performed that n/d is a valid X
+ * coordinate, and 0 is returned if not. Otherwise, 1 is returned.
+ *
+ * d being NULL is interpreted as d=1. If non-NULL, d must not be zero. q must not be zero.
+ *
+ * Constant time in the value of q, but not any other inputs.
+ */
+static int secp256k1_ecmult_const_xonly(
+ secp256k1_fe *r,
+ const secp256k1_fe *n,
+ const secp256k1_fe *d,
+ const secp256k1_scalar *q,
+ int bits,
+ int known_on_curve
+);
+
#endif /* SECP256K1_ECMULT_CONST_H */
diff --git a/src/secp256k1/src/ecmult_const_impl.h b/src/secp256k1/src/ecmult_const_impl.h
index 12dbcc6c5b..f23e0ec89d 100644
--- a/src/secp256k1/src/ecmult_const_impl.h
+++ b/src/secp256k1/src/ecmult_const_impl.h
@@ -228,4 +228,139 @@ static void secp256k1_ecmult_const(secp256k1_gej *r, const secp256k1_ge *a, cons
secp256k1_fe_mul(&r->z, &r->z, &Z);
}
+static int secp256k1_ecmult_const_xonly(secp256k1_fe* r, const secp256k1_fe *n, const secp256k1_fe *d, const secp256k1_scalar *q, int bits, int known_on_curve) {
+
+ /* This algorithm is a generalization of Peter Dettman's technique for
+ * avoiding the square root in a random-basepoint x-only multiplication
+ * on a Weierstrass curve:
+ * https://mailarchive.ietf.org/arch/msg/cfrg/7DyYY6gg32wDgHAhgSb6XxMDlJA/
+ *
+ *
+ * === Background: the effective affine technique ===
+ *
+ * Let phi_u be the isomorphism that maps (x, y) on secp256k1 curve y^2 = x^3 + 7 to
+ * x' = u^2*x, y' = u^3*y on curve y'^2 = x'^3 + u^6*7. This new curve has the same order as
+ * the original (it is isomorphic), but moreover, has the same addition/doubling formulas, as
+ * the curve b=7 coefficient does not appear in those formulas (or at least does not appear in
+ * the formulas implemented in this codebase, both affine and Jacobian). See also Example 9.5.2
+ * in https://www.math.auckland.ac.nz/~sgal018/crypto-book/ch9.pdf.
+ *
+ * This means any linear combination of secp256k1 points can be computed by applying phi_u
+ * (with non-zero u) on all input points (including the generator, if used), computing the
+ * linear combination on the isomorphic curve (using the same group laws), and then applying
+ * phi_u^{-1} to get back to secp256k1.
+ *
+ * Switching to Jacobian coordinates, note that phi_u applied to (X, Y, Z) is simply
+ * (X, Y, Z/u). Thus, if we want to compute (X1, Y1, Z) + (X2, Y2, Z), with identical Z
+ * coordinates, we can use phi_Z to transform it to (X1, Y1, 1) + (X2, Y2, 1) on an isomorphic
+ * curve where the affine addition formula can be used instead.
+ * If (X3, Y3, Z3) = (X1, Y1) + (X2, Y2) on that curve, then our answer on secp256k1 is
+ * (X3, Y3, Z3*Z).
+ *
+ * This is the effective affine technique: if we have a linear combination of group elements
+ * to compute, and all those group elements have the same Z coordinate, we can simply pretend
+ * that all those Z coordinates are 1, perform the computation that way, and then multiply the
+ * original Z coordinate back in.
+ *
+ * The technique works on any a=0 short Weierstrass curve. It is possible to generalize it to
+ * other curves too, but there the isomorphic curves will have different 'a' coefficients,
+ * which typically does affect the group laws.
+ *
+ *
+ * === Avoiding the square root for x-only point multiplication ===
+ *
+ * In this function, we want to compute the X coordinate of q*(n/d, y), for
+ * y = sqrt((n/d)^3 + 7). Its negation would also be a valid Y coordinate, but by convention
+ * we pick whatever sqrt returns (which we assume to be a deterministic function).
+ *
+ * Let g = y^2*d^3 = n^3 + 7*d^3. This also means y = sqrt(g/d^3).
+ * Further let v = sqrt(d*g), which must exist as d*g = y^2*d^4 = (y*d^2)^2.
+ *
+ * The input point (n/d, y) also has Jacobian coordinates:
+ *
+ * (n/d, y, 1)
+ * = (n/d * v^2, y * v^3, v)
+ * = (n/d * d*g, y * sqrt(d^3*g^3), v)
+ * = (n/d * d*g, sqrt(y^2 * d^3*g^3), v)
+ * = (n*g, sqrt(g/d^3 * d^3*g^3), v)
+ * = (n*g, sqrt(g^4), v)
+ * = (n*g, g^2, v)
+ *
+ * It is easy to verify that both (n*g, g^2, v) and its negation (n*g, -g^2, v) have affine X
+ * coordinate n/d, and this holds even when the square root function doesn't have a
+ * determinstic sign. We choose the (n*g, g^2, v) version.
+ *
+ * Now switch to the effective affine curve using phi_v, where the input point has coordinates
+ * (n*g, g^2). Compute (X, Y, Z) = q * (n*g, g^2) there.
+ *
+ * Back on secp256k1, that means q * (n*g, g^2, v) = (X, Y, v*Z). This last point has affine X
+ * coordinate X / (v^2*Z^2) = X / (d*g*Z^2). Determining the affine Y coordinate would involve
+ * a square root, but as long as we only care about the resulting X coordinate, no square root
+ * is needed anywhere in this computation.
+ */
+
+ secp256k1_fe g, i;
+ secp256k1_ge p;
+ secp256k1_gej rj;
+
+ /* Compute g = (n^3 + B*d^3). */
+ secp256k1_fe_sqr(&g, n);
+ secp256k1_fe_mul(&g, &g, n);
+ if (d) {
+ secp256k1_fe b;
+#ifdef VERIFY
+ VERIFY_CHECK(!secp256k1_fe_normalizes_to_zero(d));
+#endif
+ secp256k1_fe_sqr(&b, d);
+ VERIFY_CHECK(SECP256K1_B <= 8); /* magnitude of b will be <= 8 after the next call */
+ secp256k1_fe_mul_int(&b, SECP256K1_B);
+ secp256k1_fe_mul(&b, &b, d);
+ secp256k1_fe_add(&g, &b);
+ if (!known_on_curve) {
+ /* We need to determine whether (n/d)^3 + 7 is square.
+ *
+ * is_square((n/d)^3 + 7)
+ * <=> is_square(((n/d)^3 + 7) * d^4)
+ * <=> is_square((n^3 + 7*d^3) * d)
+ * <=> is_square(g * d)
+ */
+ secp256k1_fe c;
+ secp256k1_fe_mul(&c, &g, d);
+ if (!secp256k1_fe_is_square_var(&c)) return 0;
+ }
+ } else {
+ secp256k1_fe_add_int(&g, SECP256K1_B);
+ if (!known_on_curve) {
+ /* g at this point equals x^3 + 7. Test if it is square. */
+ if (!secp256k1_fe_is_square_var(&g)) return 0;
+ }
+ }
+
+ /* Compute base point P = (n*g, g^2), the effective affine version of (n*g, g^2, v), which has
+ * corresponding affine X coordinate n/d. */
+ secp256k1_fe_mul(&p.x, &g, n);
+ secp256k1_fe_sqr(&p.y, &g);
+ p.infinity = 0;
+
+ /* Perform x-only EC multiplication of P with q. */
+#ifdef VERIFY
+ VERIFY_CHECK(!secp256k1_scalar_is_zero(q));
+#endif
+ secp256k1_ecmult_const(&rj, &p, q, bits);
+#ifdef VERIFY
+ VERIFY_CHECK(!secp256k1_gej_is_infinity(&rj));
+#endif
+
+ /* The resulting (X, Y, Z) point on the effective-affine isomorphic curve corresponds to
+ * (X, Y, Z*v) on the secp256k1 curve. The affine version of that has X coordinate
+ * (X / (Z^2*d*g)). */
+ secp256k1_fe_sqr(&i, &rj.z);
+ secp256k1_fe_mul(&i, &i, &g);
+ if (d) secp256k1_fe_mul(&i, &i, d);
+ secp256k1_fe_inv(&i, &i);
+ secp256k1_fe_mul(r, &rj.x, &i);
+
+ return 1;
+}
+
#endif /* SECP256K1_ECMULT_CONST_IMPL_H */
diff --git a/src/secp256k1/src/ecmult_impl.h b/src/secp256k1/src/ecmult_impl.h
index 3776fe73fc..a9a63850ef 100644
--- a/src/secp256k1/src/ecmult_impl.h
+++ b/src/secp256k1/src/ecmult_impl.h
@@ -97,7 +97,7 @@ static void secp256k1_ecmult_odd_multiples_table(int n, secp256k1_ge *pre_a, sec
secp256k1_gej_set_ge(&ai, &pre_a[0]);
ai.z = a->z;
- /* pre_a[0] is the point (a.x*C^2, a.y*C^3, a.z*C) which is equvalent to a.
+ /* pre_a[0] is the point (a.x*C^2, a.y*C^3, a.z*C) which is equivalent to a.
* Set zr[0] to C, which is the ratio between the omitted z(pre_a[0]) value and a.z.
*/
zr[0] = d.z;
@@ -114,13 +114,16 @@ static void secp256k1_ecmult_odd_multiples_table(int n, secp256k1_ge *pre_a, sec
secp256k1_fe_mul(z, &ai.z, &d.z);
}
-#define SECP256K1_ECMULT_TABLE_VERIFY(n,w) \
- VERIFY_CHECK(((n) & 1) == 1); \
- VERIFY_CHECK((n) >= -((1 << ((w)-1)) - 1)); \
+SECP256K1_INLINE static void secp256k1_ecmult_table_verify(int n, int w) {
+ (void)n;
+ (void)w;
+ VERIFY_CHECK(((n) & 1) == 1);
+ VERIFY_CHECK((n) >= -((1 << ((w)-1)) - 1));
VERIFY_CHECK((n) <= ((1 << ((w)-1)) - 1));
+}
SECP256K1_INLINE static void secp256k1_ecmult_table_get_ge(secp256k1_ge *r, const secp256k1_ge *pre, int n, int w) {
- SECP256K1_ECMULT_TABLE_VERIFY(n,w)
+ secp256k1_ecmult_table_verify(n,w);
if (n > 0) {
*r = pre[(n-1)/2];
} else {
@@ -130,7 +133,7 @@ SECP256K1_INLINE static void secp256k1_ecmult_table_get_ge(secp256k1_ge *r, cons
}
SECP256K1_INLINE static void secp256k1_ecmult_table_get_ge_lambda(secp256k1_ge *r, const secp256k1_ge *pre, const secp256k1_fe *x, int n, int w) {
- SECP256K1_ECMULT_TABLE_VERIFY(n,w)
+ secp256k1_ecmult_table_verify(n,w);
if (n > 0) {
secp256k1_ge_set_xy(r, &x[(n-1)/2], &pre[(n-1)/2].y);
} else {
@@ -140,7 +143,7 @@ SECP256K1_INLINE static void secp256k1_ecmult_table_get_ge_lambda(secp256k1_ge *
}
SECP256K1_INLINE static void secp256k1_ecmult_table_get_ge_storage(secp256k1_ge *r, const secp256k1_ge_storage *pre, int n, int w) {
- SECP256K1_ECMULT_TABLE_VERIFY(n,w)
+ secp256k1_ecmult_table_verify(n,w);
if (n > 0) {
secp256k1_ge_from_storage(r, &pre[(n-1)/2]);
} else {
diff --git a/src/secp256k1/src/field_10x26_impl.h b/src/secp256k1/src/field_10x26_impl.h
index 46b72ce78d..3b7f4d2480 100644
--- a/src/secp256k1/src/field_10x26_impl.h
+++ b/src/secp256k1/src/field_10x26_impl.h
@@ -1147,8 +1147,9 @@ static void secp256k1_fe_sqr(secp256k1_fe *r, const secp256k1_fe *a) {
static SECP256K1_INLINE void secp256k1_fe_cmov(secp256k1_fe *r, const secp256k1_fe *a, int flag) {
uint32_t mask0, mask1;
+ volatile int vflag = flag;
SECP256K1_CHECKMEM_CHECK_VERIFY(r->n, sizeof(r->n));
- mask0 = flag + ~((uint32_t)0);
+ mask0 = vflag + ~((uint32_t)0);
mask1 = ~mask0;
r->n[0] = (r->n[0] & mask0) | (a->n[0] & mask1);
r->n[1] = (r->n[1] & mask0) | (a->n[1] & mask1);
@@ -1246,8 +1247,9 @@ static SECP256K1_INLINE void secp256k1_fe_half(secp256k1_fe *r) {
static SECP256K1_INLINE void secp256k1_fe_storage_cmov(secp256k1_fe_storage *r, const secp256k1_fe_storage *a, int flag) {
uint32_t mask0, mask1;
+ volatile int vflag = flag;
SECP256K1_CHECKMEM_CHECK_VERIFY(r->n, sizeof(r->n));
- mask0 = flag + ~((uint32_t)0);
+ mask0 = vflag + ~((uint32_t)0);
mask1 = ~mask0;
r->n[0] = (r->n[0] & mask0) | (a->n[0] & mask1);
r->n[1] = (r->n[1] & mask0) | (a->n[1] & mask1);
@@ -1363,7 +1365,9 @@ static void secp256k1_fe_inv(secp256k1_fe *r, const secp256k1_fe *x) {
secp256k1_modinv32(&s, &secp256k1_const_modinfo_fe);
secp256k1_fe_from_signed30(r, &s);
+#ifdef VERIFY
VERIFY_CHECK(secp256k1_fe_normalizes_to_zero(r) == secp256k1_fe_normalizes_to_zero(&tmp));
+#endif
}
static void secp256k1_fe_inv_var(secp256k1_fe *r, const secp256k1_fe *x) {
@@ -1376,7 +1380,9 @@ static void secp256k1_fe_inv_var(secp256k1_fe *r, const secp256k1_fe *x) {
secp256k1_modinv32_var(&s, &secp256k1_const_modinfo_fe);
secp256k1_fe_from_signed30(r, &s);
+#ifdef VERIFY
VERIFY_CHECK(secp256k1_fe_normalizes_to_zero(r) == secp256k1_fe_normalizes_to_zero(&tmp));
+#endif
}
static int secp256k1_fe_is_square_var(const secp256k1_fe *x) {
diff --git a/src/secp256k1/src/field_5x52_impl.h b/src/secp256k1/src/field_5x52_impl.h
index 4c4466eceb..6b97157d0f 100644
--- a/src/secp256k1/src/field_5x52_impl.h
+++ b/src/secp256k1/src/field_5x52_impl.h
@@ -487,8 +487,9 @@ static void secp256k1_fe_sqr(secp256k1_fe *r, const secp256k1_fe *a) {
static SECP256K1_INLINE void secp256k1_fe_cmov(secp256k1_fe *r, const secp256k1_fe *a, int flag) {
uint64_t mask0, mask1;
+ volatile int vflag = flag;
SECP256K1_CHECKMEM_CHECK_VERIFY(r->n, sizeof(r->n));
- mask0 = flag + ~((uint64_t)0);
+ mask0 = vflag + ~((uint64_t)0);
mask1 = ~mask0;
r->n[0] = (r->n[0] & mask0) | (a->n[0] & mask1);
r->n[1] = (r->n[1] & mask0) | (a->n[1] & mask1);
@@ -570,8 +571,9 @@ static SECP256K1_INLINE void secp256k1_fe_half(secp256k1_fe *r) {
static SECP256K1_INLINE void secp256k1_fe_storage_cmov(secp256k1_fe_storage *r, const secp256k1_fe_storage *a, int flag) {
uint64_t mask0, mask1;
+ volatile int vflag = flag;
SECP256K1_CHECKMEM_CHECK_VERIFY(r->n, sizeof(r->n));
- mask0 = flag + ~((uint64_t)0);
+ mask0 = vflag + ~((uint64_t)0);
mask1 = ~mask0;
r->n[0] = (r->n[0] & mask0) | (a->n[0] & mask1);
r->n[1] = (r->n[1] & mask0) | (a->n[1] & mask1);
diff --git a/src/secp256k1/src/int128_struct_impl.h b/src/secp256k1/src/int128_struct_impl.h
index 2eb337cb54..cc17bad167 100644
--- a/src/secp256k1/src/int128_struct_impl.h
+++ b/src/secp256k1/src/int128_struct_impl.h
@@ -193,7 +193,7 @@ static SECP256K1_INLINE int secp256k1_i128_check_pow2(const secp256k1_int128 *r,
VERIFY_CHECK(n < 127);
VERIFY_CHECK(sign == 1 || sign == -1);
return n >= 64 ? r->hi == (uint64_t)sign << (n - 64) && r->lo == 0
- : r->hi == (uint64_t)((sign - 1) >> 1) && r->lo == (uint64_t)sign << n;
+ : r->hi == (uint64_t)(sign >> 1) && r->lo == (uint64_t)sign << n;
}
#endif
diff --git a/src/secp256k1/src/modinv32_impl.h b/src/secp256k1/src/modinv32_impl.h
index 643750560e..8e400b697b 100644
--- a/src/secp256k1/src/modinv32_impl.h
+++ b/src/secp256k1/src/modinv32_impl.h
@@ -232,7 +232,7 @@ static int32_t secp256k1_modinv32_divsteps_30(int32_t zeta, uint32_t f0, uint32_
return zeta;
}
-/* inv256[i] = -(2*i+1)^-1 (mod 256) */
+/* secp256k1_modinv32_inv256[i] = -(2*i+1)^-1 (mod 256) */
static const uint8_t secp256k1_modinv32_inv256[128] = {
0xFF, 0x55, 0x33, 0x49, 0xC7, 0x5D, 0x3B, 0x11, 0x0F, 0xE5, 0xC3, 0x59,
0xD7, 0xED, 0xCB, 0x21, 0x1F, 0x75, 0x53, 0x69, 0xE7, 0x7D, 0x5B, 0x31,
diff --git a/src/secp256k1/src/scalar_4x64_impl.h b/src/secp256k1/src/scalar_4x64_impl.h
index 1b83575b3e..1959dae986 100644
--- a/src/secp256k1/src/scalar_4x64_impl.h
+++ b/src/secp256k1/src/scalar_4x64_impl.h
@@ -811,8 +811,9 @@ SECP256K1_INLINE static void secp256k1_scalar_mul_shift_var(secp256k1_scalar *r,
static SECP256K1_INLINE void secp256k1_scalar_cmov(secp256k1_scalar *r, const secp256k1_scalar *a, int flag) {
uint64_t mask0, mask1;
+ volatile int vflag = flag;
SECP256K1_CHECKMEM_CHECK_VERIFY(r->d, sizeof(r->d));
- mask0 = flag + ~((uint64_t)0);
+ mask0 = vflag + ~((uint64_t)0);
mask1 = ~mask0;
r->d[0] = (r->d[0] & mask0) | (a->d[0] & mask1);
r->d[1] = (r->d[1] & mask0) | (a->d[1] & mask1);
diff --git a/src/secp256k1/src/scalar_8x32_impl.h b/src/secp256k1/src/scalar_8x32_impl.h
index c433adce75..a2555cbbcd 100644
--- a/src/secp256k1/src/scalar_8x32_impl.h
+++ b/src/secp256k1/src/scalar_8x32_impl.h
@@ -632,8 +632,9 @@ SECP256K1_INLINE static void secp256k1_scalar_mul_shift_var(secp256k1_scalar *r,
static SECP256K1_INLINE void secp256k1_scalar_cmov(secp256k1_scalar *r, const secp256k1_scalar *a, int flag) {
uint32_t mask0, mask1;
+ volatile int vflag = flag;
SECP256K1_CHECKMEM_CHECK_VERIFY(r->d, sizeof(r->d));
- mask0 = flag + ~((uint32_t)0);
+ mask0 = vflag + ~((uint32_t)0);
mask1 = ~mask0;
r->d[0] = (r->d[0] & mask0) | (a->d[0] & mask1);
r->d[1] = (r->d[1] & mask0) | (a->d[1] & mask1);
diff --git a/src/secp256k1/src/scalar_low_impl.h b/src/secp256k1/src/scalar_low_impl.h
index e780083339..bfd1139110 100644
--- a/src/secp256k1/src/scalar_low_impl.h
+++ b/src/secp256k1/src/scalar_low_impl.h
@@ -116,8 +116,9 @@ SECP256K1_INLINE static int secp256k1_scalar_eq(const secp256k1_scalar *a, const
static SECP256K1_INLINE void secp256k1_scalar_cmov(secp256k1_scalar *r, const secp256k1_scalar *a, int flag) {
uint32_t mask0, mask1;
+ volatile int vflag = flag;
SECP256K1_CHECKMEM_CHECK_VERIFY(r, sizeof(*r));
- mask0 = flag + ~((uint32_t)0);
+ mask0 = vflag + ~((uint32_t)0);
mask1 = ~mask0;
*r = (*r & mask0) | (*a & mask1);
}
diff --git a/src/secp256k1/src/tests.c b/src/secp256k1/src/tests.c
index 1c0d797349..7f61f737c6 100644
--- a/src/secp256k1/src/tests.c
+++ b/src/secp256k1/src/tests.c
@@ -4452,6 +4452,68 @@ static void ecmult_const_mult_zero_one(void) {
ge_equals_ge(&res2, &point);
}
+static void ecmult_const_mult_xonly(void) {
+ int i;
+
+ /* Test correspondence between secp256k1_ecmult_const and secp256k1_ecmult_const_xonly. */
+ for (i = 0; i < 2*COUNT; ++i) {
+ secp256k1_ge base;
+ secp256k1_gej basej, resj;
+ secp256k1_fe n, d, resx, v;
+ secp256k1_scalar q;
+ int res;
+ /* Random base point. */
+ random_group_element_test(&base);
+ /* Random scalar to multiply it with. */
+ random_scalar_order_test(&q);
+ /* If i is odd, n=d*base.x for random non-zero d */
+ if (i & 1) {
+ do {
+ random_field_element_test(&d);
+ } while (secp256k1_fe_normalizes_to_zero_var(&d));
+ secp256k1_fe_mul(&n, &base.x, &d);
+ } else {
+ n = base.x;
+ }
+ /* Perform x-only multiplication. */
+ res = secp256k1_ecmult_const_xonly(&resx, &n, (i & 1) ? &d : NULL, &q, 256, i & 2);
+ CHECK(res);
+ /* Perform normal multiplication. */
+ secp256k1_gej_set_ge(&basej, &base);
+ secp256k1_ecmult(&resj, &basej, &q, NULL);
+ /* Check that resj's X coordinate corresponds with resx. */
+ secp256k1_fe_sqr(&v, &resj.z);
+ secp256k1_fe_mul(&v, &v, &resx);
+ CHECK(check_fe_equal(&v, &resj.x));
+ }
+
+ /* Test that secp256k1_ecmult_const_xonly correctly rejects X coordinates not on curve. */
+ for (i = 0; i < 2*COUNT; ++i) {
+ secp256k1_fe x, n, d, c, r;
+ int res;
+ secp256k1_scalar q;
+ random_scalar_order_test(&q);
+ /* Generate random X coordinate not on the curve. */
+ do {
+ random_field_element_test(&x);
+ secp256k1_fe_sqr(&c, &x);
+ secp256k1_fe_mul(&c, &c, &x);
+ secp256k1_fe_add(&c, &secp256k1_fe_const_b);
+ } while (secp256k1_fe_is_square_var(&c));
+ /* If i is odd, n=d*x for random non-zero d. */
+ if (i & 1) {
+ do {
+ random_field_element_test(&d);
+ } while (secp256k1_fe_normalizes_to_zero_var(&d));
+ secp256k1_fe_mul(&n, &x, &d);
+ } else {
+ n = x;
+ }
+ res = secp256k1_ecmult_const_xonly(&r, &n, (i & 1) ? &d : NULL, &q, 256, 0);
+ CHECK(res == 0);
+ }
+}
+
static void ecmult_const_chain_multiply(void) {
/* Check known result (randomly generated test problem from sage) */
const secp256k1_scalar scalar = SECP256K1_SCALAR_CONST(
@@ -4483,6 +4545,7 @@ static void run_ecmult_const_tests(void) {
ecmult_const_random_mult();
ecmult_const_commutativity();
ecmult_const_chain_multiply();
+ ecmult_const_mult_xonly();
}
typedef struct {
@@ -7306,6 +7369,44 @@ static void run_ecdsa_edge_cases(void) {
test_ecdsa_edge_cases();
}
+/** Wycheproof tests
+
+The tests check for known attacks (range checks in (r,s), arithmetic errors, malleability).
+*/
+static void test_ecdsa_wycheproof(void) {
+ #include "wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.h"
+
+ int t;
+ for (t = 0; t < SECP256K1_ECDSA_WYCHEPROOF_NUMBER_TESTVECTORS; t++) {
+ secp256k1_ecdsa_signature signature;
+ secp256k1_sha256 hasher;
+ secp256k1_pubkey pubkey;
+ const unsigned char *msg, *sig, *pk;
+ unsigned char out[32] = {0};
+ int actual_verify = 0;
+
+ memset(&pubkey, 0, sizeof(pubkey));
+ pk = &wycheproof_ecdsa_public_keys[testvectors[t].pk_offset];
+ CHECK(secp256k1_ec_pubkey_parse(CTX, &pubkey, pk, 65) == 1);
+
+ secp256k1_sha256_initialize(&hasher);
+ msg = &wycheproof_ecdsa_messages[testvectors[t].msg_offset];
+ secp256k1_sha256_write(&hasher, msg, testvectors[t].msg_len);
+ secp256k1_sha256_finalize(&hasher, out);
+
+ sig = &wycheproof_ecdsa_signatures[testvectors[t].sig_offset];
+ if (secp256k1_ecdsa_signature_parse_der(CTX, &signature, sig, testvectors[t].sig_len) == 1) {
+ actual_verify = secp256k1_ecdsa_verify(CTX, (const secp256k1_ecdsa_signature *)&signature, out, &pubkey);
+ }
+ CHECK(testvectors[t].expected_verify == actual_verify);
+ }
+}
+
+/* Tests cases from Wycheproof test suite. */
+static void run_ecdsa_wycheproof(void) {
+ test_ecdsa_wycheproof();
+}
+
#ifdef ENABLE_MODULE_ECDH
# include "modules/ecdh/tests_impl.h"
#endif
@@ -7638,6 +7739,7 @@ int main(int argc, char **argv) {
run_ecdsa_sign_verify();
run_ecdsa_end_to_end();
run_ecdsa_edge_cases();
+ run_ecdsa_wycheproof();
#ifdef ENABLE_MODULE_RECOVERY
/* ECDSA pubkey recovery tests */
diff --git a/src/secp256k1/src/tests_exhaustive.c b/src/secp256k1/src/tests_exhaustive.c
index 86b9334cae..63b6ef03af 100644
--- a/src/secp256k1/src/tests_exhaustive.c
+++ b/src/secp256k1/src/tests_exhaustive.c
@@ -59,6 +59,19 @@ static void random_fe(secp256k1_fe *x) {
}
} while(1);
}
+
+static void random_fe_non_zero(secp256k1_fe *nz) {
+ int tries = 10;
+ while (--tries >= 0) {
+ random_fe(nz);
+ secp256k1_fe_normalize(nz);
+ if (!secp256k1_fe_is_zero(nz)) {
+ break;
+ }
+ }
+ /* Infinitesimal probability of spurious failure here */
+ CHECK(tries >= 0);
+}
/** END stolen from tests.c */
static uint32_t num_cores = 1;
@@ -174,10 +187,37 @@ static void test_exhaustive_ecmult(const secp256k1_ge *group, const secp256k1_ge
secp256k1_ecmult(&tmp, &groupj[r_log], &na, &ng);
ge_equals_gej(&group[(i * r_log + j) % EXHAUSTIVE_TEST_ORDER], &tmp);
- if (i > 0) {
- secp256k1_ecmult_const(&tmp, &group[i], &ng, 256);
- ge_equals_gej(&group[(i * j) % EXHAUSTIVE_TEST_ORDER], &tmp);
- }
+ }
+ }
+ }
+
+ for (j = 0; j < EXHAUSTIVE_TEST_ORDER; j++) {
+ for (i = 1; i < EXHAUSTIVE_TEST_ORDER; i++) {
+ int ret;
+ secp256k1_gej tmp;
+ secp256k1_fe xn, xd, tmpf;
+ secp256k1_scalar ng;
+
+ if (skip_section(&iter)) continue;
+
+ secp256k1_scalar_set_int(&ng, j);
+
+ /* Test secp256k1_ecmult_const. */
+ secp256k1_ecmult_const(&tmp, &group[i], &ng, 256);
+ ge_equals_gej(&group[(i * j) % EXHAUSTIVE_TEST_ORDER], &tmp);
+
+ if (j != 0) {
+ /* Test secp256k1_ecmult_const_xonly with all curve X coordinates, and xd=NULL. */
+ ret = secp256k1_ecmult_const_xonly(&tmpf, &group[i].x, NULL, &ng, 256, 0);
+ CHECK(ret);
+ CHECK(secp256k1_fe_equal_var(&tmpf, &group[(i * j) % EXHAUSTIVE_TEST_ORDER].x));
+
+ /* Test secp256k1_ecmult_const_xonly with all curve X coordinates, with random xd. */
+ random_fe_non_zero(&xd);
+ secp256k1_fe_mul(&xn, &xd, &group[i].x);
+ ret = secp256k1_ecmult_const_xonly(&tmpf, &xn, &xd, &ng, 256, 0);
+ CHECK(ret);
+ CHECK(secp256k1_fe_equal_var(&tmpf, &group[(i * j) % EXHAUSTIVE_TEST_ORDER].x));
}
}
}
diff --git a/src/secp256k1/src/wycheproof/WYCHEPROOF_COPYING b/src/secp256k1/src/wycheproof/WYCHEPROOF_COPYING
new file mode 100644
index 0000000000..cddf9d9182
--- /dev/null
+++ b/src/secp256k1/src/wycheproof/WYCHEPROOF_COPYING
@@ -0,0 +1,212 @@
+* The file `ecdsa_secp256k1_sha256_bitcoin_test.json` in this directory
+ comes from Google's project Wycheproof with git commit
+ `b063b4aedae951c69df014cd25fa6d69ae9e8cb9`, see
+ https://github.com/google/wycheproof/blob/b063b4aedae951c69df014cd25fa6d69ae9e8cb9/testvectors_v1/ecdsa_secp256k1_sha256_bitcoin_test.json
+
+* The file `ecdsa_secp256k1_sha256_bitcoin_test.h` is generated from
+ `ecdsa_secp256k1_sha256_bitcoin_test.json` using the script
+ `tests_wycheproof_generate.py`.
+
+-------------------------------------------------------------------------------
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/src/secp256k1/src/wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.h b/src/secp256k1/src/wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.h
new file mode 100644
index 0000000000..736737fd61
--- /dev/null
+++ b/src/secp256k1/src/wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.h
@@ -0,0 +1,1564 @@
+/* Note: this file was autogenerated using tests_wycheproof_generate.py. Do not edit. */
+#define SECP256K1_ECDSA_WYCHEPROOF_NUMBER_TESTVECTORS (463)
+
+typedef struct {
+ size_t pk_offset;
+ size_t msg_offset;
+ size_t msg_len;
+ size_t sig_offset;
+ size_t sig_len;
+ int expected_verify;
+} wycheproof_ecdsa_testvector;
+
+static const unsigned char wycheproof_ecdsa_messages[] = { 0x31,0x32,0x33,0x34,0x30,0x30,
+ 0x32,0x35,0x35,0x38,0x35,
+ 0x34,0x32,0x36,0x34,0x37,0x39,0x37,0x32,0x34,
+ 0x37,0x31,0x33,0x38,0x36,0x38,0x34,0x38,0x39,0x31,
+ 0x31,0x30,0x33,0x35,0x39,0x33,0x33,0x31,0x36,0x36,0x38,
+ 0x33,0x39,0x34,0x39,0x34,0x30,0x31,0x32,0x31,0x35,
+ 0x31,0x33,0x34,0x34,0x32,0x39,0x33,0x30,0x37,0x39,
+ 0x33,0x37,0x30,0x36,0x32,0x31,0x31,0x37,0x31,0x32,
+ 0x33,0x34,0x33,0x36,0x38,0x38,0x37,0x31,0x32,
+ 0x31,0x33,0x35,0x31,0x35,0x33,0x30,0x33,0x37,0x30,
+ 0x36,0x35,0x35,0x33,0x32,0x30,0x33,0x31,0x32,0x36,
+ 0x31,0x35,0x36,0x34,0x33,0x34,0x36,0x36,0x30,0x33,
+ 0x34,0x34,0x32,0x39,0x35,0x33,0x39,0x31,0x31,0x37,
+ 0x31,0x30,0x39,0x35,0x33,0x32,0x36,0x31,0x33,0x35,0x31,
+ 0x35,0x39,0x38,0x37,0x33,0x35,0x30,0x30,0x34,0x31,
+ 0x33,0x34,0x36,0x33,0x30,0x30,0x36,0x38,0x37,0x38,
+ 0x39,0x38,0x31,0x37,0x33,0x32,0x30,0x32,0x38,0x37,
+ 0x33,0x32,0x32,0x32,0x30,0x34,0x31,0x30,0x34,0x36,
+ 0x36,0x36,0x36,0x36,0x33,0x30,0x37,0x31,0x30,0x34,
+ 0x31,0x30,0x33,0x35,0x39,0x35,0x31,0x38,0x39,0x38,
+ 0x31,0x38,0x34,0x36,0x35,0x39,0x37,0x31,0x39,0x35,
+ 0x33,0x31,0x33,0x36,0x30,0x34,0x36,0x31,0x38,0x39,
+ 0x32,0x36,0x36,0x33,0x37,0x38,0x34,0x32,0x35,0x34,
+ 0x31,0x36,0x35,0x32,0x31,0x30,0x30,0x35,0x32,0x34,
+ 0x35,0x37,0x34,0x38,0x30,0x38,0x31,0x36,0x39,0x36,
+ 0x36,0x33,0x34,0x33,0x39,0x31,0x33,0x34,0x36,0x38,
+ 0x31,0x35,0x34,0x31,0x31,0x30,0x33,0x35,0x39,0x38,
+ 0x31,0x30,0x34,0x37,0x38,0x35,0x38,0x30,0x31,0x32,0x38,
+ 0x31,0x30,0x35,0x33,0x36,0x32,0x38,0x35,0x35,0x36,0x38,
+ 0x39,0x35,0x33,0x39,0x30,0x34,0x31,0x30,0x35,
+ 0x39,0x37,0x38,0x38,0x34,0x38,0x30,0x33,0x39,
+ 0x33,0x36,0x31,0x30,0x36,0x37,0x32,0x34,0x34,0x32,
+ 0x31,0x30,0x35,0x34,0x32,0x34,0x30,0x37,0x30,0x35,
+ 0x35,0x31,0x37,0x34,0x34,0x34,0x38,0x31,0x39,0x37,
+ 0x31,0x39,0x36,0x37,0x35,0x36,0x31,0x32,0x35,0x31,
+ 0x33,0x34,0x34,0x37,0x32,0x35,0x33,0x33,0x34,0x33,
+ 0x33,0x36,0x38,0x32,0x36,0x34,0x33,0x31,0x38,
+ 0x33,0x32,0x36,0x31,0x31,0x39,0x38,0x36,0x30,0x38,
+ 0x39,0x36,0x37,0x38,0x37,0x38,0x31,0x30,0x39,0x34,
+ 0x34,0x39,0x35,0x38,0x38,0x32,0x33,0x38,0x32,0x33,
+ 0x38,0x32,0x34,0x36,0x33,0x37,0x38,0x33,0x37,
+ 0x31,0x31,0x30,0x32,0x30,0x38,0x33,0x33,0x37,0x37,0x36,
+ 0x31,0x33,0x33,0x38,0x37,0x31,0x36,0x34,0x38,
+ 0x33,0x32,0x32,0x31,0x34,0x34,0x31,0x36,0x32,
+ 0x31,0x30,0x36,0x38,0x36,0x36,0x35,0x35,0x35,0x34,0x36,
+ 0x36,0x32,0x31,0x35,0x35,0x32,0x34,0x36,
+ 0x37,0x30,0x33,0x30,0x38,0x31,0x38,0x37,0x37,0x34,
+ 0x35,0x39,0x32,0x34,0x35,0x32,0x33,0x37,0x34,0x34,
+ 0x31,0x34,0x39,0x35,0x35,0x38,0x36,0x36,0x32,0x31,
+ 0x34,0x30,0x30,0x35,0x33,0x31,0x34,0x34,0x30,0x36,
+ 0x33,0x30,0x39,0x36,0x34,0x35,0x37,0x35,0x31,0x32,
+ 0x32,0x37,0x38,0x34,0x30,0x32,0x35,0x36,0x32,0x30,
+ 0x32,0x36,0x31,0x38,0x37,0x38,0x37,0x34,0x31,0x38,
+ 0x31,0x36,0x34,0x32,0x36,0x32,0x35,0x32,0x36,0x32,
+ 0x36,0x38,0x32,0x34,0x31,0x38,0x39,0x34,0x33,0x36,
+ 0x34,0x38,0x34,0x32,0x34,0x35,0x34,0x32,0x35,
+ 0x4d,0x73,0x67,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x4d,0x65,0x73,0x73,0x61,0x67,0x65};
+
+static const unsigned char wycheproof_ecdsa_public_keys[] = { 0x04,0xb8,0x38,0xff,0x44,0xe5,0xbc,0x17,0x7b,0xf2,0x11,0x89,0xd0,0x76,0x60,0x82,0xfc,0x9d,0x84,0x32,0x26,0x88,0x7f,0xc9,0x76,0x03,0x71,0x10,0x0b,0x7e,0xe2,0x0a,0x6f,0xf0,0xc9,0xd7,0x5b,0xfb,0xa7,0xb3,0x1a,0x6b,0xca,0x19,0x74,0x49,0x6e,0xeb,0x56,0xde,0x35,0x70,0x71,0x95,0x5d,0x83,0xc4,0xb1,0xba,0xda,0xa0,0xb2,0x18,0x32,0xe9,
+ 0x04,0x07,0x31,0x0f,0x90,0xa9,0xea,0xe1,0x49,0xa0,0x84,0x02,0xf5,0x41,0x94,0xa0,0xf7,0xb4,0xac,0x42,0x7b,0xf8,0xd9,0xbd,0x6c,0x76,0x81,0x07,0x1d,0xc4,0x7d,0xc3,0x62,0x26,0xa6,0xd3,0x7a,0xc4,0x6d,0x61,0xfd,0x60,0x0c,0x0b,0xf1,0xbf,0xf8,0x76,0x89,0xed,0x11,0x7d,0xda,0x6b,0x0e,0x59,0x31,0x8a,0xe0,0x10,0xa1,0x97,0xa2,0x6c,0xa0,
+ 0x04,0xbc,0x97,0xe7,0x58,0x5e,0xec,0xad,0x48,0xe1,0x66,0x83,0xbc,0x40,0x91,0x70,0x8e,0x1a,0x93,0x0c,0x68,0x3f,0xc4,0x70,0x01,0xd4,0xb3,0x83,0x59,0x4f,0x2c,0x4e,0x22,0x70,0x59,0x89,0xcf,0x69,0xda,0xea,0xdd,0x4e,0x4e,0x4b,0x81,0x51,0xed,0x88,0x8d,0xfe,0xc2,0x0f,0xb0,0x17,0x28,0xd8,0x9d,0x56,0xb3,0xf3,0x8f,0x2a,0xe9,0xc8,0xc5,
+ 0x04,0x44,0xad,0x33,0x9a,0xfb,0xc2,0x1e,0x9a,0xbf,0x7b,0x60,0x2a,0x5c,0xa5,0x35,0xea,0x37,0x81,0x35,0xb6,0xd1,0x0d,0x81,0x31,0x0b,0xdd,0x82,0x93,0xd1,0xdf,0x32,0x52,0xb6,0x3f,0xf7,0xd0,0x77,0x47,0x70,0xf8,0xfe,0x1d,0x17,0x22,0xfa,0x83,0xac,0xd0,0x2f,0x43,0x4e,0x4f,0xc1,0x10,0xa0,0xcc,0x8f,0x6d,0xdd,0xd3,0x7d,0x56,0xc4,0x63,
+ 0x04,0x12,0x60,0xc2,0x12,0x2c,0x9e,0x24,0x4e,0x1a,0xf5,0x15,0x1b,0xed,0xe0,0xc3,0xae,0x23,0xb5,0x4d,0x7c,0x59,0x68,0x81,0xd3,0xee,0xba,0xd2,0x1f,0x37,0xdd,0x87,0x8c,0x5c,0x9a,0x0c,0x1a,0x9a,0xde,0x76,0x73,0x7a,0x88,0x11,0xbd,0x6a,0x7f,0x92,0x87,0xc9,0x78,0xee,0x39,0x6a,0xa8,0x9c,0x11,0xe4,0x72,0x29,0xd2,0xcc,0xb5,0x52,0xf0,
+ 0x04,0x18,0x77,0x04,0x5b,0xe2,0x5d,0x34,0xa1,0xd0,0x60,0x0f,0x9d,0x5c,0x00,0xd0,0x64,0x5a,0x2a,0x54,0x37,0x9b,0x6c,0xee,0xfa,0xd2,0xe6,0xbf,0x5c,0x2a,0x33,0x52,0xce,0x82,0x1a,0x53,0x2c,0xc1,0x75,0x1e,0xe1,0xd3,0x6d,0x41,0xc3,0xd6,0xab,0x4e,0x9b,0x14,0x3e,0x44,0xec,0x46,0xd7,0x34,0x78,0xea,0x6a,0x79,0xa5,0xc0,0xe5,0x41,0x59,
+ 0x04,0x45,0x54,0x39,0xfc,0xc3,0xd2,0xde,0xec,0xed,0xde,0xae,0xce,0x60,0xe7,0xbd,0x17,0x30,0x4f,0x36,0xeb,0xb6,0x02,0xad,0xf5,0xa2,0x2e,0x0b,0x8f,0x1d,0xb4,0x6a,0x50,0xae,0xc3,0x8f,0xb2,0xba,0xf2,0x21,0xe9,0xa8,0xd1,0x88,0x7c,0x7b,0xf6,0x22,0x2d,0xd1,0x83,0x46,0x34,0xe7,0x72,0x63,0x31,0x5a,0xf6,0xd2,0x36,0x09,0xd0,0x4f,0x77,
+ 0x04,0x2e,0x1f,0x46,0x6b,0x02,0x4c,0x0c,0x3a,0xce,0x24,0x37,0xde,0x09,0x12,0x7f,0xed,0x04,0xb7,0x06,0xf9,0x4b,0x19,0xa2,0x1b,0xb1,0xc2,0xac,0xf3,0x5c,0xec,0xe7,0x18,0x04,0x49,0xae,0x35,0x23,0xd7,0x25,0x34,0xe9,0x64,0x97,0x2c,0xfd,0x3b,0x38,0xaf,0x0b,0xdd,0xd9,0x61,0x9e,0x5a,0xf2,0x23,0xe4,0xd1,0xa4,0x0f,0x34,0xcf,0x9f,0x1d,
+ 0x04,0x8e,0x7a,0xbd,0xbb,0xd1,0x8d,0xe7,0x45,0x23,0x74,0xc1,0x87,0x9a,0x1c,0x3b,0x01,0xd1,0x32,0x61,0xe7,0xd4,0x57,0x1c,0x3b,0x47,0xa1,0xc7,0x6c,0x55,0xa2,0x33,0x73,0x26,0xed,0x89,0x7c,0xd5,0x17,0xa4,0xf5,0x34,0x9d,0xb8,0x09,0x78,0x0f,0x6d,0x2f,0x2b,0x9f,0x62,0x99,0xd8,0xb5,0xa8,0x90,0x77,0xf1,0x11,0x9a,0x71,0x8f,0xd7,0xb3,
+ 0x04,0x7b,0x33,0x3d,0x43,0x40,0xd3,0xd7,0x18,0xdd,0x3e,0x6a,0xff,0x7d,0xe7,0xbb,0xf8,0xb7,0x2b,0xfd,0x61,0x6c,0x84,0x20,0x05,0x60,0x52,0x84,0x23,0x76,0xb9,0xaf,0x19,0x42,0x11,0x7c,0x5a,0xfe,0xac,0x75,0x5d,0x6f,0x37,0x6f,0xc6,0x32,0x9a,0x7d,0x76,0x05,0x1b,0x87,0x12,0x3a,0x4a,0x5d,0x0b,0xc4,0xa5,0x39,0x38,0x0f,0x03,0xde,0x7b,
+ 0x04,0xd3,0x0c,0xa4,0xa0,0xdd,0xb6,0x61,0x6c,0x85,0x1d,0x30,0xce,0xd6,0x82,0xc4,0x0f,0x83,0xc6,0x27,0x58,0xa1,0xf2,0x75,0x99,0x88,0xd6,0x76,0x3a,0x88,0xf1,0xc0,0xe5,0x03,0xa8,0x0d,0x54,0x15,0x65,0x0d,0x41,0x23,0x97,0x84,0xe8,0xe2,0xfb,0x12,0x35,0xe9,0xfe,0x99,0x1d,0x11,0x2e,0xbb,0x81,0x18,0x6c,0xbf,0x0d,0xa2,0xde,0x3a,0xff,
+ 0x04,0x48,0x96,0x9b,0x39,0x99,0x12,0x97,0xb3,0x32,0xa6,0x52,0xd3,0xee,0x6e,0x01,0xe9,0x09,0xb3,0x99,0x04,0xe7,0x1f,0xa2,0x35,0x4a,0x78,0x30,0xc7,0x75,0x0b,0xaf,0x24,0xb4,0x01,0x2d,0x1b,0x83,0x0d,0x19,0x9c,0xcb,0x1f,0xc9,0x72,0xb3,0x2b,0xfd,0xed,0x55,0xf0,0x9c,0xd6,0x2d,0x25,0x7e,0x5e,0x84,0x4e,0x27,0xe5,0x7a,0x15,0x94,0xec,
+ 0x04,0x02,0xef,0x4d,0x6d,0x6c,0xfd,0x5a,0x94,0xf1,0xd7,0x78,0x42,0x26,0xe3,0xe2,0xa6,0xc0,0xa4,0x36,0xc5,0x58,0x39,0x61,0x9f,0x38,0xfb,0x44,0x72,0xb5,0xf9,0xee,0x77,0x7e,0xb4,0xac,0xd4,0xee,0xbd,0xa5,0xcd,0x72,0x87,0x5f,0xfd,0x2a,0x2f,0x26,0x22,0x9c,0x2d,0xc6,0xb4,0x65,0x00,0x91,0x9a,0x43,0x2c,0x86,0x73,0x9f,0x3a,0xe8,0x66,
+ 0x04,0x46,0x4f,0x4f,0xf7,0x15,0x72,0x9c,0xae,0x50,0x72,0xca,0x3b,0xd8,0x01,0xd3,0x19,0x5b,0x67,0xae,0xc6,0x5e,0x9b,0x01,0xaa,0xd2,0x0a,0x29,0x43,0xdc,0xbc,0xb5,0x84,0xb1,0xaf,0xd2,0x9d,0x31,0xa3,0x9a,0x11,0xd5,0x70,0xaa,0x15,0x97,0x43,0x9b,0x3b,0x2d,0x19,0x71,0xbf,0x2f,0x1a,0xbf,0x15,0x43,0x2d,0x02,0x07,0xb1,0x0d,0x1d,0x08,
+ 0x04,0x15,0x7f,0x8f,0xdd,0xf3,0x73,0xeb,0x5f,0x49,0xcf,0xcf,0x10,0xd8,0xb8,0x53,0xcf,0x91,0xcb,0xcd,0x7d,0x66,0x5c,0x35,0x22,0xba,0x7d,0xd7,0x38,0xdd,0xb7,0x9a,0x4c,0xde,0xad,0xf1,0xa5,0xc4,0x48,0xea,0x3c,0x9f,0x41,0x91,0xa8,0x99,0x9a,0xbf,0xcc,0x75,0x7a,0xc6,0xd6,0x45,0x67,0xef,0x07,0x2c,0x47,0xfe,0xc6,0x13,0x44,0x3b,0x8f,
+ 0x04,0x09,0x34,0xa5,0x37,0x46,0x6c,0x07,0x43,0x0e,0x2c,0x48,0xfe,0xb9,0x90,0xbb,0x19,0xfb,0x78,0xce,0xcc,0x9c,0xee,0x42,0x4e,0xa4,0xd1,0x30,0x29,0x1a,0xa2,0x37,0xf0,0xd4,0xf9,0x2d,0x23,0xb4,0x62,0x80,0x4b,0x5b,0x68,0xc5,0x25,0x58,0xc0,0x1c,0x99,0x96,0xdb,0xf7,0x27,0xfc,0xca,0xbb,0xee,0xdb,0x96,0x21,0xa4,0x00,0x53,0x5a,0xfa,
+ 0x04,0xd6,0xef,0x20,0xbe,0x66,0xc8,0x93,0xf7,0x41,0xa9,0xbf,0x90,0xd9,0xb7,0x46,0x75,0xd1,0xc2,0xa3,0x12,0x96,0x39,0x7a,0xcb,0x3e,0xf1,0x74,0xfd,0x0b,0x30,0x0c,0x65,0x4a,0x0c,0x95,0x47,0x8c,0xa0,0x03,0x99,0x16,0x2d,0x7f,0x0f,0x2d,0xc8,0x9e,0xfd,0xc2,0xb2,0x8a,0x30,0xfb,0xab,0xe2,0x85,0x85,0x72,0x95,0xa4,0xb0,0xc4,0xe2,0x65,
+ 0x04,0xb7,0x29,0x1d,0x14,0x04,0xe0,0xc0,0xc0,0x7d,0xab,0x93,0x72,0x18,0x9f,0x4b,0xd5,0x8d,0x2c,0xea,0xa8,0xd1,0x5e,0xde,0x54,0x4d,0x95,0x14,0x54,0x5b,0xa9,0xee,0x06,0x29,0xc9,0xa6,0x3d,0x5e,0x30,0x87,0x69,0xcc,0x30,0xec,0x27,0x6a,0x41,0x0e,0x64,0x64,0xa2,0x7e,0xea,0xfd,0x9e,0x59,0x9d,0xb1,0x0f,0x05,0x3a,0x4f,0xe4,0xa8,0x29,
+ 0x04,0x6e,0x28,0x30,0x33,0x05,0xd6,0x42,0xcc,0xb9,0x23,0xb7,0x22,0xea,0x86,0xb2,0xa0,0xbc,0x8e,0x37,0x35,0xec,0xb2,0x6e,0x84,0x9b,0x19,0xc9,0xf7,0x6b,0x2f,0xdb,0xb8,0x18,0x6e,0x80,0xd6,0x4d,0x8c,0xab,0x16,0x4f,0x52,0x38,0xf5,0x31,0x84,0x61,0xbf,0x89,0xd4,0xd9,0x6e,0xe6,0x54,0x4c,0x81,0x6c,0x75,0x66,0x94,0x77,0x74,0xe0,0xf6,
+ 0x04,0x37,0x5b,0xda,0x93,0xf6,0xaf,0x92,0xfb,0x5f,0x8f,0x4b,0x1b,0x5f,0x05,0x34,0xe3,0xba,0xfa,0xb3,0x4c,0xb7,0xad,0x9f,0xb9,0xd0,0xb7,0x22,0xe4,0xa5,0xc3,0x02,0xa9,0xa0,0x0b,0x9f,0x38,0x7a,0x5a,0x39,0x60,0x97,0xaa,0x21,0x62,0xfc,0x5b,0xbc,0xf4,0xa5,0x26,0x33,0x72,0xf6,0x81,0xc9,0x4d,0xa5,0x1e,0x97,0x99,0x12,0x09,0x90,0xfd,
+ 0x04,0xd7,0x5b,0x68,0x21,0x6b,0xab,0xe0,0x3a,0xe2,0x57,0xe9,0x4b,0x4e,0x3b,0xf1,0xc5,0x2f,0x44,0xe3,0xdf,0x26,0x6d,0x15,0x24,0xff,0x8c,0x5e,0xa6,0x9d,0xa7,0x31,0x97,0xda,0x4b,0xff,0x9e,0xd1,0xc5,0x3f,0x44,0x91,0x7a,0x67,0xd7,0xb9,0x78,0x59,0x8e,0x89,0xdf,0x35,0x9e,0x3d,0x59,0x13,0xea,0xea,0x24,0xf3,0xae,0x25,0x9a,0xbc,0x44,
+ 0x04,0x78,0xbc,0xda,0x14,0x0a,0xed,0x23,0xd4,0x30,0xcb,0x23,0xc3,0xdc,0x0d,0x01,0xf4,0x23,0xdb,0x13,0x4e,0xe9,0x4a,0x3a,0x8c,0xb4,0x83,0xf2,0xde,0xac,0x2a,0xc6,0x53,0x11,0x81,0x14,0xf6,0xf3,0x30,0x45,0xd4,0xe9,0xed,0x91,0x07,0x08,0x50,0x07,0xbf,0xbd,0xdf,0x8f,0x58,0xfe,0x7a,0x1a,0x24,0x45,0xd6,0x6a,0x99,0x00,0x45,0x47,0x6e,
+ 0x04,0xbb,0x79,0xf6,0x18,0x57,0xf7,0x43,0xbf,0xa1,0xb6,0xe7,0x11,0x1c,0xe4,0x09,0x43,0x77,0x25,0x69,0x69,0xe4,0xe1,0x51,0x59,0x12,0x3d,0x95,0x48,0xac,0xc3,0xbe,0x6c,0x1f,0x9d,0x9f,0x88,0x60,0xdc,0xff,0xd3,0xeb,0x36,0xdd,0x6c,0x31,0xff,0x2e,0x72,0x26,0xc2,0x00,0x9c,0x4c,0x94,0xd8,0xd7,0xd2,0xb5,0x68,0x6b,0xf7,0xab,0xd6,0x77,
+ 0x04,0x93,0x59,0x18,0x27,0xd9,0xe6,0x71,0x3b,0x4e,0x9f,0xae,0xa6,0x2c,0x72,0xb2,0x8d,0xfe,0xfa,0x68,0xe0,0xc0,0x51,0x60,0xb5,0xd6,0xaa,0xe8,0x8f,0xd2,0xe3,0x6c,0x36,0x07,0x3f,0x55,0x45,0xad,0x5a,0xf4,0x10,0xaf,0x26,0xaf,0xff,0x68,0x65,0x4c,0xf7,0x2d,0x45,0xe4,0x93,0x48,0x93,0x11,0x20,0x32,0x47,0x34,0x7a,0x89,0x0f,0x45,0x18,
+ 0x04,0x31,0xed,0x30,0x81,0xae,0xfe,0x00,0x1e,0xb6,0x40,0x20,0x69,0xee,0x2c,0xcc,0x18,0x62,0x93,0x7b,0x85,0x99,0x51,0x44,0xdb,0xa9,0x50,0x39,0x43,0x58,0x7b,0xf0,0xda,0xda,0x01,0xb8,0xcc,0x4d,0xf3,0x4f,0x5a,0xb3,0xb1,0xa3,0x59,0x61,0x52,0x08,0x94,0x6e,0x5e,0xe3,0x5f,0x98,0xee,0x77,0x5b,0x8c,0xce,0xcd,0x86,0xcc,0xc1,0x65,0x0f,
+ 0x04,0x7d,0xff,0x66,0xfa,0x98,0x50,0x9f,0xf3,0xe2,0xe5,0x10,0x45,0xf4,0x39,0x05,0x23,0xdc,0xcd,0xa4,0x3a,0x3b,0xc2,0x88,0x5e,0x58,0xc2,0x48,0x09,0x09,0x90,0xee,0xa8,0x54,0xc7,0x6c,0x2b,0x9a,0xde,0xb6,0xbb,0x57,0x18,0x23,0xe0,0x7f,0xd7,0xc6,0x5c,0x86,0x39,0xcf,0x9d,0x90,0x52,0x60,0x06,0x4c,0x8e,0x76,0x75,0xce,0x6d,0x98,0xb4,
+ 0x04,0x42,0x80,0x50,0x9a,0xab,0x64,0xed,0xfc,0x0b,0x4a,0x29,0x67,0xe4,0xcb,0xce,0x84,0x9c,0xb5,0x44,0xe4,0xa7,0x73,0x13,0xc8,0xe6,0xec,0xe5,0x79,0xfb,0xd7,0x42,0x0a,0x2e,0x89,0xfe,0x5c,0xc1,0x92,0x7d,0x55,0x4e,0x6a,0x3b,0xb1,0x40,0x33,0xea,0x7c,0x92,0x2c,0xd7,0x5c,0xba,0x2c,0x74,0x15,0xfd,0xab,0x52,0xf2,0x0b,0x18,0x60,0xf1,
+ 0x04,0x4f,0x8d,0xf1,0x45,0x19,0x4e,0x3c,0x4f,0xc3,0xee,0xa2,0x6d,0x43,0xce,0x75,0xb4,0x02,0xd6,0xb1,0x74,0x72,0xdd,0xcb,0xb2,0x54,0xb8,0xa7,0x9b,0x0b,0xf3,0xd9,0xcb,0x2a,0xa2,0x0d,0x82,0x84,0x4c,0xb2,0x66,0x34,0x4e,0x71,0xca,0x78,0xf2,0xad,0x27,0xa7,0x5a,0x09,0xe5,0xbc,0x0f,0xa5,0x7e,0x4e,0xfd,0x9d,0x46,0x5a,0x08,0x88,0xdb,
+ 0x04,0x95,0x98,0xa5,0x7d,0xd6,0x7e,0xc3,0xe1,0x6b,0x58,0x7a,0x33,0x8a,0xa3,0xa1,0x0a,0x3a,0x39,0x13,0xb4,0x1a,0x3a,0xf3,0x2e,0x3e,0xd3,0xff,0x01,0x35,0x8c,0x6b,0x14,0x12,0x28,0x19,0xed,0xf8,0x07,0x4b,0xbc,0x52,0x1f,0x7d,0x4c,0xdc,0xe8,0x2f,0xef,0x7a,0x51,0x67,0x06,0xaf,0xfb,0xa1,0xd9,0x3d,0x9d,0xea,0x9c,0xca,0xe1,0xa2,0x07,
+ 0x04,0x91,0x71,0xfe,0xc3,0xca,0x20,0x80,0x6b,0xc0,0x84,0xf1,0x2f,0x07,0x60,0x91,0x1b,0x60,0x99,0x0b,0xd8,0x0e,0x5b,0x2a,0x71,0xca,0x03,0xa0,0x48,0xb2,0x0f,0x83,0x7e,0x63,0x4f,0xd1,0x78,0x63,0x76,0x1b,0x29,0x58,0xd2,0xbe,0x4e,0x14,0x9f,0x8d,0x3d,0x7a,0xbb,0xdc,0x18,0xbe,0x03,0xf4,0x51,0xab,0x6c,0x17,0xfa,0x0a,0x1f,0x83,0x30,
+ 0x04,0x77,0x7c,0x89,0x30,0xb6,0xe1,0xd2,0x71,0x10,0x0f,0xe6,0x8c,0xe9,0x3f,0x16,0x3f,0xa3,0x76,0x12,0xc5,0xff,0xf6,0x7f,0x4a,0x62,0xfc,0x3b,0xaf,0xaf,0x3d,0x17,0xa9,0xed,0x73,0xd8,0x6f,0x60,0xa5,0x1b,0x5e,0xd9,0x13,0x53,0xa3,0xb0,0x54,0xed,0xc0,0xaa,0x92,0xc9,0xeb,0xcb,0xd0,0xb7,0x5d,0x18,0x8f,0xdc,0x88,0x27,0x91,0xd6,0x8d,
+ 0x04,0xea,0xbc,0x24,0x8f,0x62,0x6e,0x0a,0x63,0xe1,0xeb,0x81,0xc4,0x3d,0x46,0x1a,0x39,0xa1,0xdb,0xa8,0x81,0xeb,0x6e,0xe2,0x15,0x2b,0x07,0xc3,0x2d,0x71,0xbc,0xf4,0x70,0x06,0x03,0xca,0xa8,0xb9,0xd3,0x3d,0xb1,0x3a,0xf4,0x4c,0x6e,0xfb,0xec,0x8a,0x19,0x8e,0xd6,0x12,0x4a,0xc9,0xeb,0x17,0xea,0xaf,0xd2,0x82,0x4a,0x54,0x5e,0xc0,0x00,
+ 0x04,0x9f,0x7a,0x13,0xad,0xa1,0x58,0xa5,0x5f,0x9d,0xdf,0x1a,0x45,0xf0,0x44,0xf0,0x73,0xd9,0xb8,0x00,0x30,0xef,0xdc,0xfc,0x9f,0x9f,0x58,0x41,0x8f,0xbc,0xea,0xf0,0x01,0xf8,0xad,0xa0,0x17,0x50,0x90,0xf8,0x0d,0x47,0x22,0x7d,0x67,0x13,0xb6,0x74,0x0f,0x9a,0x00,0x91,0xd8,0x8a,0x83,0x7d,0x0a,0x1c,0xd7,0x7b,0x58,0xa8,0xf2,0x8d,0x73,
+ 0x04,0x11,0xc4,0xf3,0xe4,0x61,0xcd,0x01,0x9b,0x5c,0x06,0xea,0x0c,0xea,0x4c,0x40,0x90,0xc3,0xcc,0x3e,0x3c,0x5d,0x9f,0x3c,0x6d,0x65,0xb4,0x36,0x82,0x6d,0xa9,0xb4,0xdb,0xbb,0xeb,0x7a,0x77,0xe4,0xcb,0xfd,0xa2,0x07,0x09,0x7c,0x43,0x42,0x37,0x05,0xf7,0x2c,0x80,0x47,0x6d,0xa3,0xda,0xc4,0x0a,0x48,0x3b,0x0a,0xb0,0xf2,0xea,0xd1,0xcb,
+ 0x04,0xe2,0xe1,0x86,0x82,0xd5,0x31,0x23,0xaa,0x01,0xa6,0xc5,0xd0,0x0b,0x0c,0x62,0x3d,0x67,0x1b,0x46,0x2e,0xa8,0x0b,0xdd,0xd6,0x52,0x27,0xfd,0x51,0x05,0x98,0x8a,0xa4,0x16,0x19,0x07,0xb3,0xfd,0x25,0x04,0x4a,0x94,0x9e,0xa4,0x1c,0x8e,0x2e,0xa8,0x45,0x9d,0xc6,0xf1,0x65,0x48,0x56,0xb8,0xb6,0x1b,0x31,0x54,0x3b,0xb1,0xb4,0x5b,0xdb,
+ 0x04,0x90,0xf8,0xd4,0xca,0x73,0xde,0x08,0xa6,0x56,0x4a,0xaf,0x00,0x52,0x47,0xb6,0xf0,0xff,0xe9,0x78,0x50,0x4d,0xce,0x52,0x60,0x5f,0x46,0xb7,0xc3,0xe5,0x61,0x97,0xda,0xfa,0xdb,0xe5,0x28,0xeb,0x70,0xd9,0xee,0x7e,0xa0,0xe7,0x07,0x02,0xdb,0x54,0xf7,0x21,0x51,0x4c,0x7b,0x86,0x04,0xac,0x2c,0xb2,0x14,0xf1,0xde,0xcb,0x7e,0x38,0x3d,
+ 0x04,0x82,0x4c,0x19,0x5c,0x73,0xcf,0xfd,0xf0,0x38,0xd1,0x01,0xbc,0xe1,0x68,0x7b,0x5c,0x3b,0x61,0x46,0xf3,0x95,0xc8,0x85,0x97,0x6f,0x77,0x53,0xb2,0x37,0x6b,0x94,0x8e,0x3c,0xde,0xfa,0x6f,0xc3,0x47,0xd1,0x3e,0x4d,0xcb,0xc6,0x3a,0x0b,0x03,0xa1,0x65,0x18,0x0c,0xd2,0xbe,0x14,0x31,0xa0,0xcf,0x74,0xce,0x1e,0xa2,0x50,0x82,0xd2,0xbc,
+ 0x04,0x27,0x88,0xa5,0x2f,0x07,0x8e,0xb3,0xf2,0x02,0xc4,0xfa,0x73,0xe0,0xd3,0x38,0x6f,0xaf,0x3d,0xf6,0xbe,0x85,0x60,0x03,0x63,0x6f,0x59,0x99,0x22,0xd4,0xf5,0x26,0x8f,0x30,0xb4,0xf2,0x07,0xc9,0x19,0xbb,0xdf,0x5e,0x67,0xa8,0xbe,0x42,0x65,0xa8,0x17,0x47,0x54,0xb3,0xab,0xa8,0xf1,0x6e,0x57,0x5b,0x77,0xff,0x4d,0x5a,0x7e,0xb6,0x4f,
+ 0x04,0xd5,0x33,0xb7,0x89,0xa4,0xaf,0x89,0x0f,0xa7,0xa8,0x2a,0x1f,0xae,0x58,0xc4,0x04,0xf9,0xa6,0x2a,0x50,0xb4,0x9a,0xda,0xfa,0xb3,0x49,0xc5,0x13,0xb4,0x15,0x08,0x74,0x01,0xb4,0x17,0x1b,0x80,0x3e,0x76,0xb3,0x4a,0x98,0x61,0xe1,0x0f,0x7b,0xc2,0x89,0xa0,0x66,0xfd,0x01,0xbd,0x29,0xf8,0x4c,0x98,0x7a,0x10,0xa5,0xfb,0x18,0xc2,0xd4,
+ 0x04,0x3a,0x31,0x50,0x79,0x8c,0x8a,0xf6,0x9d,0x1e,0x6e,0x98,0x1f,0x3a,0x45,0x40,0x2b,0xa1,0xd7,0x32,0xf4,0xbe,0x83,0x30,0xc5,0x16,0x4f,0x49,0xe1,0x0e,0xc5,0x55,0xb4,0x22,0x1b,0xd8,0x42,0xbc,0x5e,0x4d,0x97,0xef,0xf3,0x71,0x65,0xf6,0x0e,0x39,0x98,0xa4,0x24,0xd7,0x2a,0x45,0x0c,0xf9,0x5e,0xa4,0x77,0xc7,0x82,0x87,0xd0,0x34,0x3a,
+ 0x04,0x3b,0x37,0xdf,0x5f,0xb3,0x47,0xc6,0x9a,0x0f,0x17,0xd8,0x5c,0x0c,0x7c,0xa8,0x37,0x36,0x88,0x3a,0x82,0x5e,0x13,0x14,0x3d,0x0f,0xcf,0xc8,0x10,0x1e,0x85,0x1e,0x80,0x0d,0xe3,0xc0,0x90,0xb6,0xca,0x21,0xba,0x54,0x35,0x17,0x33,0x0c,0x04,0xb1,0x2f,0x94,0x8c,0x6b,0xad,0xf1,0x4a,0x63,0xab,0xff,0xdf,0x4e,0xf8,0xc7,0x53,0x70,0x26,
+ 0x04,0xfe,0xb5,0x16,0x3b,0x0e,0xce,0x30,0xff,0x3e,0x03,0xc7,0xd5,0x5c,0x43,0x80,0xfa,0x2f,0xa8,0x1e,0xe2,0xc0,0x35,0x49,0x42,0xff,0x6f,0x08,0xc9,0x9d,0x0c,0xd8,0x2c,0xe8,0x7d,0xe0,0x5e,0xe1,0xbd,0xa0,0x89,0xd3,0xe4,0xe2,0x48,0xfa,0x0f,0x72,0x11,0x02,0xac,0xff,0xfd,0xf5,0x0e,0x65,0x4b,0xe2,0x81,0x43,0x39,0x99,0xdf,0x89,0x7e,
+ 0x04,0x23,0x8c,0xed,0x00,0x1c,0xf2,0x2b,0x88,0x53,0xe0,0x2e,0xdc,0x89,0xcb,0xec,0xa5,0x05,0x0b,0xa7,0xe0,0x42,0xa7,0xa7,0x7f,0x93,0x82,0xcd,0x41,0x49,0x22,0x89,0x76,0x40,0x68,0x3d,0x30,0x94,0x64,0x38,0x40,0xf2,0x95,0x89,0x0a,0xa4,0xc1,0x8a,0xa3,0x9b,0x41,0xd7,0x7d,0xd0,0xfb,0x3b,0xb2,0x70,0x0e,0x4f,0x9e,0xc2,0x84,0xff,0xc2,
+ 0x04,0x96,0x1c,0xf6,0x48,0x17,0xc0,0x6c,0x0e,0x51,0xb3,0xc2,0x73,0x6c,0x92,0x2f,0xde,0x18,0xbd,0x8c,0x49,0x06,0xfc,0xd7,0xf5,0xef,0x66,0xc4,0x67,0x85,0x08,0xf3,0x5e,0xd2,0xc5,0xd1,0x81,0x68,0xcf,0xbe,0x70,0xf2,0xf1,0x23,0xbd,0x74,0x19,0x23,0x2b,0xb9,0x2d,0xd6,0x91,0x13,0xe2,0x94,0x10,0x61,0x88,0x94,0x81,0xc5,0xa0,0x27,0xbf,
+ 0x04,0x13,0x68,0x1e,0xae,0x16,0x8c,0xd4,0xea,0x7c,0xf2,0xe2,0xa4,0x5d,0x05,0x27,0x42,0xd1,0x0a,0x9f,0x64,0xe7,0x96,0x86,0x7d,0xbd,0xcb,0x82,0x9f,0xe0,0xb1,0x02,0x88,0x16,0x52,0x87,0x60,0xd1,0x77,0x37,0x6c,0x09,0xdf,0x79,0xde,0x39,0x55,0x7c,0x32,0x9c,0xc1,0x75,0x35,0x17,0xac,0xff,0xe8,0xfa,0x2e,0xc2,0x98,0x02,0x6b,0x83,0x84,
+ 0x04,0x5a,0xa7,0xab,0xfd,0xb6,0xb4,0x08,0x6d,0x54,0x33,0x25,0xe5,0xd7,0x9c,0x6e,0x95,0xce,0x42,0xf8,0x66,0xd2,0xbb,0x84,0x90,0x96,0x33,0xa0,0x4b,0xb1,0xaa,0x31,0xc2,0x91,0xc8,0x00,0x88,0x79,0x49,0x05,0xe1,0xda,0x33,0x33,0x6d,0x87,0x4e,0x2f,0x91,0xcc,0xf4,0x5c,0xc5,0x91,0x85,0xbe,0xde,0x5d,0xd6,0xf3,0xf7,0xac,0xaa,0xe1,0x8b,
+ 0x04,0x00,0x27,0x77,0x91,0xb3,0x05,0xa4,0x5b,0x2b,0x39,0x59,0x0b,0x2f,0x05,0xd3,0x39,0x2a,0x6c,0x81,0x82,0xce,0xf4,0xeb,0x54,0x01,0x20,0xe0,0xf5,0xc2,0x06,0xc3,0xe4,0x64,0x10,0x82,0x33,0xfb,0x0b,0x8c,0x3a,0xc8,0x92,0xd7,0x9e,0xf8,0xe0,0xfb,0xf9,0x2e,0xd1,0x33,0xad,0xdb,0x45,0x54,0x27,0x01,0x32,0x58,0x4d,0xc5,0x2e,0xef,0x41,
+ 0x04,0x6e,0xfa,0x09,0x2b,0x68,0xde,0x94,0x60,0xf0,0xbc,0xc9,0x19,0x00,0x5a,0x5f,0x6e,0x80,0xe1,0x9d,0xe9,0x89,0x68,0xbe,0x3c,0xd2,0xc7,0x70,0xa9,0x94,0x9b,0xfb,0x1a,0xc7,0x5e,0x6e,0x50,0x87,0xd6,0x55,0x0d,0x5f,0x9b,0xeb,0x1e,0x79,0xe5,0x02,0x93,0x07,0xbc,0x25,0x52,0x35,0xe2,0xd5,0xdc,0x99,0x24,0x1a,0xc3,0xab,0x88,0x6c,0x49,
+ 0x04,0x72,0xd4,0xa1,0x9c,0x4f,0x9d,0x2c,0xf5,0x84,0x8e,0xa4,0x04,0x45,0xb7,0x0d,0x46,0x96,0xb5,0xf0,0x2d,0x63,0x2c,0x0c,0x65,0x4c,0xc7,0xd7,0xee,0xb0,0xc6,0xd0,0x58,0xe8,0xc4,0xcd,0x99,0x43,0xe4,0x59,0x17,0x4c,0x7a,0xc0,0x1f,0xa7,0x42,0x19,0x8e,0x47,0xe6,0xc1,0x9a,0x6b,0xdb,0x0c,0x4f,0x6c,0x23,0x78,0x31,0xc1,0xb3,0xf9,0x42,
+ 0x04,0x2a,0x8e,0xa2,0xf5,0x0d,0xcc,0xed,0x0c,0x21,0x75,0x75,0xbd,0xfa,0x7c,0xd4,0x7d,0x1c,0x6f,0x10,0x00,0x41,0xec,0x0e,0x35,0x51,0x27,0x94,0xc1,0xbe,0x7e,0x74,0x02,0x58,0xf8,0xc1,0x71,0x22,0xed,0x30,0x3f,0xda,0x71,0x43,0xeb,0x58,0xbe,0xde,0x70,0x29,0x5b,0x65,0x32,0x66,0x01,0x3b,0x0b,0x0e,0xbd,0x3f,0x05,0x31,0x37,0xf6,0xec,
+ 0x04,0x88,0xde,0x68,0x9c,0xe9,0xaf,0x1e,0x94,0xbe,0x6a,0x20,0x89,0xc8,0xa8,0xb1,0x25,0x3f,0xfd,0xbb,0x6c,0x8e,0x9c,0x86,0x24,0x9b,0xa2,0x20,0x00,0x1a,0x4a,0xd3,0xb8,0x0c,0x49,0x98,0xe5,0x48,0x42,0xf4,0x13,0xb9,0xed,0xb1,0x82,0x5a,0xcb,0xb6,0x33,0x5e,0x81,0xe4,0xd1,0x84,0xb2,0xb0,0x1c,0x8b,0xeb,0xdc,0x85,0xd1,0xf2,0x89,0x46,
+ 0x04,0xfe,0xa2,0xd3,0x1f,0x70,0xf9,0x0d,0x5f,0xb3,0xe0,0x0e,0x18,0x6a,0xc4,0x2a,0xb3,0xc1,0x61,0x5c,0xee,0x71,0x4e,0x0b,0x4e,0x11,0x31,0xb3,0xd4,0xd8,0x22,0x5b,0xf7,0xb0,0x37,0xa1,0x8d,0xf2,0xac,0x15,0x34,0x3f,0x30,0xf7,0x40,0x67,0xdd,0xf2,0x9e,0x81,0x7d,0x5f,0x77,0xf8,0xdc,0xe0,0x57,0x14,0xda,0x59,0xc0,0x94,0xf0,0xcd,0xa9,
+ 0x04,0x72,0x58,0x91,0x1e,0x3d,0x42,0x33,0x49,0x16,0x64,0x79,0xdb,0xe0,0xb8,0x34,0x1a,0xf7,0xfb,0xd0,0x3d,0x0a,0x7e,0x10,0xed,0xcc,0xb3,0x6b,0x6c,0xee,0xa5,0xa3,0xdb,0x17,0xac,0x2b,0x89,0x92,0x79,0x11,0x28,0xfa,0x3b,0x96,0xdc,0x2f,0xbd,0x4c,0xa3,0xbf,0xa7,0x82,0xef,0x28,0x32,0xfc,0x66,0x56,0x94,0x3d,0xb1,0x8e,0x73,0x46,0xb0,
+ 0x04,0x4f,0x28,0x46,0x1d,0xea,0x64,0x47,0x4d,0x6b,0xb3,0x4d,0x14,0x99,0xc9,0x7d,0x37,0xb9,0xe9,0x56,0x33,0xdf,0x1c,0xee,0xea,0xac,0xd4,0x50,0x16,0xc9,0x8b,0x39,0x14,0xc8,0x81,0x88,0x10,0xb8,0xcc,0x06,0xdd,0xb4,0x0e,0x8a,0x12,0x61,0xc5,0x28,0xfa,0xa5,0x89,0x45,0x5d,0x5a,0x6d,0xf9,0x3b,0x77,0xbc,0x5e,0x0e,0x49,0x3c,0x74,0x70,
+ 0x04,0x74,0xf2,0xa8,0x14,0xfb,0x5d,0x8e,0xca,0x91,0xa6,0x9b,0x5e,0x60,0x71,0x27,0x32,0xb3,0x93,0x7d,0xe3,0x28,0x29,0xbe,0x97,0x4e,0xd7,0xb6,0x8c,0x5c,0x2f,0x5d,0x66,0xef,0xf0,0xf0,0x7c,0x56,0xf9,0x87,0xa6,0x57,0xf4,0x21,0x96,0x20,0x5f,0x58,0x8c,0x0f,0x1d,0x96,0xfd,0x8a,0x63,0xa5,0xf2,0x38,0xb4,0x8f,0x47,0x87,0x88,0xfe,0x3b,
+ 0x04,0x19,0x5b,0x51,0xa7,0xcc,0x4a,0x21,0xb8,0x27,0x4a,0x70,0xa9,0x0d,0xe7,0x79,0x81,0x4c,0x3c,0x8c,0xa3,0x58,0x32,0x82,0x08,0xc0,0x9a,0x29,0xf3,0x36,0xb8,0x2d,0x6a,0xb2,0x41,0x6b,0x7c,0x92,0xff,0xfd,0xc2,0x9c,0x3b,0x12,0x82,0xdd,0x2a,0x77,0xa4,0xd0,0x4d,0xf7,0xf7,0x45,0x20,0x47,0x39,0x3d,0x84,0x99,0x89,0xc5,0xce,0xe9,0xad,
+ 0x04,0x62,0x2f,0xc7,0x47,0x32,0x03,0x4b,0xec,0x2d,0xdf,0x3b,0xc1,0x6d,0x34,0xb3,0xd1,0xf7,0xa3,0x27,0xdd,0x2a,0x8c,0x19,0xba,0xb4,0xbb,0x4f,0xe3,0xa2,0x4b,0x58,0xaa,0x73,0x6b,0x2f,0x2f,0xae,0x76,0xf4,0xdf,0xae,0xcc,0x90,0x96,0x33,0x3b,0x01,0x32,0x8d,0x51,0xeb,0x3f,0xda,0x9c,0x92,0x27,0xe9,0x0d,0x0b,0x44,0x99,0x83,0xc4,0xf0,
+ 0x04,0x1f,0x7f,0x85,0xca,0xf2,0xd7,0x55,0x0e,0x7a,0xf9,0xb6,0x50,0x23,0xeb,0xb4,0xdc,0xe3,0x45,0x03,0x11,0x69,0x23,0x09,0xdb,0x26,0x99,0x69,0xb8,0x34,0xb6,0x11,0xc7,0x08,0x27,0xf4,0x5b,0x78,0x02,0x0e,0xcb,0xba,0xf4,0x84,0xfd,0xd5,0xbf,0xaa,0xe6,0x87,0x0f,0x11,0x84,0xc2,0x15,0x81,0xba,0xf6,0xef,0x82,0xbd,0x7b,0x53,0x0f,0x93,
+ 0x04,0x49,0xc1,0x97,0xdc,0x80,0xad,0x1d,0xa4,0x7a,0x43,0x42,0xb9,0x38,0x93,0xe8,0xe1,0xfb,0x0b,0xb9,0x4f,0xc3,0x3a,0x83,0xe7,0x83,0xc0,0x0b,0x24,0xc7,0x81,0x37,0x7a,0xef,0xc2,0x0d,0xa9,0x2b,0xac,0x76,0x29,0x51,0xf7,0x24,0x74,0xbe,0xcc,0x73,0x4d,0x4c,0xc2,0x2b,0xa8,0x1b,0x89,0x5e,0x28,0x2f,0xda,0xc4,0xdf,0x7a,0xf0,0xf3,0x7d,
+ 0x04,0xd8,0xcb,0x68,0x51,0x7b,0x61,0x6a,0x56,0x40,0x0a,0xa3,0x86,0x86,0x35,0xe5,0x4b,0x6f,0x69,0x95,0x98,0xa2,0xf6,0x16,0x77,0x57,0x65,0x49,0x80,0xba,0xf6,0xac,0xbe,0x7e,0xc8,0xcf,0x44,0x9c,0x84,0x9a,0xa0,0x34,0x61,0xa3,0x0e,0xfa,0xda,0x41,0x45,0x3c,0x57,0xc6,0xe6,0xfb,0xc9,0x3b,0xbc,0x6f,0xa4,0x9a,0xda,0x6d,0xc0,0x55,0x5c,
+ 0x04,0x03,0x07,0x13,0xfb,0x63,0xf2,0xaa,0x6f,0xe2,0xca,0xdf,0x1b,0x20,0xef,0xc2,0x59,0xc7,0x74,0x45,0xda,0xfa,0x87,0xda,0xc3,0x98,0xb8,0x40,0x65,0xca,0x34,0x7d,0xf3,0xb2,0x27,0x81,0x8d,0xe1,0xa3,0x9b,0x58,0x9c,0xb0,0x71,0xd8,0x3e,0x53,0x17,0xcc,0xcd,0xc2,0x33,0x8e,0x51,0xe3,0x12,0xfe,0x31,0xd8,0xdc,0x34,0xa4,0x80,0x17,0x50,
+ 0x04,0xba,0xbb,0x36,0x77,0xb0,0x95,0x58,0x02,0xd8,0xe9,0x29,0xa4,0x13,0x55,0x64,0x0e,0xaf,0x1e,0xa1,0x35,0x3f,0x8a,0x77,0x13,0x31,0xc4,0x94,0x6e,0x34,0x80,0xaf,0xa7,0x25,0x2f,0x19,0x6c,0x87,0xed,0x3d,0x2a,0x59,0xd3,0xb1,0xb5,0x59,0x13,0x7f,0xed,0x00,0x13,0xfe,0xce,0xfc,0x19,0xfb,0x5a,0x92,0x68,0x2b,0x9b,0xca,0x51,0xb9,0x50,
+ 0x04,0x1a,0xab,0x20,0x18,0x79,0x34,0x71,0x11,0x1a,0x8a,0x0e,0x9b,0x14,0x3f,0xde,0x02,0xfc,0x95,0x92,0x07,0x96,0xd3,0xa6,0x3d,0xe3,0x29,0xb4,0x24,0x39,0x6f,0xba,0x60,0xbb,0xe4,0x13,0x07,0x05,0x17,0x47,0x92,0x44,0x1b,0x31,0x8d,0x3a,0xa3,0x1d,0xfe,0x85,0x77,0x82,0x1e,0x9b,0x44,0x6e,0xc5,0x73,0xd2,0x72,0xe0,0x36,0xc4,0xeb,0xe9,
+ 0x04,0x8c,0xb0,0xb9,0x09,0x49,0x9c,0x83,0xea,0x80,0x6c,0xd8,0x85,0xb1,0xdd,0x46,0x7a,0x01,0x19,0xf0,0x6a,0x88,0xa0,0x27,0x6e,0xb0,0xcf,0xda,0x27,0x45,0x35,0xa8,0xff,0x47,0xb5,0x42,0x88,0x33,0xbc,0x3f,0x2c,0x8b,0xf9,0xd9,0x04,0x11,0x58,0xcf,0x33,0x71,0x8a,0x69,0x96,0x1c,0xd0,0x17,0x29,0xbc,0x00,0x11,0xd1,0xe5,0x86,0xab,0x75,
+ 0x04,0x8f,0x03,0xcf,0x1a,0x42,0x27,0x2b,0xb1,0x53,0x27,0x23,0x09,0x3f,0x72,0xe6,0xfe,0xea,0xc8,0x5e,0x17,0x00,0xe9,0xfb,0xe9,0xa6,0xa2,0xdd,0x64,0x2d,0x74,0xbf,0x5d,0x3b,0x89,0xa7,0x18,0x9d,0xad,0x8c,0xf7,0x5f,0xc2,0x2f,0x6f,0x15,0x8a,0xa2,0x7f,0x9c,0x2c,0xa0,0x0d,0xac,0xa7,0x85,0xbe,0x33,0x58,0xf2,0xbd,0xa3,0x86,0x2c,0xa0,
+ 0x04,0x44,0xde,0x3b,0x9c,0x7a,0x57,0xa8,0xc9,0xe8,0x20,0x95,0x27,0x53,0x42,0x1e,0x7d,0x98,0x7b,0xb3,0xd7,0x9f,0x71,0xf0,0x13,0x80,0x5c,0x89,0x7e,0x01,0x8f,0x8a,0xce,0xa2,0x46,0x07,0x58,0xc8,0xf9,0x8d,0x3f,0xdc,0xe1,0x21,0xa9,0x43,0x65,0x9e,0x37,0x2c,0x32,0x6f,0xff,0x2e,0x5f,0xc2,0xae,0x7f,0xa3,0xf7,0x9d,0xaa,0xe1,0x3c,0x12,
+ 0x04,0x6f,0xb8,0xb2,0xb4,0x8e,0x33,0x03,0x12,0x68,0xad,0x6a,0x51,0x74,0x84,0xdc,0x88,0x39,0xea,0x90,0xf6,0x66,0x9e,0xa0,0xc7,0xac,0x32,0x33,0xe2,0xac,0x31,0x39,0x4a,0x0a,0xc8,0xbb,0xe7,0xf7,0x3c,0x2f,0xf4,0xdf,0x99,0x78,0x72,0x7a,0xc1,0xdf,0xc2,0xfd,0x58,0x64,0x7d,0x20,0xf3,0x1f,0x99,0x10,0x53,0x16,0xb6,0x46,0x71,0xf2,0x04,
+ 0x04,0xbe,0xa7,0x11,0x22,0xa0,0x48,0x69,0x3e,0x90,0x5f,0xf6,0x02,0xb3,0xcf,0x9d,0xd1,0x8a,0xf6,0x9b,0x9f,0xc9,0xd8,0x43,0x1d,0x2b,0x1d,0xd2,0x6b,0x94,0x2c,0x95,0xe6,0xf4,0x3c,0x7b,0x8b,0x95,0xeb,0x62,0x08,0x2c,0x12,0xdb,0x9d,0xbd,0xa7,0xfe,0x38,0xe4,0x5c,0xbe,0x4a,0x48,0x86,0x90,0x7f,0xb8,0x1b,0xdb,0x0c,0x5e,0xa9,0x24,0x6c,
+ 0x04,0xda,0x91,0x8c,0x73,0x1b,0xa0,0x6a,0x20,0xcb,0x94,0xef,0x33,0xb7,0x78,0xe9,0x81,0xa4,0x04,0xa3,0x05,0xf1,0x94,0x1f,0xe3,0x36,0x66,0xb4,0x5b,0x03,0x35,0x31,0x56,0xe2,0xbb,0x26,0x94,0xf5,0x75,0xb4,0x51,0x83,0xbe,0x78,0xe5,0xc9,0xb5,0x21,0x0b,0xf3,0xbf,0x48,0x8f,0xd4,0xc8,0x29,0x45,0x16,0xd8,0x95,0x72,0xca,0x4f,0x53,0x91,
+ 0x04,0x30,0x07,0xe9,0x2c,0x39,0x37,0xda,0xde,0x79,0x64,0xdf,0xa3,0x5b,0x0e,0xff,0x03,0x1f,0x7e,0xb0,0x2a,0xed,0x0a,0x03,0x14,0x41,0x11,0x06,0xcd,0xeb,0x70,0xfe,0x3d,0x5a,0x75,0x46,0xfc,0x05,0x52,0x99,0x7b,0x20,0xe3,0xd6,0xf4,0x13,0xe7,0x5e,0x2c,0xb6,0x6e,0x11,0x63,0x22,0x69,0x71,0x14,0xb7,0x9b,0xac,0x73,0x4b,0xfc,0x4d,0xc5,
+ 0x04,0x60,0xe7,0x34,0xef,0x56,0x24,0xd3,0xcb,0xf0,0xdd,0xd3,0x75,0x01,0x1b,0xd6,0x63,0xd6,0xd6,0xae,0xbc,0x64,0x4e,0xb5,0x99,0xfd,0xf9,0x8d,0xbd,0xcd,0x18,0xce,0x9b,0xd2,0xd9,0x0b,0x3a,0xc3,0x1f,0x13,0x9a,0xf8,0x32,0xcc,0xcf,0x6c,0xcb,0xbb,0x2c,0x6e,0xa1,0x1f,0xa9,0x73,0x70,0xdc,0x99,0x06,0xda,0x47,0x4d,0x7d,0x8a,0x75,0x67,
+ 0x04,0x85,0xa9,0x00,0xe9,0x78,0x58,0xf6,0x93,0xc0,0xb7,0xdf,0xa2,0x61,0xe3,0x80,0xda,0xd6,0xea,0x04,0x6d,0x1f,0x65,0xdd,0xee,0xed,0xd5,0xf7,0xd8,0xaf,0x0b,0xa3,0x37,0x69,0x74,0x4d,0x15,0xad,0xd4,0xf6,0xc0,0xbc,0x3b,0x0d,0xa2,0xae,0xc9,0x3b,0x34,0xcb,0x8c,0x65,0xf9,0x34,0x0d,0xdf,0x74,0xe7,0xb0,0x00,0x9e,0xee,0xcc,0xce,0x3c,
+ 0x04,0x38,0x06,0x6f,0x75,0xd8,0x8e,0xfc,0x4c,0x93,0xde,0x36,0xf4,0x9e,0x03,0x7b,0x23,0x4c,0xc1,0x8b,0x1d,0xe5,0x60,0x87,0x50,0xa6,0x2c,0xab,0x03,0x45,0x40,0x10,0x46,0xa3,0xe8,0x4b,0xed,0x8c,0xfc,0xb8,0x19,0xef,0x4d,0x55,0x04,0x44,0xf2,0xce,0x4b,0x65,0x17,0x66,0xb6,0x9e,0x2e,0x29,0x01,0xf8,0x88,0x36,0xff,0x90,0x03,0x4f,0xed,
+ 0x04,0x98,0xf6,0x81,0x77,0xdc,0x95,0xc1,0xb4,0xcb,0xfa,0x52,0x45,0x48,0x8c,0xa5,0x23,0xa7,0xd5,0x62,0x94,0x70,0xd0,0x35,0xd6,0x21,0xa4,0x43,0xc7,0x2f,0x39,0xaa,0xbf,0xa3,0x3d,0x29,0x54,0x6f,0xa1,0xc6,0x48,0xf2,0xc7,0xd5,0xcc,0xf7,0x0c,0xf1,0xce,0x4a,0xb7,0x9b,0x5d,0xb1,0xac,0x05,0x9d,0xbe,0xcd,0x06,0x8d,0xbd,0xff,0x1b,0x89,
+ 0x04,0x5c,0x2b,0xbf,0xa2,0x3c,0x9b,0x9a,0xd0,0x7f,0x03,0x8a,0xa8,0x9b,0x49,0x30,0xbf,0x26,0x7d,0x94,0x01,0xe4,0x25,0x5d,0xe9,0xe8,0xda,0x0a,0x50,0x78,0xec,0x82,0x77,0xe3,0xe8,0x82,0xa3,0x1d,0x5e,0x6a,0x37,0x9e,0x07,0x93,0x98,0x3c,0xcd,0xed,0x39,0xb9,0x5c,0x43,0x53,0xab,0x2f,0xf0,0x1e,0xa5,0x36,0x9b,0xa4,0x7b,0x0c,0x31,0x91,
+ 0x04,0x2e,0xa7,0x13,0x34,0x32,0x33,0x9c,0x69,0xd2,0x7f,0x9b,0x26,0x72,0x81,0xbd,0x2d,0xdd,0x5f,0x19,0xd6,0x33,0x8d,0x40,0x0a,0x05,0xcd,0x36,0x47,0xb1,0x57,0xa3,0x85,0x35,0x47,0x80,0x82,0x98,0x44,0x8e,0xdb,0x5e,0x70,0x1a,0xde,0x84,0xcd,0x5f,0xb1,0xac,0x95,0x67,0xba,0x5e,0x8f,0xb6,0x8a,0x6b,0x93,0x3e,0xc4,0xb5,0xcc,0x84,0xcc,
+ 0x04,0x2e,0xa7,0x13,0x34,0x32,0x33,0x9c,0x69,0xd2,0x7f,0x9b,0x26,0x72,0x81,0xbd,0x2d,0xdd,0x5f,0x19,0xd6,0x33,0x8d,0x40,0x0a,0x05,0xcd,0x36,0x47,0xb1,0x57,0xa3,0x85,0xca,0xb8,0x7f,0x7d,0x67,0xbb,0x71,0x24,0xa1,0x8f,0xe5,0x21,0x7b,0x32,0xa0,0x4e,0x53,0x6a,0x98,0x45,0xa1,0x70,0x49,0x75,0x94,0x6c,0xc1,0x3a,0x4a,0x33,0x77,0x63,
+ 0x04,0x8a,0xa2,0xc6,0x4f,0xa9,0xc6,0x43,0x75,0x63,0xab,0xfb,0xcb,0xd0,0x0b,0x20,0x48,0xd4,0x8c,0x18,0xc1,0x52,0xa2,0xa6,0xf4,0x90,0x36,0xde,0x76,0x47,0xeb,0xe8,0x2e,0x1c,0xe6,0x43,0x87,0x99,0x5c,0x68,0xa0,0x60,0xfa,0x3b,0xc0,0x39,0x9b,0x05,0xcc,0x06,0xee,0xc7,0xd5,0x98,0xf7,0x50,0x41,0xa4,0x91,0x7e,0x69,0x2b,0x7f,0x51,0xff,
+ 0x04,0x39,0x14,0x27,0xff,0x7e,0xe7,0x80,0x13,0xc1,0x4a,0xec,0x7d,0x96,0xa8,0xa0,0x62,0x20,0x92,0x98,0xa7,0x83,0x83,0x5e,0x94,0xfd,0x65,0x49,0xd5,0x02,0xff,0xf7,0x1f,0xdd,0x66,0x24,0xec,0x34,0x3a,0xd9,0xfc,0xf4,0xd9,0x87,0x21,0x81,0xe5,0x9f,0x84,0x2f,0x9b,0xa4,0xcc,0xca,0xe0,0x9a,0x6c,0x09,0x72,0xfb,0x6a,0xc6,0xb4,0xc6,0xbd,
+ 0x04,0xe7,0x62,0xb8,0xa2,0x19,0xb4,0xf1,0x80,0x21,0x9c,0xc7,0xa9,0x05,0x92,0x45,0xe4,0x96,0x1b,0xd1,0x91,0xc0,0x38,0x99,0x78,0x9c,0x7a,0x34,0xb8,0x9e,0x8c,0x13,0x8e,0xc1,0x53,0x3e,0xf0,0x41,0x9b,0xb7,0x37,0x6e,0x0b,0xfd,0xe9,0x31,0x9d,0x10,0xa0,0x69,0x68,0x79,0x1d,0x9e,0xa0,0xee,0xd9,0xc1,0xce,0x63,0x45,0xae,0xd9,0x75,0x9e,
+ 0x04,0x9a,0xed,0xb0,0xd2,0x81,0xdb,0x16,0x4e,0x13,0x00,0x00,0xc5,0x69,0x7f,0xae,0x0f,0x30,0x5e,0xf8,0x48,0xbe,0x6f,0xff,0xb4,0x3a,0xc5,0x93,0xfb,0xb9,0x50,0xe9,0x52,0xfa,0x6f,0x63,0x33,0x59,0xbd,0xcd,0x82,0xb5,0x6b,0x0b,0x9f,0x96,0x5b,0x03,0x77,0x89,0xd4,0x6b,0x9a,0x81,0x41,0xb7,0x91,0xb2,0xae,0xfa,0x71,0x3f,0x96,0xc1,0x75,
+ 0x04,0x8a,0xd4,0x45,0xdb,0x62,0x81,0x62,0x60,0xe4,0xe6,0x87,0xfd,0x18,0x84,0xe4,0x8b,0x9f,0xc0,0x63,0x6d,0x03,0x15,0x47,0xd6,0x33,0x15,0xe7,0x92,0xe1,0x9b,0xfa,0xee,0x1d,0xe6,0x4f,0x99,0xd5,0xf1,0xcd,0x8b,0x6e,0xc9,0xcb,0x0f,0x78,0x7a,0x65,0x4a,0xe8,0x69,0x93,0xba,0x3d,0xb1,0x00,0x8e,0xf4,0x3c,0xff,0x06,0x84,0xcb,0x22,0xbd,
+ 0x04,0x1f,0x57,0x99,0xc9,0x5b,0xe8,0x90,0x63,0xb2,0x4f,0x26,0xe4,0x0c,0xb9,0x28,0xc1,0xa8,0x68,0xa7,0x6f,0xb0,0x09,0x46,0x07,0xe8,0x04,0x3d,0xb4,0x09,0xc9,0x1c,0x32,0xe7,0x57,0x24,0xe8,0x13,0xa4,0x19,0x1e,0x3a,0x83,0x90,0x07,0xf0,0x8e,0x2e,0x89,0x73,0x88,0xb0,0x6d,0x4a,0x00,0xde,0x6d,0xe6,0x0e,0x53,0x6d,0x91,0xfa,0xb5,0x66,
+ 0x04,0xa3,0x33,0x1a,0x4e,0x1b,0x42,0x23,0xec,0x2c,0x02,0x7e,0xdd,0x48,0x2c,0x92,0x8a,0x14,0xed,0x35,0x8d,0x93,0xf1,0xd4,0x21,0x7d,0x39,0xab,0xf6,0x9f,0xcb,0x5c,0xcc,0x28,0xd6,0x84,0xd2,0xaa,0xab,0xcd,0x63,0x83,0x77,0x5c,0xaa,0x62,0x39,0xde,0x26,0xd4,0xc6,0x93,0x7b,0xb6,0x03,0xec,0xb4,0x19,0x60,0x82,0xf4,0xcf,0xfd,0x50,0x9d,
+ 0x04,0x3f,0x39,0x52,0x19,0x97,0x74,0xc7,0xcf,0x39,0xb3,0x8b,0x66,0xcb,0x10,0x42,0xa6,0x26,0x0d,0x86,0x80,0x80,0x38,0x45,0xe4,0xd4,0x33,0xad,0xba,0x3b,0xb2,0x48,0x18,0x5e,0xa4,0x95,0xb6,0x8c,0xbc,0x7e,0xd4,0x17,0x3e,0xe6,0x3c,0x90,0x42,0xdc,0x50,0x26,0x25,0xc7,0xeb,0x7e,0x21,0xfb,0x02,0xca,0x9a,0x91,0x14,0xe0,0xa3,0xa1,0x8d,
+ 0x04,0xcd,0xfb,0x8c,0x0f,0x42,0x2e,0x14,0x4e,0x13,0x7c,0x24,0x12,0xc8,0x6c,0x17,0x1f,0x5f,0xe3,0xfa,0x3f,0x5b,0xbb,0x54,0x4e,0x90,0x76,0x28,0x8f,0x3c,0xed,0x78,0x6e,0x05,0x4f,0xd0,0x72,0x1b,0x77,0xc1,0x1c,0x79,0xbe,0xac,0xb3,0xc9,0x42,0x11,0xb0,0xa1,0x9b,0xda,0x08,0x65,0x2e,0xfe,0xaf,0x92,0x51,0x3a,0x3b,0x0a,0x16,0x36,0x98,
+ 0x04,0x73,0x59,0x8a,0x6a,0x1c,0x68,0x27,0x8f,0xa6,0xbf,0xd0,0xce,0x40,0x64,0xe6,0x82,0x35,0xbc,0x1c,0x0f,0x6b,0x20,0xa9,0x28,0x10,0x8b,0xe3,0x36,0x73,0x0f,0x87,0xe3,0xcb,0xae,0x61,0x25,0x19,0xb5,0x03,0x2e,0xcc,0x85,0xae,0xd8,0x11,0x27,0x1a,0x95,0xfe,0x79,0x39,0xd5,0xd3,0x46,0x01,0x40,0xba,0x31,0x8f,0x4d,0x14,0xab,0xa3,0x1d,
+ 0x04,0x58,0xde,0xbd,0x9a,0x7e,0xe2,0xc9,0xd5,0x91,0x32,0x47,0x8a,0x54,0x40,0xae,0x4d,0x5d,0x7e,0xd4,0x37,0x30,0x83,0x69,0xf9,0x2e,0xa8,0x6c,0x82,0x18,0x3f,0x10,0xa1,0x67,0x73,0xe7,0x6f,0x5e,0xdb,0xf4,0xda,0x0e,0x4f,0x1b,0xdf,0xfa,0xc0,0xf5,0x72,0x57,0xe1,0xdf,0xa4,0x65,0x84,0x29,0x31,0x30,0x9a,0x24,0x24,0x5f,0xda,0x6a,0x5d,
+ 0x04,0x8b,0x90,0x4d,0xe4,0x79,0x67,0x34,0x0c,0x5f,0x8c,0x35,0x72,0xa7,0x20,0x92,0x4e,0xf7,0x57,0x86,0x37,0xfe,0xab,0x19,0x49,0xac,0xb2,0x41,0xa5,0xa6,0xac,0x3f,0x5b,0x95,0x09,0x04,0x49,0x6f,0x98,0x24,0xb1,0xd6,0x3f,0x33,0x13,0xba,0xe2,0x1b,0x89,0xfa,0xe8,0x9a,0xfd,0xfc,0x81,0x1b,0x5e,0xce,0x03,0xfd,0x5a,0xa3,0x01,0x86,0x4f,
+ 0x04,0xf4,0x89,0x2b,0x6d,0x52,0x5c,0x77,0x1e,0x03,0x5f,0x2a,0x25,0x27,0x08,0xf3,0x78,0x4e,0x48,0x23,0x86,0x04,0xb4,0xf9,0x4d,0xc5,0x6e,0xaa,0x1e,0x54,0x6d,0x94,0x1a,0x34,0x6b,0x1a,0xa0,0xbc,0xe6,0x8b,0x1c,0x50,0xe5,0xb5,0x2f,0x50,0x9f,0xb5,0x52,0x2e,0x5c,0x25,0xe0,0x28,0xbc,0x8f,0x86,0x34,0x02,0xed,0xb7,0xbc,0xad,0x8b,0x1b,
+ 0x04,0x79,0xbe,0x66,0x7e,0xf9,0xdc,0xbb,0xac,0x55,0xa0,0x62,0x95,0xce,0x87,0x0b,0x07,0x02,0x9b,0xfc,0xdb,0x2d,0xce,0x28,0xd9,0x59,0xf2,0x81,0x5b,0x16,0xf8,0x17,0x98,0x48,0x3a,0xda,0x77,0x26,0xa3,0xc4,0x65,0x5d,0xa4,0xfb,0xfc,0x0e,0x11,0x08,0xa8,0xfd,0x17,0xb4,0x48,0xa6,0x85,0x54,0x19,0x9c,0x47,0xd0,0x8f,0xfb,0x10,0xd4,0xb8,
+ 0x04,0x79,0xbe,0x66,0x7e,0xf9,0xdc,0xbb,0xac,0x55,0xa0,0x62,0x95,0xce,0x87,0x0b,0x07,0x02,0x9b,0xfc,0xdb,0x2d,0xce,0x28,0xd9,0x59,0xf2,0x81,0x5b,0x16,0xf8,0x17,0x98,0xb7,0xc5,0x25,0x88,0xd9,0x5c,0x3b,0x9a,0xa2,0x5b,0x04,0x03,0xf1,0xee,0xf7,0x57,0x02,0xe8,0x4b,0xb7,0x59,0x7a,0xab,0xe6,0x63,0xb8,0x2f,0x6f,0x04,0xef,0x27,0x77,
+ 0x04,0x78,0x2c,0x8e,0xd1,0x7e,0x3b,0x2a,0x78,0x3b,0x54,0x64,0xf3,0x3b,0x09,0x65,0x2a,0x71,0xc6,0x78,0xe0,0x5e,0xc5,0x1e,0x84,0xe2,0xbc,0xfc,0x66,0x3a,0x3d,0xe9,0x63,0xaf,0x9a,0xcb,0x42,0x80,0xb8,0xc7,0xf7,0xc4,0x2f,0x4e,0xf9,0xab,0xa6,0x24,0x5e,0xc1,0xec,0x17,0x12,0xfd,0x38,0xa0,0xfa,0x96,0x41,0x8d,0x8c,0xd6,0xaa,0x61,0x52,
+ 0x04,0x6e,0x82,0x35,0x55,0x45,0x29,0x14,0x09,0x91,0x82,0xc6,0xb2,0xc1,0xd6,0xf0,0xb5,0xd2,0x8d,0x50,0xcc,0xd0,0x05,0xaf,0x2c,0xe1,0xbb,0xa5,0x41,0xaa,0x40,0xca,0xff,0x00,0x00,0x00,0x01,0x06,0x04,0x92,0xd5,0xa5,0x67,0x3e,0x0f,0x25,0xd8,0xd5,0x0f,0xb7,0xe5,0x8c,0x49,0xd8,0x6d,0x46,0xd4,0x21,0x69,0x55,0xe0,0xaa,0x3d,0x40,0xe1,
+ 0x04,0x6e,0x82,0x35,0x55,0x45,0x29,0x14,0x09,0x91,0x82,0xc6,0xb2,0xc1,0xd6,0xf0,0xb5,0xd2,0x8d,0x50,0xcc,0xd0,0x05,0xaf,0x2c,0xe1,0xbb,0xa5,0x41,0xaa,0x40,0xca,0xff,0xff,0xff,0xff,0xfe,0xf9,0xfb,0x6d,0x2a,0x5a,0x98,0xc1,0xf0,0xda,0x27,0x2a,0xf0,0x48,0x1a,0x73,0xb6,0x27,0x92,0xb9,0x2b,0xde,0x96,0xaa,0x1e,0x55,0xc2,0xbb,0x4e,
+ 0x04,0x00,0x00,0x00,0x01,0x3f,0xd2,0x22,0x48,0xd6,0x4d,0x95,0xf7,0x3c,0x29,0xb4,0x8a,0xb4,0x86,0x31,0x85,0x0b,0xe5,0x03,0xfd,0x00,0xf8,0x46,0x8b,0x5f,0x0f,0x70,0xe0,0xf6,0xee,0x7a,0xa4,0x3b,0xc2,0xc6,0xfd,0x25,0xb1,0xd8,0x26,0x92,0x41,0xcb,0xdd,0x9d,0xbb,0x0d,0xac,0x96,0xdc,0x96,0x23,0x1f,0x43,0x07,0x05,0xf8,0x38,0x71,0x7d,
+ 0x04,0x25,0xaf,0xd6,0x89,0xac,0xab,0xae,0xd6,0x7c,0x1f,0x29,0x6d,0xe5,0x94,0x06,0xf8,0xc5,0x50,0xf5,0x71,0x46,0xa0,0xb4,0xec,0x2c,0x97,0x87,0x6d,0xff,0xff,0xff,0xff,0xfa,0x46,0xa7,0x6e,0x52,0x03,0x22,0xdf,0xbc,0x49,0x1e,0xc4,0xf0,0xcc,0x19,0x74,0x20,0xfc,0x4e,0xa5,0x88,0x3d,0x8f,0x6d,0xd5,0x3c,0x35,0x4b,0xc4,0xf6,0x7c,0x35,
+ 0x04,0xd1,0x2e,0x6c,0x66,0xb6,0x77,0x34,0xc3,0xc8,0x4d,0x26,0x01,0xcf,0x5d,0x35,0xdc,0x09,0x7e,0x27,0x63,0x7f,0x0a,0xca,0x4a,0x4f,0xdb,0x74,0xb6,0xaa,0xdd,0x3b,0xb9,0x3f,0x5b,0xdf,0xf8,0x8b,0xd5,0x73,0x6d,0xf8,0x98,0xe6,0x99,0x00,0x6e,0xd7,0x50,0xf1,0x1c,0xf0,0x7c,0x58,0x66,0xcd,0x7a,0xd7,0x0c,0x71,0x21,0xff,0xff,0xff,0xff,
+ 0x04,0x6d,0x4a,0x7f,0x60,0xd4,0x77,0x4a,0x4f,0x0a,0xa8,0xbb,0xde,0xdb,0x95,0x3c,0x7e,0xea,0x79,0x09,0x40,0x7e,0x31,0x64,0x75,0x56,0x64,0xbc,0x28,0x00,0x00,0x00,0x00,0xe6,0x59,0xd3,0x4e,0x4d,0xf3,0x8d,0x9e,0x8c,0x9e,0xaa,0xdf,0xba,0x36,0x61,0x2c,0x76,0x91,0x95,0xbe,0x86,0xc7,0x7a,0xac,0x3f,0x36,0xe7,0x8b,0x53,0x86,0x80,0xfb};
+
+static const unsigned char wycheproof_ecdsa_signatures[] = { 0x30,0x46,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x21,0x00,0x90,0x0e,0x75,0xad,0x23,0x3f,0xcc,0x90,0x85,0x09,0xdb,0xff,0x59,0x22,0x64,0x7d,0xb3,0x7c,0x21,0xf4,0xaf,0xd3,0x20,0x3a,0xe8,0xdc,0x4a,0xe7,0x79,0x4b,0x0f,0x87,
+ 0x30,0x45,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x81,0x45,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x82,0x00,0x45,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x46,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x44,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x85,0x01,0x00,0x00,0x00,0x45,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x89,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x45,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x84,0x7f,0xff,0xff,0xff,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x84,0x80,0x00,0x00,0x00,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x84,0xff,0xff,0xff,0xff,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x85,0xff,0xff,0xff,0xff,0xff,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x88,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0xff,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x80,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,
+ 0x30,0x47,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,0x00,0x00,
+ 0x30,0x47,0x00,0x00,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x45,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,0x00,0x00,
+ 0x30,0x47,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,0x05,0x00,
+ 0x30,0x4a,0x49,0x81,0x77,0x30,0x45,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x49,0x25,0x00,0x30,0x45,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x47,0x30,0x45,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,0x00,0x04,0xde,0xad,0xbe,0xef,
+ 0x30,0x4d,0xaa,0x00,0xbb,0x00,0xcd,0x00,0x30,0x45,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x4d,0x22,0x29,0xaa,0x00,0xbb,0x00,0xcd,0x00,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x4d,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x22,0x28,0xaa,0x00,0xbb,0x00,0xcd,0x00,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x81,
+ 0x30,0x4b,0xaa,0x02,0xaa,0xbb,0x30,0x45,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x80,0x30,0x45,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,0x00,0x00,
+ 0x30,0x80,0x31,0x45,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,0x00,0x00,
+ 0x05,0x00,
+ 0x2e,0x45,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x2f,0x45,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x31,0x45,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x32,0x45,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0xff,0x45,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x00,
+ 0x30,0x49,0x30,0x01,0x02,0x30,0x44,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x44,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,
+ 0x30,0x44,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x82,0x10,0x46,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x30,0x80,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,0x00,0x00,
+ 0x30,0x80,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,0x00,
+ 0x30,0x80,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,0x05,0x00,0x00,0x00,
+ 0x30,0x80,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,0x06,0x08,0x11,0x22,0x00,0x00,
+ 0x30,0x80,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,0x00,0x00,0xfe,0x02,0xbe,0xef,
+ 0x30,0x80,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,0x00,0x02,0xbe,0xef,
+ 0x30,0x47,0x30,0x00,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x47,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,0x30,0x00,
+ 0x30,0x48,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,0x02,0x01,0x00,
+ 0x30,0x48,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,0xbf,0x7f,0x00,
+ 0x30,0x49,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,0xa0,0x02,0x05,0x00,
+ 0x30,0x47,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,0xa0,0x00,
+ 0x30,0x47,0x30,0x45,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x23,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,
+ 0x30,0x67,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x43,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x64,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x43,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xca,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x43,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x13,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x43,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x08,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x46,0x02,0x81,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x47,0x02,0x82,0x00,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x45,0x02,0x22,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x45,0x02,0x20,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x4a,0x02,0x85,0x01,0x00,0x00,0x00,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x4e,0x02,0x89,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x49,0x02,0x84,0x7f,0xff,0xff,0xff,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x49,0x02,0x84,0x80,0x00,0x00,0x00,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x49,0x02,0x84,0xff,0xff,0xff,0xff,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x4a,0x02,0x85,0xff,0xff,0xff,0xff,0xff,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x4d,0x02,0x88,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x45,0x02,0xff,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x45,0x02,0x80,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x22,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x23,0x02,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x24,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,
+ 0x30,0x47,0x02,0x23,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x00,0x00,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x47,0x02,0x23,0x00,0x00,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x47,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x00,0x00,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x47,0x02,0x23,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x05,0x00,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x4a,0x22,0x26,0x49,0x81,0x77,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x49,0x22,0x25,0x25,0x00,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x4d,0x22,0x23,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x00,0x04,0xde,0xad,0xbe,0xef,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x24,0x02,0x81,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x4b,0x22,0x27,0xaa,0x02,0xaa,0xbb,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x49,0x22,0x80,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x00,0x00,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x49,0x22,0x80,0x03,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x00,0x00,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x24,0x05,0x00,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x45,0x00,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x45,0x01,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x45,0x03,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x45,0x04,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x45,0xff,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x24,0x02,0x00,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x49,0x22,0x25,0x02,0x01,0x00,0x02,0x20,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x45,0x02,0x21,0x02,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x45,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0xe5,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x44,0x02,0x20,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x44,0x02,0x20,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x82,0x10,0x48,0x02,0x82,0x10,0x22,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x46,0x02,0x22,0xff,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x25,0x09,0x01,0x80,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x25,0x02,0x01,0x00,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x43,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xbb,
+ 0x30,0x43,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa4,0x56,0xeb,0x31,0xba,
+ 0x30,0x43,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf7,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x43,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x01,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x46,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x81,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x47,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x82,0x00,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x45,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x21,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x45,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x1f,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x4a,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x85,0x01,0x00,0x00,0x00,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x4e,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x89,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x49,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x84,0x7f,0xff,0xff,0xff,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x49,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x84,0x80,0x00,0x00,0x00,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x49,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x84,0xff,0xff,0xff,0xff,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x4a,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x85,0xff,0xff,0xff,0xff,0xff,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x4d,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x88,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x45,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0xff,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x45,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x80,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x47,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x22,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,0x00,0x00,
+ 0x30,0x47,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x22,0x00,0x00,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x47,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x22,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,0x05,0x00,
+ 0x30,0x4a,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x22,0x25,0x49,0x81,0x77,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x49,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x22,0x24,0x25,0x00,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x4d,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x22,0x22,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,0x00,0x04,0xde,0xad,0xbe,0xef,
+ 0x30,0x25,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x81,
+ 0x30,0x4b,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x22,0x26,0xaa,0x02,0xaa,0xbb,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x49,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x22,0x80,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,0x00,0x00,
+ 0x30,0x49,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x22,0x80,0x03,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,0x00,0x00,
+ 0x30,0x25,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x05,0x00,
+ 0x30,0x45,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x00,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x45,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x01,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x45,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x03,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x45,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x04,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x45,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0xff,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x25,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x00,
+ 0x30,0x49,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x22,0x24,0x02,0x01,0x6f,0x02,0x1f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x45,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6d,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x45,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0x3a,
+ 0x30,0x44,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x1f,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,
+ 0x30,0x44,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x1f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x82,0x10,0x48,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x82,0x10,0x21,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x30,0x46,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x21,0xff,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x26,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x09,0x01,0x80,
+ 0x30,0x26,0x02,0x21,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x01,0x00,
+ 0x30,0x45,0x02,0x21,0x01,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x83,0xb9,0x0d,0xea,0xbc,0xa4,0xb0,0x5c,0x45,0x74,0xe4,0x9b,0x58,0x99,0xb9,0x64,0xa6,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x44,0x02,0x20,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x86,0x43,0xb0,0x30,0xef,0x46,0x1f,0x1b,0xcd,0xf5,0x3f,0xde,0x3e,0xf9,0x4c,0xe2,0x24,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x46,0x02,0x22,0x01,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x84,0x3f,0xad,0x3b,0xf4,0x85,0x3e,0x07,0xf7,0xc9,0x87,0x70,0xc9,0x9b,0xff,0xc4,0x64,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x45,0x02,0x21,0xff,0x7e,0xc1,0x08,0x63,0x31,0x05,0x65,0xa9,0x08,0x45,0x7f,0xa0,0xf1,0xb8,0x7a,0x7b,0x01,0xa0,0xf2,0x2a,0x0a,0x98,0x43,0xf6,0x4a,0xed,0xc3,0x34,0x36,0x7c,0xdc,0x9b,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x44,0x02,0x20,0x7e,0xc1,0x08,0x63,0x31,0x05,0x65,0xa9,0x08,0x45,0x7f,0xa0,0xf1,0xb8,0x7a,0x79,0xbc,0x4f,0xcf,0x10,0xb9,0xe0,0xe4,0x32,0x0a,0xc0,0x21,0xc1,0x06,0xb3,0x1d,0xdc,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x45,0x02,0x21,0xfe,0x7e,0xc1,0x08,0x63,0x31,0x05,0x65,0xa9,0x08,0x45,0x7f,0xa0,0xf1,0xb8,0x7a,0x7c,0x46,0xf2,0x15,0x43,0x5b,0x4f,0xa3,0xba,0x8b,0x1b,0x64,0xa7,0x66,0x46,0x9b,0x5a,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x45,0x02,0x21,0x01,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x4d,0x02,0x29,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0x3e,0xf7,0x9c,0xce,0xfa,0x9a,0x56,0xf7,0xba,0x80,0x5f,0x0e,0x47,0x85,0x84,0xfe,0x5f,0x0d,0xd5,0xf5,0x67,0xbc,0x09,0xb5,0x12,0x3c,0xcb,0xc9,0x83,0x23,0x65,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x45,0x02,0x21,0x01,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x7f,0xc1,0xe1,0x97,0xd8,0xae,0xbe,0x20,0x3c,0x96,0xc8,0x72,0x32,0x27,0x21,0x72,0xfb,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x45,0x02,0x21,0xff,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x82,0x4c,0x83,0xde,0x0b,0x50,0x2c,0xdf,0xc5,0x17,0x23,0xb5,0x18,0x86,0xb4,0xf0,0x79,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x46,0x02,0x22,0x01,0x00,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9a,0x3b,0xb6,0x0f,0xa1,0xa1,0x48,0x15,0xbb,0xc0,0xa9,0x54,0xa0,0x75,0x8d,0x2c,0x72,0xba,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x44,0x02,0x20,0x90,0x0e,0x75,0xad,0x23,0x3f,0xcc,0x90,0x85,0x09,0xdb,0xff,0x59,0x22,0x64,0x7e,0xf8,0xcd,0x45,0x0e,0x00,0x8a,0x7f,0xff,0x29,0x09,0xec,0x5a,0xa9,0x14,0xce,0x46,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x45,0x02,0x21,0xfe,0x90,0x0e,0x75,0xad,0x23,0x3f,0xcc,0x90,0x85,0x09,0xdb,0xff,0x59,0x22,0x64,0x80,0x3e,0x1e,0x68,0x27,0x51,0x41,0xdf,0xc3,0x69,0x37,0x8d,0xcd,0xd8,0xde,0x8d,0x05,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x45,0x02,0x21,0x01,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x45,0x02,0x21,0xff,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x4d,0x02,0x29,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,0x02,0x20,0x6f,0xf1,0x8a,0x52,0xdc,0xc0,0x33,0x6f,0x7a,0xf6,0x24,0x00,0xa6,0xdd,0x9b,0x81,0x07,0x32,0xba,0xf1,0xff,0x75,0x80,0x00,0xd6,0xf6,0x13,0xa5,0x56,0xeb,0x31,0xba,
+ 0x30,0x06,0x02,0x01,0x00,0x02,0x01,0x00,
+ 0x30,0x06,0x02,0x01,0x00,0x02,0x01,0x01,
+ 0x30,0x06,0x02,0x01,0x00,0x02,0x01,0xff,
+ 0x30,0x26,0x02,0x01,0x00,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x41,
+ 0x30,0x26,0x02,0x01,0x00,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x40,
+ 0x30,0x26,0x02,0x01,0x00,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x42,
+ 0x30,0x26,0x02,0x01,0x00,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x2f,
+ 0x30,0x26,0x02,0x01,0x00,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x30,
+ 0x30,0x06,0x02,0x01,0x01,0x02,0x01,0x00,
+ 0x30,0x06,0x02,0x01,0x01,0x02,0x01,0x01,
+ 0x30,0x06,0x02,0x01,0x01,0x02,0x01,0xff,
+ 0x30,0x26,0x02,0x01,0x01,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x41,
+ 0x30,0x26,0x02,0x01,0x01,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x40,
+ 0x30,0x26,0x02,0x01,0x01,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x42,
+ 0x30,0x26,0x02,0x01,0x01,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x2f,
+ 0x30,0x26,0x02,0x01,0x01,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x30,
+ 0x30,0x06,0x02,0x01,0xff,0x02,0x01,0x00,
+ 0x30,0x06,0x02,0x01,0xff,0x02,0x01,0x01,
+ 0x30,0x06,0x02,0x01,0xff,0x02,0x01,0xff,
+ 0x30,0x26,0x02,0x01,0xff,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x41,
+ 0x30,0x26,0x02,0x01,0xff,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x40,
+ 0x30,0x26,0x02,0x01,0xff,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x42,
+ 0x30,0x26,0x02,0x01,0xff,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x2f,
+ 0x30,0x26,0x02,0x01,0xff,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x30,
+ 0x30,0x26,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x41,0x02,0x01,0x00,
+ 0x30,0x26,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x41,0x02,0x01,0x01,
+ 0x30,0x26,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x41,0x02,0x01,0xff,
+ 0x30,0x46,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x41,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x41,
+ 0x30,0x46,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x41,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x40,
+ 0x30,0x46,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x41,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x42,
+ 0x30,0x46,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x41,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x2f,
+ 0x30,0x46,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x41,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x30,
+ 0x30,0x26,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x40,0x02,0x01,0x00,
+ 0x30,0x26,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x40,0x02,0x01,0x01,
+ 0x30,0x26,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x40,0x02,0x01,0xff,
+ 0x30,0x46,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x40,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x41,
+ 0x30,0x46,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x40,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x40,
+ 0x30,0x46,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x40,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x42,
+ 0x30,0x46,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x40,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x2f,
+ 0x30,0x46,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x40,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x30,
+ 0x30,0x26,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x42,0x02,0x01,0x00,
+ 0x30,0x26,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x42,0x02,0x01,0x01,
+ 0x30,0x26,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x42,0x02,0x01,0xff,
+ 0x30,0x46,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x42,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x41,
+ 0x30,0x46,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x42,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x40,
+ 0x30,0x46,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x42,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x42,
+ 0x30,0x46,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x42,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x2f,
+ 0x30,0x46,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x42,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x30,
+ 0x30,0x26,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x2f,0x02,0x01,0x00,
+ 0x30,0x26,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x2f,0x02,0x01,0x01,
+ 0x30,0x26,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x2f,0x02,0x01,0xff,
+ 0x30,0x46,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x2f,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x41,
+ 0x30,0x46,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x2f,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x40,
+ 0x30,0x46,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x2f,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x42,
+ 0x30,0x46,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x2f,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x2f,
+ 0x30,0x46,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x2f,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x30,
+ 0x30,0x26,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x30,0x02,0x01,0x00,
+ 0x30,0x26,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x30,0x02,0x01,0x01,
+ 0x30,0x26,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x30,0x02,0x01,0xff,
+ 0x30,0x46,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x30,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x41,
+ 0x30,0x46,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x30,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x40,
+ 0x30,0x46,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x30,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x42,
+ 0x30,0x46,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x30,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x2f,
+ 0x30,0x46,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x30,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x30,
+ 0x30,0x08,0x02,0x01,0x00,0x09,0x03,0x80,0xfe,0x01,
+ 0x30,0x06,0x02,0x01,0x00,0x09,0x01,0x42,
+ 0x30,0x06,0x02,0x01,0x00,0x01,0x01,0x01,
+ 0x30,0x06,0x02,0x01,0x00,0x01,0x01,0x00,
+ 0x30,0x05,0x02,0x01,0x00,0x05,0x00,
+ 0x30,0x05,0x02,0x01,0x00,0x0c,0x00,
+ 0x30,0x06,0x02,0x01,0x00,0x0c,0x01,0x30,
+ 0x30,0x05,0x02,0x01,0x00,0x30,0x00,
+ 0x30,0x08,0x02,0x01,0x00,0x30,0x03,0x02,0x01,0x00,
+ 0x30,0x08,0x02,0x01,0x01,0x09,0x03,0x80,0xfe,0x01,
+ 0x30,0x06,0x02,0x01,0x01,0x09,0x01,0x42,
+ 0x30,0x06,0x02,0x01,0x01,0x01,0x01,0x01,
+ 0x30,0x06,0x02,0x01,0x01,0x01,0x01,0x00,
+ 0x30,0x05,0x02,0x01,0x01,0x05,0x00,
+ 0x30,0x05,0x02,0x01,0x01,0x0c,0x00,
+ 0x30,0x06,0x02,0x01,0x01,0x0c,0x01,0x30,
+ 0x30,0x05,0x02,0x01,0x01,0x30,0x00,
+ 0x30,0x08,0x02,0x01,0x01,0x30,0x03,0x02,0x01,0x00,
+ 0x30,0x08,0x02,0x01,0xff,0x09,0x03,0x80,0xfe,0x01,
+ 0x30,0x06,0x02,0x01,0xff,0x09,0x01,0x42,
+ 0x30,0x06,0x02,0x01,0xff,0x01,0x01,0x01,
+ 0x30,0x06,0x02,0x01,0xff,0x01,0x01,0x00,
+ 0x30,0x05,0x02,0x01,0xff,0x05,0x00,
+ 0x30,0x05,0x02,0x01,0xff,0x0c,0x00,
+ 0x30,0x06,0x02,0x01,0xff,0x0c,0x01,0x30,
+ 0x30,0x05,0x02,0x01,0xff,0x30,0x00,
+ 0x30,0x08,0x02,0x01,0xff,0x30,0x03,0x02,0x01,0x00,
+ 0x30,0x28,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x41,0x09,0x03,0x80,0xfe,0x01,
+ 0x30,0x26,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x41,0x09,0x01,0x42,
+ 0x30,0x26,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x41,0x01,0x01,0x01,
+ 0x30,0x26,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x41,0x01,0x01,0x00,
+ 0x30,0x25,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x41,0x05,0x00,
+ 0x30,0x25,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x41,0x0c,0x00,
+ 0x30,0x26,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x41,0x0c,0x01,0x30,
+ 0x30,0x25,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x41,0x30,0x00,
+ 0x30,0x28,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x41,0x30,0x03,0x02,0x01,0x00,
+ 0x30,0x28,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x2f,0x09,0x03,0x80,0xfe,0x01,
+ 0x30,0x26,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x2f,0x09,0x01,0x42,
+ 0x30,0x26,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x2f,0x01,0x01,0x01,
+ 0x30,0x26,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x2f,0x01,0x01,0x00,
+ 0x30,0x25,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x2f,0x05,0x00,
+ 0x30,0x25,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x2f,0x0c,0x00,
+ 0x30,0x26,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x2f,0x0c,0x01,0x30,
+ 0x30,0x25,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x2f,0x30,0x00,
+ 0x30,0x28,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x2f,0x30,0x03,0x02,0x01,0x00,
+ 0x30,0x0a,0x09,0x03,0x80,0xfe,0x01,0x09,0x03,0x80,0xfe,0x01,
+ 0x30,0x06,0x09,0x01,0x42,0x09,0x01,0x42,
+ 0x30,0x06,0x01,0x01,0x01,0x01,0x01,0x01,
+ 0x30,0x06,0x01,0x01,0x00,0x01,0x01,0x00,
+ 0x30,0x04,0x05,0x00,0x05,0x00,
+ 0x30,0x04,0x0c,0x00,0x0c,0x00,
+ 0x30,0x06,0x0c,0x01,0x30,0x0c,0x01,0x30,
+ 0x30,0x04,0x30,0x00,0x30,0x00,
+ 0x30,0x0a,0x30,0x03,0x02,0x01,0x00,0x30,0x03,0x02,0x01,0x00,
+ 0x30,0x08,0x09,0x03,0x80,0xfe,0x01,0x02,0x01,0x00,
+ 0x30,0x06,0x09,0x01,0x42,0x02,0x01,0x00,
+ 0x30,0x06,0x01,0x01,0x01,0x02,0x01,0x00,
+ 0x30,0x06,0x01,0x01,0x00,0x02,0x01,0x00,
+ 0x30,0x05,0x05,0x00,0x02,0x01,0x00,
+ 0x30,0x05,0x0c,0x00,0x02,0x01,0x00,
+ 0x30,0x06,0x0c,0x01,0x30,0x02,0x01,0x00,
+ 0x30,0x05,0x30,0x00,0x02,0x01,0x00,
+ 0x30,0x08,0x30,0x03,0x02,0x01,0x00,0x02,0x01,0x00,
+ 0x30,0x45,0x02,0x21,0x00,0xdd,0x1b,0x7d,0x09,0xa7,0xbd,0x82,0x18,0x96,0x10,0x34,0xa3,0x9a,0x87,0xfe,0xcf,0x53,0x14,0xf0,0x0c,0x4d,0x25,0xeb,0x58,0xa0,0x7a,0xc8,0x5e,0x85,0xea,0xb5,0x16,0x02,0x20,0x35,0x13,0x8c,0x40,0x1e,0xf8,0xd3,0x49,0x3d,0x65,0xc9,0x00,0x2f,0xe6,0x2b,0x43,0xae,0xe5,0x68,0x73,0x1b,0x74,0x45,0x48,0x35,0x89,0x96,0xd9,0xcc,0x42,0x7e,0x06,
+ 0x30,0x45,0x02,0x21,0x00,0x95,0xc2,0x92,0x67,0xd9,0x72,0xa0,0x43,0xd9,0x55,0x22,0x45,0x46,0x22,0x2b,0xba,0x34,0x3f,0xc1,0xd4,0xdb,0x0f,0xec,0x26,0x2a,0x33,0xac,0x61,0x30,0x56,0x96,0xae,0x02,0x20,0x6e,0xdf,0xe9,0x67,0x13,0xae,0xd5,0x6f,0x8a,0x28,0xa6,0x65,0x3f,0x57,0xe0,0xb8,0x29,0x71,0x2e,0x5e,0xdd,0xc6,0x7f,0x34,0x68,0x2b,0x24,0xf0,0x67,0x6b,0x26,0x40,
+ 0x30,0x44,0x02,0x20,0x28,0xf9,0x4a,0x89,0x4e,0x92,0x02,0x46,0x99,0xe3,0x45,0xfe,0x66,0x97,0x1e,0x3e,0xdc,0xd0,0x50,0x02,0x33,0x86,0x13,0x5a,0xb3,0x93,0x9d,0x55,0x08,0x98,0xfb,0x25,0x02,0x20,0x32,0x96,0x3e,0x5b,0xd4,0x1f,0xa5,0x91,0x1e,0xd8,0xf3,0x7d,0xeb,0x86,0xda,0xe0,0xa7,0x62,0xbb,0x61,0x21,0xc8,0x94,0x61,0x50,0x83,0xc5,0xd9,0x5e,0xa0,0x1d,0xb3,
+ 0x30,0x45,0x02,0x21,0x00,0xbe,0x26,0xb1,0x8f,0x95,0x49,0xf8,0x9f,0x41,0x1a,0x9b,0x52,0x53,0x6b,0x15,0xaa,0x27,0x0b,0x84,0x54,0x8d,0x0e,0x85,0x9a,0x19,0x52,0xa2,0x7a,0xf1,0xa7,0x7a,0xc6,0x02,0x20,0x70,0xc1,0xd4,0xfa,0x9c,0xd0,0x3c,0xc8,0xea,0xa8,0xd5,0x06,0xed,0xb9,0x7e,0xed,0x7b,0x83,0x58,0xb4,0x53,0xc8,0x8a,0xef,0xbb,0x88,0x0a,0x3f,0x0e,0x8d,0x47,0x2f,
+ 0x30,0x45,0x02,0x21,0x00,0xb1,0xa4,0xb1,0x47,0x8e,0x65,0xcc,0x3e,0xaf,0xdf,0x22,0x5d,0x12,0x98,0xb4,0x3f,0x2d,0xa1,0x9e,0x4b,0xcf,0xf7,0xea,0xcc,0x0a,0x2e,0x98,0xcd,0x4b,0x74,0xb1,0x14,0x02,0x20,0x17,0x9a,0xa3,0x1e,0x30,0x4c,0xc1,0x42,0xcf,0x50,0x73,0x17,0x17,0x51,0xb2,0x8f,0x3f,0x5e,0x0f,0xa8,0x8c,0x99,0x4e,0x7c,0x55,0xf1,0xbc,0x07,0xb8,0xd5,0x6c,0x16,
+ 0x30,0x44,0x02,0x20,0x32,0x53,0x32,0x02,0x12,0x61,0xf1,0xbd,0x18,0xf2,0x71,0x2a,0xa1,0xe2,0x25,0x2d,0xa2,0x37,0x96,0xda,0x8a,0x4b,0x1f,0xf6,0xea,0x18,0xca,0xfe,0xc7,0xe1,0x71,0xf2,0x02,0x20,0x40,0xb4,0xf5,0xe2,0x87,0xee,0x61,0xfc,0x3c,0x80,0x41,0x86,0x98,0x23,0x60,0x89,0x1e,0xaa,0x35,0xc7,0x5f,0x05,0xa4,0x3e,0xcd,0x48,0xb3,0x5d,0x98,0x4a,0x66,0x48,
+ 0x30,0x45,0x02,0x21,0x00,0xa2,0x3a,0xd1,0x8d,0x8f,0xc6,0x6d,0x81,0xaf,0x09,0x03,0x89,0x0c,0xbd,0x45,0x3a,0x55,0x4c,0xb0,0x4c,0xdc,0x1a,0x8c,0xa7,0xf7,0xf7,0x8e,0x53,0x67,0xed,0x88,0xa0,0x02,0x20,0x23,0xe3,0xeb,0x2c,0xe1,0xc0,0x4e,0xa7,0x48,0xc3,0x89,0xbd,0x97,0x37,0x4a,0xa9,0x41,0x3b,0x92,0x68,0x85,0x1c,0x04,0xdc,0xd9,0xf8,0x8e,0x78,0x81,0x3f,0xee,0x56,
+ 0x30,0x44,0x02,0x20,0x2b,0xde,0xa4,0x1c,0xda,0x63,0xa2,0xd1,0x4b,0xf4,0x73,0x53,0xbd,0x20,0x88,0x0a,0x69,0x09,0x01,0xde,0x7c,0xd6,0xe3,0xcc,0x6d,0x8e,0xd5,0xba,0x0c,0xdb,0x10,0x91,0x02,0x20,0x3c,0xea,0x66,0xbc,0xcf,0xc9,0xf9,0xbf,0x8c,0x7c,0xa4,0xe1,0xc1,0x45,0x7c,0xc9,0x14,0x5e,0x13,0xe9,0x36,0xd9,0x0b,0x3d,0x9c,0x77,0x86,0xb8,0xb2,0x6c,0xf4,0xc7,
+ 0x30,0x45,0x02,0x21,0x00,0xd7,0xcd,0x76,0xec,0x01,0xc1,0xb1,0x07,0x9e,0xba,0x9e,0x2a,0xa2,0xa3,0x97,0x24,0x3c,0x47,0x58,0xc9,0x8a,0x1b,0xa0,0xb7,0x40,0x4a,0x34,0x0b,0x9b,0x00,0xce,0xd6,0x02,0x20,0x35,0x75,0x00,0x1e,0x19,0xd9,0x22,0xe6,0xde,0x8b,0x3d,0x6c,0x84,0xea,0x43,0xb5,0xc3,0x33,0x81,0x06,0xcf,0x29,0x99,0x01,0x34,0xe7,0x66,0x9a,0x82,0x6f,0x78,0xe6,
+ 0x30,0x45,0x02,0x21,0x00,0xa8,0x72,0xc7,0x44,0xd9,0x36,0xdb,0x21,0xa1,0x0c,0x36,0x1d,0xd5,0xc9,0x06,0x33,0x55,0xf8,0x49,0x02,0x21,0x96,0x52,0xf6,0xfc,0x56,0xdc,0x95,0xa7,0x13,0x9d,0x96,0x02,0x20,0x40,0x0d,0xf7,0x57,0x5d,0x97,0x56,0x21,0x0e,0x9c,0xcc,0x77,0x16,0x2c,0x6b,0x59,0x3c,0x77,0x46,0xcf,0xb4,0x8a,0xc2,0x63,0xc4,0x27,0x50,0xb4,0x21,0xef,0x4b,0xb9,
+ 0x30,0x45,0x02,0x21,0x00,0x9f,0xa9,0xaf,0xe0,0x77,0x52,0xda,0x10,0xb3,0x6d,0x3a,0xfc,0xd0,0xfe,0x44,0xbf,0xc4,0x02,0x44,0xd7,0x52,0x03,0x59,0x9c,0xf8,0xf5,0x04,0x7f,0xa3,0x45,0x38,0x54,0x02,0x20,0x50,0xe0,0xa7,0xc0,0x13,0xbf,0xbf,0x51,0x81,0x97,0x36,0x97,0x2d,0x44,0xb4,0xb5,0x6b,0xc2,0xa2,0xb2,0xc1,0x80,0xdf,0x6e,0xc6,0x72,0xdf,0x17,0x14,0x10,0xd7,0x7a,
+ 0x30,0x45,0x02,0x21,0x00,0x88,0x56,0x40,0x38,0x4d,0x0d,0x91,0x0e,0xfb,0x17,0x7b,0x46,0xbe,0x6c,0x3d,0xc5,0xca,0xc8,0x1f,0x0b,0x88,0xc3,0x19,0x0b,0xb6,0xb5,0xf9,0x9c,0x26,0x41,0xf2,0x05,0x02,0x20,0x73,0x8e,0xd9,0xbf,0xf1,0x16,0x30,0x6d,0x9c,0xaa,0x0f,0x8f,0xc6,0x08,0xbe,0x24,0x3e,0x0b,0x56,0x77,0x79,0xd8,0xda,0xb0,0x3e,0x8e,0x19,0xd5,0x53,0xf1,0xdc,0x8e,
+ 0x30,0x44,0x02,0x20,0x2d,0x05,0x1f,0x91,0xc5,0xa9,0xd4,0x40,0xc5,0x67,0x69,0x85,0x71,0x04,0x83,0xbc,0x4f,0x1a,0x6c,0x61,0x1b,0x10,0xc9,0x5a,0x2f,0xf0,0x36,0x3d,0x90,0xc2,0xa4,0x58,0x02,0x20,0x6d,0xdf,0x94,0xe6,0xfb,0xa5,0xbe,0x58,0x68,0x33,0xd0,0xc5,0x3c,0xf2,0x16,0xad,0x39,0x48,0xf3,0x79,0x53,0xc2,0x6c,0x1c,0xf4,0x96,0x8e,0x9a,0x9e,0x82,0x43,0xdc,
+ 0x30,0x45,0x02,0x21,0x00,0xf3,0xac,0x25,0x23,0x96,0x74,0x82,0xf5,0x3d,0x50,0x85,0x22,0x71,0x2d,0x58,0x3f,0x43,0x79,0xcd,0x82,0x41,0x01,0xff,0x63,0x5e,0xa0,0x93,0x51,0x17,0xba,0xa5,0x4f,0x02,0x20,0x27,0xf1,0x08,0x12,0x22,0x73,0x97,0xe0,0x2c,0xea,0x96,0xfb,0x0e,0x68,0x07,0x61,0x63,0x6d,0xab,0x2b,0x08,0x0d,0x1f,0xc5,0xd1,0x16,0x85,0xcb,0xe8,0x50,0x0c,0xfe,
+ 0x30,0x45,0x02,0x21,0x00,0x96,0x44,0x7c,0xf6,0x8c,0x3a,0xb7,0x26,0x6e,0xd7,0x44,0x7d,0xe3,0xac,0x52,0xfe,0xd7,0xcc,0x08,0xcb,0xdf,0xea,0x39,0x1c,0x18,0xa9,0xb8,0xab,0x37,0x0b,0xc9,0x13,0x02,0x20,0x0f,0x5e,0x78,0x74,0xd3,0xac,0x0e,0x91,0x8f,0x01,0xc8,0x85,0xa1,0x63,0x91,0x77,0xc9,0x23,0xf8,0x66,0x0d,0x1c,0xeb,0xa1,0xca,0x1f,0x30,0x1b,0xc6,0x75,0xcd,0xbc,
+ 0x30,0x44,0x02,0x20,0x53,0x0a,0x08,0x32,0xb6,0x91,0xda,0x0b,0x56,0x19,0xa0,0xb1,0x1d,0xe6,0x87,0x7f,0x3c,0x09,0x71,0xba,0xaa,0x68,0xed,0x12,0x27,0x58,0xc2,0x9c,0xaa,0xf4,0x6b,0x72,0x02,0x20,0x6c,0x89,0xe4,0x4f,0x5e,0xb3,0x30,0x60,0xea,0x4b,0x46,0x31,0x8c,0x39,0x13,0x8e,0xae,0xde,0xc7,0x2d,0xe4,0x2b,0xa5,0x76,0x57,0x9a,0x6a,0x46,0x90,0xe3,0x39,0xf3,
+ 0x30,0x45,0x02,0x21,0x00,0x9c,0x54,0xc2,0x55,0x00,0xbd,0xe0,0xb9,0x2d,0x72,0xd6,0xec,0x48,0x3d,0xc2,0x48,0x2f,0x36,0x54,0x29,0x4c,0xa7,0x4d,0xe7,0x96,0xb6,0x81,0x25,0x5e,0xd5,0x8a,0x77,0x02,0x20,0x67,0x74,0x53,0xc6,0xb5,0x6f,0x52,0x76,0x31,0xc9,0xf6,0x7b,0x3f,0x3e,0xb6,0x21,0xfd,0x88,0x58,0x2b,0x4a,0xff,0x15,0x6d,0x2f,0x15,0x67,0xd6,0x21,0x1a,0x2a,0x33,
+ 0x30,0x45,0x02,0x21,0x00,0xe7,0x90,0x9d,0x41,0x43,0x9e,0x2f,0x6a,0xf2,0x91,0x36,0xc7,0x34,0x8c,0xa2,0x64,0x1a,0x2b,0x07,0x0d,0x5b,0x64,0xf9,0x1e,0xa9,0xda,0x70,0x70,0xc7,0xa2,0x61,0x8b,0x02,0x20,0x42,0xd7,0x82,0xf1,0x32,0xfa,0x1d,0x36,0xc2,0xc8,0x8b,0xa2,0x7c,0x3d,0x67,0x8d,0x80,0x18,0x4a,0x5d,0x1e,0xcc,0xac,0x75,0x01,0xf0,0xb4,0x7e,0x3d,0x20,0x50,0x08,
+ 0x30,0x44,0x02,0x20,0x59,0x24,0x87,0x32,0x09,0x59,0x31,0x35,0xa4,0xc3,0xda,0x7b,0xb3,0x81,0x22,0x7f,0x8a,0x4b,0x6a,0xa9,0xf3,0x4f,0xe5,0xbb,0x7f,0x8f,0xbc,0x13,0x1a,0x03,0x9f,0xfe,0x02,0x20,0x1f,0x1b,0xb1,0x1b,0x44,0x1c,0x8f,0xea,0xa4,0x0f,0x44,0x21,0x3d,0x9a,0x40,0x5e,0xd7,0x92,0xd5,0x9f,0xb4,0x9d,0x5b,0xcd,0xd9,0xa4,0x28,0x5a,0xe5,0x69,0x30,0x22,
+ 0x30,0x45,0x02,0x21,0x00,0xee,0xb6,0x92,0xc9,0xb2,0x62,0x96,0x9b,0x23,0x1c,0x38,0xb5,0xa7,0xf6,0x06,0x49,0xe0,0xc8,0x75,0xcd,0x64,0xdf,0x88,0xf3,0x3a,0xa5,0x71,0xfa,0x3d,0x29,0xab,0x0e,0x02,0x20,0x21,0x8b,0x3a,0x1e,0xb0,0x63,0x79,0xc2,0xc1,0x8c,0xf5,0x1b,0x06,0x43,0x07,0x86,0xd1,0xc6,0x4c,0xd2,0xd2,0x4c,0x9b,0x23,0x2b,0x23,0xe5,0xba,0xc7,0x98,0x9a,0xcd,
+ 0x30,0x45,0x02,0x21,0x00,0xa4,0x00,0x34,0x17,0x7f,0x36,0x09,0x1c,0x2b,0x65,0x36,0x84,0xa0,0xe3,0xeb,0x5d,0x4b,0xff,0x18,0xe4,0xd0,0x9f,0x66,0x4c,0x28,0x00,0xe7,0xca,0xfd,0xa1,0xda,0xf8,0x02,0x20,0x3a,0x3e,0xc2,0x98,0x53,0x70,0x4e,0x52,0x03,0x1c,0x58,0x92,0x7a,0x80,0x0a,0x96,0x83,0x53,0xad,0xc3,0xd9,0x73,0xbe,0xba,0x91,0x72,0xcb,0xbe,0xab,0x4d,0xd1,0x49,
+ 0x30,0x45,0x02,0x21,0x00,0xb5,0xd7,0x95,0xcc,0x75,0xce,0xa5,0xc4,0x34,0xfa,0x41,0x85,0x18,0x0c,0xd6,0xbd,0x21,0x22,0x3f,0x3d,0x5a,0x86,0xda,0x66,0x70,0xd7,0x1d,0x95,0x68,0x0d,0xad,0xbf,0x02,0x20,0x54,0xe4,0xd8,0x81,0x0a,0x00,0x1e,0xcb,0xb9,0xf7,0xca,0x1c,0x2e,0xbf,0xdb,0x9d,0x00,0x9e,0x90,0x31,0xa4,0x31,0xac,0xa3,0xc2,0x0a,0xb4,0xe0,0xd1,0x37,0x4e,0xc1,
+ 0x30,0x44,0x02,0x20,0x07,0xdc,0x24,0x78,0xd4,0x3c,0x12,0x32,0xa4,0x59,0x56,0x08,0xc6,0x44,0x26,0xc3,0x55,0x10,0x05,0x1a,0x63,0x1a,0xe6,0xa5,0xa6,0xeb,0x11,0x61,0xe5,0x7e,0x42,0xe1,0x02,0x20,0x4a,0x59,0xea,0x0f,0xdb,0x72,0xd1,0x21,0x65,0xce,0xa3,0xbf,0x1c,0xa8,0x6b,0xa9,0x75,0x17,0xbd,0x18,0x8d,0xb3,0xdb,0xd2,0x1a,0x5a,0x15,0x78,0x50,0x02,0x19,0x84,
+ 0x30,0x45,0x02,0x21,0x00,0xdd,0xd2,0x0c,0x4a,0x05,0x59,0x6c,0xa8,0x68,0xb5,0x58,0x83,0x9f,0xce,0x9f,0x65,0x11,0xdd,0xd8,0x3d,0x1c,0xcb,0x53,0xf8,0x2e,0x52,0x69,0xd5,0x59,0xa0,0x15,0x52,0x02,0x20,0x5b,0x91,0x73,0x47,0x29,0xd9,0x30,0x93,0xff,0x22,0x12,0x3c,0x4a,0x25,0x81,0x9d,0x7f,0xeb,0x66,0xa2,0x50,0x66,0x3f,0xc7,0x80,0xcb,0x66,0xfc,0x7b,0x6e,0x6d,0x17,
+ 0x30,0x45,0x02,0x21,0x00,0x9c,0xde,0x6e,0x0e,0xde,0x0a,0x00,0x3f,0x02,0xfd,0xa0,0xa0,0x1b,0x59,0xfa,0xcf,0xe5,0xde,0xc0,0x63,0x31,0x8f,0x27,0x9c,0xe2,0xde,0x7a,0x9b,0x10,0x62,0xf7,0xb7,0x02,0x20,0x28,0x86,0xa5,0xb8,0xc6,0x79,0xbd,0xf8,0x22,0x4c,0x66,0xf9,0x08,0xfd,0x62,0x05,0x49,0x2c,0xb7,0x0b,0x00,0x68,0xd4,0x6a,0xe4,0xf3,0x3a,0x41,0x49,0xb1,0x2a,0x52,
+ 0x30,0x45,0x02,0x21,0x00,0xc5,0x77,0x10,0x16,0xd0,0xdd,0x63,0x57,0x14,0x3c,0x89,0xf6,0x84,0xcd,0x74,0x04,0x23,0x50,0x25,0x54,0xc0,0xc5,0x9a,0xa8,0xc9,0x95,0x84,0xf1,0xff,0x38,0xf6,0x09,0x02,0x20,0x54,0xb4,0x05,0xf4,0x47,0x75,0x46,0x68,0x6e,0x46,0x4c,0x54,0x63,0xb4,0xfd,0x41,0x90,0x57,0x2e,0x58,0xd0,0xf7,0xe7,0x35,0x7f,0x6e,0x61,0x94,0x7d,0x20,0x71,0x5c,
+ 0x30,0x45,0x02,0x21,0x00,0xa2,0x4e,0xbc,0x0e,0xc2,0x24,0xbd,0x67,0xae,0x39,0x7c,0xbe,0x6f,0xa3,0x7b,0x31,0x25,0xad,0xbd,0x34,0x89,0x1a,0xbe,0x2d,0x7c,0x73,0x56,0x92,0x19,0x16,0xdf,0xe6,0x02,0x20,0x34,0xf6,0xeb,0x63,0x74,0x73,0x1b,0xbb,0xaf,0xc4,0x92,0x4f,0xb8,0xb0,0xbd,0xcd,0xda,0x49,0x45,0x6d,0x72,0x4c,0xda,0xe6,0x17,0x8d,0x87,0x01,0x4c,0xb5,0x3d,0x8c,
+ 0x30,0x44,0x02,0x20,0x25,0x57,0xd6,0x4a,0x7a,0xee,0x2e,0x09,0x31,0xc0,0x12,0xe4,0xfe,0xa1,0xcd,0x3a,0x2c,0x33,0x4e,0xda,0xe6,0x8c,0xde,0xb7,0x15,0x8c,0xaf,0x21,0xb6,0x8e,0x5a,0x24,0x02,0x20,0x7f,0x06,0xcd,0xbb,0x6a,0x90,0x02,0x3a,0x97,0x38,0x82,0xed,0x97,0xb0,0x80,0xfe,0x6b,0x05,0xaf,0x3e,0xc9,0x3d,0xb6,0xf1,0xa4,0x39,0x9a,0x69,0xed,0xf7,0x67,0x0d,
+ 0x30,0x45,0x02,0x21,0x00,0xc4,0xf2,0xec,0xcb,0xb6,0xa2,0x43,0x50,0xc8,0x46,0x64,0x50,0xb9,0xd6,0x1b,0x20,0x7e,0xe3,0x59,0xe0,0x37,0xb3,0xdc,0xed,0xb4,0x2a,0x3f,0x2e,0x6d,0xd6,0xae,0xb5,0x02,0x20,0x32,0x63,0xc6,0xb5,0x9a,0x2f,0x55,0xcd,0xd1,0xc6,0xe1,0x48,0x94,0xd5,0xe5,0x96,0x3b,0x28,0xbc,0x3e,0x24,0x69,0xac,0x9b,0xa1,0x19,0x79,0x91,0xca,0x7f,0xf9,0xc7,
+ 0x30,0x45,0x02,0x21,0x00,0xef,0xf0,0x47,0x81,0xc9,0xcb,0xcd,0x16,0x2d,0x0a,0x25,0xa6,0xe2,0xeb,0xcc,0xa4,0x35,0x06,0xc5,0x23,0x38,0x5c,0xb5,0x15,0xd4,0x9e,0xa3,0x8a,0x1b,0x12,0xfc,0xad,0x02,0x20,0x15,0xac,0xd7,0x31,0x94,0xc9,0x1a,0x95,0x47,0x85,0x34,0xf2,0x30,0x15,0xb6,0x72,0xeb,0xed,0x21,0x3e,0x45,0x42,0x4d,0xd2,0xc8,0xe2,0x6a,0xc8,0xb3,0xeb,0x34,0xa5,
+ 0x30,0x45,0x02,0x21,0x00,0xf5,0x8b,0x4e,0x31,0x10,0xa6,0x4b,0xf1,0xb5,0xdb,0x97,0x63,0x9e,0xe0,0xe5,0xa9,0xc8,0xdf,0xa4,0x9d,0xc5,0x9b,0x67,0x98,0x91,0xf5,0x20,0xfd,0xf0,0x58,0x4c,0x87,0x02,0x20,0x2c,0xd8,0xfe,0x51,0x88,0x8a,0xee,0x9d,0xb3,0xe0,0x75,0x44,0x0f,0xd4,0xdb,0x73,0xb5,0xc7,0x32,0xfb,0x87,0xb5,0x10,0xe9,0x70,0x93,0xd6,0x64,0x15,0xf6,0x2a,0xf7,
+ 0x30,0x45,0x02,0x21,0x00,0xf8,0xab,0xec,0xaa,0x4f,0x0c,0x50,0x2d,0xe4,0xbf,0x59,0x03,0xd4,0x84,0x17,0xf7,0x86,0xbf,0x92,0xe8,0xad,0x72,0xfe,0xc0,0xbd,0x7f,0xcb,0x78,0x00,0xc0,0xbb,0xe3,0x02,0x20,0x4c,0x7f,0x9e,0x23,0x10,0x76,0xa3,0x0b,0x7a,0xe3,0x6b,0x0c,0xeb,0xe6,0x9c,0xce,0xf1,0xcd,0x19,0x4f,0x7c,0xce,0x93,0xa5,0x58,0x8f,0xd6,0x81,0x4f,0x43,0x7c,0x0e,
+ 0x30,0x44,0x02,0x20,0x5d,0x5b,0x38,0xbd,0x37,0xad,0x49,0x8b,0x22,0x27,0xa6,0x33,0x26,0x8a,0x8c,0xca,0x87,0x9a,0x5c,0x7c,0x94,0xa4,0xe4,0x16,0xbd,0x0a,0x61,0x4d,0x09,0xe6,0x06,0xd2,0x02,0x20,0x12,0xb8,0xd6,0x64,0xea,0x99,0x91,0x06,0x2e,0xcb,0xb8,0x34,0xe5,0x84,0x00,0xe2,0x5c,0x46,0x00,0x7a,0xf8,0x4f,0x60,0x07,0xd7,0xf1,0x68,0x54,0x43,0x26,0x9a,0xfe,
+ 0x30,0x44,0x02,0x20,0x0c,0x1c,0xd9,0xfe,0x40,0x34,0xf0,0x86,0xa2,0xb5,0x2d,0x65,0xb9,0xd3,0x83,0x4d,0x72,0xae,0xbe,0x7f,0x33,0xdf,0xe8,0xf9,0x76,0xda,0x82,0x64,0x81,0x77,0xd8,0xe3,0x02,0x20,0x13,0x10,0x57,0x82,0xe3,0xd0,0xcf,0xe8,0x5c,0x27,0x78,0xde,0xc1,0xa8,0x48,0xb2,0x7a,0xc0,0xae,0x07,0x1a,0xa6,0xda,0x34,0x1a,0x95,0x53,0xa9,0x46,0xb4,0x1e,0x59,
+ 0x30,0x45,0x02,0x21,0x00,0xae,0x79,0x35,0xfb,0x96,0xff,0x24,0x6b,0x7b,0x5d,0x56,0x62,0x87,0x0d,0x1b,0xa5,0x87,0xb0,0x3d,0x6e,0x13,0x60,0xba,0xf4,0x79,0x88,0xb5,0xc0,0x2c,0xcc,0x1a,0x5b,0x02,0x20,0x5f,0x00,0xc3,0x23,0x27,0x20,0x83,0x78,0x2d,0x4a,0x59,0xf2,0xdf,0xd6,0x5e,0x49,0xde,0x06,0x93,0x62,0x70,0x16,0x90,0x0e,0xf7,0xe6,0x14,0x28,0x05,0x66,0x64,0xb3,
+ 0x30,0x44,0x02,0x20,0x00,0xa1,0x34,0xb5,0xc6,0xcc,0xbc,0xef,0xd4,0xc8,0x82,0xb9,0x45,0xba,0xeb,0x49,0x33,0x44,0x41,0x72,0x79,0x5f,0xa6,0x79,0x6a,0xae,0x14,0x90,0x67,0x54,0x70,0x98,0x02,0x20,0x56,0x6e,0x46,0x10,0x5d,0x24,0xd8,0x90,0x15,0x1e,0x3e,0xea,0x3e,0xbf,0x88,0xf5,0xb9,0x2b,0x3f,0x5e,0xc9,0x3a,0x21,0x77,0x65,0xa6,0xdc,0xbd,0x94,0xf2,0xc5,0x5b,
+ 0x30,0x44,0x02,0x20,0x2e,0x47,0x21,0x36,0x3a,0xd3,0x99,0x2c,0x13,0x9e,0x5a,0x1c,0x26,0x39,0x5d,0x2c,0x2d,0x77,0x78,0x24,0xaa,0x24,0xfd,0xe0,0x75,0xe0,0xd7,0x38,0x11,0x71,0x30,0x9d,0x02,0x20,0x74,0x0f,0x7c,0x49,0x44,0x18,0xe1,0x30,0x0d,0xd4,0x51,0x2f,0x78,0x2a,0x58,0x80,0x0b,0xff,0x6a,0x7a,0xbd,0xfd,0xd2,0x0f,0xbb,0xd4,0xf0,0x55,0x15,0xca,0x1a,0x4f,
+ 0x30,0x44,0x02,0x20,0x68,0x52,0xe9,0xd3,0xcd,0x9f,0xe3,0x73,0xc2,0xd5,0x04,0x87,0x79,0x67,0xd3,0x65,0xab,0x14,0x56,0x70,0x7b,0x68,0x17,0xa0,0x42,0x86,0x46,0x94,0xe1,0x96,0x0c,0xcf,0x02,0x20,0x06,0x4b,0x27,0xea,0x14,0x2b,0x30,0x88,0x7b,0x84,0xc8,0x6a,0xdc,0xcb,0x2f,0xa3,0x9a,0x69,0x11,0xad,0x21,0xfc,0x7e,0x81,0x9f,0x59,0x3b,0xe5,0x2b,0xc4,0xf3,0xbd,
+ 0x30,0x44,0x02,0x20,0x18,0x8a,0x8c,0x56,0x48,0xdc,0x79,0xea,0xce,0x15,0x8c,0xf8,0x86,0xc6,0x2b,0x54,0x68,0xf0,0x5f,0xd9,0x5f,0x03,0xa7,0x63,0x5c,0x5b,0x4c,0x31,0xf0,0x9a,0xf4,0xc5,0x02,0x20,0x36,0x36,0x1a,0x0b,0x57,0x1a,0x00,0xc6,0xcd,0x5e,0x68,0x6c,0xcb,0xfc,0xfa,0x70,0x3c,0x4f,0x97,0xe4,0x89,0x38,0x34,0x6d,0x0c,0x10,0x3f,0xdc,0x76,0xdc,0x58,0x67,
+ 0x30,0x45,0x02,0x21,0x00,0xa7,0x4f,0x1f,0xb9,0xa8,0x26,0x3f,0x62,0xfc,0x44,0x16,0xa5,0xb7,0xd5,0x84,0xf4,0x20,0x6f,0x39,0x96,0xbb,0x91,0xf6,0xfc,0x8e,0x73,0xb9,0xe9,0x2b,0xad,0x0e,0x13,0x02,0x20,0x68,0x15,0x03,0x2e,0x8c,0x7d,0x76,0xc3,0xab,0x06,0xa8,0x6f,0x33,0x24,0x9c,0xe9,0x94,0x01,0x48,0xcb,0x36,0xd1,0xf4,0x17,0xc2,0xe9,0x92,0xe8,0x01,0xaf,0xa3,0xfa,
+ 0x30,0x44,0x02,0x20,0x07,0x24,0x48,0x65,0xb7,0x2f,0xf3,0x7e,0x62,0xe3,0x14,0x6f,0x0d,0xc1,0x46,0x82,0xba,0xdd,0x71,0x97,0x79,0x91,0x35,0xf0,0xb0,0x0a,0xde,0x76,0x71,0x74,0x2b,0xfe,0x02,0x20,0x0d,0x80,0xc2,0x23,0x8e,0xdb,0x4e,0x4a,0x7a,0x86,0xa8,0xc5,0x7c,0xa9,0xaf,0x17,0x11,0xf4,0x06,0xf7,0xf5,0xda,0x02,0x99,0xaa,0x04,0xe2,0x93,0x2d,0x96,0x07,0x54,
+ 0x30,0x45,0x02,0x21,0x00,0xda,0x7f,0xdd,0x05,0xb5,0xba,0xda,0xbd,0x61,0x9d,0x80,0x5c,0x4e,0xe7,0xd9,0xa8,0x4f,0x84,0xdd,0xd5,0xcf,0x9c,0x5b,0xf4,0xd4,0x33,0x81,0x40,0xd6,0x89,0xef,0x08,0x02,0x20,0x28,0xf1,0xcf,0x4f,0xa1,0xc3,0xc5,0x86,0x2c,0xfa,0x14,0x9c,0x00,0x13,0xcf,0x5f,0xe6,0xcf,0x50,0x76,0xca,0xe0,0x00,0x51,0x10,0x63,0xe7,0xde,0x25,0xbb,0x38,0xe5,
+ 0x30,0x45,0x02,0x21,0x00,0xd3,0x02,0x7c,0x65,0x6f,0x6d,0x4f,0xdf,0xd8,0xed,0xe2,0x20,0x93,0xe3,0xc3,0x03,0xb0,0x13,0x3c,0x34,0x0d,0x61,0x5e,0x77,0x56,0xf6,0x25,0x3a,0xea,0x92,0x72,0x38,0x02,0x20,0x09,0xae,0xf0,0x60,0xc8,0xe4,0xce,0xf9,0x72,0x97,0x40,0x11,0x55,0x8d,0xf1,0x44,0xfe,0xd2,0x5c,0xa6,0x9a,0xe8,0xd0,0xb2,0xea,0xf1,0xa8,0xfe,0xef,0xbe,0xc4,0x17,
+ 0x30,0x44,0x02,0x20,0x0b,0xf6,0xc0,0x18,0x8d,0xc9,0x57,0x1c,0xd0,0xe2,0x1e,0xec,0xac,0x5f,0xbb,0x19,0xd2,0x43,0x49,0x88,0xe9,0xcc,0x10,0x24,0x45,0x93,0xef,0x3a,0x98,0x09,0x9f,0x69,0x02,0x20,0x48,0x64,0xa5,0x62,0x66,0x1f,0x92,0x21,0xec,0x88,0xe3,0xdd,0x0b,0xc2,0xf6,0xe2,0x7a,0xc1,0x28,0xc3,0x0c,0xc1,0xa8,0x0f,0x79,0xec,0x67,0x0a,0x22,0xb0,0x42,0xee,
+ 0x30,0x45,0x02,0x21,0x00,0xae,0x45,0x96,0x40,0xd5,0xd1,0x17,0x9b,0xe4,0x7a,0x47,0xfa,0x53,0x8e,0x16,0xd9,0x4d,0xde,0xa5,0x58,0x5e,0x7a,0x24,0x48,0x04,0xa5,0x17,0x42,0xc6,0x86,0x44,0x3a,0x02,0x20,0x6c,0x8e,0x30,0xe5,0x30,0xa6,0x34,0xfa,0xe8,0x0b,0x3c,0xeb,0x06,0x29,0x78,0xb3,0x9e,0xdb,0xe1,0x97,0x77,0xe0,0xa2,0x45,0x53,0xb6,0x88,0x86,0x18,0x1f,0xd8,0x97,
+ 0x30,0x44,0x02,0x20,0x1c,0xf3,0x51,0x7b,0xa3,0xbf,0x2a,0xb8,0xb9,0xea,0xd4,0xeb,0xb6,0xe8,0x66,0xcb,0x88,0xa1,0xde,0xac,0xb6,0xa7,0x85,0xd3,0xb6,0x3b,0x48,0x3c,0xa0,0x2a,0xc4,0x95,0x02,0x20,0x24,0x9a,0x79,0x8b,0x73,0x60,0x6f,0x55,0xf5,0xf1,0xc7,0x0d,0xe6,0x7c,0xb1,0xa0,0xcf,0xf9,0x5d,0x7d,0xc5,0x0b,0x3a,0x61,0x7d,0xf8,0x61,0xba,0xd3,0xc6,0xb1,0xc9,
+ 0x30,0x45,0x02,0x21,0x00,0xe6,0x9b,0x52,0x38,0x26,0x5e,0xa3,0x5d,0x77,0xe4,0xdd,0x17,0x22,0x88,0xd8,0xce,0xa1,0x98,0x10,0xa1,0x02,0x92,0x61,0x7d,0x59,0x76,0x51,0x9d,0xc5,0x75,0x7c,0xb8,0x02,0x20,0x4b,0x03,0xc5,0xbc,0x47,0xe8,0x26,0xbd,0xb2,0x73,0x28,0xab,0xd3,0x8d,0x30,0x56,0xd7,0x74,0x76,0xb2,0x13,0x0f,0x3d,0xf6,0xec,0x48,0x91,0xaf,0x08,0xba,0x1e,0x29,
+ 0x30,0x44,0x02,0x20,0x5f,0x9d,0x7d,0x7c,0x87,0x0d,0x08,0x5f,0xc1,0xd4,0x9f,0xff,0x69,0xe4,0xa2,0x75,0x81,0x28,0x00,0xd2,0xcf,0x89,0x73,0xe7,0x32,0x58,0x66,0xcb,0x40,0xfa,0x2b,0x6f,0x02,0x20,0x6d,0x1f,0x54,0x91,0xd9,0xf7,0x17,0xa5,0x97,0xa1,0x5f,0xd5,0x40,0x40,0x64,0x86,0xd7,0x6a,0x44,0x69,0x7b,0x3f,0x0d,0x9d,0x6d,0xce,0xf6,0x66,0x9f,0x8a,0x0a,0x56,
+ 0x30,0x44,0x02,0x20,0x0a,0x7d,0x5b,0x19,0x59,0xf7,0x1d,0xf9,0xf8,0x17,0x14,0x6e,0xe4,0x9b,0xd5,0xc8,0x9b,0x43,0x1e,0x79,0x93,0xe2,0xfd,0xec,0xab,0x68,0x58,0x95,0x7d,0xa6,0x85,0xae,0x02,0x20,0x0f,0x8a,0xad,0x2d,0x25,0x46,0x90,0xbd,0xc1,0x3f,0x34,0xa4,0xfe,0xc4,0x4a,0x02,0xfd,0x74,0x5a,0x42,0x2d,0xf0,0x5c,0xcb,0xb5,0x46,0x35,0xa8,0xb8,0x6b,0x96,0x09,
+ 0x30,0x44,0x02,0x20,0x79,0xe8,0x8b,0xf5,0x76,0xb7,0x4b,0xc0,0x7c,0xa1,0x42,0x39,0x5f,0xda,0x28,0xf0,0x3d,0x3d,0x5e,0x64,0x0b,0x0b,0x4f,0xf0,0x75,0x2c,0x6d,0x94,0xcd,0x55,0x34,0x08,0x02,0x20,0x32,0xce,0xa0,0x5b,0xd2,0xd7,0x06,0xc8,0xf6,0x03,0x6a,0x50,0x7e,0x2a,0xb7,0x76,0x60,0x04,0xf0,0x90,0x4e,0x2e,0x5c,0x58,0x62,0x74,0x9c,0x00,0x73,0x24,0x5d,0x6a,
+ 0x30,0x45,0x02,0x21,0x00,0x9d,0x54,0xe0,0x37,0xa0,0x02,0x12,0xb3,0x77,0xbc,0x88,0x74,0x79,0x8b,0x8d,0xa0,0x80,0x56,0x4b,0xbd,0xf7,0xe0,0x75,0x91,0xb8,0x61,0x28,0x58,0x09,0xd0,0x14,0x88,0x02,0x20,0x18,0xb4,0xe5,0x57,0x66,0x7a,0x82,0xbd,0x95,0x96,0x5f,0x07,0x06,0xf8,0x1a,0x29,0x24,0x3f,0xbd,0xd8,0x69,0x68,0xa7,0xeb,0xeb,0x43,0x06,0x9d,0xb3,0xb1,0x8c,0x7f,
+ 0x30,0x44,0x02,0x20,0x26,0x64,0xf1,0xff,0xa9,0x82,0xfe,0xdb,0xcc,0x7c,0xab,0x1b,0x8b,0xc6,0xe2,0xcb,0x42,0x02,0x18,0xd2,0xa6,0x07,0x7a,0xd0,0x8e,0x59,0x1b,0xa9,0xfe,0xab,0x33,0xbd,0x02,0x20,0x49,0xf5,0xc7,0xcb,0x51,0x5e,0x83,0x87,0x2a,0x3d,0x41,0xb4,0xcd,0xb8,0x5f,0x24,0x2a,0xd9,0xd6,0x1a,0x5b,0xfc,0x01,0xde,0xbf,0xbb,0x52,0xc6,0xc8,0x4b,0xa7,0x28,
+ 0x30,0x44,0x02,0x20,0x58,0x27,0x51,0x83,0x44,0x84,0x4f,0xd6,0xa7,0xde,0x73,0xcb,0xb0,0xa6,0xbe,0xfd,0xea,0x7b,0x13,0xd2,0xde,0xe4,0x47,0x53,0x17,0xf0,0xf1,0x8f,0xfc,0x81,0x52,0x4b,0x02,0x20,0x4f,0x5c,0xcb,0x4e,0x0b,0x48,0x8b,0x5a,0x5d,0x76,0x0a,0xac,0xdd,0xb2,0xd7,0x91,0x97,0x0f,0xe4,0x3d,0xa6,0x1e,0xb3,0x0e,0x2e,0x90,0x20,0x8a,0x81,0x7e,0x46,0xdb,
+ 0x30,0x45,0x02,0x21,0x00,0x97,0xab,0x19,0xbd,0x13,0x9c,0xac,0x31,0x93,0x25,0x86,0x92,0x18,0xb1,0xbc,0xe1,0x11,0x87,0x5d,0x63,0xfb,0x12,0x09,0x8a,0x04,0xb0,0xcd,0x59,0xb6,0xfd,0xd3,0xa3,0x02,0x20,0x43,0x1d,0x9c,0xea,0x3a,0x24,0x38,0x47,0x30,0x3c,0xeb,0xda,0x56,0x47,0x64,0x31,0xd0,0x34,0x33,0x9f,0x31,0xd7,0x85,0xee,0x88,0x52,0xdb,0x4f,0x04,0x0d,0x49,0x21,
+ 0x30,0x44,0x02,0x20,0x52,0xc6,0x83,0x14,0x4e,0x44,0x11,0x9a,0xe2,0x01,0x37,0x49,0xd4,0x96,0x4e,0xf6,0x75,0x09,0x27,0x8f,0x6d,0x38,0xba,0x86,0x9a,0xdc,0xfa,0x69,0x97,0x0e,0x12,0x3d,0x02,0x20,0x34,0x79,0x91,0x01,0x67,0x40,0x8f,0x45,0xbd,0xa4,0x20,0xa6,0x26,0xec,0x9c,0x4e,0xc7,0x11,0xc1,0x27,0x4b,0xe0,0x92,0x19,0x8b,0x41,0x87,0xc0,0x18,0xb5,0x62,0xca,
+ 0x30,0x16,0x02,0x11,0x01,0x45,0x51,0x23,0x19,0x50,0xb7,0x5f,0xc4,0x40,0x2d,0xa1,0x72,0x2f,0xc9,0xba,0xeb,0x02,0x01,0x03,
+ 0x30,0x26,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfc,0x2c,0x02,0x01,0x03,
+ 0x30,0x26,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x3f,0x02,0x01,0x03,
+ 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x20,0x3e,0x9a,0x75,0x82,0x88,0x60,0x89,0xc6,0x2f,0xb8,0x40,0xcf,0x3b,0x83,0x06,0x1c,0xd1,0xcf,0xf3,0xae,0x43,0x41,0x80,0x8b,0xb5,0xbd,0xee,0x61,0x91,0x17,0x41,0x77,
+ 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x20,0x24,0x23,0x8e,0x70,0xb4,0x31,0xb1,0xa6,0x4e,0xfd,0xf9,0x03,0x26,0x69,0x93,0x9d,0x4b,0x77,0xf2,0x49,0x50,0x3f,0xc6,0x90,0x5f,0xeb,0x75,0x40,0xde,0xa3,0xe6,0xd2,
+ 0x30,0x06,0x02,0x01,0x01,0x02,0x01,0x01,
+ 0x30,0x06,0x02,0x01,0x01,0x02,0x01,0x02,
+ 0x30,0x06,0x02,0x01,0x01,0x02,0x01,0x03,
+ 0x30,0x06,0x02,0x01,0x02,0x02,0x01,0x01,
+ 0x30,0x06,0x02,0x01,0x02,0x02,0x01,0x02,
+ 0x30,0x06,0x02,0x01,0x02,0x02,0x01,0x03,
+ 0x30,0x26,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x41,0x43,0x02,0x01,0x03,
+ 0x30,0x08,0x02,0x01,0x02,0x02,0x03,0xed,0x29,0x79,
+ 0x30,0x26,0x02,0x02,0x01,0x01,0x02,0x20,0x3a,0x74,0xe9,0xd3,0xa7,0x4e,0x9d,0x3a,0x74,0xe9,0xd3,0xa7,0x4e,0x9d,0x3a,0x74,0x9f,0x8a,0xb3,0x73,0x2a,0x0a,0x89,0x60,0x4a,0x09,0xbc,0xe5,0xb2,0x91,0x6d,0xa4,
+ 0x30,0x2b,0x02,0x07,0x2d,0x9b,0x4d,0x34,0x79,0x52,0xcc,0x02,0x20,0x03,0x43,0xae,0xfc,0x2f,0x25,0xd9,0x8b,0x88,0x2e,0x86,0xeb,0x9e,0x30,0xd5,0x5a,0x6e,0xb5,0x08,0xb5,0x16,0x51,0x0b,0x34,0x02,0x4a,0xe4,0xb6,0x36,0x23,0x30,0xb3,
+ 0x30,0x31,0x02,0x0d,0x10,0x33,0xe6,0x7e,0x37,0xb3,0x2b,0x44,0x55,0x80,0xbf,0x4e,0xfc,0x02,0x20,0x6f,0x90,0x6f,0x90,0x6f,0x90,0x6f,0x90,0x6f,0x90,0x6f,0x90,0x6f,0x90,0x6f,0x8f,0xe1,0xca,0xb5,0xee,0xfd,0xb2,0x14,0x06,0x1d,0xce,0x3b,0x22,0x78,0x9f,0x1d,0x6f,
+ 0x30,0x26,0x02,0x02,0x01,0x01,0x02,0x20,0x78,0x32,0x66,0xe9,0x0f,0x43,0xda,0xfe,0x5c,0xd9,0xb3,0xb0,0xbe,0x86,0xde,0x22,0xf9,0xde,0x83,0x67,0x7d,0x0f,0x50,0x71,0x3a,0x46,0x8e,0xc7,0x2f,0xcf,0x5d,0x57,
+ 0x30,0x31,0x02,0x0d,0x06,0x25,0x22,0xbb,0xd3,0xec,0xbe,0x7c,0x39,0xe9,0x3e,0x7c,0x26,0x02,0x20,0x78,0x32,0x66,0xe9,0x0f,0x43,0xda,0xfe,0x5c,0xd9,0xb3,0xb0,0xbe,0x86,0xde,0x22,0xf9,0xde,0x83,0x67,0x7d,0x0f,0x50,0x71,0x3a,0x46,0x8e,0xc7,0x2f,0xcf,0x5d,0x57,
+ 0x30,0x45,0x02,0x21,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xba,0xae,0xdc,0xe6,0xaf,0x48,0xa0,0x3b,0xbf,0xd2,0x5e,0x8c,0xd0,0x36,0x40,0xc1,0x02,0x20,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0xe8,0xe4,0xf4,0x4c,0xe5,0x18,0x35,0x69,0x3f,0xf0,0xca,0x2e,0xf0,0x12,0x15,0xc0,
+ 0x30,0x16,0x02,0x09,0x00,0x9c,0x44,0xfe,0xbf,0x31,0xc3,0x59,0x4d,0x02,0x09,0x00,0x83,0x9e,0xd2,0x82,0x47,0xc2,0xb0,0x6b,
+ 0x30,0x1e,0x02,0x0d,0x09,0xdf,0x8b,0x68,0x24,0x30,0xbe,0xef,0x6f,0x5f,0xd7,0xc7,0xcf,0x02,0x0d,0x0f,0xd0,0xa6,0x2e,0x13,0x77,0x8f,0x42,0x22,0xa0,0xd6,0x1c,0x8a,
+ 0x30,0x26,0x02,0x11,0x00,0x8a,0x59,0x8e,0x56,0x3a,0x89,0xf5,0x26,0xc3,0x2e,0xbe,0xc8,0xde,0x26,0x36,0x7a,0x02,0x11,0x00,0x84,0xf6,0x33,0xe2,0x04,0x26,0x30,0xe9,0x9d,0xd0,0xf1,0xe1,0x6f,0x7a,0x04,0xbf,
+ 0x30,0x2e,0x02,0x15,0x00,0xaa,0x6e,0xeb,0x58,0x23,0xf7,0xfa,0x31,0xb4,0x66,0xbb,0x47,0x37,0x97,0xf0,0xd0,0x31,0x4c,0x0b,0xdf,0x02,0x15,0x00,0xe2,0x97,0x7c,0x47,0x9e,0x6d,0x25,0x70,0x3c,0xeb,0xbc,0x6b,0xd5,0x61,0x93,0x8c,0xc9,0xd1,0xbf,0xb9,
+ 0x30,0x25,0x02,0x20,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0xe8,0xe4,0xf4,0x4c,0xe5,0x18,0x35,0x69,0x3f,0xf0,0xca,0x2e,0xf0,0x12,0x15,0xc1,0x02,0x01,0x01,
+ 0x30,0x25,0x02,0x20,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0xe8,0xe4,0xf4,0x4c,0xe5,0x18,0x35,0x69,0x3f,0xf0,0xca,0x2e,0xf0,0x12,0x15,0xc1,0x02,0x01,0x00,
+ 0x30,0x44,0x02,0x20,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0xe8,0xe4,0xf4,0x4c,0xe5,0x18,0x35,0x69,0x3f,0xf0,0xca,0x2e,0xf0,0x12,0x15,0xc1,0x02,0x20,0x41,0x9d,0x98,0x1c,0x51,0x5a,0xf8,0xcc,0x82,0x54,0x5a,0xac,0x0c,0x85,0xe9,0xe3,0x08,0xfb,0xb2,0xea,0xb6,0xac,0xd7,0xed,0x49,0x7e,0x0b,0x41,0x45,0xa1,0x8f,0xd9,
+ 0x30,0x44,0x02,0x20,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0xe8,0xe4,0xf4,0x4c,0xe5,0x18,0x35,0x69,0x3f,0xf0,0xca,0x2e,0xf0,0x12,0x15,0xc1,0x02,0x20,0x1b,0x21,0x71,0x7a,0xd7,0x1d,0x23,0xbb,0xac,0x60,0xa9,0xad,0x0b,0xaf,0x75,0xb0,0x63,0xc9,0xfd,0xf5,0x2a,0x00,0xeb,0xf9,0x9d,0x02,0x21,0x72,0x91,0x09,0x93,0xc9,
+ 0x30,0x44,0x02,0x20,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0xe8,0xe4,0xf4,0x4c,0xe5,0x18,0x35,0x69,0x3f,0xf0,0xca,0x2e,0xf0,0x12,0x15,0xc1,0x02,0x20,0x2f,0x58,0x8f,0x66,0x01,0x8f,0x3d,0xd1,0x4d,0xb3,0xe2,0x8e,0x77,0x99,0x64,0x87,0xe3,0x24,0x86,0xb5,0x21,0xed,0x8e,0x5a,0x20,0xf0,0x65,0x91,0x95,0x17,0x77,0xe9,
+ 0x30,0x44,0x02,0x20,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0xe8,0xe4,0xf4,0x4c,0xe5,0x18,0x35,0x69,0x3f,0xf0,0xca,0x2e,0xf0,0x12,0x15,0xc1,0x02,0x20,0x09,0x1a,0x08,0x87,0x0f,0xf4,0xda,0xf9,0x12,0x3b,0x30,0xc2,0x0e,0x8c,0x4f,0xc8,0x50,0x57,0x58,0xdc,0xf4,0x07,0x4f,0xca,0xff,0x21,0x70,0xc9,0xbf,0xcf,0x74,0xf4,
+ 0x30,0x44,0x02,0x20,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0xe8,0xe4,0xf4,0x4c,0xe5,0x18,0x35,0x69,0x3f,0xf0,0xca,0x2e,0xf0,0x12,0x15,0xc1,0x02,0x20,0x7c,0x37,0x0d,0xc0,0xce,0x8c,0x59,0xa8,0xb2,0x73,0xcb,0xa4,0x4a,0x7c,0x11,0x91,0xfc,0x31,0x86,0xdc,0x03,0xca,0xb9,0x6b,0x05,0x67,0x31,0x2d,0xf0,0xd0,0xb2,0x50,
+ 0x30,0x44,0x02,0x20,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0xe8,0xe4,0xf4,0x4c,0xe5,0x18,0x35,0x69,0x3f,0xf0,0xca,0x2e,0xf0,0x12,0x15,0xc1,0x02,0x20,0x70,0xb5,0x9a,0x7d,0x1e,0xe7,0x7a,0x2f,0x9e,0x04,0x91,0xc2,0xa7,0xcf,0xcd,0x0e,0xd0,0x4d,0xf4,0xa3,0x51,0x92,0xf6,0x13,0x2d,0xcc,0x66,0x8c,0x79,0xa6,0x16,0x0e,
+ 0x30,0x44,0x02,0x20,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0xe8,0xe4,0xf4,0x4c,0xe5,0x18,0x35,0x69,0x3f,0xf0,0xca,0x2e,0xf0,0x12,0x15,0xc1,0x02,0x20,0x27,0x36,0xd7,0x6e,0x41,0x22,0x46,0xe0,0x97,0x14,0x8e,0x2b,0xf6,0x29,0x15,0x61,0x4e,0xb7,0xc4,0x28,0x91,0x3a,0x58,0xeb,0x5e,0x9c,0xd4,0x67,0x4a,0x94,0x23,0xde,
+ 0x30,0x44,0x02,0x20,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0xe8,0xe4,0xf4,0x4c,0xe5,0x18,0x35,0x69,0x3f,0xf0,0xca,0x2e,0xf0,0x12,0x15,0xc1,0x02,0x20,0x4a,0x1e,0x12,0x83,0x1f,0xbe,0x93,0x62,0x7b,0x02,0xd6,0xe7,0xf2,0x4b,0xcc,0xdd,0x6e,0xf4,0xb2,0xd0,0xf4,0x67,0x39,0xea,0xf3,0xb1,0xea,0xf0,0xca,0x11,0x77,0x70,
+ 0x30,0x44,0x02,0x20,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0xe8,0xe4,0xf4,0x4c,0xe5,0x18,0x35,0x69,0x3f,0xf0,0xca,0x2e,0xf0,0x12,0x15,0xc1,0x02,0x20,0x06,0xc7,0x78,0xd4,0xdf,0xff,0x7d,0xee,0x06,0xed,0x88,0xbc,0x4e,0x0e,0xd3,0x4f,0xc5,0x53,0xaa,0xd6,0x7c,0xaf,0x79,0x6f,0x2a,0x1c,0x64,0x87,0xc1,0xb2,0xe8,0x77,
+ 0x30,0x44,0x02,0x20,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0xe8,0xe4,0xf4,0x4c,0xe5,0x18,0x35,0x69,0x3f,0xf0,0xca,0x2e,0xf0,0x12,0x15,0xc1,0x02,0x20,0x4d,0xe4,0x59,0xef,0x91,0x59,0xaf,0xa0,0x57,0xfe,0xb3,0xec,0x40,0xfe,0xf0,0x1c,0x45,0xb8,0x09,0xf4,0xab,0x29,0x6e,0xa4,0x8c,0x20,0x6d,0x42,0x49,0xa2,0xb4,0x51,
+ 0x30,0x44,0x02,0x20,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0xe8,0xe4,0xf4,0x4c,0xe5,0x18,0x35,0x69,0x3f,0xf0,0xca,0x2e,0xf0,0x12,0x15,0xc1,0x02,0x20,0x74,0x5d,0x29,0x49,0x78,0x00,0x73,0x02,0x03,0x35,0x02,0xe1,0xac,0xc4,0x8b,0x63,0xae,0x65,0x00,0xbe,0x43,0xad,0xbe,0xa1,0xb2,0x58,0xd6,0xb4,0x23,0xdb,0xb4,0x16,
+ 0x30,0x44,0x02,0x20,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0xe8,0xe4,0xf4,0x4c,0xe5,0x18,0x35,0x69,0x3f,0xf0,0xca,0x2e,0xf0,0x12,0x15,0xc1,0x02,0x20,0x7b,0x2a,0x78,0x5e,0x38,0x96,0xf5,0x9b,0x2d,0x69,0xda,0x57,0x64,0x8e,0x80,0xad,0x3c,0x13,0x3a,0x75,0x0a,0x28,0x47,0xfd,0x20,0x98,0xcc,0xd9,0x02,0x04,0x2b,0x6c,
+ 0x30,0x44,0x02,0x20,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0xe8,0xe4,0xf4,0x4c,0xe5,0x18,0x35,0x69,0x3f,0xf0,0xca,0x2e,0xf0,0x12,0x15,0xc1,0x02,0x20,0x71,0xae,0x94,0xa7,0x2c,0xa8,0x96,0x87,0x5e,0x7a,0xa4,0xa4,0xc3,0xd2,0x9a,0xfd,0xb4,0xb3,0x5b,0x69,0x96,0x27,0x3e,0x63,0xc4,0x7a,0xc5,0x19,0x25,0x6c,0x5e,0xb1,
+ 0x30,0x44,0x02,0x20,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0xe8,0xe4,0xf4,0x4c,0xe5,0x18,0x35,0x69,0x3f,0xf0,0xca,0x2e,0xf0,0x12,0x15,0xc1,0x02,0x20,0x0f,0xa5,0x27,0xfa,0x73,0x43,0xc0,0xbc,0x9e,0xc3,0x5a,0x62,0x78,0xbf,0xbf,0xf4,0xd8,0x33,0x01,0xb1,0x54,0xfc,0x4b,0xd1,0x4a,0xee,0x7e,0xb9,0x34,0x45,0xb5,0xf9,
+ 0x30,0x44,0x02,0x20,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0xe8,0xe4,0xf4,0x4c,0xe5,0x18,0x35,0x69,0x3f,0xf0,0xca,0x2e,0xf0,0x12,0x15,0xc1,0x02,0x20,0x65,0x39,0xc0,0xad,0xad,0xd0,0x52,0x5f,0xf4,0x26,0x22,0x16,0x4c,0xe9,0x31,0x43,0x48,0xbd,0x08,0x63,0xb4,0xc8,0x0e,0x93,0x6b,0x23,0xca,0x04,0x14,0x26,0x46,0x71,
+ 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x5d,0x57,0x6e,0x73,0x57,0xa4,0x50,0x1d,0xdf,0xe9,0x2f,0x46,0x68,0x1b,0x20,0xa0,0x02,0x20,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0xe8,0xe4,0xf4,0x4c,0xe5,0x18,0x35,0x69,0x3f,0xf0,0xca,0x2e,0xf0,0x12,0x15,0xc0,
+ 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x5d,0x57,0x6e,0x73,0x57,0xa4,0x50,0x1d,0xdf,0xe9,0x2f,0x46,0x68,0x1b,0x20,0xa0,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x5d,0x57,0x6e,0x73,0x57,0xa4,0x50,0x1d,0xdf,0xe9,0x2f,0x46,0x68,0x1b,0x20,0xa0,
+ 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x5d,0x57,0x6e,0x73,0x57,0xa4,0x50,0x1d,0xdf,0xe9,0x2f,0x46,0x68,0x1b,0x20,0xa0,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x5d,0x57,0x6e,0x73,0x57,0xa4,0x50,0x1d,0xdf,0xe9,0x2f,0x46,0x68,0x1b,0x20,0xa1,
+ 0x30,0x44,0x02,0x20,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0xe8,0xe4,0xf4,0x4c,0xe5,0x18,0x35,0x69,0x3f,0xf0,0xca,0x2e,0xf0,0x12,0x15,0xb8,0x02,0x20,0x44,0xa5,0xad,0x0b,0xd0,0x63,0x6d,0x9e,0x12,0xbc,0x9e,0x0a,0x6b,0xdd,0x5e,0x1b,0xba,0x77,0xf5,0x23,0x84,0x21,0x93,0xb3,0xb8,0x2e,0x44,0x8e,0x05,0xd5,0xf1,0x1e,
+ 0x30,0x44,0x02,0x20,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0xe8,0xe4,0xf4,0x4c,0xe5,0x18,0x35,0x69,0x3f,0xf0,0xca,0x2e,0xf0,0x12,0x15,0xb8,0x02,0x20,0x44,0xa5,0xad,0x0b,0xd0,0x63,0x6d,0x9e,0x12,0xbc,0x9e,0x0a,0x6b,0xdd,0x5e,0x1b,0xba,0x77,0xf5,0x23,0x84,0x21,0x93,0xb3,0xb8,0x2e,0x44,0x8e,0x05,0xd5,0xf1,0x1e,
+ 0x30,0x44,0x02,0x20,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0xe8,0xe4,0xf4,0x4c,0xe5,0x18,0x35,0x69,0x3f,0xf0,0xca,0x2e,0xf0,0x12,0x15,0xb8,0x02,0x20,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0xe8,0xe4,0xf4,0x4c,0xe5,0x18,0x35,0x69,0x3f,0xf0,0xca,0x2e,0xf0,0x12,0x15,0xb8,
+ 0x30,0x44,0x02,0x20,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0xe8,0xe4,0xf4,0x4c,0xe5,0x18,0x35,0x69,0x3f,0xf0,0xca,0x2e,0xf0,0x12,0x15,0xb8,0x02,0x20,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0xe8,0xe4,0xf4,0x4c,0xe5,0x18,0x35,0x69,0x3f,0xf0,0xca,0x2e,0xf0,0x12,0x15,0xb8,
+ 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x20,0x16,0xe1,0xe4,0x59,0x45,0x76,0x79,0xdf,0x5b,0x94,0x34,0xae,0x23,0xf4,0x74,0xb3,0xe8,0xd2,0xa7,0x0b,0xd6,0xb5,0xdb,0xe6,0x92,0xba,0x16,0xda,0x01,0xf1,0xfb,0x0a,
+ 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x20,0x1c,0x94,0x0f,0x31,0x3f,0x92,0x64,0x7b,0xe2,0x57,0xec,0xcd,0x7e,0xd0,0x8b,0x0b,0xae,0xf3,0xf0,0x47,0x8f,0x25,0x87,0x1b,0x53,0x63,0x53,0x02,0xc5,0xf6,0x31,0x4a,
+ 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x20,0x15,0xd9,0x4a,0x85,0x07,0x7b,0x49,0x3f,0x91,0xcb,0x71,0x01,0xec,0x63,0xe1,0xb0,0x1b,0xe5,0x8b,0x59,0x4e,0x85,0x5f,0x45,0x05,0x0a,0x8c,0x14,0x06,0x2d,0x68,0x9b,
+ 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x20,0x5b,0x1d,0x27,0xa7,0x69,0x4c,0x14,0x62,0x44,0xa5,0xad,0x0b,0xd0,0x63,0x6d,0x9d,0x9e,0xf3,0xb9,0xfb,0x58,0x38,0x54,0x18,0xd9,0xc9,0x82,0x10,0x50,0x77,0xd1,0xb7,
+ 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x20,0x2d,0x85,0x89,0x6b,0x3e,0xb9,0xdb,0xb5,0xa5,0x2f,0x42,0xf9,0xc9,0x26,0x1e,0xd3,0xfc,0x46,0x64,0x4e,0xc6,0x5f,0x06,0xad,0xe3,0xfd,0x78,0xf2,0x57,0xe4,0x34,0x32,
+ 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x20,0x5b,0x0b,0x12,0xd6,0x7d,0x73,0xb7,0x6b,0x4a,0x5e,0x85,0xf3,0x92,0x4c,0x3d,0xa7,0xf8,0x8c,0xc8,0x9d,0x8c,0xbe,0x0d,0x5b,0xc7,0xfa,0xf1,0xe4,0xaf,0xc8,0x68,0x64,
+ 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x20,0x69,0x4c,0x14,0x62,0x44,0xa5,0xad,0x0b,0xd0,0x63,0x6d,0x9e,0x12,0xbc,0x9e,0x09,0xe6,0x0e,0x68,0xb9,0x0d,0x0b,0x5e,0x6c,0x5d,0xdd,0xd0,0xcb,0x69,0x4d,0x87,0x99,
+ 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x20,0x3d,0x7f,0x48,0x7c,0x07,0xbf,0xc5,0xf3,0x08,0x46,0x93,0x8a,0x3d,0xce,0xf6,0x96,0x44,0x47,0x07,0xcf,0x96,0x77,0x25,0x4a,0x92,0xb0,0x6c,0x63,0xab,0x86,0x7d,0x22,
+ 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x20,0x6c,0x76,0x48,0xfc,0x0f,0xbf,0x8a,0x06,0xad,0xb8,0xb8,0x39,0xf9,0x7b,0x4f,0xf7,0xa8,0x00,0xf1,0x1b,0x1e,0x37,0xc5,0x93,0xb2,0x61,0x39,0x45,0x99,0x79,0x2b,0xa4,
+ 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x20,0x64,0x1c,0x9c,0x5d,0x79,0x0d,0xc0,0x9c,0xdd,0x3d,0xfa,0xbb,0x62,0xcd,0xf4,0x53,0xe6,0x97,0x47,0xa7,0xe3,0xd7,0xaa,0x1a,0x71,0x41,0x89,0xef,0x53,0x17,0x1a,0x99,
+ 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x20,0x29,0x79,0x8c,0x5c,0x45,0xbd,0xf5,0x8b,0x4a,0x7b,0x2f,0xdc,0x2c,0x46,0xab,0x4a,0xf1,0x21,0x8c,0x7e,0xeb,0x9f,0x0f,0x27,0xa8,0x8f,0x12,0x67,0x67,0x4d,0xe3,0xb0,
+ 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x20,0x0b,0x70,0xf2,0x2c,0xa2,0xbb,0x3c,0xef,0xad,0xca,0x1a,0x57,0x11,0xfa,0x3a,0x59,0xf4,0x69,0x53,0x85,0xeb,0x5a,0xed,0xf3,0x49,0x5d,0x0b,0x6d,0x00,0xf8,0xfd,0x85,
+ 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x20,0x16,0xe1,0xe4,0x59,0x45,0x76,0x79,0xdf,0x5b,0x94,0x34,0xae,0x23,0xf4,0x74,0xb3,0xe8,0xd2,0xa7,0x0b,0xd6,0xb5,0xdb,0xe6,0x92,0xba,0x16,0xda,0x01,0xf1,0xfb,0x0a,
+ 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x20,0x22,0x52,0xd6,0x85,0xe8,0x31,0xb6,0xcf,0x09,0x5e,0x4f,0x05,0x35,0xee,0xaf,0x0d,0xdd,0x3b,0xfa,0x91,0xc2,0x10,0xc9,0xd9,0xdc,0x17,0x22,0x47,0x02,0xea,0xf8,0x8f,
+ 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x20,0x75,0x13,0x5a,0xbd,0x7c,0x42,0x5b,0x60,0x37,0x1a,0x47,0x7f,0x09,0xce,0x0f,0x27,0x4f,0x64,0xa8,0xc6,0xb0,0x61,0xa0,0x7b,0x5d,0x63,0xe9,0x3c,0x65,0x04,0x6c,0x53,
+ 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x20,0x2a,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0x3e,0x3a,0x49,0xa2,0x3a,0x6d,0x8a,0xbe,0x95,0x46,0x1f,0x84,0x45,0x67,0x6b,0x17,
+ 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x20,0x3e,0x88,0x83,0x77,0xac,0x6c,0x71,0xac,0x9d,0xec,0x3f,0xdb,0x9b,0x56,0xc9,0xfe,0xaf,0x0c,0xfa,0xca,0x9f,0x82,0x7f,0xc5,0xeb,0x65,0xfc,0x3e,0xac,0x81,0x12,0x10,
+ 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x20,0x30,0xbb,0xb7,0x94,0xdb,0x58,0x83,0x63,0xb4,0x06,0x79,0xf6,0xc1,0x82,0xa5,0x0d,0x3c,0xe9,0x67,0x9a,0xcd,0xd3,0xff,0xbe,0x36,0xd7,0x81,0x3d,0xac,0xbd,0xc8,0x18,
+ 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x20,0x2c,0x37,0xfd,0x99,0x56,0x22,0xc4,0xfb,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc7,0xce,0xe7,0x45,0x11,0x0c,0xb4,0x5a,0xb5,0x58,0xed,0x7c,0x90,0xc1,0x5a,0x2f,
+ 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x20,0x7f,0xd9,0x95,0x62,0x2c,0x4f,0xb7,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x5d,0x88,0x3f,0xfa,0xb5,0xb3,0x26,0x52,0xcc,0xdc,0xaa,0x29,0x0f,0xcc,0xb9,0x7d,
+ 0x30,0x43,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x1f,0x4c,0xd5,0x3b,0xa7,0x60,0x8f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x9e,0x5c,0xf1,0x43,0xe2,0x53,0x96,0x26,0x19,0x0a,0x3a,0xb0,0x9c,0xce,0x47,
+ 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x20,0x56,0x22,0xc4,0xfb,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x92,0x8a,0x8f,0x1c,0x7a,0xc7,0xbe,0xc1,0x80,0x8b,0x9f,0x61,0xc0,0x1e,0xc3,0x27,
+ 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x20,0x44,0x10,0x41,0x04,0x10,0x41,0x04,0x10,0x41,0x04,0x10,0x41,0x04,0x10,0x41,0x03,0xb8,0x78,0x53,0xfd,0x3b,0x7d,0x3f,0x8e,0x17,0x51,0x25,0xb4,0x38,0x2f,0x25,0xed,
+ 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x20,0x27,0x39,0xce,0x73,0x9c,0xe7,0x39,0xce,0x73,0x9c,0xe7,0x39,0xce,0x73,0x9c,0xe7,0x05,0x56,0x02,0x98,0xd1,0xf2,0xf0,0x8d,0xc4,0x19,0xac,0x27,0x3a,0x5b,0x54,0xd9,
+ 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x20,0x48,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x31,0xc8,0x3a,0xe8,0x2e,0xbe,0x08,0x98,0x77,0x6b,0x4c,0x69,0xd1,0x1f,0x88,0xde,
+ 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x20,0x64,0x92,0x49,0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x06,0xdd,0x3a,0x19,0xb8,0xd5,0xfb,0x87,0x52,0x35,0x96,0x3c,0x59,0x3b,0xd2,0xd3,
+ 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x20,0x6a,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0x3e,0x3a,0x49,0xa2,0x3a,0x6d,0x8a,0xbe,0x95,0x46,0x1f,0x84,0x45,0x67,0x6b,0x15,
+ 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x20,0x2a,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0x3e,0x3a,0x49,0xa2,0x3a,0x6d,0x8a,0xbe,0x95,0x46,0x1f,0x84,0x45,0x67,0x6b,0x17,
+ 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x20,0x3f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,
+ 0x30,0x44,0x02,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x02,0x20,0x18,0x5d,0xdb,0xca,0x6d,0xac,0x41,0xb1,0xda,0x03,0x3c,0xfb,0x60,0xc1,0x52,0x86,0x9e,0x74,0xb3,0xcd,0x66,0xe9,0xff,0xdf,0x1b,0x6b,0xc0,0x9e,0xd6,0x5e,0xe4,0x0c,
+ 0x30,0x44,0x02,0x20,0x32,0xb0,0xd1,0x0d,0x8d,0x0e,0x04,0xbc,0x8d,0x4d,0x06,0x4d,0x27,0x06,0x99,0xe8,0x7c,0xff,0xc9,0xb4,0x9c,0x5c,0x20,0x73,0x0e,0x1c,0x26,0xf6,0x10,0x5d,0xdc,0xda,0x02,0x20,0x29,0xed,0x3d,0x67,0xb3,0xd5,0x05,0xbe,0x95,0x58,0x0d,0x77,0xd5,0xb7,0x92,0xb4,0x36,0x88,0x11,0x79,0xb2,0xb6,0xb2,0xe0,0x4c,0x5f,0xe5,0x92,0xd3,0x8d,0x82,0xd9,
+ 0x30,0x44,0x02,0x20,0x32,0xb0,0xd1,0x0d,0x8d,0x0e,0x04,0xbc,0x8d,0x4d,0x06,0x4d,0x27,0x06,0x99,0xe8,0x7c,0xff,0xc9,0xb4,0x9c,0x5c,0x20,0x73,0x0e,0x1c,0x26,0xf6,0x10,0x5d,0xdc,0xda,0x02,0x20,0x29,0xed,0x3d,0x67,0xb3,0xd5,0x05,0xbe,0x95,0x58,0x0d,0x77,0xd5,0xb7,0x92,0xb4,0x36,0x88,0x11,0x79,0xb2,0xb6,0xb2,0xe0,0x4c,0x5f,0xe5,0x92,0xd3,0x8d,0x82,0xd9,
+ 0x30,0x44,0x02,0x20,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0xe8,0xe4,0xf4,0x4c,0xe5,0x18,0x35,0x69,0x3f,0xf0,0xca,0x2e,0xf0,0x12,0x15,0xc0,0x02,0x20,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x32,0xf2,0x22,0xf8,0xfa,0xef,0xdb,0x53,0x3f,0x26,0x5d,0x46,0x1c,0x29,0xa4,0x73,0x73,
+ 0x30,0x45,0x02,0x21,0x00,0xc6,0x04,0x7f,0x94,0x41,0xed,0x7d,0x6d,0x30,0x45,0x40,0x6e,0x95,0xc0,0x7c,0xd8,0x5c,0x77,0x8e,0x4b,0x8c,0xef,0x3c,0xa7,0xab,0xac,0x09,0xb9,0x5c,0x70,0x9e,0xe5,0x02,0x20,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0xe8,0xe4,0xf4,0x4c,0xe5,0x18,0x35,0x69,0x3f,0xf0,0xca,0x2e,0xf0,0x12,0x15,0xc0,
+ 0x30,0x45,0x02,0x21,0x00,0xc6,0x04,0x7f,0x94,0x41,0xed,0x7d,0x6d,0x30,0x45,0x40,0x6e,0x95,0xc0,0x7c,0xd8,0x5c,0x77,0x8e,0x4b,0x8c,0xef,0x3c,0xa7,0xab,0xac,0x09,0xb9,0x5c,0x70,0x9e,0xe5,0x02,0x20,0x49,0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x92,0x48,0xc7,0x9f,0xac,0xd4,0x32,0x14,0xc0,0x11,0x12,0x3c,0x1b,0x03,0xa9,0x34,0x12,0xa5,
+ 0x30,0x45,0x02,0x21,0x00,0xc6,0x04,0x7f,0x94,0x41,0xed,0x7d,0x6d,0x30,0x45,0x40,0x6e,0x95,0xc0,0x7c,0xd8,0x5c,0x77,0x8e,0x4b,0x8c,0xef,0x3c,0xa7,0xab,0xac,0x09,0xb9,0x5c,0x70,0x9e,0xe5,0x02,0x20,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x65,0xe4,0x45,0xf1,0xf5,0xdf,0xb6,0xa6,0x7e,0x4c,0xba,0x8c,0x38,0x53,0x48,0xe6,0xe7,
+ 0x30,0x45,0x02,0x21,0x00,0xc6,0x04,0x7f,0x94,0x41,0xed,0x7d,0x6d,0x30,0x45,0x40,0x6e,0x95,0xc0,0x7c,0xd8,0x5c,0x77,0x8e,0x4b,0x8c,0xef,0x3c,0xa7,0xab,0xac,0x09,0xb9,0x5c,0x70,0x9e,0xe5,0x02,0x20,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x65,0xe4,0x45,0xf1,0xf5,0xdf,0xb6,0xa6,0x7e,0x4c,0xba,0x8c,0x38,0x53,0x48,0xe6,0xe7,
+ 0x30,0x45,0x02,0x21,0x00,0xc6,0x04,0x7f,0x94,0x41,0xed,0x7d,0x6d,0x30,0x45,0x40,0x6e,0x95,0xc0,0x7c,0xd8,0x5c,0x77,0x8e,0x4b,0x8c,0xef,0x3c,0xa7,0xab,0xac,0x09,0xb9,0x5c,0x70,0x9e,0xe5,0x02,0x20,0x49,0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x92,0x48,0xc7,0x9f,0xac,0xd4,0x32,0x14,0xc0,0x11,0x12,0x3c,0x1b,0x03,0xa9,0x34,0x12,0xa5,
+ 0x30,0x45,0x02,0x21,0x00,0xc6,0x04,0x7f,0x94,0x41,0xed,0x7d,0x6d,0x30,0x45,0x40,0x6e,0x95,0xc0,0x7c,0xd8,0x5c,0x77,0x8e,0x4b,0x8c,0xef,0x3c,0xa7,0xab,0xac,0x09,0xb9,0x5c,0x70,0x9e,0xe5,0x02,0x20,0x0e,0xb1,0x0e,0x5a,0xb9,0x5f,0x2f,0x27,0x53,0x48,0xd8,0x2a,0xd2,0xe4,0xd7,0x94,0x9c,0x81,0x93,0x80,0x0d,0x8c,0x9c,0x75,0xdf,0x58,0xe3,0x43,0xf0,0xeb,0xba,0x7b,
+ 0x30,0x44,0x02,0x20,0x79,0xbe,0x66,0x7e,0xf9,0xdc,0xbb,0xac,0x55,0xa0,0x62,0x95,0xce,0x87,0x0b,0x07,0x02,0x9b,0xfc,0xdb,0x2d,0xce,0x28,0xd9,0x59,0xf2,0x81,0x5b,0x16,0xf8,0x17,0x98,0x02,0x20,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0xe8,0xe4,0xf4,0x4c,0xe5,0x18,0x35,0x69,0x3f,0xf0,0xca,0x2e,0xf0,0x12,0x15,0xc0,
+ 0x30,0x44,0x02,0x20,0x79,0xbe,0x66,0x7e,0xf9,0xdc,0xbb,0xac,0x55,0xa0,0x62,0x95,0xce,0x87,0x0b,0x07,0x02,0x9b,0xfc,0xdb,0x2d,0xce,0x28,0xd9,0x59,0xf2,0x81,0x5b,0x16,0xf8,0x17,0x98,0x02,0x20,0x49,0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x92,0x48,0xc7,0x9f,0xac,0xd4,0x32,0x14,0xc0,0x11,0x12,0x3c,0x1b,0x03,0xa9,0x34,0x12,0xa5,
+ 0x30,0x44,0x02,0x20,0x79,0xbe,0x66,0x7e,0xf9,0xdc,0xbb,0xac,0x55,0xa0,0x62,0x95,0xce,0x87,0x0b,0x07,0x02,0x9b,0xfc,0xdb,0x2d,0xce,0x28,0xd9,0x59,0xf2,0x81,0x5b,0x16,0xf8,0x17,0x98,0x02,0x20,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x65,0xe4,0x45,0xf1,0xf5,0xdf,0xb6,0xa6,0x7e,0x4c,0xba,0x8c,0x38,0x53,0x48,0xe6,0xe7,
+ 0x30,0x44,0x02,0x20,0x79,0xbe,0x66,0x7e,0xf9,0xdc,0xbb,0xac,0x55,0xa0,0x62,0x95,0xce,0x87,0x0b,0x07,0x02,0x9b,0xfc,0xdb,0x2d,0xce,0x28,0xd9,0x59,0xf2,0x81,0x5b,0x16,0xf8,0x17,0x98,0x02,0x20,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x65,0xe4,0x45,0xf1,0xf5,0xdf,0xb6,0xa6,0x7e,0x4c,0xba,0x8c,0x38,0x53,0x48,0xe6,0xe7,
+ 0x30,0x44,0x02,0x20,0x79,0xbe,0x66,0x7e,0xf9,0xdc,0xbb,0xac,0x55,0xa0,0x62,0x95,0xce,0x87,0x0b,0x07,0x02,0x9b,0xfc,0xdb,0x2d,0xce,0x28,0xd9,0x59,0xf2,0x81,0x5b,0x16,0xf8,0x17,0x98,0x02,0x20,0x49,0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x92,0x48,0xc7,0x9f,0xac,0xd4,0x32,0x14,0xc0,0x11,0x12,0x3c,0x1b,0x03,0xa9,0x34,0x12,0xa5,
+ 0x30,0x44,0x02,0x20,0x79,0xbe,0x66,0x7e,0xf9,0xdc,0xbb,0xac,0x55,0xa0,0x62,0x95,0xce,0x87,0x0b,0x07,0x02,0x9b,0xfc,0xdb,0x2d,0xce,0x28,0xd9,0x59,0xf2,0x81,0x5b,0x16,0xf8,0x17,0x98,0x02,0x20,0x0e,0xb1,0x0e,0x5a,0xb9,0x5f,0x2f,0x27,0x53,0x48,0xd8,0x2a,0xd2,0xe4,0xd7,0x94,0x9c,0x81,0x93,0x80,0x0d,0x8c,0x9c,0x75,0xdf,0x58,0xe3,0x43,0xf0,0xeb,0xba,0x7b,
+ 0x30,0x45,0x02,0x21,0x00,0xbb,0x5a,0x52,0xf4,0x2f,0x9c,0x92,0x61,0xed,0x43,0x61,0xf5,0x94,0x22,0xa1,0xe3,0x00,0x36,0xe7,0xc3,0x2b,0x27,0x0c,0x88,0x07,0xa4,0x19,0xfe,0xca,0x60,0x50,0x23,0x02,0x20,0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x63,0xcf,0xd6,0x6a,0x19,0x0a,0x60,0x08,0x89,0x1e,0x0d,0x81,0xd4,0x9a,0x09,0x52,
+ 0x30,0x44,0x02,0x20,0x44,0xa5,0xad,0x0b,0xd0,0x63,0x6d,0x9e,0x12,0xbc,0x9e,0x0a,0x6b,0xdd,0x5e,0x1b,0xba,0x77,0xf5,0x23,0x84,0x21,0x93,0xb3,0xb8,0x2e,0x44,0x8e,0x05,0xd5,0xf1,0x1e,0x02,0x20,0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x63,0xcf,0xd6,0x6a,0x19,0x0a,0x60,0x08,0x89,0x1e,0x0d,0x81,0xd4,0x9a,0x09,0x52,
+ 0x30,0x45,0x02,0x21,0x00,0xbb,0x5a,0x52,0xf4,0x2f,0x9c,0x92,0x61,0xed,0x43,0x61,0xf5,0x94,0x22,0xa1,0xe3,0x00,0x36,0xe7,0xc3,0x2b,0x27,0x0c,0x88,0x07,0xa4,0x19,0xfe,0xca,0x60,0x50,0x23,0x02,0x20,0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x63,0xcf,0xd6,0x6a,0x19,0x0a,0x60,0x08,0x89,0x1e,0x0d,0x81,0xd4,0x9a,0x09,0x52,
+ 0x30,0x44,0x02,0x20,0x44,0xa5,0xad,0x0b,0xd0,0x63,0x6d,0x9e,0x12,0xbc,0x9e,0x0a,0x6b,0xdd,0x5e,0x1b,0xba,0x77,0xf5,0x23,0x84,0x21,0x93,0xb3,0xb8,0x2e,0x44,0x8e,0x05,0xd5,0xf1,0x1e,0x02,0x20,0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x63,0xcf,0xd6,0x6a,0x19,0x0a,0x60,0x08,0x89,0x1e,0x0d,0x81,0xd4,0x9a,0x09,0x52,
+ 0x30,0x45,0x02,0x21,0x00,0xf8,0x0a,0xe4,0xf9,0x6c,0xdb,0xc9,0xd8,0x53,0xf8,0x3d,0x47,0xaa,0xe2,0x25,0xbf,0x40,0x7d,0x51,0xc5,0x6b,0x77,0x76,0xcd,0x67,0xd0,0xdc,0x19,0x5d,0x99,0xa9,0xdc,0x02,0x20,0x4c,0xfc,0x1d,0x94,0x1e,0x08,0xcb,0x9a,0xce,0xad,0xde,0x0f,0x4c,0xce,0xad,0x76,0xb3,0x0d,0x33,0x2f,0xc4,0x42,0x11,0x5d,0x50,0xe6,0x73,0xe2,0x86,0x86,0xb7,0x0b,
+ 0x30,0x44,0x02,0x20,0x10,0x9c,0xd8,0xae,0x03,0x74,0x35,0x89,0x84,0xa8,0x24,0x9c,0x0a,0x84,0x36,0x28,0xf2,0x83,0x5f,0xfa,0xd1,0xdf,0x1a,0x9a,0x69,0xaa,0x2f,0xe7,0x23,0x55,0x54,0x5c,0x02,0x20,0x53,0x90,0xff,0x25,0x0a,0xc4,0x27,0x4e,0x1c,0xb2,0x5c,0xd6,0xca,0x64,0x91,0xf6,0xb9,0x12,0x81,0xe3,0x2f,0x5b,0x26,0x4d,0x87,0x97,0x7a,0xed,0x4a,0x94,0xe7,0x7b,
+ 0x30,0x45,0x02,0x21,0x00,0xd0,0x35,0xee,0x1f,0x17,0xfd,0xb0,0xb2,0x68,0x1b,0x16,0x3e,0x33,0xc3,0x59,0x93,0x26,0x59,0x99,0x0a,0xf7,0x7d,0xca,0x63,0x20,0x12,0xb3,0x0b,0x27,0xa0,0x57,0xb3,0x02,0x20,0x19,0x39,0xd9,0xf3,0xb2,0x85,0x8b,0xc1,0x3e,0x34,0x74,0xcb,0x50,0xe6,0xa8,0x2b,0xe4,0x4f,0xaa,0x71,0x94,0x0f,0x87,0x6c,0x1c,0xba,0x4c,0x3e,0x98,0x92,0x02,0xb6,
+ 0x30,0x44,0x02,0x20,0x4f,0x05,0x3f,0x56,0x3a,0xd3,0x4b,0x74,0xfd,0x8c,0x99,0x34,0xce,0x59,0xe7,0x9c,0x2e,0xb8,0xe6,0xec,0xa0,0xfe,0xf5,0xb3,0x23,0xca,0x67,0xd5,0xac,0x7e,0xd2,0x38,0x02,0x20,0x4d,0x4b,0x05,0xda,0xa0,0x71,0x9e,0x77,0x3d,0x86,0x17,0xdc,0xe5,0x63,0x1c,0x5f,0xd6,0xf5,0x9c,0x9b,0xdc,0x74,0x8e,0x4b,0x55,0xc9,0x70,0x04,0x0a,0xf0,0x1b,0xe5,
+ 0x30,0x44,0x02,0x20,0x6d,0x6a,0x4f,0x55,0x6c,0xcc,0xe1,0x54,0xe7,0xfb,0x9f,0x19,0xe7,0x6c,0x3d,0xec,0xa1,0x3d,0x59,0xcc,0x2a,0xeb,0x4e,0xca,0xd9,0x68,0xaa,0xb2,0xde,0xd4,0x59,0x65,0x02,0x20,0x53,0xb9,0xfa,0x74,0x80,0x3e,0xde,0x0f,0xc4,0x44,0x1b,0xf6,0x83,0xd5,0x6c,0x56,0x4d,0x3e,0x27,0x4e,0x09,0xcc,0xf4,0x73,0x90,0xba,0xdd,0x14,0x71,0xc0,0x5f,0xb7,
+ 0x30,0x44,0x02,0x21,0x00,0xaa,0xd5,0x03,0xde,0x9b,0x9f,0xd6,0x6b,0x94,0x8e,0x9a,0xcf,0x59,0x6f,0x0a,0x0e,0x65,0xe7,0x00,0xb2,0x8b,0x26,0xec,0x56,0xe6,0xe4,0x5e,0x84,0x64,0x89,0xb3,0xc4,0x02,0x1f,0x0d,0xdc,0x3a,0x2f,0x89,0xab,0xb8,0x17,0xbb,0x85,0xc0,0x62,0xce,0x02,0xf8,0x23,0xc6,0x3f,0xc2,0x6b,0x26,0x9e,0x0b,0xc9,0xb8,0x4d,0x81,0xa5,0xaa,0x12,0x3d,
+ 0x30,0x45,0x02,0x21,0x00,0x91,0x82,0xce,0xbd,0x3b,0xb8,0xab,0x57,0x2e,0x16,0x71,0x74,0x39,0x72,0x09,0xef,0x4b,0x1d,0x43,0x9a,0xf3,0xb2,0x00,0xcd,0xf0,0x03,0x62,0x00,0x89,0xe4,0x32,0x25,0x02,0x20,0x54,0x47,0x7c,0x98,0x2e,0xa0,0x19,0xd2,0xe1,0x00,0x04,0x97,0xfc,0x25,0xfc,0xee,0x1b,0xcc,0xae,0x55,0xf2,0xac,0x27,0x53,0x0a,0xe5,0x3b,0x29,0xc4,0xb3,0x56,0xa4,
+ 0x30,0x44,0x02,0x20,0x38,0x54,0xa3,0x99,0x8a,0xeb,0xdf,0x2d,0xbc,0x28,0xad,0xac,0x41,0x81,0x46,0x2c,0xca,0xc7,0x87,0x39,0x07,0xab,0x7f,0x21,0x2c,0x42,0xdb,0x0e,0x69,0xb5,0x6e,0xd8,0x02,0x20,0x3e,0xd3,0xf6,0xb8,0xa3,0x88,0xd0,0x2f,0x3e,0x4d,0xf9,0xf2,0xae,0x9c,0x1b,0xd2,0xc3,0x91,0x6a,0x68,0x64,0x60,0xdf,0xfc,0xd4,0x29,0x09,0xcd,0x7f,0x82,0x05,0x8e,
+ 0x30,0x45,0x02,0x21,0x00,0xe9,0x4d,0xbd,0xc3,0x87,0x95,0xfe,0x5c,0x90,0x4d,0x8f,0x16,0xd9,0x69,0xd3,0xb5,0x87,0xf0,0xa2,0x5d,0x2d,0xe9,0x0b,0x6d,0x8c,0x5c,0x53,0xff,0x88,0x7e,0x36,0x07,0x02,0x20,0x7a,0x94,0x73,0x69,0xc1,0x64,0x97,0x25,0x21,0xbb,0x8a,0xf4,0x06,0x81,0x3b,0x2d,0x9f,0x94,0xd2,0xae,0xaa,0x53,0xd4,0xc2,0x15,0xaa,0xa0,0xa2,0x57,0x8a,0x2c,0x5d,
+ 0x30,0x44,0x02,0x20,0x49,0xfc,0x10,0x2a,0x08,0xca,0x47,0xb6,0x0e,0x08,0x58,0xcd,0x02,0x84,0xd2,0x2c,0xdd,0xd7,0x23,0x3f,0x94,0xaa,0xff,0xbb,0x2d,0xb1,0xdd,0x2c,0xf0,0x84,0x25,0xe1,0x02,0x20,0x5b,0x16,0xfc,0xa5,0xa1,0x2c,0xdb,0x39,0x70,0x16,0x97,0xad,0x8e,0x39,0xff,0xd6,0xbd,0xec,0x00,0x24,0x29,0x8a,0xfa,0xa2,0x32,0x6a,0xea,0x09,0x20,0x0b,0x14,0xd6,
+ 0x30,0x44,0x02,0x20,0x41,0xef,0xa7,0xd3,0xf0,0x5a,0x00,0x10,0x67,0x5f,0xcb,0x91,0x8a,0x45,0xc6,0x93,0xda,0x4b,0x34,0x8d,0xf2,0x1a,0x59,0xd6,0xf9,0xcd,0x73,0xe0,0xd8,0x31,0xd6,0x7a,0x02,0x20,0x44,0x54,0xad,0xa6,0x93,0xe5,0xe2,0x6b,0x7b,0xd6,0x93,0x23,0x6d,0x34,0x0f,0x80,0x54,0x5c,0x83,0x45,0x77,0xb6,0xf7,0x3d,0x37,0x8c,0x7b,0xcc,0x53,0x42,0x44,0xda,
+ 0x30,0x45,0x02,0x21,0x00,0xb6,0x15,0x69,0x8c,0x35,0x8b,0x35,0x92,0x0d,0xd8,0x83,0xec,0xa6,0x25,0xa6,0xc5,0xf7,0x56,0x39,0x70,0xcd,0xfc,0x37,0x8f,0x8f,0xe0,0xce,0xe1,0x70,0x92,0x14,0x4c,0x02,0x20,0x25,0xf4,0x7b,0x32,0x6b,0x5b,0xe1,0xfb,0x61,0x0b,0x88,0x51,0x53,0xea,0x84,0xd4,0x1e,0xb4,0x71,0x6b,0xe6,0x6a,0x99,0x4e,0x87,0x79,0x98,0x9d,0xf1,0xc8,0x63,0xd4,
+ 0x30,0x45,0x02,0x21,0x00,0x87,0xcf,0x8c,0x0e,0xb8,0x2d,0x44,0xf6,0x9c,0x60,0xa2,0xff,0x54,0x57,0xd3,0xaa,0xa3,0x22,0xe7,0xec,0x61,0xae,0x5a,0xec,0xfd,0x67,0x8a,0xe1,0xc1,0x93,0x2b,0x0e,0x02,0x20,0x3a,0xdd,0x3b,0x11,0x58,0x15,0x04,0x7d,0x6e,0xb3,0x40,0xa3,0xe0,0x08,0x98,0x9e,0xaa,0x0f,0x87,0x08,0xd1,0x79,0x48,0x14,0x72,0x90,0x94,0xd0,0x8d,0x24,0x60,0xd3,
+ 0x30,0x44,0x02,0x20,0x62,0xf4,0x8e,0xf7,0x1a,0xce,0x27,0xbf,0x5a,0x01,0x83,0x4d,0xe1,0xf7,0xe3,0xf9,0x48,0xb9,0xdc,0xe1,0xca,0x1e,0x91,0x1d,0x5e,0x13,0xd3,0xb1,0x04,0x47,0x1d,0x82,0x02,0x20,0x5e,0xa8,0xf3,0x3f,0x0c,0x77,0x89,0x72,0xc4,0x58,0x20,0x80,0xde,0xda,0x9b,0x34,0x18,0x57,0xdd,0x64,0x51,0x4f,0x08,0x49,0xa0,0x5f,0x69,0x64,0xc2,0xe3,0x40,0x22,
+ 0x30,0x45,0x02,0x21,0x00,0xf6,0xb0,0xe2,0xf6,0xfe,0x02,0x0c,0xf7,0xc0,0xc2,0x01,0x37,0x43,0x43,0x44,0xed,0x7a,0xdd,0x6c,0x4b,0xe5,0x18,0x61,0xe2,0xd1,0x4c,0xbd,0xa4,0x72,0xa6,0xff,0xb4,0x02,0x20,0x64,0x16,0xc8,0xdd,0x3e,0x5c,0x52,0x82,0xb3,0x06,0xe8,0xdc,0x8f,0xf3,0x4a,0xb6,0x4c,0xc9,0x95,0x49,0x23,0x2d,0x67,0x8d,0x71,0x44,0x02,0xeb,0x6c,0xa7,0xaa,0x0f,
+ 0x30,0x45,0x02,0x21,0x00,0xdb,0x09,0xd8,0x46,0x0f,0x05,0xef,0xf2,0x3b,0xc7,0xe4,0x36,0xb6,0x7d,0xa5,0x63,0xfa,0x4b,0x4e,0xdb,0x58,0xac,0x24,0xce,0x20,0x1f,0xa8,0xa3,0x58,0x12,0x50,0x57,0x02,0x20,0x46,0xda,0x11,0x67,0x54,0x60,0x29,0x40,0xc8,0x99,0x9c,0x8d,0x66,0x5f,0x78,0x6c,0x50,0xf5,0x77,0x2c,0x0a,0x3c,0xdb,0xda,0x07,0x5e,0x77,0xea,0xbc,0x64,0xdf,0x16,
+ 0x30,0x44,0x02,0x20,0x59,0x2c,0x41,0xe1,0x65,0x17,0xf1,0x2f,0xca,0xbd,0x98,0x26,0x76,0x74,0xf9,0x74,0xb5,0x88,0xe9,0xf3,0x5d,0x35,0x40,0x6c,0x1a,0x7b,0xb2,0xed,0x1d,0x19,0xb7,0xb8,0x02,0x20,0x3e,0x65,0xa0,0x6b,0xd9,0xf8,0x3c,0xaa,0xeb,0x7b,0x00,0xf2,0x36,0x8d,0x7e,0x0d,0xec,0xe6,0xb1,0x22,0x21,0x26,0x9a,0x9b,0x5b,0x76,0x51,0x98,0xf8,0x40,0xa3,0xa1,
+ 0x30,0x45,0x02,0x21,0x00,0xbe,0x0d,0x70,0x88,0x7d,0x5e,0x40,0x82,0x1a,0x61,0xb6,0x80,0x47,0xde,0x4e,0xa0,0x3d,0xeb,0xfd,0xf5,0x1c,0xdf,0x4d,0x4b,0x19,0x55,0x58,0xb9,0x59,0xa0,0x32,0xb2,0x02,0x20,0x7d,0x99,0x4b,0x2d,0x8f,0x1d,0xbb,0xeb,0x13,0x53,0x4e,0xb3,0xf6,0xe5,0xdc,0xcd,0x85,0xf5,0xc4,0x13,0x3c,0x27,0xd9,0xe6,0x42,0x71,0xb1,0x82,0x6c,0xe1,0xf6,0x7d,
+ 0x30,0x45,0x02,0x21,0x00,0xfa,0xe9,0x2d,0xfc,0xb2,0xee,0x39,0x2d,0x27,0x0a,0xf3,0xa5,0x73,0x9f,0xaa,0x26,0xd4,0xf9,0x7b,0xfd,0x39,0xed,0x3c,0xbe,0xe4,0xd2,0x9e,0x26,0xaf,0x3b,0x20,0x6a,0x02,0x20,0x6c,0x9b,0xa3,0x7f,0x9f,0xaa,0x6a,0x1f,0xd3,0xf6,0x5f,0x23,0xb4,0xe8,0x53,0xd4,0x69,0x2a,0x72,0x74,0x24,0x0a,0x12,0xdb,0x7b,0xa3,0x88,0x48,0x30,0x63,0x0d,0x16,
+ 0x30,0x44,0x02,0x20,0x17,0x6a,0x25,0x57,0x56,0x6f,0xfa,0x51,0x8b,0x11,0x22,0x66,0x94,0xeb,0x98,0x02,0xed,0x20,0x98,0xbf,0xe2,0x78,0xe5,0x57,0x0f,0xe1,0xd5,0xd7,0xaf,0x18,0xa9,0x43,0x02,0x20,0x12,0x91,0xdf,0x6a,0x0e,0xd5,0xfc,0x0d,0x15,0x09,0x8e,0x70,0xbc,0xf1,0x3a,0x00,0x92,0x84,0xdf,0xd0,0x68,0x9d,0x3b,0xb4,0xbe,0x6c,0xee,0xb9,0xbe,0x14,0x87,0xc4,
+ 0x30,0x44,0x02,0x20,0x60,0xbe,0x20,0xc3,0xdb,0xc1,0x62,0xdd,0x34,0xd2,0x67,0x80,0x62,0x1c,0x10,0x4b,0xbe,0x5d,0xac,0xe6,0x30,0x17,0x1b,0x2d,0xae,0xf0,0xd8,0x26,0x40,0x9e,0xe5,0xc2,0x02,0x20,0x42,0x7f,0x7e,0x4d,0x88,0x9d,0x54,0x91,0x70,0xbd,0xa6,0xa9,0x40,0x9f,0xb1,0xcb,0x8b,0x0e,0x76,0x3d,0x13,0xee,0xa7,0xbd,0x97,0xf6,0x4c,0xf4,0x1d,0xc6,0xe4,0x97,
+ 0x30,0x45,0x02,0x21,0x00,0xed,0xf0,0x3c,0xf6,0x3f,0x65,0x88,0x83,0x28,0x9a,0x1a,0x59,0x3d,0x10,0x07,0x89,0x5b,0x9f,0x23,0x6d,0x27,0xc9,0xc1,0xf1,0x31,0x30,0x89,0xaa,0xed,0x6b,0x16,0xae,0x02,0x20,0x1a,0x4d,0xd6,0xfc,0x08,0x14,0xdc,0x52,0x3d,0x1f,0xef,0xa8,0x1c,0x64,0xfb,0xf5,0xe6,0x18,0xe6,0x51,0xe7,0x09,0x6f,0xcc,0xad,0xbb,0x94,0xcd,0x48,0xe5,0xe0,0xcd};
+
+static const wycheproof_ecdsa_testvector testvectors[SECP256K1_ECDSA_WYCHEPROOF_NUMBER_TESTVECTORS] = {
+ /* tcId: 1. Signature malleability */
+ {0, 0, 6, 0, 72, 0 },
+ /* tcId: 2. valid */
+ {0, 0, 6, 72, 71, 1 },
+ /* tcId: 3. length of sequence [r, s] uses long form encoding */
+ {0, 0, 6, 143, 72, 0 },
+ /* tcId: 4. length of sequence [r, s] contains a leading 0 */
+ {0, 0, 6, 215, 73, 0 },
+ /* tcId: 5. length of sequence [r, s] uses 70 instead of 69 */
+ {0, 0, 6, 288, 71, 0 },
+ /* tcId: 6. length of sequence [r, s] uses 68 instead of 69 */
+ {0, 0, 6, 359, 71, 0 },
+ /* tcId: 7. uint32 overflow in length of sequence [r, s] */
+ {0, 0, 6, 430, 76, 0 },
+ /* tcId: 8. uint64 overflow in length of sequence [r, s] */
+ {0, 0, 6, 506, 80, 0 },
+ /* tcId: 9. length of sequence [r, s] = 2**31 - 1 */
+ {0, 0, 6, 586, 75, 0 },
+ /* tcId: 10. length of sequence [r, s] = 2**31 */
+ {0, 0, 6, 661, 75, 0 },
+ /* tcId: 11. length of sequence [r, s] = 2**32 - 1 */
+ {0, 0, 6, 736, 75, 0 },
+ /* tcId: 12. length of sequence [r, s] = 2**40 - 1 */
+ {0, 0, 6, 811, 76, 0 },
+ /* tcId: 13. length of sequence [r, s] = 2**64 - 1 */
+ {0, 0, 6, 887, 79, 0 },
+ /* tcId: 14. incorrect length of sequence [r, s] */
+ {0, 0, 6, 966, 71, 0 },
+ /* tcId: 15. replaced sequence [r, s] by an indefinite length tag without termination */
+ {0, 0, 6, 1037, 71, 0 },
+ /* tcId: 16. removing sequence [r, s] */
+ {0, 0, 6, 1108, 0, 0 },
+ /* tcId: 17. lonely sequence tag */
+ {0, 0, 6, 1108, 1, 0 },
+ /* tcId: 18. appending 0's to sequence [r, s] */
+ {0, 0, 6, 1109, 73, 0 },
+ /* tcId: 19. prepending 0's to sequence [r, s] */
+ {0, 0, 6, 1182, 73, 0 },
+ /* tcId: 20. appending unused 0's to sequence [r, s] */
+ {0, 0, 6, 1255, 73, 0 },
+ /* tcId: 21. appending null value to sequence [r, s] */
+ {0, 0, 6, 1328, 73, 0 },
+ /* tcId: 22. prepending garbage to sequence [r, s] */
+ {0, 0, 6, 1401, 76, 0 },
+ /* tcId: 23. prepending garbage to sequence [r, s] */
+ {0, 0, 6, 1477, 75, 0 },
+ /* tcId: 24. appending garbage to sequence [r, s] */
+ {0, 0, 6, 1552, 79, 0 },
+ /* tcId: 25. including undefined tags */
+ {0, 0, 6, 1631, 79, 0 },
+ /* tcId: 26. including undefined tags */
+ {0, 0, 6, 1710, 79, 0 },
+ /* tcId: 27. including undefined tags */
+ {0, 0, 6, 1789, 79, 0 },
+ /* tcId: 28. truncated length of sequence [r, s] */
+ {0, 0, 6, 1868, 2, 0 },
+ /* tcId: 29. including undefined tags to sequence [r, s] */
+ {0, 0, 6, 1870, 77, 0 },
+ /* tcId: 30. using composition with indefinite length for sequence [r, s] */
+ {0, 0, 6, 1947, 75, 0 },
+ /* tcId: 31. using composition with wrong tag for sequence [r, s] */
+ {0, 0, 6, 2022, 75, 0 },
+ /* tcId: 32. Replacing sequence [r, s] with NULL */
+ {0, 0, 6, 2097, 2, 0 },
+ /* tcId: 33. changing tag value of sequence [r, s] */
+ {0, 0, 6, 2099, 71, 0 },
+ /* tcId: 34. changing tag value of sequence [r, s] */
+ {0, 0, 6, 2170, 71, 0 },
+ /* tcId: 35. changing tag value of sequence [r, s] */
+ {0, 0, 6, 2241, 71, 0 },
+ /* tcId: 36. changing tag value of sequence [r, s] */
+ {0, 0, 6, 2312, 71, 0 },
+ /* tcId: 37. changing tag value of sequence [r, s] */
+ {0, 0, 6, 2383, 71, 0 },
+ /* tcId: 38. dropping value of sequence [r, s] */
+ {0, 0, 6, 2454, 2, 0 },
+ /* tcId: 39. using composition for sequence [r, s] */
+ {0, 0, 6, 2456, 75, 0 },
+ /* tcId: 40. truncated sequence [r, s] */
+ {0, 0, 6, 2531, 70, 0 },
+ /* tcId: 41. truncated sequence [r, s] */
+ {0, 0, 6, 2601, 70, 0 },
+ /* tcId: 42. sequence [r, s] of size 4166 to check for overflows */
+ {0, 0, 6, 2671, 4170, 0 },
+ /* tcId: 43. indefinite length */
+ {0, 0, 6, 6841, 73, 0 },
+ /* tcId: 44. indefinite length with truncated delimiter */
+ {0, 0, 6, 6914, 72, 0 },
+ /* tcId: 45. indefinite length with additional element */
+ {0, 0, 6, 6986, 75, 0 },
+ /* tcId: 46. indefinite length with truncated element */
+ {0, 0, 6, 7061, 77, 0 },
+ /* tcId: 47. indefinite length with garbage */
+ {0, 0, 6, 7138, 77, 0 },
+ /* tcId: 48. indefinite length with nonempty EOC */
+ {0, 0, 6, 7215, 75, 0 },
+ /* tcId: 49. prepend empty sequence */
+ {0, 0, 6, 7290, 73, 0 },
+ /* tcId: 50. append empty sequence */
+ {0, 0, 6, 7363, 73, 0 },
+ /* tcId: 51. append zero */
+ {0, 0, 6, 7436, 74, 0 },
+ /* tcId: 52. append garbage with high tag number */
+ {0, 0, 6, 7510, 74, 0 },
+ /* tcId: 53. append null with explicit tag */
+ {0, 0, 6, 7584, 75, 0 },
+ /* tcId: 54. append null with implicit tag */
+ {0, 0, 6, 7659, 73, 0 },
+ /* tcId: 55. sequence of sequence */
+ {0, 0, 6, 7732, 73, 0 },
+ /* tcId: 56. truncated sequence: removed last 1 elements */
+ {0, 0, 6, 7805, 37, 0 },
+ /* tcId: 57. repeating element in sequence */
+ {0, 0, 6, 7842, 105, 0 },
+ /* tcId: 58. flipped bit 0 in r */
+ {0, 0, 6, 7947, 69, 0 },
+ /* tcId: 59. flipped bit 32 in r */
+ {0, 0, 6, 8016, 69, 0 },
+ /* tcId: 60. flipped bit 48 in r */
+ {0, 0, 6, 8085, 69, 0 },
+ /* tcId: 61. flipped bit 64 in r */
+ {0, 0, 6, 8154, 69, 0 },
+ /* tcId: 62. length of r uses long form encoding */
+ {0, 0, 6, 8223, 72, 0 },
+ /* tcId: 63. length of r contains a leading 0 */
+ {0, 0, 6, 8295, 73, 0 },
+ /* tcId: 64. length of r uses 34 instead of 33 */
+ {0, 0, 6, 8368, 71, 0 },
+ /* tcId: 65. length of r uses 32 instead of 33 */
+ {0, 0, 6, 8439, 71, 0 },
+ /* tcId: 66. uint32 overflow in length of r */
+ {0, 0, 6, 8510, 76, 0 },
+ /* tcId: 67. uint64 overflow in length of r */
+ {0, 0, 6, 8586, 80, 0 },
+ /* tcId: 68. length of r = 2**31 - 1 */
+ {0, 0, 6, 8666, 75, 0 },
+ /* tcId: 69. length of r = 2**31 */
+ {0, 0, 6, 8741, 75, 0 },
+ /* tcId: 70. length of r = 2**32 - 1 */
+ {0, 0, 6, 8816, 75, 0 },
+ /* tcId: 71. length of r = 2**40 - 1 */
+ {0, 0, 6, 8891, 76, 0 },
+ /* tcId: 72. length of r = 2**64 - 1 */
+ {0, 0, 6, 8967, 79, 0 },
+ /* tcId: 73. incorrect length of r */
+ {0, 0, 6, 9046, 71, 0 },
+ /* tcId: 74. replaced r by an indefinite length tag without termination */
+ {0, 0, 6, 9117, 71, 0 },
+ /* tcId: 75. removing r */
+ {0, 0, 6, 9188, 36, 0 },
+ /* tcId: 76. lonely integer tag */
+ {0, 0, 6, 9224, 37, 0 },
+ /* tcId: 77. lonely integer tag */
+ {0, 0, 6, 9261, 38, 0 },
+ /* tcId: 78. appending 0's to r */
+ {0, 0, 6, 9299, 73, 0 },
+ /* tcId: 79. prepending 0's to r */
+ {0, 0, 6, 9372, 73, 0 },
+ /* tcId: 80. appending unused 0's to r */
+ {0, 0, 6, 9445, 73, 0 },
+ /* tcId: 81. appending null value to r */
+ {0, 0, 6, 9518, 73, 0 },
+ /* tcId: 82. prepending garbage to r */
+ {0, 0, 6, 9591, 76, 0 },
+ /* tcId: 83. prepending garbage to r */
+ {0, 0, 6, 9667, 75, 0 },
+ /* tcId: 84. appending garbage to r */
+ {0, 0, 6, 9742, 79, 0 },
+ /* tcId: 85. truncated length of r */
+ {0, 0, 6, 9821, 38, 0 },
+ /* tcId: 86. including undefined tags to r */
+ {0, 0, 6, 9859, 77, 0 },
+ /* tcId: 87. using composition with indefinite length for r */
+ {0, 0, 6, 9936, 75, 0 },
+ /* tcId: 88. using composition with wrong tag for r */
+ {0, 0, 6, 10011, 75, 0 },
+ /* tcId: 89. Replacing r with NULL */
+ {0, 0, 6, 10086, 38, 0 },
+ /* tcId: 90. changing tag value of r */
+ {0, 0, 6, 10124, 71, 0 },
+ /* tcId: 91. changing tag value of r */
+ {0, 0, 6, 10195, 71, 0 },
+ /* tcId: 92. changing tag value of r */
+ {0, 0, 6, 10266, 71, 0 },
+ /* tcId: 93. changing tag value of r */
+ {0, 0, 6, 10337, 71, 0 },
+ /* tcId: 94. changing tag value of r */
+ {0, 0, 6, 10408, 71, 0 },
+ /* tcId: 95. dropping value of r */
+ {0, 0, 6, 10479, 38, 0 },
+ /* tcId: 96. using composition for r */
+ {0, 0, 6, 10517, 75, 0 },
+ /* tcId: 97. modifying first byte of r */
+ {0, 0, 6, 10592, 71, 0 },
+ /* tcId: 98. modifying last byte of r */
+ {0, 0, 6, 10663, 71, 0 },
+ /* tcId: 99. truncated r */
+ {0, 0, 6, 10734, 70, 0 },
+ /* tcId: 100. truncated r */
+ {0, 0, 6, 10804, 70, 0 },
+ /* tcId: 101. r of size 4130 to check for overflows */
+ {0, 0, 6, 10874, 4172, 0 },
+ /* tcId: 102. leading ff in r */
+ {0, 0, 6, 15046, 72, 0 },
+ /* tcId: 103. replaced r by infinity */
+ {0, 0, 6, 15118, 39, 0 },
+ /* tcId: 104. replacing r with zero */
+ {0, 0, 6, 15157, 39, 0 },
+ /* tcId: 105. flipped bit 0 in s */
+ {0, 0, 6, 15196, 69, 0 },
+ /* tcId: 106. flipped bit 32 in s */
+ {0, 0, 6, 15265, 69, 0 },
+ /* tcId: 107. flipped bit 48 in s */
+ {0, 0, 6, 15334, 69, 0 },
+ /* tcId: 108. flipped bit 64 in s */
+ {0, 0, 6, 15403, 69, 0 },
+ /* tcId: 109. length of s uses long form encoding */
+ {0, 0, 6, 15472, 72, 0 },
+ /* tcId: 110. length of s contains a leading 0 */
+ {0, 0, 6, 15544, 73, 0 },
+ /* tcId: 111. length of s uses 33 instead of 32 */
+ {0, 0, 6, 15617, 71, 0 },
+ /* tcId: 112. length of s uses 31 instead of 32 */
+ {0, 0, 6, 15688, 71, 0 },
+ /* tcId: 113. uint32 overflow in length of s */
+ {0, 0, 6, 15759, 76, 0 },
+ /* tcId: 114. uint64 overflow in length of s */
+ {0, 0, 6, 15835, 80, 0 },
+ /* tcId: 115. length of s = 2**31 - 1 */
+ {0, 0, 6, 15915, 75, 0 },
+ /* tcId: 116. length of s = 2**31 */
+ {0, 0, 6, 15990, 75, 0 },
+ /* tcId: 117. length of s = 2**32 - 1 */
+ {0, 0, 6, 16065, 75, 0 },
+ /* tcId: 118. length of s = 2**40 - 1 */
+ {0, 0, 6, 16140, 76, 0 },
+ /* tcId: 119. length of s = 2**64 - 1 */
+ {0, 0, 6, 16216, 79, 0 },
+ /* tcId: 120. incorrect length of s */
+ {0, 0, 6, 16295, 71, 0 },
+ /* tcId: 121. replaced s by an indefinite length tag without termination */
+ {0, 0, 6, 16366, 71, 0 },
+ /* tcId: 122. appending 0's to s */
+ {0, 0, 6, 16437, 73, 0 },
+ /* tcId: 123. prepending 0's to s */
+ {0, 0, 6, 16510, 73, 0 },
+ /* tcId: 124. appending null value to s */
+ {0, 0, 6, 16583, 73, 0 },
+ /* tcId: 125. prepending garbage to s */
+ {0, 0, 6, 16656, 76, 0 },
+ /* tcId: 126. prepending garbage to s */
+ {0, 0, 6, 16732, 75, 0 },
+ /* tcId: 127. appending garbage to s */
+ {0, 0, 6, 16807, 79, 0 },
+ /* tcId: 128. truncated length of s */
+ {0, 0, 6, 16886, 39, 0 },
+ /* tcId: 129. including undefined tags to s */
+ {0, 0, 6, 16925, 77, 0 },
+ /* tcId: 130. using composition with indefinite length for s */
+ {0, 0, 6, 17002, 75, 0 },
+ /* tcId: 131. using composition with wrong tag for s */
+ {0, 0, 6, 17077, 75, 0 },
+ /* tcId: 132. Replacing s with NULL */
+ {0, 0, 6, 17152, 39, 0 },
+ /* tcId: 133. changing tag value of s */
+ {0, 0, 6, 17191, 71, 0 },
+ /* tcId: 134. changing tag value of s */
+ {0, 0, 6, 17262, 71, 0 },
+ /* tcId: 135. changing tag value of s */
+ {0, 0, 6, 17333, 71, 0 },
+ /* tcId: 136. changing tag value of s */
+ {0, 0, 6, 17404, 71, 0 },
+ /* tcId: 137. changing tag value of s */
+ {0, 0, 6, 17475, 71, 0 },
+ /* tcId: 138. dropping value of s */
+ {0, 0, 6, 17546, 39, 0 },
+ /* tcId: 139. using composition for s */
+ {0, 0, 6, 17585, 75, 0 },
+ /* tcId: 140. modifying first byte of s */
+ {0, 0, 6, 17660, 71, 0 },
+ /* tcId: 141. modifying last byte of s */
+ {0, 0, 6, 17731, 71, 0 },
+ /* tcId: 142. truncated s */
+ {0, 0, 6, 17802, 70, 0 },
+ /* tcId: 143. truncated s */
+ {0, 0, 6, 17872, 70, 0 },
+ /* tcId: 144. s of size 4129 to check for overflows */
+ {0, 0, 6, 17942, 4172, 0 },
+ /* tcId: 145. leading ff in s */
+ {0, 0, 6, 22114, 72, 0 },
+ /* tcId: 146. replaced s by infinity */
+ {0, 0, 6, 22186, 40, 0 },
+ /* tcId: 147. replacing s with zero */
+ {0, 0, 6, 22226, 40, 0 },
+ /* tcId: 148. replaced r by r + n */
+ {0, 0, 6, 22266, 71, 0 },
+ /* tcId: 149. replaced r by r - n */
+ {0, 0, 6, 22337, 70, 0 },
+ /* tcId: 150. replaced r by r + 256 * n */
+ {0, 0, 6, 22407, 72, 0 },
+ /* tcId: 151. replaced r by -r */
+ {0, 0, 6, 22479, 71, 0 },
+ /* tcId: 152. replaced r by n - r */
+ {0, 0, 6, 22550, 70, 0 },
+ /* tcId: 153. replaced r by -n - r */
+ {0, 0, 6, 22620, 71, 0 },
+ /* tcId: 154. replaced r by r + 2**256 */
+ {0, 0, 6, 22691, 71, 0 },
+ /* tcId: 155. replaced r by r + 2**320 */
+ {0, 0, 6, 22762, 79, 0 },
+ /* tcId: 156. replaced s by s + n */
+ {0, 0, 6, 22841, 71, 0 },
+ /* tcId: 157. replaced s by s - n */
+ {0, 0, 6, 22912, 71, 0 },
+ /* tcId: 158. replaced s by s + 256 * n */
+ {0, 0, 6, 22983, 72, 0 },
+ /* tcId: 159. replaced s by -s */
+ {0, 0, 6, 23055, 70, 0 },
+ /* tcId: 160. replaced s by -n - s */
+ {0, 0, 6, 23125, 71, 0 },
+ /* tcId: 161. replaced s by s + 2**256 */
+ {0, 0, 6, 23196, 71, 0 },
+ /* tcId: 162. replaced s by s - 2**256 */
+ {0, 0, 6, 23267, 71, 0 },
+ /* tcId: 163. replaced s by s + 2**320 */
+ {0, 0, 6, 23338, 79, 0 },
+ /* tcId: 164. Signature with special case values r=0 and s=0 */
+ {0, 0, 6, 23417, 8, 0 },
+ /* tcId: 165. Signature with special case values r=0 and s=1 */
+ {0, 0, 6, 23425, 8, 0 },
+ /* tcId: 166. Signature with special case values r=0 and s=-1 */
+ {0, 0, 6, 23433, 8, 0 },
+ /* tcId: 167. Signature with special case values r=0 and s=n */
+ {0, 0, 6, 23441, 40, 0 },
+ /* tcId: 168. Signature with special case values r=0 and s=n - 1 */
+ {0, 0, 6, 23481, 40, 0 },
+ /* tcId: 169. Signature with special case values r=0 and s=n + 1 */
+ {0, 0, 6, 23521, 40, 0 },
+ /* tcId: 170. Signature with special case values r=0 and s=p */
+ {0, 0, 6, 23561, 40, 0 },
+ /* tcId: 171. Signature with special case values r=0 and s=p + 1 */
+ {0, 0, 6, 23601, 40, 0 },
+ /* tcId: 172. Signature with special case values r=1 and s=0 */
+ {0, 0, 6, 23641, 8, 0 },
+ /* tcId: 173. Signature with special case values r=1 and s=1 */
+ {0, 0, 6, 23649, 8, 0 },
+ /* tcId: 174. Signature with special case values r=1 and s=-1 */
+ {0, 0, 6, 23657, 8, 0 },
+ /* tcId: 175. Signature with special case values r=1 and s=n */
+ {0, 0, 6, 23665, 40, 0 },
+ /* tcId: 176. Signature with special case values r=1 and s=n - 1 */
+ {0, 0, 6, 23705, 40, 0 },
+ /* tcId: 177. Signature with special case values r=1 and s=n + 1 */
+ {0, 0, 6, 23745, 40, 0 },
+ /* tcId: 178. Signature with special case values r=1 and s=p */
+ {0, 0, 6, 23785, 40, 0 },
+ /* tcId: 179. Signature with special case values r=1 and s=p + 1 */
+ {0, 0, 6, 23825, 40, 0 },
+ /* tcId: 180. Signature with special case values r=-1 and s=0 */
+ {0, 0, 6, 23865, 8, 0 },
+ /* tcId: 181. Signature with special case values r=-1 and s=1 */
+ {0, 0, 6, 23873, 8, 0 },
+ /* tcId: 182. Signature with special case values r=-1 and s=-1 */
+ {0, 0, 6, 23881, 8, 0 },
+ /* tcId: 183. Signature with special case values r=-1 and s=n */
+ {0, 0, 6, 23889, 40, 0 },
+ /* tcId: 184. Signature with special case values r=-1 and s=n - 1 */
+ {0, 0, 6, 23929, 40, 0 },
+ /* tcId: 185. Signature with special case values r=-1 and s=n + 1 */
+ {0, 0, 6, 23969, 40, 0 },
+ /* tcId: 186. Signature with special case values r=-1 and s=p */
+ {0, 0, 6, 24009, 40, 0 },
+ /* tcId: 187. Signature with special case values r=-1 and s=p + 1 */
+ {0, 0, 6, 24049, 40, 0 },
+ /* tcId: 188. Signature with special case values r=n and s=0 */
+ {0, 0, 6, 24089, 40, 0 },
+ /* tcId: 189. Signature with special case values r=n and s=1 */
+ {0, 0, 6, 24129, 40, 0 },
+ /* tcId: 190. Signature with special case values r=n and s=-1 */
+ {0, 0, 6, 24169, 40, 0 },
+ /* tcId: 191. Signature with special case values r=n and s=n */
+ {0, 0, 6, 24209, 72, 0 },
+ /* tcId: 192. Signature with special case values r=n and s=n - 1 */
+ {0, 0, 6, 24281, 72, 0 },
+ /* tcId: 193. Signature with special case values r=n and s=n + 1 */
+ {0, 0, 6, 24353, 72, 0 },
+ /* tcId: 194. Signature with special case values r=n and s=p */
+ {0, 0, 6, 24425, 72, 0 },
+ /* tcId: 195. Signature with special case values r=n and s=p + 1 */
+ {0, 0, 6, 24497, 72, 0 },
+ /* tcId: 196. Signature with special case values r=n - 1 and s=0 */
+ {0, 0, 6, 24569, 40, 0 },
+ /* tcId: 197. Signature with special case values r=n - 1 and s=1 */
+ {0, 0, 6, 24609, 40, 0 },
+ /* tcId: 198. Signature with special case values r=n - 1 and s=-1 */
+ {0, 0, 6, 24649, 40, 0 },
+ /* tcId: 199. Signature with special case values r=n - 1 and s=n */
+ {0, 0, 6, 24689, 72, 0 },
+ /* tcId: 200. Signature with special case values r=n - 1 and s=n - 1 */
+ {0, 0, 6, 24761, 72, 0 },
+ /* tcId: 201. Signature with special case values r=n - 1 and s=n + 1 */
+ {0, 0, 6, 24833, 72, 0 },
+ /* tcId: 202. Signature with special case values r=n - 1 and s=p */
+ {0, 0, 6, 24905, 72, 0 },
+ /* tcId: 203. Signature with special case values r=n - 1 and s=p + 1 */
+ {0, 0, 6, 24977, 72, 0 },
+ /* tcId: 204. Signature with special case values r=n + 1 and s=0 */
+ {0, 0, 6, 25049, 40, 0 },
+ /* tcId: 205. Signature with special case values r=n + 1 and s=1 */
+ {0, 0, 6, 25089, 40, 0 },
+ /* tcId: 206. Signature with special case values r=n + 1 and s=-1 */
+ {0, 0, 6, 25129, 40, 0 },
+ /* tcId: 207. Signature with special case values r=n + 1 and s=n */
+ {0, 0, 6, 25169, 72, 0 },
+ /* tcId: 208. Signature with special case values r=n + 1 and s=n - 1 */
+ {0, 0, 6, 25241, 72, 0 },
+ /* tcId: 209. Signature with special case values r=n + 1 and s=n + 1 */
+ {0, 0, 6, 25313, 72, 0 },
+ /* tcId: 210. Signature with special case values r=n + 1 and s=p */
+ {0, 0, 6, 25385, 72, 0 },
+ /* tcId: 211. Signature with special case values r=n + 1 and s=p + 1 */
+ {0, 0, 6, 25457, 72, 0 },
+ /* tcId: 212. Signature with special case values r=p and s=0 */
+ {0, 0, 6, 25529, 40, 0 },
+ /* tcId: 213. Signature with special case values r=p and s=1 */
+ {0, 0, 6, 25569, 40, 0 },
+ /* tcId: 214. Signature with special case values r=p and s=-1 */
+ {0, 0, 6, 25609, 40, 0 },
+ /* tcId: 215. Signature with special case values r=p and s=n */
+ {0, 0, 6, 25649, 72, 0 },
+ /* tcId: 216. Signature with special case values r=p and s=n - 1 */
+ {0, 0, 6, 25721, 72, 0 },
+ /* tcId: 217. Signature with special case values r=p and s=n + 1 */
+ {0, 0, 6, 25793, 72, 0 },
+ /* tcId: 218. Signature with special case values r=p and s=p */
+ {0, 0, 6, 25865, 72, 0 },
+ /* tcId: 219. Signature with special case values r=p and s=p + 1 */
+ {0, 0, 6, 25937, 72, 0 },
+ /* tcId: 220. Signature with special case values r=p + 1 and s=0 */
+ {0, 0, 6, 26009, 40, 0 },
+ /* tcId: 221. Signature with special case values r=p + 1 and s=1 */
+ {0, 0, 6, 26049, 40, 0 },
+ /* tcId: 222. Signature with special case values r=p + 1 and s=-1 */
+ {0, 0, 6, 26089, 40, 0 },
+ /* tcId: 223. Signature with special case values r=p + 1 and s=n */
+ {0, 0, 6, 26129, 72, 0 },
+ /* tcId: 224. Signature with special case values r=p + 1 and s=n - 1 */
+ {0, 0, 6, 26201, 72, 0 },
+ /* tcId: 225. Signature with special case values r=p + 1 and s=n + 1 */
+ {0, 0, 6, 26273, 72, 0 },
+ /* tcId: 226. Signature with special case values r=p + 1 and s=p */
+ {0, 0, 6, 26345, 72, 0 },
+ /* tcId: 227. Signature with special case values r=p + 1 and s=p + 1 */
+ {0, 0, 6, 26417, 72, 0 },
+ /* tcId: 228. Signature encoding contains incorrect types: r=0, s=0.25 */
+ {0, 0, 6, 26489, 10, 0 },
+ /* tcId: 229. Signature encoding contains incorrect types: r=0, s=nan */
+ {0, 0, 6, 26499, 8, 0 },
+ /* tcId: 230. Signature encoding contains incorrect types: r=0, s=True */
+ {0, 0, 6, 26507, 8, 0 },
+ /* tcId: 231. Signature encoding contains incorrect types: r=0, s=False */
+ {0, 0, 6, 26515, 8, 0 },
+ /* tcId: 232. Signature encoding contains incorrect types: r=0, s=Null */
+ {0, 0, 6, 26523, 7, 0 },
+ /* tcId: 233. Signature encoding contains incorrect types: r=0, s=empyt UTF-8 string */
+ {0, 0, 6, 26530, 7, 0 },
+ /* tcId: 234. Signature encoding contains incorrect types: r=0, s="0" */
+ {0, 0, 6, 26537, 8, 0 },
+ /* tcId: 235. Signature encoding contains incorrect types: r=0, s=empty list */
+ {0, 0, 6, 26545, 7, 0 },
+ /* tcId: 236. Signature encoding contains incorrect types: r=0, s=list containing 0 */
+ {0, 0, 6, 26552, 10, 0 },
+ /* tcId: 237. Signature encoding contains incorrect types: r=1, s=0.25 */
+ {0, 0, 6, 26562, 10, 0 },
+ /* tcId: 238. Signature encoding contains incorrect types: r=1, s=nan */
+ {0, 0, 6, 26572, 8, 0 },
+ /* tcId: 239. Signature encoding contains incorrect types: r=1, s=True */
+ {0, 0, 6, 26580, 8, 0 },
+ /* tcId: 240. Signature encoding contains incorrect types: r=1, s=False */
+ {0, 0, 6, 26588, 8, 0 },
+ /* tcId: 241. Signature encoding contains incorrect types: r=1, s=Null */
+ {0, 0, 6, 26596, 7, 0 },
+ /* tcId: 242. Signature encoding contains incorrect types: r=1, s=empyt UTF-8 string */
+ {0, 0, 6, 26603, 7, 0 },
+ /* tcId: 243. Signature encoding contains incorrect types: r=1, s="0" */
+ {0, 0, 6, 26610, 8, 0 },
+ /* tcId: 244. Signature encoding contains incorrect types: r=1, s=empty list */
+ {0, 0, 6, 26618, 7, 0 },
+ /* tcId: 245. Signature encoding contains incorrect types: r=1, s=list containing 0 */
+ {0, 0, 6, 26625, 10, 0 },
+ /* tcId: 246. Signature encoding contains incorrect types: r=-1, s=0.25 */
+ {0, 0, 6, 26635, 10, 0 },
+ /* tcId: 247. Signature encoding contains incorrect types: r=-1, s=nan */
+ {0, 0, 6, 26645, 8, 0 },
+ /* tcId: 248. Signature encoding contains incorrect types: r=-1, s=True */
+ {0, 0, 6, 26653, 8, 0 },
+ /* tcId: 249. Signature encoding contains incorrect types: r=-1, s=False */
+ {0, 0, 6, 26661, 8, 0 },
+ /* tcId: 250. Signature encoding contains incorrect types: r=-1, s=Null */
+ {0, 0, 6, 26669, 7, 0 },
+ /* tcId: 251. Signature encoding contains incorrect types: r=-1, s=empyt UTF-8 string */
+ {0, 0, 6, 26676, 7, 0 },
+ /* tcId: 252. Signature encoding contains incorrect types: r=-1, s="0" */
+ {0, 0, 6, 26683, 8, 0 },
+ /* tcId: 253. Signature encoding contains incorrect types: r=-1, s=empty list */
+ {0, 0, 6, 26691, 7, 0 },
+ /* tcId: 254. Signature encoding contains incorrect types: r=-1, s=list containing 0 */
+ {0, 0, 6, 26698, 10, 0 },
+ /* tcId: 255. Signature encoding contains incorrect types: r=n, s=0.25 */
+ {0, 0, 6, 26708, 42, 0 },
+ /* tcId: 256. Signature encoding contains incorrect types: r=n, s=nan */
+ {0, 0, 6, 26750, 40, 0 },
+ /* tcId: 257. Signature encoding contains incorrect types: r=n, s=True */
+ {0, 0, 6, 26790, 40, 0 },
+ /* tcId: 258. Signature encoding contains incorrect types: r=n, s=False */
+ {0, 0, 6, 26830, 40, 0 },
+ /* tcId: 259. Signature encoding contains incorrect types: r=n, s=Null */
+ {0, 0, 6, 26870, 39, 0 },
+ /* tcId: 260. Signature encoding contains incorrect types: r=n, s=empyt UTF-8 string */
+ {0, 0, 6, 26909, 39, 0 },
+ /* tcId: 261. Signature encoding contains incorrect types: r=n, s="0" */
+ {0, 0, 6, 26948, 40, 0 },
+ /* tcId: 262. Signature encoding contains incorrect types: r=n, s=empty list */
+ {0, 0, 6, 26988, 39, 0 },
+ /* tcId: 263. Signature encoding contains incorrect types: r=n, s=list containing 0 */
+ {0, 0, 6, 27027, 42, 0 },
+ /* tcId: 264. Signature encoding contains incorrect types: r=p, s=0.25 */
+ {0, 0, 6, 27069, 42, 0 },
+ /* tcId: 265. Signature encoding contains incorrect types: r=p, s=nan */
+ {0, 0, 6, 27111, 40, 0 },
+ /* tcId: 266. Signature encoding contains incorrect types: r=p, s=True */
+ {0, 0, 6, 27151, 40, 0 },
+ /* tcId: 267. Signature encoding contains incorrect types: r=p, s=False */
+ {0, 0, 6, 27191, 40, 0 },
+ /* tcId: 268. Signature encoding contains incorrect types: r=p, s=Null */
+ {0, 0, 6, 27231, 39, 0 },
+ /* tcId: 269. Signature encoding contains incorrect types: r=p, s=empyt UTF-8 string */
+ {0, 0, 6, 27270, 39, 0 },
+ /* tcId: 270. Signature encoding contains incorrect types: r=p, s="0" */
+ {0, 0, 6, 27309, 40, 0 },
+ /* tcId: 271. Signature encoding contains incorrect types: r=p, s=empty list */
+ {0, 0, 6, 27349, 39, 0 },
+ /* tcId: 272. Signature encoding contains incorrect types: r=p, s=list containing 0 */
+ {0, 0, 6, 27388, 42, 0 },
+ /* tcId: 273. Signature encoding contains incorrect types: r=0.25, s=0.25 */
+ {0, 0, 6, 27430, 12, 0 },
+ /* tcId: 274. Signature encoding contains incorrect types: r=nan, s=nan */
+ {0, 0, 6, 27442, 8, 0 },
+ /* tcId: 275. Signature encoding contains incorrect types: r=True, s=True */
+ {0, 0, 6, 27450, 8, 0 },
+ /* tcId: 276. Signature encoding contains incorrect types: r=False, s=False */
+ {0, 0, 6, 27458, 8, 0 },
+ /* tcId: 277. Signature encoding contains incorrect types: r=Null, s=Null */
+ {0, 0, 6, 27466, 6, 0 },
+ /* tcId: 278. Signature encoding contains incorrect types: r=empyt UTF-8 string, s=empyt UTF-8 string */
+ {0, 0, 6, 27472, 6, 0 },
+ /* tcId: 279. Signature encoding contains incorrect types: r="0", s="0" */
+ {0, 0, 6, 27478, 8, 0 },
+ /* tcId: 280. Signature encoding contains incorrect types: r=empty list, s=empty list */
+ {0, 0, 6, 27486, 6, 0 },
+ /* tcId: 281. Signature encoding contains incorrect types: r=list containing 0, s=list containing 0 */
+ {0, 0, 6, 27492, 12, 0 },
+ /* tcId: 282. Signature encoding contains incorrect types: r=0.25, s=0 */
+ {0, 0, 6, 27504, 10, 0 },
+ /* tcId: 283. Signature encoding contains incorrect types: r=nan, s=0 */
+ {0, 0, 6, 27514, 8, 0 },
+ /* tcId: 284. Signature encoding contains incorrect types: r=True, s=0 */
+ {0, 0, 6, 27522, 8, 0 },
+ /* tcId: 285. Signature encoding contains incorrect types: r=False, s=0 */
+ {0, 0, 6, 27530, 8, 0 },
+ /* tcId: 286. Signature encoding contains incorrect types: r=Null, s=0 */
+ {0, 0, 6, 27538, 7, 0 },
+ /* tcId: 287. Signature encoding contains incorrect types: r=empyt UTF-8 string, s=0 */
+ {0, 0, 6, 27545, 7, 0 },
+ /* tcId: 288. Signature encoding contains incorrect types: r="0", s=0 */
+ {0, 0, 6, 27552, 8, 0 },
+ /* tcId: 289. Signature encoding contains incorrect types: r=empty list, s=0 */
+ {0, 0, 6, 27560, 7, 0 },
+ /* tcId: 290. Signature encoding contains incorrect types: r=list containing 0, s=0 */
+ {0, 0, 6, 27567, 10, 0 },
+ /* tcId: 291. Edge case for Shamir multiplication */
+ {0, 6, 5, 27577, 71, 1 },
+ /* tcId: 292. special case hash */
+ {0, 11, 9, 27648, 71, 1 },
+ /* tcId: 293. special case hash */
+ {0, 20, 10, 27719, 70, 1 },
+ /* tcId: 294. special case hash */
+ {0, 30, 11, 27789, 71, 1 },
+ /* tcId: 295. special case hash */
+ {0, 41, 10, 27860, 71, 1 },
+ /* tcId: 296. special case hash */
+ {0, 51, 10, 27931, 70, 1 },
+ /* tcId: 297. special case hash */
+ {0, 61, 10, 28001, 71, 1 },
+ /* tcId: 298. special case hash */
+ {0, 71, 9, 28072, 70, 1 },
+ /* tcId: 299. special case hash */
+ {0, 80, 10, 28142, 71, 1 },
+ /* tcId: 300. special case hash */
+ {0, 90, 10, 28213, 71, 1 },
+ /* tcId: 301. special case hash */
+ {0, 100, 10, 28284, 71, 1 },
+ /* tcId: 302. special case hash */
+ {0, 110, 10, 28355, 71, 1 },
+ /* tcId: 303. special case hash */
+ {0, 120, 11, 28426, 70, 1 },
+ /* tcId: 304. special case hash */
+ {0, 131, 10, 28496, 71, 1 },
+ /* tcId: 305. special case hash */
+ {0, 141, 10, 28567, 71, 1 },
+ /* tcId: 306. special case hash */
+ {0, 151, 10, 28638, 70, 1 },
+ /* tcId: 307. special case hash */
+ {0, 161, 10, 28708, 71, 1 },
+ /* tcId: 308. special case hash */
+ {0, 171, 10, 28779, 71, 1 },
+ /* tcId: 309. special case hash */
+ {0, 181, 10, 28850, 70, 1 },
+ /* tcId: 310. special case hash */
+ {0, 191, 10, 28920, 71, 1 },
+ /* tcId: 311. special case hash */
+ {0, 201, 10, 28991, 71, 1 },
+ /* tcId: 312. special case hash */
+ {0, 211, 10, 29062, 71, 1 },
+ /* tcId: 313. special case hash */
+ {0, 221, 10, 29133, 70, 1 },
+ /* tcId: 314. special case hash */
+ {0, 231, 10, 29203, 71, 1 },
+ /* tcId: 315. special case hash */
+ {0, 241, 10, 29274, 71, 1 },
+ /* tcId: 316. special case hash */
+ {0, 251, 10, 29345, 71, 1 },
+ /* tcId: 317. special case hash */
+ {0, 261, 11, 29416, 71, 1 },
+ /* tcId: 318. special case hash */
+ {0, 272, 11, 29487, 70, 1 },
+ /* tcId: 319. special case hash */
+ {0, 283, 9, 29557, 71, 1 },
+ /* tcId: 320. special case hash */
+ {0, 292, 9, 29628, 71, 1 },
+ /* tcId: 321. special case hash */
+ {0, 301, 10, 29699, 71, 1 },
+ /* tcId: 322. special case hash */
+ {0, 311, 10, 29770, 71, 1 },
+ /* tcId: 323. special case hash */
+ {0, 321, 10, 29841, 70, 1 },
+ /* tcId: 324. special case hash */
+ {0, 331, 10, 29911, 70, 1 },
+ /* tcId: 325. special case hash */
+ {0, 341, 10, 29981, 71, 1 },
+ /* tcId: 326. special case hash */
+ {0, 351, 9, 30052, 70, 1 },
+ /* tcId: 327. special case hash */
+ {0, 360, 10, 30122, 70, 1 },
+ /* tcId: 328. special case hash */
+ {0, 370, 10, 30192, 70, 1 },
+ /* tcId: 329. special case hash */
+ {0, 380, 10, 30262, 70, 1 },
+ /* tcId: 330. special case hash */
+ {0, 390, 9, 30332, 71, 1 },
+ /* tcId: 331. special case hash */
+ {0, 399, 11, 30403, 70, 1 },
+ /* tcId: 332. special case hash */
+ {0, 410, 9, 30473, 71, 1 },
+ /* tcId: 333. special case hash */
+ {0, 419, 9, 30544, 71, 1 },
+ /* tcId: 334. special case hash */
+ {0, 428, 11, 30615, 70, 1 },
+ /* tcId: 335. special case hash */
+ {0, 439, 8, 30685, 71, 1 },
+ /* tcId: 336. special case hash */
+ {0, 447, 10, 30756, 70, 1 },
+ /* tcId: 337. special case hash */
+ {0, 457, 10, 30826, 71, 1 },
+ /* tcId: 338. special case hash */
+ {0, 467, 10, 30897, 70, 1 },
+ /* tcId: 339. special case hash */
+ {0, 477, 10, 30967, 70, 1 },
+ /* tcId: 340. special case hash */
+ {0, 487, 10, 31037, 70, 1 },
+ /* tcId: 341. special case hash */
+ {0, 497, 10, 31107, 71, 1 },
+ /* tcId: 342. special case hash */
+ {0, 507, 10, 31178, 70, 1 },
+ /* tcId: 343. special case hash */
+ {0, 517, 10, 31248, 70, 1 },
+ /* tcId: 344. special case hash */
+ {0, 527, 10, 31318, 71, 1 },
+ /* tcId: 345. special case hash */
+ {0, 537, 9, 31389, 70, 1 },
+ /* tcId: 346. k*G has a large x-coordinate */
+ {65, 0, 6, 31459, 24, 1 },
+ /* tcId: 347. r too large */
+ {65, 0, 6, 31483, 40, 0 },
+ /* tcId: 348. r,s are large */
+ {130, 0, 6, 31523, 40, 1 },
+ /* tcId: 349. r and s^-1 have a large Hamming weight */
+ {195, 0, 6, 31563, 70, 1 },
+ /* tcId: 350. r and s^-1 have a large Hamming weight */
+ {260, 0, 6, 31633, 70, 1 },
+ /* tcId: 351. small r and s */
+ {325, 0, 6, 31703, 8, 1 },
+ /* tcId: 352. small r and s */
+ {390, 0, 6, 31711, 8, 1 },
+ /* tcId: 353. small r and s */
+ {455, 0, 6, 31719, 8, 1 },
+ /* tcId: 354. small r and s */
+ {520, 0, 6, 31727, 8, 1 },
+ /* tcId: 355. small r and s */
+ {585, 0, 6, 31735, 8, 1 },
+ /* tcId: 356. small r and s */
+ {650, 0, 6, 31743, 8, 1 },
+ /* tcId: 357. r is larger than n */
+ {650, 0, 6, 31751, 40, 0 },
+ /* tcId: 358. s is larger than n */
+ {715, 0, 6, 31791, 10, 0 },
+ /* tcId: 359. small r and s^-1 */
+ {780, 0, 6, 31801, 40, 1 },
+ /* tcId: 360. smallish r and s^-1 */
+ {845, 0, 6, 31841, 45, 1 },
+ /* tcId: 361. 100-bit r and small s^-1 */
+ {910, 0, 6, 31886, 51, 1 },
+ /* tcId: 362. small r and 100 bit s^-1 */
+ {975, 0, 6, 31937, 40, 1 },
+ /* tcId: 363. 100-bit r and s^-1 */
+ {1040, 0, 6, 31977, 51, 1 },
+ /* tcId: 364. r and s^-1 are close to n */
+ {1105, 0, 6, 32028, 71, 1 },
+ /* tcId: 365. r and s are 64-bit integer */
+ {1170, 0, 6, 32099, 24, 1 },
+ /* tcId: 366. r and s are 100-bit integer */
+ {1235, 0, 6, 32123, 32, 1 },
+ /* tcId: 367. r and s are 128-bit integer */
+ {1300, 0, 6, 32155, 40, 1 },
+ /* tcId: 368. r and s are 160-bit integer */
+ {1365, 0, 6, 32195, 48, 1 },
+ /* tcId: 369. s == 1 */
+ {1430, 0, 6, 32243, 39, 1 },
+ /* tcId: 370. s == 0 */
+ {1430, 0, 6, 32282, 39, 0 },
+ /* tcId: 371. edge case modular inverse */
+ {1495, 0, 6, 32321, 70, 1 },
+ /* tcId: 372. edge case modular inverse */
+ {1560, 0, 6, 32391, 70, 1 },
+ /* tcId: 373. edge case modular inverse */
+ {1625, 0, 6, 32461, 70, 1 },
+ /* tcId: 374. edge case modular inverse */
+ {1690, 0, 6, 32531, 70, 1 },
+ /* tcId: 375. edge case modular inverse */
+ {1755, 0, 6, 32601, 70, 1 },
+ /* tcId: 376. edge case modular inverse */
+ {1820, 0, 6, 32671, 70, 1 },
+ /* tcId: 377. edge case modular inverse */
+ {1885, 0, 6, 32741, 70, 1 },
+ /* tcId: 378. edge case modular inverse */
+ {1950, 0, 6, 32811, 70, 1 },
+ /* tcId: 379. edge case modular inverse */
+ {2015, 0, 6, 32881, 70, 1 },
+ /* tcId: 380. edge case modular inverse */
+ {2080, 0, 6, 32951, 70, 1 },
+ /* tcId: 381. edge case modular inverse */
+ {2145, 0, 6, 33021, 70, 1 },
+ /* tcId: 382. edge case modular inverse */
+ {2210, 0, 6, 33091, 70, 1 },
+ /* tcId: 383. edge case modular inverse */
+ {2275, 0, 6, 33161, 70, 1 },
+ /* tcId: 384. edge case modular inverse */
+ {2340, 0, 6, 33231, 70, 1 },
+ /* tcId: 385. edge case modular inverse */
+ {2405, 0, 6, 33301, 70, 1 },
+ /* tcId: 386. point at infinity during verify */
+ {2470, 0, 6, 33371, 70, 0 },
+ /* tcId: 387. edge case for signature malleability */
+ {2535, 0, 6, 33441, 70, 1 },
+ /* tcId: 388. edge case for signature malleability */
+ {2600, 0, 6, 33511, 70, 0 },
+ /* tcId: 389. u1 == 1 */
+ {2665, 0, 6, 33581, 70, 1 },
+ /* tcId: 390. u1 == n - 1 */
+ {2730, 0, 6, 33651, 70, 1 },
+ /* tcId: 391. u2 == 1 */
+ {2795, 0, 6, 33721, 70, 1 },
+ /* tcId: 392. u2 == n - 1 */
+ {2860, 0, 6, 33791, 70, 1 },
+ /* tcId: 393. edge case for u1 */
+ {2925, 0, 6, 33861, 70, 1 },
+ /* tcId: 394. edge case for u1 */
+ {2990, 0, 6, 33931, 70, 1 },
+ /* tcId: 395. edge case for u1 */
+ {3055, 0, 6, 34001, 70, 1 },
+ /* tcId: 396. edge case for u1 */
+ {3120, 0, 6, 34071, 70, 1 },
+ /* tcId: 397. edge case for u1 */
+ {3185, 0, 6, 34141, 70, 1 },
+ /* tcId: 398. edge case for u1 */
+ {3250, 0, 6, 34211, 70, 1 },
+ /* tcId: 399. edge case for u1 */
+ {3315, 0, 6, 34281, 70, 1 },
+ /* tcId: 400. edge case for u1 */
+ {3380, 0, 6, 34351, 70, 1 },
+ /* tcId: 401. edge case for u1 */
+ {3445, 0, 6, 34421, 70, 1 },
+ /* tcId: 402. edge case for u1 */
+ {3510, 0, 6, 34491, 70, 1 },
+ /* tcId: 403. edge case for u1 */
+ {3575, 0, 6, 34561, 70, 1 },
+ /* tcId: 404. edge case for u1 */
+ {3640, 0, 6, 34631, 70, 1 },
+ /* tcId: 405. edge case for u1 */
+ {3705, 0, 6, 34701, 70, 1 },
+ /* tcId: 406. edge case for u1 */
+ {3770, 0, 6, 34771, 70, 1 },
+ /* tcId: 407. edge case for u1 */
+ {3835, 0, 6, 34841, 70, 1 },
+ /* tcId: 408. edge case for u2 */
+ {3900, 0, 6, 34911, 70, 1 },
+ /* tcId: 409. edge case for u2 */
+ {3965, 0, 6, 34981, 70, 1 },
+ /* tcId: 410. edge case for u2 */
+ {4030, 0, 6, 35051, 70, 1 },
+ /* tcId: 411. edge case for u2 */
+ {4095, 0, 6, 35121, 70, 1 },
+ /* tcId: 412. edge case for u2 */
+ {4160, 0, 6, 35191, 70, 1 },
+ /* tcId: 413. edge case for u2 */
+ {4225, 0, 6, 35261, 69, 1 },
+ /* tcId: 414. edge case for u2 */
+ {4290, 0, 6, 35330, 70, 1 },
+ /* tcId: 415. edge case for u2 */
+ {4355, 0, 6, 35400, 70, 1 },
+ /* tcId: 416. edge case for u2 */
+ {4420, 0, 6, 35470, 70, 1 },
+ /* tcId: 417. edge case for u2 */
+ {4485, 0, 6, 35540, 70, 1 },
+ /* tcId: 418. edge case for u2 */
+ {4550, 0, 6, 35610, 70, 1 },
+ /* tcId: 419. edge case for u2 */
+ {4615, 0, 6, 35680, 70, 1 },
+ /* tcId: 420. edge case for u2 */
+ {4680, 0, 6, 35750, 70, 1 },
+ /* tcId: 421. edge case for u2 */
+ {4745, 0, 6, 35820, 70, 1 },
+ /* tcId: 422. edge case for u2 */
+ {4810, 0, 6, 35890, 70, 1 },
+ /* tcId: 423. point duplication during verification */
+ {4875, 0, 6, 35960, 70, 1 },
+ /* tcId: 424. duplication bug */
+ {4940, 0, 6, 36030, 70, 0 },
+ /* tcId: 425. comparison with point at infinity */
+ {5005, 0, 6, 36100, 70, 0 },
+ /* tcId: 426. extreme value for k and edgecase s */
+ {5070, 0, 6, 36170, 71, 1 },
+ /* tcId: 427. extreme value for k and s^-1 */
+ {5135, 0, 6, 36241, 71, 1 },
+ /* tcId: 428. extreme value for k and s^-1 */
+ {5200, 0, 6, 36312, 71, 1 },
+ /* tcId: 429. extreme value for k and s^-1 */
+ {5265, 0, 6, 36383, 71, 1 },
+ /* tcId: 430. extreme value for k and s^-1 */
+ {5330, 0, 6, 36454, 71, 1 },
+ /* tcId: 431. extreme value for k */
+ {5395, 0, 6, 36525, 71, 1 },
+ /* tcId: 432. extreme value for k and edgecase s */
+ {5460, 0, 6, 36596, 70, 1 },
+ /* tcId: 433. extreme value for k and s^-1 */
+ {5525, 0, 6, 36666, 70, 1 },
+ /* tcId: 434. extreme value for k and s^-1 */
+ {5590, 0, 6, 36736, 70, 1 },
+ /* tcId: 435. extreme value for k and s^-1 */
+ {5655, 0, 6, 36806, 70, 1 },
+ /* tcId: 436. extreme value for k and s^-1 */
+ {5720, 0, 6, 36876, 70, 1 },
+ /* tcId: 437. extreme value for k */
+ {5785, 0, 6, 36946, 70, 1 },
+ /* tcId: 438. public key shares x-coordinate with generator */
+ {5850, 0, 6, 37016, 71, 0 },
+ /* tcId: 439. public key shares x-coordinate with generator */
+ {5850, 0, 6, 37087, 70, 0 },
+ /* tcId: 440. public key shares x-coordinate with generator */
+ {5915, 0, 6, 37157, 71, 0 },
+ /* tcId: 441. public key shares x-coordinate with generator */
+ {5915, 0, 6, 37228, 70, 0 },
+ /* tcId: 442. pseudorandom signature */
+ {5980, 546, 0, 37298, 71, 1 },
+ /* tcId: 443. pseudorandom signature */
+ {5980, 546, 3, 37369, 70, 1 },
+ /* tcId: 444. pseudorandom signature */
+ {5980, 0, 6, 37439, 71, 1 },
+ /* tcId: 445. pseudorandom signature */
+ {5980, 549, 20, 37510, 70, 1 },
+ /* tcId: 446. y-coordinate of the public key is small */
+ {6045, 569, 7, 37580, 70, 1 },
+ /* tcId: 447. y-coordinate of the public key is small */
+ {6045, 569, 7, 37650, 70, 1 },
+ /* tcId: 448. y-coordinate of the public key is small */
+ {6045, 569, 7, 37720, 71, 1 },
+ /* tcId: 449. y-coordinate of the public key is large */
+ {6110, 569, 7, 37791, 70, 1 },
+ /* tcId: 450. y-coordinate of the public key is large */
+ {6110, 569, 7, 37861, 71, 1 },
+ /* tcId: 451. y-coordinate of the public key is large */
+ {6110, 569, 7, 37932, 70, 1 },
+ /* tcId: 452. x-coordinate of the public key is small */
+ {6175, 569, 7, 38002, 70, 1 },
+ /* tcId: 453. x-coordinate of the public key is small */
+ {6175, 569, 7, 38072, 71, 1 },
+ /* tcId: 454. x-coordinate of the public key is small */
+ {6175, 569, 7, 38143, 71, 1 },
+ /* tcId: 455. x-coordinate of the public key has many trailing 1's */
+ {6240, 569, 7, 38214, 70, 1 },
+ /* tcId: 456. x-coordinate of the public key has many trailing 1's */
+ {6240, 569, 7, 38284, 71, 1 },
+ /* tcId: 457. x-coordinate of the public key has many trailing 1's */
+ {6240, 569, 7, 38355, 71, 1 },
+ /* tcId: 458. y-coordinate of the public key has many trailing 1's */
+ {6305, 569, 7, 38426, 70, 1 },
+ /* tcId: 459. y-coordinate of the public key has many trailing 1's */
+ {6305, 569, 7, 38496, 71, 1 },
+ /* tcId: 460. y-coordinate of the public key has many trailing 1's */
+ {6305, 569, 7, 38567, 71, 1 },
+ /* tcId: 461. x-coordinate of the public key has many trailing 0's */
+ {6370, 569, 7, 38638, 70, 1 },
+ /* tcId: 462. x-coordinate of the public key has many trailing 0's */
+ {6370, 569, 7, 38708, 70, 1 },
+ /* tcId: 463. x-coordinate of the public key has many trailing 0's */
+ {6370, 569, 7, 38778, 71, 1 },
+
+};
diff --git a/src/secp256k1/src/wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.json b/src/secp256k1/src/wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.json
new file mode 100644
index 0000000000..9c90747993
--- /dev/null
+++ b/src/secp256k1/src/wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.json
@@ -0,0 +1,6360 @@
+{
+ "algorithm" : "ECDSA",
+ "schema" : "ecdsa_bitcoin_verify_schema.json",
+ "generatorVersion" : "0.9rc5",
+ "numberOfTests" : 463,
+ "header" : [
+ "Test vectors of type EcdsaBitcoinVerify are meant for the verification",
+ "of a ECDSA variant used for bitcoin, that add signature non-malleability."
+ ],
+ "notes" : {
+ "ArithmeticError" : {
+ "bugType" : "EDGE_CASE",
+ "description" : "Some implementations of ECDSA have arithmetic errors that occur when intermediate results have extreme values. This test vector has been constructed to test such occurences.",
+ "cves" : [
+ "CVE-2017-18146"
+ ]
+ },
+ "BerEncodedSignature" : {
+ "bugType" : "BER_ENCODING",
+ "description" : "ECDSA signatures are usually DER encoded. This signature contains valid values for r and s, but it uses alternative BER encoding.",
+ "effect" : "Accepting alternative BER encodings may be benign in some cases, or be an issue if protocol requires signature malleability.",
+ "cves" : [
+ "CVE-2020-14966",
+ "CVE-2020-13822",
+ "CVE-2019-14859",
+ "CVE-2016-1000342"
+ ]
+ },
+ "EdgeCasePublicKey" : {
+ "bugType" : "EDGE_CASE",
+ "description" : "The test vector uses a special case public key. "
+ },
+ "EdgeCaseShamirMultiplication" : {
+ "bugType" : "EDGE_CASE",
+ "description" : "Shamir proposed a fast method for computing the sum of two scalar multiplications efficiently. This test vector has been constructed so that an intermediate result is the point at infinity if Shamir's method is used."
+ },
+ "IntegerOverflow" : {
+ "bugType" : "CAN_OF_WORMS",
+ "description" : "The test vector contains an r and s that has been modified, so that the original value is restored if the implementation ignores the most significant bits.",
+ "effect" : "Without further analysis it is unclear if the modification can be used to forge signatures."
+ },
+ "InvalidEncoding" : {
+ "bugType" : "CAN_OF_WORMS",
+ "description" : "ECDSA signatures are encoded using ASN.1. This test vector contains an incorrectly encoded signature. The test vector itself was generated from a valid signature by modifying its encoding.",
+ "effect" : "Without further analysis it is unclear if the modification can be used to forge signatures."
+ },
+ "InvalidSignature" : {
+ "bugType" : "AUTH_BYPASS",
+ "description" : "The signature contains special case values such as r=0 and s=0. Buggy implementations may accept such values, if the implementation does not check boundaries and computes s^(-1) == 0.",
+ "effect" : "Accepting such signatures can have the effect that an adversary can forge signatures without even knowning the message to sign.",
+ "cves" : [
+ "CVE-2022-21449",
+ "CVE-2021-43572",
+ "CVE-2022-24884"
+ ]
+ },
+ "InvalidTypesInSignature" : {
+ "bugType" : "AUTH_BYPASS",
+ "description" : "The signature contains invalid types. Dynamic typed languages sometime coerce such values of different types into integers. If an implementation is careless and has additional bugs, such as not checking integer boundaries then it may be possible that such signatures are accepted.",
+ "effect" : "Accepting such signatures can have the effect that an adversary can forge signatures without even knowning the message to sign.",
+ "cves" : [
+ "CVE-2022-21449"
+ ]
+ },
+ "ModifiedInteger" : {
+ "bugType" : "CAN_OF_WORMS",
+ "description" : "The test vector contains an r and s that has been modified. The goal is to check for arithmetic errors.",
+ "effect" : "Without further analysis it is unclear if the modification can be used to forge signatures."
+ },
+ "ModifiedSignature" : {
+ "bugType" : "CAN_OF_WORMS",
+ "description" : "The test vector contains an invalid signature that was generated from a valid signature by modifying it.",
+ "effect" : "Without further analysis it is unclear if the modification can be used to forge signatures."
+ },
+ "ModularInverse" : {
+ "bugType" : "EDGE_CASE",
+ "description" : "The test vectors contains a signature where computing the modular inverse of s hits an edge case.",
+ "effect" : "While the signature in this test vector is constructed and similar cases are unlikely to occur, it is important to determine if the underlying arithmetic error can be used to forge signatures.",
+ "cves" : [
+ "CVE-2019-0865"
+ ]
+ },
+ "PointDuplication" : {
+ "bugType" : "EDGE_CASE",
+ "description" : "Some implementations of ECDSA do not handle duplication and points at infinity correctly. This is a test vector that has been specially crafted to check for such an omission.",
+ "cves" : [
+ "2020-12607",
+ "CVE-2015-2730"
+ ]
+ },
+ "RangeCheck" : {
+ "bugType" : "CAN_OF_WORMS",
+ "description" : "The test vector contains an r and s that has been modified. By adding or subtracting the order of the group (or other values) the test vector checks whether signature verification verifies the range of r and s.",
+ "effect" : "Without further analysis it is unclear if the modification can be used to forge signatures."
+ },
+ "SignatureMalleabilityBitcoin" : {
+ "bugType" : "SIGNATURE_MALLEABILITY",
+ "description" : "\"BitCoins\"-curves are curves where signature malleability can be a serious issue. An implementation should only accept a signature s where s < n/2. If an implementation is not meant for uses cases that require signature malleability then this implemenation should be tested with another set of test vectors.",
+ "effect" : "In bitcoin exchanges, it may be used to make a double deposits or double withdrawals",
+ "links" : [
+ "https://en.bitcoin.it/wiki/Transaction_malleability",
+ "https://en.bitcoinwiki.org/wiki/Transaction_Malleability"
+ ]
+ },
+ "SmallRandS" : {
+ "bugType" : "EDGE_CASE",
+ "description" : "The test vectors contains a signature where both r and s are small integers. Some libraries cannot verify such signatures.",
+ "effect" : "While the signature in this test vector is constructed and similar cases are unlikely to occur, it is important to determine if the underlying arithmetic error can be used to forge signatures.",
+ "cves" : [
+ "2020-13895"
+ ]
+ },
+ "SpecialCaseHash" : {
+ "bugType" : "EDGE_CASE",
+ "description" : "The test vector contains a signature where the hash of the message is a special case, e.g., contains a long run of 0 or 1 bits."
+ },
+ "ValidSignature" : {
+ "bugType" : "BASIC",
+ "description" : "The test vector contains a valid signature that was generated pseudorandomly. Such signatures should not fail to verify unless some of the parameters (e.g. curve or hash function) are not supported."
+ }
+ },
+ "testGroups" : [
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "04b838ff44e5bc177bf21189d0766082fc9d843226887fc9760371100b7ee20a6ff0c9d75bfba7b31a6bca1974496eeb56de357071955d83c4b1badaa0b21832e9",
+ "wx" : "00b838ff44e5bc177bf21189d0766082fc9d843226887fc9760371100b7ee20a6f",
+ "wy" : "00f0c9d75bfba7b31a6bca1974496eeb56de357071955d83c4b1badaa0b21832e9"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004b838ff44e5bc177bf21189d0766082fc9d843226887fc9760371100b7ee20a6ff0c9d75bfba7b31a6bca1974496eeb56de357071955d83c4b1badaa0b21832e9",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEuDj/ROW8F3vyEYnQdmCC/J2EMiaIf8l2\nA3EQC37iCm/wyddb+6ezGmvKGXRJbutW3jVwcZVdg8Sxutqgshgy6Q==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 1,
+ "comment" : "Signature malleability",
+ "flags" : [
+ "SignatureMalleabilityBitcoin"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3046022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365022100900e75ad233fcc908509dbff5922647db37c21f4afd3203ae8dc4ae7794b0f87",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 2,
+ "comment" : "valid",
+ "flags" : [
+ "ValidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 3,
+ "comment" : "length of sequence [r, s] uses long form encoding",
+ "flags" : [
+ "BerEncodedSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "308145022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 4,
+ "comment" : "length of sequence [r, s] contains a leading 0",
+ "flags" : [
+ "BerEncodedSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30820045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 5,
+ "comment" : "length of sequence [r, s] uses 70 instead of 69",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3046022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 6,
+ "comment" : "length of sequence [r, s] uses 68 instead of 69",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3044022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 7,
+ "comment" : "uint32 overflow in length of sequence [r, s]",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30850100000045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 8,
+ "comment" : "uint64 overflow in length of sequence [r, s]",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3089010000000000000045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 9,
+ "comment" : "length of sequence [r, s] = 2**31 - 1",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30847fffffff022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 10,
+ "comment" : "length of sequence [r, s] = 2**31",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "308480000000022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 11,
+ "comment" : "length of sequence [r, s] = 2**32 - 1",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3084ffffffff022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 12,
+ "comment" : "length of sequence [r, s] = 2**40 - 1",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3085ffffffffff022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 13,
+ "comment" : "length of sequence [r, s] = 2**64 - 1",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3088ffffffffffffffff022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 14,
+ "comment" : "incorrect length of sequence [r, s]",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30ff022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 15,
+ "comment" : "replaced sequence [r, s] by an indefinite length tag without termination",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3080022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 16,
+ "comment" : "removing sequence [r, s]",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 17,
+ "comment" : "lonely sequence tag",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 18,
+ "comment" : "appending 0's to sequence [r, s]",
+ "flags" : [
+ "ModifiedSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3047022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0000",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 19,
+ "comment" : "prepending 0's to sequence [r, s]",
+ "flags" : [
+ "ModifiedSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30470000022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 20,
+ "comment" : "appending unused 0's to sequence [r, s]",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0000",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 21,
+ "comment" : "appending null value to sequence [r, s]",
+ "flags" : [
+ "ModifiedSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3047022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0500",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 22,
+ "comment" : "prepending garbage to sequence [r, s]",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304a4981773045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 23,
+ "comment" : "prepending garbage to sequence [r, s]",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304925003045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 24,
+ "comment" : "appending garbage to sequence [r, s]",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30473045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0004deadbeef",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 25,
+ "comment" : "including undefined tags",
+ "flags" : [
+ "ModifiedSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304daa00bb00cd003045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 26,
+ "comment" : "including undefined tags",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304d2229aa00bb00cd00022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 27,
+ "comment" : "including undefined tags",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304d022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323652228aa00bb00cd0002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 28,
+ "comment" : "truncated length of sequence [r, s]",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3081",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 29,
+ "comment" : "including undefined tags to sequence [r, s]",
+ "flags" : [
+ "ModifiedSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304baa02aabb3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 30,
+ "comment" : "using composition with indefinite length for sequence [r, s]",
+ "flags" : [
+ "ModifiedSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30803045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0000",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 31,
+ "comment" : "using composition with wrong tag for sequence [r, s]",
+ "flags" : [
+ "ModifiedSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30803145022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0000",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 32,
+ "comment" : "Replacing sequence [r, s] with NULL",
+ "flags" : [
+ "ModifiedSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "0500",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 33,
+ "comment" : "changing tag value of sequence [r, s]",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "2e45022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 34,
+ "comment" : "changing tag value of sequence [r, s]",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "2f45022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 35,
+ "comment" : "changing tag value of sequence [r, s]",
+ "flags" : [
+ "ModifiedSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3145022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 36,
+ "comment" : "changing tag value of sequence [r, s]",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3245022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 37,
+ "comment" : "changing tag value of sequence [r, s]",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "ff45022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 38,
+ "comment" : "dropping value of sequence [r, s]",
+ "flags" : [
+ "ModifiedSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3000",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 39,
+ "comment" : "using composition for sequence [r, s]",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304930010230442100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 40,
+ "comment" : "truncated sequence [r, s]",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3044022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 41,
+ "comment" : "truncated sequence [r, s]",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30442100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 42,
+ "comment" : "sequence [r, s] of size 4166 to check for overflows",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30821046022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 43,
+ "comment" : "indefinite length",
+ "flags" : [
+ "BerEncodedSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3080022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0000",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 44,
+ "comment" : "indefinite length with truncated delimiter",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3080022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba00",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 45,
+ "comment" : "indefinite length with additional element",
+ "flags" : [
+ "ModifiedSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3080022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba05000000",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 46,
+ "comment" : "indefinite length with truncated element",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3080022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba060811220000",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 47,
+ "comment" : "indefinite length with garbage",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3080022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0000fe02beef",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 48,
+ "comment" : "indefinite length with nonempty EOC",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3080022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0002beef",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 49,
+ "comment" : "prepend empty sequence",
+ "flags" : [
+ "ModifiedSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30473000022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 50,
+ "comment" : "append empty sequence",
+ "flags" : [
+ "ModifiedSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3047022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba3000",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 51,
+ "comment" : "append zero",
+ "flags" : [
+ "ModifiedSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3048022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba020100",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 52,
+ "comment" : "append garbage with high tag number",
+ "flags" : [
+ "ModifiedSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3048022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31babf7f00",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 53,
+ "comment" : "append null with explicit tag",
+ "flags" : [
+ "ModifiedSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3049022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31baa0020500",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 54,
+ "comment" : "append null with implicit tag",
+ "flags" : [
+ "ModifiedSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3047022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31baa000",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 55,
+ "comment" : "sequence of sequence",
+ "flags" : [
+ "ModifiedSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30473045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 56,
+ "comment" : "truncated sequence: removed last 1 elements",
+ "flags" : [
+ "ModifiedSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3023022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 57,
+ "comment" : "repeating element in sequence",
+ "flags" : [
+ "ModifiedSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3067022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba02206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 58,
+ "comment" : "flipped bit 0 in r",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304300813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236402206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 59,
+ "comment" : "flipped bit 32 in r",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304300813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccac983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 60,
+ "comment" : "flipped bit 48 in r",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304300813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5133ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 61,
+ "comment" : "flipped bit 64 in r",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304300813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc08b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 62,
+ "comment" : "length of r uses long form encoding",
+ "flags" : [
+ "BerEncodedSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304602812100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 63,
+ "comment" : "length of r contains a leading 0",
+ "flags" : [
+ "BerEncodedSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30470282002100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 64,
+ "comment" : "length of r uses 34 instead of 33",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3045022200813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 65,
+ "comment" : "length of r uses 32 instead of 33",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3045022000813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 66,
+ "comment" : "uint32 overflow in length of r",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304a0285010000002100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 67,
+ "comment" : "uint64 overflow in length of r",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304e028901000000000000002100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 68,
+ "comment" : "length of r = 2**31 - 1",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304902847fffffff00813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 69,
+ "comment" : "length of r = 2**31",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304902848000000000813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 70,
+ "comment" : "length of r = 2**32 - 1",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30490284ffffffff00813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 71,
+ "comment" : "length of r = 2**40 - 1",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304a0285ffffffffff00813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 72,
+ "comment" : "length of r = 2**64 - 1",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304d0288ffffffffffffffff00813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 73,
+ "comment" : "incorrect length of r",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304502ff00813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 74,
+ "comment" : "replaced r by an indefinite length tag without termination",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3045028000813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 75,
+ "comment" : "removing r",
+ "flags" : [
+ "ModifiedSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "302202206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 76,
+ "comment" : "lonely integer tag",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30230202206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 77,
+ "comment" : "lonely integer tag",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3024022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 78,
+ "comment" : "appending 0's to r",
+ "flags" : [
+ "ModifiedSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3047022300813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365000002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 79,
+ "comment" : "prepending 0's to r",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30470223000000813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 80,
+ "comment" : "appending unused 0's to r",
+ "flags" : [
+ "ModifiedSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3047022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365000002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 81,
+ "comment" : "appending null value to r",
+ "flags" : [
+ "ModifiedSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3047022300813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365050002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 82,
+ "comment" : "prepending garbage to r",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304a2226498177022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 83,
+ "comment" : "prepending garbage to r",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304922252500022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 84,
+ "comment" : "appending garbage to r",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304d2223022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323650004deadbeef02206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 85,
+ "comment" : "truncated length of r",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3024028102206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 86,
+ "comment" : "including undefined tags to r",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304b2227aa02aabb022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 87,
+ "comment" : "using composition with indefinite length for r",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30492280022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365000002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 88,
+ "comment" : "using composition with wrong tag for r",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30492280032100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365000002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 89,
+ "comment" : "Replacing r with NULL",
+ "flags" : [
+ "ModifiedSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3024050002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 90,
+ "comment" : "changing tag value of r",
+ "flags" : [
+ "ModifiedSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3045002100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 91,
+ "comment" : "changing tag value of r",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3045012100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 92,
+ "comment" : "changing tag value of r",
+ "flags" : [
+ "ModifiedSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3045032100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 93,
+ "comment" : "changing tag value of r",
+ "flags" : [
+ "ModifiedSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3045042100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 94,
+ "comment" : "changing tag value of r",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3045ff2100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 95,
+ "comment" : "dropping value of r",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3024020002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 96,
+ "comment" : "using composition for r",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304922250201000220813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 97,
+ "comment" : "modifying first byte of r",
+ "flags" : [
+ "ModifiedSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3045022102813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 98,
+ "comment" : "modifying last byte of r",
+ "flags" : [
+ "ModifiedSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323e502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 99,
+ "comment" : "truncated r",
+ "flags" : [
+ "ModifiedSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3044022000813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832302206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 100,
+ "comment" : "truncated r",
+ "flags" : [
+ "ModifiedSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30440220813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 101,
+ "comment" : "r of size 4130 to check for overflows",
+ "flags" : [
+ "ModifiedSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "308210480282102200813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 102,
+ "comment" : "leading ff in r",
+ "flags" : [
+ "ModifiedSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30460222ff00813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 103,
+ "comment" : "replaced r by infinity",
+ "flags" : [
+ "ModifiedSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "302509018002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 104,
+ "comment" : "replacing r with zero",
+ "flags" : [
+ "ModifiedSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "302502010002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 105,
+ "comment" : "flipped bit 0 in s",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3043022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323656ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31bb",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 106,
+ "comment" : "flipped bit 32 in s",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3043022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323656ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a456eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 107,
+ "comment" : "flipped bit 48 in s",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3043022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323656ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f713a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 108,
+ "comment" : "flipped bit 64 in s",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3043022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323656ff18a52dcc0336f7af62400a6dd9b810732baf1ff758001d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 109,
+ "comment" : "length of s uses long form encoding",
+ "flags" : [
+ "BerEncodedSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3046022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323650281206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 110,
+ "comment" : "length of s contains a leading 0",
+ "flags" : [
+ "BerEncodedSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3047022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365028200206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 111,
+ "comment" : "length of s uses 33 instead of 32",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502216ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 112,
+ "comment" : "length of s uses 31 instead of 32",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365021f6ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 113,
+ "comment" : "uint32 overflow in length of s",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304a022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365028501000000206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 114,
+ "comment" : "uint64 overflow in length of s",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304e022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502890100000000000000206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 115,
+ "comment" : "length of s = 2**31 - 1",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3049022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502847fffffff6ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 116,
+ "comment" : "length of s = 2**31",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3049022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323650284800000006ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 117,
+ "comment" : "length of s = 2**32 - 1",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3049022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323650284ffffffff6ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 118,
+ "comment" : "length of s = 2**40 - 1",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304a022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323650285ffffffffff6ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 119,
+ "comment" : "length of s = 2**64 - 1",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304d022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323650288ffffffffffffffff6ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 120,
+ "comment" : "incorrect length of s",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502ff6ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 121,
+ "comment" : "replaced s by an indefinite length tag without termination",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502806ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 122,
+ "comment" : "appending 0's to s",
+ "flags" : [
+ "ModifiedSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3047022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502226ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0000",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 123,
+ "comment" : "prepending 0's to s",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3047022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365022200006ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 124,
+ "comment" : "appending null value to s",
+ "flags" : [
+ "ModifiedSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3047022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502226ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0500",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 125,
+ "comment" : "prepending garbage to s",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304a022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365222549817702206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 126,
+ "comment" : "prepending garbage to s",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3049022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323652224250002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 127,
+ "comment" : "appending garbage to s",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304d022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365222202206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0004deadbeef",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 128,
+ "comment" : "truncated length of s",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3025022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323650281",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 129,
+ "comment" : "including undefined tags to s",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304b022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323652226aa02aabb02206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 130,
+ "comment" : "using composition with indefinite length for s",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3049022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365228002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0000",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 131,
+ "comment" : "using composition with wrong tag for s",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3049022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365228003206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0000",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 132,
+ "comment" : "Replacing s with NULL",
+ "flags" : [
+ "ModifiedSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3025022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323650500",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 133,
+ "comment" : "changing tag value of s",
+ "flags" : [
+ "ModifiedSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236500206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 134,
+ "comment" : "changing tag value of s",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236501206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 135,
+ "comment" : "changing tag value of s",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236503206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 136,
+ "comment" : "changing tag value of s",
+ "flags" : [
+ "ModifiedSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236504206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 137,
+ "comment" : "changing tag value of s",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365ff206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 138,
+ "comment" : "dropping value of s",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3025022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323650200",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 139,
+ "comment" : "using composition for s",
+ "flags" : [
+ "InvalidEncoding"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3049022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365222402016f021ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 140,
+ "comment" : "modifying first byte of s",
+ "flags" : [
+ "ModifiedSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206df18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 141,
+ "comment" : "modifying last byte of s",
+ "flags" : [
+ "ModifiedSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb313a",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 142,
+ "comment" : "truncated s",
+ "flags" : [
+ "ModifiedSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3044022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365021f6ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 143,
+ "comment" : "truncated s",
+ "flags" : [
+ "ModifiedSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3044022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365021ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 144,
+ "comment" : "s of size 4129 to check for overflows",
+ "flags" : [
+ "ModifiedSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30821048022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365028210216ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 145,
+ "comment" : "leading ff in s",
+ "flags" : [
+ "ModifiedSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3046022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323650221ff6ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 146,
+ "comment" : "replaced s by infinity",
+ "flags" : [
+ "ModifiedSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3026022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365090180",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 147,
+ "comment" : "replacing s with zero",
+ "flags" : [
+ "ModifiedSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3026022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365020100",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 148,
+ "comment" : "replaced r by r + n",
+ "flags" : [
+ "RangeCheck"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3045022101813ef79ccefa9a56f7ba805f0e478583b90deabca4b05c4574e49b5899b964a602206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 149,
+ "comment" : "replaced r by r - n",
+ "flags" : [
+ "RangeCheck"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30440220813ef79ccefa9a56f7ba805f0e47858643b030ef461f1bcdf53fde3ef94ce22402206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 150,
+ "comment" : "replaced r by r + 256 * n",
+ "flags" : [
+ "RangeCheck"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304602220100813ef79ccefa9a56f7ba805f0e47843fad3bf4853e07f7c98770c99bffc4646502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 151,
+ "comment" : "replaced r by -r",
+ "flags" : [
+ "ModifiedInteger"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30450221ff7ec10863310565a908457fa0f1b87a7b01a0f22a0a9843f64aedc334367cdc9b02206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 152,
+ "comment" : "replaced r by n - r",
+ "flags" : [
+ "ModifiedInteger"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304402207ec10863310565a908457fa0f1b87a79bc4fcf10b9e0e4320ac021c106b31ddc02206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 153,
+ "comment" : "replaced r by -n - r",
+ "flags" : [
+ "ModifiedInteger"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30450221fe7ec10863310565a908457fa0f1b87a7c46f215435b4fa3ba8b1b64a766469b5a02206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 154,
+ "comment" : "replaced r by r + 2**256",
+ "flags" : [
+ "IntegerOverflow"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3045022101813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 155,
+ "comment" : "replaced r by r + 2**320",
+ "flags" : [
+ "IntegerOverflow"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304d0229010000000000000000813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 156,
+ "comment" : "replaced s by s + n",
+ "flags" : [
+ "RangeCheck"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30450221016ff18a52dcc0336f7af62400a6dd9b7fc1e197d8aebe203c96c87232272172fb02206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 157,
+ "comment" : "replaced s by s - n",
+ "flags" : [
+ "RangeCheck"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30450221ff6ff18a52dcc0336f7af62400a6dd9b824c83de0b502cdfc51723b51886b4f07902206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 158,
+ "comment" : "replaced s by s + 256 * n",
+ "flags" : [
+ "RangeCheck"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3046022201006ff18a52dcc0336f7af62400a6dd9a3bb60fa1a14815bbc0a954a0758d2c72ba02206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 159,
+ "comment" : "replaced s by -s",
+ "flags" : [
+ "ModifiedInteger"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30440220900e75ad233fcc908509dbff5922647ef8cd450e008a7fff2909ec5aa914ce4602206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 160,
+ "comment" : "replaced s by -n - s",
+ "flags" : [
+ "ModifiedInteger"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30450221fe900e75ad233fcc908509dbff592264803e1e68275141dfc369378dcdd8de8d0502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 161,
+ "comment" : "replaced s by s + 2**256",
+ "flags" : [
+ "IntegerOverflow"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30450221016ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba02206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 162,
+ "comment" : "replaced s by s - 2**256",
+ "flags" : [
+ "IntegerOverflow"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30450221ff6ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba02206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 163,
+ "comment" : "replaced s by s + 2**320",
+ "flags" : [
+ "IntegerOverflow"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304d02290100000000000000006ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba02206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 164,
+ "comment" : "Signature with special case values r=0 and s=0",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3006020100020100",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 165,
+ "comment" : "Signature with special case values r=0 and s=1",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3006020100020101",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 166,
+ "comment" : "Signature with special case values r=0 and s=-1",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30060201000201ff",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 167,
+ "comment" : "Signature with special case values r=0 and s=n",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3026020100022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 168,
+ "comment" : "Signature with special case values r=0 and s=n - 1",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3026020100022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 169,
+ "comment" : "Signature with special case values r=0 and s=n + 1",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3026020100022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 170,
+ "comment" : "Signature with special case values r=0 and s=p",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3026020100022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 171,
+ "comment" : "Signature with special case values r=0 and s=p + 1",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3026020100022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 172,
+ "comment" : "Signature with special case values r=1 and s=0",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3006020101020100",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 173,
+ "comment" : "Signature with special case values r=1 and s=1",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3006020101020101",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 174,
+ "comment" : "Signature with special case values r=1 and s=-1",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30060201010201ff",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 175,
+ "comment" : "Signature with special case values r=1 and s=n",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3026020101022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 176,
+ "comment" : "Signature with special case values r=1 and s=n - 1",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3026020101022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 177,
+ "comment" : "Signature with special case values r=1 and s=n + 1",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3026020101022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 178,
+ "comment" : "Signature with special case values r=1 and s=p",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3026020101022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 179,
+ "comment" : "Signature with special case values r=1 and s=p + 1",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3026020101022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 180,
+ "comment" : "Signature with special case values r=-1 and s=0",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30060201ff020100",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 181,
+ "comment" : "Signature with special case values r=-1 and s=1",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30060201ff020101",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 182,
+ "comment" : "Signature with special case values r=-1 and s=-1",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30060201ff0201ff",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 183,
+ "comment" : "Signature with special case values r=-1 and s=n",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30260201ff022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 184,
+ "comment" : "Signature with special case values r=-1 and s=n - 1",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30260201ff022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 185,
+ "comment" : "Signature with special case values r=-1 and s=n + 1",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30260201ff022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 186,
+ "comment" : "Signature with special case values r=-1 and s=p",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30260201ff022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 187,
+ "comment" : "Signature with special case values r=-1 and s=p + 1",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30260201ff022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 188,
+ "comment" : "Signature with special case values r=n and s=0",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141020100",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 189,
+ "comment" : "Signature with special case values r=n and s=1",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141020101",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 190,
+ "comment" : "Signature with special case values r=n and s=-1",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd03641410201ff",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 191,
+ "comment" : "Signature with special case values r=n and s=n",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 192,
+ "comment" : "Signature with special case values r=n and s=n - 1",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 193,
+ "comment" : "Signature with special case values r=n and s=n + 1",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 194,
+ "comment" : "Signature with special case values r=n and s=p",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 195,
+ "comment" : "Signature with special case values r=n and s=p + 1",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 196,
+ "comment" : "Signature with special case values r=n - 1 and s=0",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140020100",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 197,
+ "comment" : "Signature with special case values r=n - 1 and s=1",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140020101",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 198,
+ "comment" : "Signature with special case values r=n - 1 and s=-1",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd03641400201ff",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 199,
+ "comment" : "Signature with special case values r=n - 1 and s=n",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 200,
+ "comment" : "Signature with special case values r=n - 1 and s=n - 1",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 201,
+ "comment" : "Signature with special case values r=n - 1 and s=n + 1",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 202,
+ "comment" : "Signature with special case values r=n - 1 and s=p",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 203,
+ "comment" : "Signature with special case values r=n - 1 and s=p + 1",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 204,
+ "comment" : "Signature with special case values r=n + 1 and s=0",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142020100",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 205,
+ "comment" : "Signature with special case values r=n + 1 and s=1",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142020101",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 206,
+ "comment" : "Signature with special case values r=n + 1 and s=-1",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd03641420201ff",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 207,
+ "comment" : "Signature with special case values r=n + 1 and s=n",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 208,
+ "comment" : "Signature with special case values r=n + 1 and s=n - 1",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 209,
+ "comment" : "Signature with special case values r=n + 1 and s=n + 1",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 210,
+ "comment" : "Signature with special case values r=n + 1 and s=p",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 211,
+ "comment" : "Signature with special case values r=n + 1 and s=p + 1",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 212,
+ "comment" : "Signature with special case values r=p and s=0",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3026022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f020100",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 213,
+ "comment" : "Signature with special case values r=p and s=1",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3026022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f020101",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 214,
+ "comment" : "Signature with special case values r=p and s=-1",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3026022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f0201ff",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 215,
+ "comment" : "Signature with special case values r=p and s=n",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3046022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 216,
+ "comment" : "Signature with special case values r=p and s=n - 1",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3046022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 217,
+ "comment" : "Signature with special case values r=p and s=n + 1",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3046022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 218,
+ "comment" : "Signature with special case values r=p and s=p",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3046022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 219,
+ "comment" : "Signature with special case values r=p and s=p + 1",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3046022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 220,
+ "comment" : "Signature with special case values r=p + 1 and s=0",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3026022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30020100",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 221,
+ "comment" : "Signature with special case values r=p + 1 and s=1",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3026022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30020101",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 222,
+ "comment" : "Signature with special case values r=p + 1 and s=-1",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3026022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc300201ff",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 223,
+ "comment" : "Signature with special case values r=p + 1 and s=n",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3046022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 224,
+ "comment" : "Signature with special case values r=p + 1 and s=n - 1",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3046022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 225,
+ "comment" : "Signature with special case values r=p + 1 and s=n + 1",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3046022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 226,
+ "comment" : "Signature with special case values r=p + 1 and s=p",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3046022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 227,
+ "comment" : "Signature with special case values r=p + 1 and s=p + 1",
+ "flags" : [
+ "InvalidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3046022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 228,
+ "comment" : "Signature encoding contains incorrect types: r=0, s=0.25",
+ "flags" : [
+ "InvalidTypesInSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3008020100090380fe01",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 229,
+ "comment" : "Signature encoding contains incorrect types: r=0, s=nan",
+ "flags" : [
+ "InvalidTypesInSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3006020100090142",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 230,
+ "comment" : "Signature encoding contains incorrect types: r=0, s=True",
+ "flags" : [
+ "InvalidTypesInSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3006020100010101",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 231,
+ "comment" : "Signature encoding contains incorrect types: r=0, s=False",
+ "flags" : [
+ "InvalidTypesInSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3006020100010100",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 232,
+ "comment" : "Signature encoding contains incorrect types: r=0, s=Null",
+ "flags" : [
+ "InvalidTypesInSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30050201000500",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 233,
+ "comment" : "Signature encoding contains incorrect types: r=0, s=empyt UTF-8 string",
+ "flags" : [
+ "InvalidTypesInSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30050201000c00",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 234,
+ "comment" : "Signature encoding contains incorrect types: r=0, s=\"0\"",
+ "flags" : [
+ "InvalidTypesInSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30060201000c0130",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 235,
+ "comment" : "Signature encoding contains incorrect types: r=0, s=empty list",
+ "flags" : [
+ "InvalidTypesInSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30050201003000",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 236,
+ "comment" : "Signature encoding contains incorrect types: r=0, s=list containing 0",
+ "flags" : [
+ "InvalidTypesInSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30080201003003020100",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 237,
+ "comment" : "Signature encoding contains incorrect types: r=1, s=0.25",
+ "flags" : [
+ "InvalidTypesInSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3008020101090380fe01",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 238,
+ "comment" : "Signature encoding contains incorrect types: r=1, s=nan",
+ "flags" : [
+ "InvalidTypesInSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3006020101090142",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 239,
+ "comment" : "Signature encoding contains incorrect types: r=1, s=True",
+ "flags" : [
+ "InvalidTypesInSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3006020101010101",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 240,
+ "comment" : "Signature encoding contains incorrect types: r=1, s=False",
+ "flags" : [
+ "InvalidTypesInSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3006020101010100",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 241,
+ "comment" : "Signature encoding contains incorrect types: r=1, s=Null",
+ "flags" : [
+ "InvalidTypesInSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30050201010500",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 242,
+ "comment" : "Signature encoding contains incorrect types: r=1, s=empyt UTF-8 string",
+ "flags" : [
+ "InvalidTypesInSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30050201010c00",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 243,
+ "comment" : "Signature encoding contains incorrect types: r=1, s=\"0\"",
+ "flags" : [
+ "InvalidTypesInSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30060201010c0130",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 244,
+ "comment" : "Signature encoding contains incorrect types: r=1, s=empty list",
+ "flags" : [
+ "InvalidTypesInSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30050201013000",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 245,
+ "comment" : "Signature encoding contains incorrect types: r=1, s=list containing 0",
+ "flags" : [
+ "InvalidTypesInSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30080201013003020100",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 246,
+ "comment" : "Signature encoding contains incorrect types: r=-1, s=0.25",
+ "flags" : [
+ "InvalidTypesInSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30080201ff090380fe01",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 247,
+ "comment" : "Signature encoding contains incorrect types: r=-1, s=nan",
+ "flags" : [
+ "InvalidTypesInSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30060201ff090142",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 248,
+ "comment" : "Signature encoding contains incorrect types: r=-1, s=True",
+ "flags" : [
+ "InvalidTypesInSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30060201ff010101",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 249,
+ "comment" : "Signature encoding contains incorrect types: r=-1, s=False",
+ "flags" : [
+ "InvalidTypesInSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30060201ff010100",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 250,
+ "comment" : "Signature encoding contains incorrect types: r=-1, s=Null",
+ "flags" : [
+ "InvalidTypesInSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30050201ff0500",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 251,
+ "comment" : "Signature encoding contains incorrect types: r=-1, s=empyt UTF-8 string",
+ "flags" : [
+ "InvalidTypesInSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30050201ff0c00",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 252,
+ "comment" : "Signature encoding contains incorrect types: r=-1, s=\"0\"",
+ "flags" : [
+ "InvalidTypesInSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30060201ff0c0130",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 253,
+ "comment" : "Signature encoding contains incorrect types: r=-1, s=empty list",
+ "flags" : [
+ "InvalidTypesInSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30050201ff3000",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 254,
+ "comment" : "Signature encoding contains incorrect types: r=-1, s=list containing 0",
+ "flags" : [
+ "InvalidTypesInSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30080201ff3003020100",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 255,
+ "comment" : "Signature encoding contains incorrect types: r=n, s=0.25",
+ "flags" : [
+ "InvalidTypesInSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3028022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141090380fe01",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 256,
+ "comment" : "Signature encoding contains incorrect types: r=n, s=nan",
+ "flags" : [
+ "InvalidTypesInSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141090142",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 257,
+ "comment" : "Signature encoding contains incorrect types: r=n, s=True",
+ "flags" : [
+ "InvalidTypesInSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141010101",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 258,
+ "comment" : "Signature encoding contains incorrect types: r=n, s=False",
+ "flags" : [
+ "InvalidTypesInSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141010100",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 259,
+ "comment" : "Signature encoding contains incorrect types: r=n, s=Null",
+ "flags" : [
+ "InvalidTypesInSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3025022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd03641410500",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 260,
+ "comment" : "Signature encoding contains incorrect types: r=n, s=empyt UTF-8 string",
+ "flags" : [
+ "InvalidTypesInSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3025022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd03641410c00",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 261,
+ "comment" : "Signature encoding contains incorrect types: r=n, s=\"0\"",
+ "flags" : [
+ "InvalidTypesInSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd03641410c0130",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 262,
+ "comment" : "Signature encoding contains incorrect types: r=n, s=empty list",
+ "flags" : [
+ "InvalidTypesInSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3025022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd03641413000",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 263,
+ "comment" : "Signature encoding contains incorrect types: r=n, s=list containing 0",
+ "flags" : [
+ "InvalidTypesInSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3028022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd03641413003020100",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 264,
+ "comment" : "Signature encoding contains incorrect types: r=p, s=0.25",
+ "flags" : [
+ "InvalidTypesInSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3028022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f090380fe01",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 265,
+ "comment" : "Signature encoding contains incorrect types: r=p, s=nan",
+ "flags" : [
+ "InvalidTypesInSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3026022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f090142",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 266,
+ "comment" : "Signature encoding contains incorrect types: r=p, s=True",
+ "flags" : [
+ "InvalidTypesInSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3026022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f010101",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 267,
+ "comment" : "Signature encoding contains incorrect types: r=p, s=False",
+ "flags" : [
+ "InvalidTypesInSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3026022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f010100",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 268,
+ "comment" : "Signature encoding contains incorrect types: r=p, s=Null",
+ "flags" : [
+ "InvalidTypesInSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3025022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f0500",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 269,
+ "comment" : "Signature encoding contains incorrect types: r=p, s=empyt UTF-8 string",
+ "flags" : [
+ "InvalidTypesInSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3025022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f0c00",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 270,
+ "comment" : "Signature encoding contains incorrect types: r=p, s=\"0\"",
+ "flags" : [
+ "InvalidTypesInSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3026022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f0c0130",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 271,
+ "comment" : "Signature encoding contains incorrect types: r=p, s=empty list",
+ "flags" : [
+ "InvalidTypesInSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3025022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f3000",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 272,
+ "comment" : "Signature encoding contains incorrect types: r=p, s=list containing 0",
+ "flags" : [
+ "InvalidTypesInSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3028022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f3003020100",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 273,
+ "comment" : "Signature encoding contains incorrect types: r=0.25, s=0.25",
+ "flags" : [
+ "InvalidTypesInSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "300a090380fe01090380fe01",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 274,
+ "comment" : "Signature encoding contains incorrect types: r=nan, s=nan",
+ "flags" : [
+ "InvalidTypesInSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3006090142090142",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 275,
+ "comment" : "Signature encoding contains incorrect types: r=True, s=True",
+ "flags" : [
+ "InvalidTypesInSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3006010101010101",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 276,
+ "comment" : "Signature encoding contains incorrect types: r=False, s=False",
+ "flags" : [
+ "InvalidTypesInSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3006010100010100",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 277,
+ "comment" : "Signature encoding contains incorrect types: r=Null, s=Null",
+ "flags" : [
+ "InvalidTypesInSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "300405000500",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 278,
+ "comment" : "Signature encoding contains incorrect types: r=empyt UTF-8 string, s=empyt UTF-8 string",
+ "flags" : [
+ "InvalidTypesInSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30040c000c00",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 279,
+ "comment" : "Signature encoding contains incorrect types: r=\"0\", s=\"0\"",
+ "flags" : [
+ "InvalidTypesInSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30060c01300c0130",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 280,
+ "comment" : "Signature encoding contains incorrect types: r=empty list, s=empty list",
+ "flags" : [
+ "InvalidTypesInSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "300430003000",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 281,
+ "comment" : "Signature encoding contains incorrect types: r=list containing 0, s=list containing 0",
+ "flags" : [
+ "InvalidTypesInSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "300a30030201003003020100",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 282,
+ "comment" : "Signature encoding contains incorrect types: r=0.25, s=0",
+ "flags" : [
+ "InvalidTypesInSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3008090380fe01020100",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 283,
+ "comment" : "Signature encoding contains incorrect types: r=nan, s=0",
+ "flags" : [
+ "InvalidTypesInSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3006090142020100",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 284,
+ "comment" : "Signature encoding contains incorrect types: r=True, s=0",
+ "flags" : [
+ "InvalidTypesInSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3006010101020100",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 285,
+ "comment" : "Signature encoding contains incorrect types: r=False, s=0",
+ "flags" : [
+ "InvalidTypesInSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3006010100020100",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 286,
+ "comment" : "Signature encoding contains incorrect types: r=Null, s=0",
+ "flags" : [
+ "InvalidTypesInSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30050500020100",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 287,
+ "comment" : "Signature encoding contains incorrect types: r=empyt UTF-8 string, s=0",
+ "flags" : [
+ "InvalidTypesInSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30050c00020100",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 288,
+ "comment" : "Signature encoding contains incorrect types: r=\"0\", s=0",
+ "flags" : [
+ "InvalidTypesInSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30060c0130020100",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 289,
+ "comment" : "Signature encoding contains incorrect types: r=empty list, s=0",
+ "flags" : [
+ "InvalidTypesInSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30053000020100",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 290,
+ "comment" : "Signature encoding contains incorrect types: r=list containing 0, s=0",
+ "flags" : [
+ "InvalidTypesInSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30083003020100020100",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 291,
+ "comment" : "Edge case for Shamir multiplication",
+ "flags" : [
+ "EdgeCaseShamirMultiplication"
+ ],
+ "msg" : "3235353835",
+ "sig" : "3045022100dd1b7d09a7bd8218961034a39a87fecf5314f00c4d25eb58a07ac85e85eab516022035138c401ef8d3493d65c9002fe62b43aee568731b744548358996d9cc427e06",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 292,
+ "comment" : "special case hash",
+ "flags" : [
+ "SpecialCaseHash"
+ ],
+ "msg" : "343236343739373234",
+ "sig" : "304502210095c29267d972a043d955224546222bba343fc1d4db0fec262a33ac61305696ae02206edfe96713aed56f8a28a6653f57e0b829712e5eddc67f34682b24f0676b2640",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 293,
+ "comment" : "special case hash",
+ "flags" : [
+ "SpecialCaseHash"
+ ],
+ "msg" : "37313338363834383931",
+ "sig" : "3044022028f94a894e92024699e345fe66971e3edcd050023386135ab3939d550898fb25022032963e5bd41fa5911ed8f37deb86dae0a762bb6121c894615083c5d95ea01db3",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 294,
+ "comment" : "special case hash",
+ "flags" : [
+ "SpecialCaseHash"
+ ],
+ "msg" : "3130333539333331363638",
+ "sig" : "3045022100be26b18f9549f89f411a9b52536b15aa270b84548d0e859a1952a27af1a77ac6022070c1d4fa9cd03cc8eaa8d506edb97eed7b8358b453c88aefbb880a3f0e8d472f",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 295,
+ "comment" : "special case hash",
+ "flags" : [
+ "SpecialCaseHash"
+ ],
+ "msg" : "33393439343031323135",
+ "sig" : "3045022100b1a4b1478e65cc3eafdf225d1298b43f2da19e4bcff7eacc0a2e98cd4b74b1140220179aa31e304cc142cf5073171751b28f3f5e0fa88c994e7c55f1bc07b8d56c16",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 296,
+ "comment" : "special case hash",
+ "flags" : [
+ "SpecialCaseHash"
+ ],
+ "msg" : "31333434323933303739",
+ "sig" : "30440220325332021261f1bd18f2712aa1e2252da23796da8a4b1ff6ea18cafec7e171f2022040b4f5e287ee61fc3c804186982360891eaa35c75f05a43ecd48b35d984a6648",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 297,
+ "comment" : "special case hash",
+ "flags" : [
+ "SpecialCaseHash"
+ ],
+ "msg" : "33373036323131373132",
+ "sig" : "3045022100a23ad18d8fc66d81af0903890cbd453a554cb04cdc1a8ca7f7f78e5367ed88a0022023e3eb2ce1c04ea748c389bd97374aa9413b9268851c04dcd9f88e78813fee56",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 298,
+ "comment" : "special case hash",
+ "flags" : [
+ "SpecialCaseHash"
+ ],
+ "msg" : "333433363838373132",
+ "sig" : "304402202bdea41cda63a2d14bf47353bd20880a690901de7cd6e3cc6d8ed5ba0cdb109102203cea66bccfc9f9bf8c7ca4e1c1457cc9145e13e936d90b3d9c7786b8b26cf4c7",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 299,
+ "comment" : "special case hash",
+ "flags" : [
+ "SpecialCaseHash"
+ ],
+ "msg" : "31333531353330333730",
+ "sig" : "3045022100d7cd76ec01c1b1079eba9e2aa2a397243c4758c98a1ba0b7404a340b9b00ced602203575001e19d922e6de8b3d6c84ea43b5c3338106cf29990134e7669a826f78e6",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 300,
+ "comment" : "special case hash",
+ "flags" : [
+ "SpecialCaseHash"
+ ],
+ "msg" : "36353533323033313236",
+ "sig" : "3045022100a872c744d936db21a10c361dd5c9063355f84902219652f6fc56dc95a7139d960220400df7575d9756210e9ccc77162c6b593c7746cfb48ac263c42750b421ef4bb9",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 301,
+ "comment" : "special case hash",
+ "flags" : [
+ "SpecialCaseHash"
+ ],
+ "msg" : "31353634333436363033",
+ "sig" : "30450221009fa9afe07752da10b36d3afcd0fe44bfc40244d75203599cf8f5047fa3453854022050e0a7c013bfbf51819736972d44b4b56bc2a2b2c180df6ec672df171410d77a",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 302,
+ "comment" : "special case hash",
+ "flags" : [
+ "SpecialCaseHash"
+ ],
+ "msg" : "34343239353339313137",
+ "sig" : "3045022100885640384d0d910efb177b46be6c3dc5cac81f0b88c3190bb6b5f99c2641f2050220738ed9bff116306d9caa0f8fc608be243e0b567779d8dab03e8e19d553f1dc8e",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 303,
+ "comment" : "special case hash",
+ "flags" : [
+ "SpecialCaseHash"
+ ],
+ "msg" : "3130393533323631333531",
+ "sig" : "304402202d051f91c5a9d440c5676985710483bc4f1a6c611b10c95a2ff0363d90c2a45802206ddf94e6fba5be586833d0c53cf216ad3948f37953c26c1cf4968e9a9e8243dc",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 304,
+ "comment" : "special case hash",
+ "flags" : [
+ "SpecialCaseHash"
+ ],
+ "msg" : "35393837333530303431",
+ "sig" : "3045022100f3ac2523967482f53d508522712d583f4379cd824101ff635ea0935117baa54f022027f10812227397e02cea96fb0e680761636dab2b080d1fc5d11685cbe8500cfe",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 305,
+ "comment" : "special case hash",
+ "flags" : [
+ "SpecialCaseHash"
+ ],
+ "msg" : "33343633303036383738",
+ "sig" : "304502210096447cf68c3ab7266ed7447de3ac52fed7cc08cbdfea391c18a9b8ab370bc91302200f5e7874d3ac0e918f01c885a1639177c923f8660d1ceba1ca1f301bc675cdbc",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 306,
+ "comment" : "special case hash",
+ "flags" : [
+ "SpecialCaseHash"
+ ],
+ "msg" : "39383137333230323837",
+ "sig" : "30440220530a0832b691da0b5619a0b11de6877f3c0971baaa68ed122758c29caaf46b7202206c89e44f5eb33060ea4b46318c39138eaedec72de42ba576579a6a4690e339f3",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 307,
+ "comment" : "special case hash",
+ "flags" : [
+ "SpecialCaseHash"
+ ],
+ "msg" : "33323232303431303436",
+ "sig" : "30450221009c54c25500bde0b92d72d6ec483dc2482f3654294ca74de796b681255ed58a770220677453c6b56f527631c9f67b3f3eb621fd88582b4aff156d2f1567d6211a2a33",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 308,
+ "comment" : "special case hash",
+ "flags" : [
+ "SpecialCaseHash"
+ ],
+ "msg" : "36363636333037313034",
+ "sig" : "3045022100e7909d41439e2f6af29136c7348ca2641a2b070d5b64f91ea9da7070c7a2618b022042d782f132fa1d36c2c88ba27c3d678d80184a5d1eccac7501f0b47e3d205008",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 309,
+ "comment" : "special case hash",
+ "flags" : [
+ "SpecialCaseHash"
+ ],
+ "msg" : "31303335393531383938",
+ "sig" : "304402205924873209593135a4c3da7bb381227f8a4b6aa9f34fe5bb7f8fbc131a039ffe02201f1bb11b441c8feaa40f44213d9a405ed792d59fb49d5bcdd9a4285ae5693022",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 310,
+ "comment" : "special case hash",
+ "flags" : [
+ "SpecialCaseHash"
+ ],
+ "msg" : "31383436353937313935",
+ "sig" : "3045022100eeb692c9b262969b231c38b5a7f60649e0c875cd64df88f33aa571fa3d29ab0e0220218b3a1eb06379c2c18cf51b06430786d1c64cd2d24c9b232b23e5bac7989acd",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 311,
+ "comment" : "special case hash",
+ "flags" : [
+ "SpecialCaseHash"
+ ],
+ "msg" : "33313336303436313839",
+ "sig" : "3045022100a40034177f36091c2b653684a0e3eb5d4bff18e4d09f664c2800e7cafda1daf802203a3ec29853704e52031c58927a800a968353adc3d973beba9172cbbeab4dd149",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 312,
+ "comment" : "special case hash",
+ "flags" : [
+ "SpecialCaseHash"
+ ],
+ "msg" : "32363633373834323534",
+ "sig" : "3045022100b5d795cc75cea5c434fa4185180cd6bd21223f3d5a86da6670d71d95680dadbf022054e4d8810a001ecbb9f7ca1c2ebfdb9d009e9031a431aca3c20ab4e0d1374ec1",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 313,
+ "comment" : "special case hash",
+ "flags" : [
+ "SpecialCaseHash"
+ ],
+ "msg" : "31363532313030353234",
+ "sig" : "3044022007dc2478d43c1232a4595608c64426c35510051a631ae6a5a6eb1161e57e42e102204a59ea0fdb72d12165cea3bf1ca86ba97517bd188db3dbd21a5a157850021984",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 314,
+ "comment" : "special case hash",
+ "flags" : [
+ "SpecialCaseHash"
+ ],
+ "msg" : "35373438303831363936",
+ "sig" : "3045022100ddd20c4a05596ca868b558839fce9f6511ddd83d1ccb53f82e5269d559a0155202205b91734729d93093ff22123c4a25819d7feb66a250663fc780cb66fc7b6e6d17",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 315,
+ "comment" : "special case hash",
+ "flags" : [
+ "SpecialCaseHash"
+ ],
+ "msg" : "36333433393133343638",
+ "sig" : "30450221009cde6e0ede0a003f02fda0a01b59facfe5dec063318f279ce2de7a9b1062f7b702202886a5b8c679bdf8224c66f908fd6205492cb70b0068d46ae4f33a4149b12a52",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 316,
+ "comment" : "special case hash",
+ "flags" : [
+ "SpecialCaseHash"
+ ],
+ "msg" : "31353431313033353938",
+ "sig" : "3045022100c5771016d0dd6357143c89f684cd740423502554c0c59aa8c99584f1ff38f609022054b405f4477546686e464c5463b4fd4190572e58d0f7e7357f6e61947d20715c",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 317,
+ "comment" : "special case hash",
+ "flags" : [
+ "SpecialCaseHash"
+ ],
+ "msg" : "3130343738353830313238",
+ "sig" : "3045022100a24ebc0ec224bd67ae397cbe6fa37b3125adbd34891abe2d7c7356921916dfe6022034f6eb6374731bbbafc4924fb8b0bdcdda49456d724cdae6178d87014cb53d8c",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 318,
+ "comment" : "special case hash",
+ "flags" : [
+ "SpecialCaseHash"
+ ],
+ "msg" : "3130353336323835353638",
+ "sig" : "304402202557d64a7aee2e0931c012e4fea1cd3a2c334edae68cdeb7158caf21b68e5a2402207f06cdbb6a90023a973882ed97b080fe6b05af3ec93db6f1a4399a69edf7670d",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 319,
+ "comment" : "special case hash",
+ "flags" : [
+ "SpecialCaseHash"
+ ],
+ "msg" : "393533393034313035",
+ "sig" : "3045022100c4f2eccbb6a24350c8466450b9d61b207ee359e037b3dcedb42a3f2e6dd6aeb502203263c6b59a2f55cdd1c6e14894d5e5963b28bc3e2469ac9ba1197991ca7ff9c7",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 320,
+ "comment" : "special case hash",
+ "flags" : [
+ "SpecialCaseHash"
+ ],
+ "msg" : "393738383438303339",
+ "sig" : "3045022100eff04781c9cbcd162d0a25a6e2ebcca43506c523385cb515d49ea38a1b12fcad022015acd73194c91a95478534f23015b672ebed213e45424dd2c8e26ac8b3eb34a5",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 321,
+ "comment" : "special case hash",
+ "flags" : [
+ "SpecialCaseHash"
+ ],
+ "msg" : "33363130363732343432",
+ "sig" : "3045022100f58b4e3110a64bf1b5db97639ee0e5a9c8dfa49dc59b679891f520fdf0584c8702202cd8fe51888aee9db3e075440fd4db73b5c732fb87b510e97093d66415f62af7",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 322,
+ "comment" : "special case hash",
+ "flags" : [
+ "SpecialCaseHash"
+ ],
+ "msg" : "31303534323430373035",
+ "sig" : "3045022100f8abecaa4f0c502de4bf5903d48417f786bf92e8ad72fec0bd7fcb7800c0bbe302204c7f9e231076a30b7ae36b0cebe69ccef1cd194f7cce93a5588fd6814f437c0e",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 323,
+ "comment" : "special case hash",
+ "flags" : [
+ "SpecialCaseHash"
+ ],
+ "msg" : "35313734343438313937",
+ "sig" : "304402205d5b38bd37ad498b2227a633268a8cca879a5c7c94a4e416bd0a614d09e606d2022012b8d664ea9991062ecbb834e58400e25c46007af84f6007d7f1685443269afe",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 324,
+ "comment" : "special case hash",
+ "flags" : [
+ "SpecialCaseHash"
+ ],
+ "msg" : "31393637353631323531",
+ "sig" : "304402200c1cd9fe4034f086a2b52d65b9d3834d72aebe7f33dfe8f976da82648177d8e3022013105782e3d0cfe85c2778dec1a848b27ac0ae071aa6da341a9553a946b41e59",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 325,
+ "comment" : "special case hash",
+ "flags" : [
+ "SpecialCaseHash"
+ ],
+ "msg" : "33343437323533333433",
+ "sig" : "3045022100ae7935fb96ff246b7b5d5662870d1ba587b03d6e1360baf47988b5c02ccc1a5b02205f00c323272083782d4a59f2dfd65e49de0693627016900ef7e61428056664b3",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 326,
+ "comment" : "special case hash",
+ "flags" : [
+ "SpecialCaseHash"
+ ],
+ "msg" : "333638323634333138",
+ "sig" : "3044022000a134b5c6ccbcefd4c882b945baeb4933444172795fa6796aae1490675470980220566e46105d24d890151e3eea3ebf88f5b92b3f5ec93a217765a6dcbd94f2c55b",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 327,
+ "comment" : "special case hash",
+ "flags" : [
+ "SpecialCaseHash"
+ ],
+ "msg" : "33323631313938363038",
+ "sig" : "304402202e4721363ad3992c139e5a1c26395d2c2d777824aa24fde075e0d7381171309d0220740f7c494418e1300dd4512f782a58800bff6a7abdfdd20fbbd4f05515ca1a4f",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 328,
+ "comment" : "special case hash",
+ "flags" : [
+ "SpecialCaseHash"
+ ],
+ "msg" : "39363738373831303934",
+ "sig" : "304402206852e9d3cd9fe373c2d504877967d365ab1456707b6817a042864694e1960ccf0220064b27ea142b30887b84c86adccb2fa39a6911ad21fc7e819f593be52bc4f3bd",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 329,
+ "comment" : "special case hash",
+ "flags" : [
+ "SpecialCaseHash"
+ ],
+ "msg" : "34393538383233383233",
+ "sig" : "30440220188a8c5648dc79eace158cf886c62b5468f05fd95f03a7635c5b4c31f09af4c5022036361a0b571a00c6cd5e686ccbfcfa703c4f97e48938346d0c103fdc76dc5867",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 330,
+ "comment" : "special case hash",
+ "flags" : [
+ "SpecialCaseHash"
+ ],
+ "msg" : "383234363337383337",
+ "sig" : "3045022100a74f1fb9a8263f62fc4416a5b7d584f4206f3996bb91f6fc8e73b9e92bad0e1302206815032e8c7d76c3ab06a86f33249ce9940148cb36d1f417c2e992e801afa3fa",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 331,
+ "comment" : "special case hash",
+ "flags" : [
+ "SpecialCaseHash"
+ ],
+ "msg" : "3131303230383333373736",
+ "sig" : "3044022007244865b72ff37e62e3146f0dc14682badd7197799135f0b00ade7671742bfe02200d80c2238edb4e4a7a86a8c57ca9af1711f406f7f5da0299aa04e2932d960754",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 332,
+ "comment" : "special case hash",
+ "flags" : [
+ "SpecialCaseHash"
+ ],
+ "msg" : "313333383731363438",
+ "sig" : "3045022100da7fdd05b5badabd619d805c4ee7d9a84f84ddd5cf9c5bf4d4338140d689ef08022028f1cf4fa1c3c5862cfa149c0013cf5fe6cf5076cae000511063e7de25bb38e5",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 333,
+ "comment" : "special case hash",
+ "flags" : [
+ "SpecialCaseHash"
+ ],
+ "msg" : "333232313434313632",
+ "sig" : "3045022100d3027c656f6d4fdfd8ede22093e3c303b0133c340d615e7756f6253aea927238022009aef060c8e4cef972974011558df144fed25ca69ae8d0b2eaf1a8feefbec417",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 334,
+ "comment" : "special case hash",
+ "flags" : [
+ "SpecialCaseHash"
+ ],
+ "msg" : "3130363836363535353436",
+ "sig" : "304402200bf6c0188dc9571cd0e21eecac5fbb19d2434988e9cc10244593ef3a98099f6902204864a562661f9221ec88e3dd0bc2f6e27ac128c30cc1a80f79ec670a22b042ee",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 335,
+ "comment" : "special case hash",
+ "flags" : [
+ "SpecialCaseHash"
+ ],
+ "msg" : "3632313535323436",
+ "sig" : "3045022100ae459640d5d1179be47a47fa538e16d94ddea5585e7a244804a51742c686443a02206c8e30e530a634fae80b3ceb062978b39edbe19777e0a24553b68886181fd897",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 336,
+ "comment" : "special case hash",
+ "flags" : [
+ "SpecialCaseHash"
+ ],
+ "msg" : "37303330383138373734",
+ "sig" : "304402201cf3517ba3bf2ab8b9ead4ebb6e866cb88a1deacb6a785d3b63b483ca02ac4950220249a798b73606f55f5f1c70de67cb1a0cff95d7dc50b3a617df861bad3c6b1c9",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 337,
+ "comment" : "special case hash",
+ "flags" : [
+ "SpecialCaseHash"
+ ],
+ "msg" : "35393234353233373434",
+ "sig" : "3045022100e69b5238265ea35d77e4dd172288d8cea19810a10292617d5976519dc5757cb802204b03c5bc47e826bdb27328abd38d3056d77476b2130f3df6ec4891af08ba1e29",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 338,
+ "comment" : "special case hash",
+ "flags" : [
+ "SpecialCaseHash"
+ ],
+ "msg" : "31343935353836363231",
+ "sig" : "304402205f9d7d7c870d085fc1d49fff69e4a275812800d2cf8973e7325866cb40fa2b6f02206d1f5491d9f717a597a15fd540406486d76a44697b3f0d9d6dcef6669f8a0a56",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 339,
+ "comment" : "special case hash",
+ "flags" : [
+ "SpecialCaseHash"
+ ],
+ "msg" : "34303035333134343036",
+ "sig" : "304402200a7d5b1959f71df9f817146ee49bd5c89b431e7993e2fdecab6858957da685ae02200f8aad2d254690bdc13f34a4fec44a02fd745a422df05ccbb54635a8b86b9609",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 340,
+ "comment" : "special case hash",
+ "flags" : [
+ "SpecialCaseHash"
+ ],
+ "msg" : "33303936343537353132",
+ "sig" : "3044022079e88bf576b74bc07ca142395fda28f03d3d5e640b0b4ff0752c6d94cd553408022032cea05bd2d706c8f6036a507e2ab7766004f0904e2e5c5862749c0073245d6a",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 341,
+ "comment" : "special case hash",
+ "flags" : [
+ "SpecialCaseHash"
+ ],
+ "msg" : "32373834303235363230",
+ "sig" : "30450221009d54e037a00212b377bc8874798b8da080564bbdf7e07591b861285809d01488022018b4e557667a82bd95965f0706f81a29243fbdd86968a7ebeb43069db3b18c7f",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 342,
+ "comment" : "special case hash",
+ "flags" : [
+ "SpecialCaseHash"
+ ],
+ "msg" : "32363138373837343138",
+ "sig" : "304402202664f1ffa982fedbcc7cab1b8bc6e2cb420218d2a6077ad08e591ba9feab33bd022049f5c7cb515e83872a3d41b4cdb85f242ad9d61a5bfc01debfbb52c6c84ba728",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 343,
+ "comment" : "special case hash",
+ "flags" : [
+ "SpecialCaseHash"
+ ],
+ "msg" : "31363432363235323632",
+ "sig" : "304402205827518344844fd6a7de73cbb0a6befdea7b13d2dee4475317f0f18ffc81524b02204f5ccb4e0b488b5a5d760aacddb2d791970fe43da61eb30e2e90208a817e46db",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 344,
+ "comment" : "special case hash",
+ "flags" : [
+ "SpecialCaseHash"
+ ],
+ "msg" : "36383234313839343336",
+ "sig" : "304502210097ab19bd139cac319325869218b1bce111875d63fb12098a04b0cd59b6fdd3a30220431d9cea3a243847303cebda56476431d034339f31d785ee8852db4f040d4921",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 345,
+ "comment" : "special case hash",
+ "flags" : [
+ "SpecialCaseHash"
+ ],
+ "msg" : "343834323435343235",
+ "sig" : "3044022052c683144e44119ae2013749d4964ef67509278f6d38ba869adcfa69970e123d02203479910167408f45bda420a626ec9c4ec711c1274be092198b4187c018b562ca",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "0407310f90a9eae149a08402f54194a0f7b4ac427bf8d9bd6c7681071dc47dc36226a6d37ac46d61fd600c0bf1bff87689ed117dda6b0e59318ae010a197a26ca0",
+ "wx" : "07310f90a9eae149a08402f54194a0f7b4ac427bf8d9bd6c7681071dc47dc362",
+ "wy" : "26a6d37ac46d61fd600c0bf1bff87689ed117dda6b0e59318ae010a197a26ca0"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000407310f90a9eae149a08402f54194a0f7b4ac427bf8d9bd6c7681071dc47dc36226a6d37ac46d61fd600c0bf1bff87689ed117dda6b0e59318ae010a197a26ca0",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEBzEPkKnq4UmghAL1QZSg97SsQnv42b1s\ndoEHHcR9w2ImptN6xG1h/WAMC/G/+HaJ7RF92msOWTGK4BChl6JsoA==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 346,
+ "comment" : "k*G has a large x-coordinate",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30160211014551231950b75fc4402da1722fc9baeb020103",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 347,
+ "comment" : "r too large",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3026022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2c020103",
+ "result" : "invalid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "04bc97e7585eecad48e16683bc4091708e1a930c683fc47001d4b383594f2c4e22705989cf69daeadd4e4e4b8151ed888dfec20fb01728d89d56b3f38f2ae9c8c5",
+ "wx" : "00bc97e7585eecad48e16683bc4091708e1a930c683fc47001d4b383594f2c4e22",
+ "wy" : "705989cf69daeadd4e4e4b8151ed888dfec20fb01728d89d56b3f38f2ae9c8c5"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004bc97e7585eecad48e16683bc4091708e1a930c683fc47001d4b383594f2c4e22705989cf69daeadd4e4e4b8151ed888dfec20fb01728d89d56b3f38f2ae9c8c5",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEvJfnWF7srUjhZoO8QJFwjhqTDGg/xHAB\n1LODWU8sTiJwWYnPadrq3U5OS4FR7YiN/sIPsBco2J1Ws/OPKunIxQ==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 348,
+ "comment" : "r,s are large",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd036413f020103",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "0444ad339afbc21e9abf7b602a5ca535ea378135b6d10d81310bdd8293d1df3252b63ff7d0774770f8fe1d1722fa83acd02f434e4fc110a0cc8f6dddd37d56c463",
+ "wx" : "44ad339afbc21e9abf7b602a5ca535ea378135b6d10d81310bdd8293d1df3252",
+ "wy" : "00b63ff7d0774770f8fe1d1722fa83acd02f434e4fc110a0cc8f6dddd37d56c463"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000444ad339afbc21e9abf7b602a5ca535ea378135b6d10d81310bdd8293d1df3252b63ff7d0774770f8fe1d1722fa83acd02f434e4fc110a0cc8f6dddd37d56c463",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAERK0zmvvCHpq/e2AqXKU16jeBNbbRDYEx\nC92Ck9HfMlK2P/fQd0dw+P4dFyL6g6zQL0NOT8EQoMyPbd3TfVbEYw==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 349,
+ "comment" : "r and s^-1 have a large Hamming weight",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02203e9a7582886089c62fb840cf3b83061cd1cff3ae4341808bb5bdee6191174177",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "041260c2122c9e244e1af5151bede0c3ae23b54d7c596881d3eebad21f37dd878c5c9a0c1a9ade76737a8811bd6a7f9287c978ee396aa89c11e47229d2ccb552f0",
+ "wx" : "1260c2122c9e244e1af5151bede0c3ae23b54d7c596881d3eebad21f37dd878c",
+ "wy" : "5c9a0c1a9ade76737a8811bd6a7f9287c978ee396aa89c11e47229d2ccb552f0"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200041260c2122c9e244e1af5151bede0c3ae23b54d7c596881d3eebad21f37dd878c5c9a0c1a9ade76737a8811bd6a7f9287c978ee396aa89c11e47229d2ccb552f0",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEEmDCEiyeJE4a9RUb7eDDriO1TXxZaIHT\n7rrSHzfdh4xcmgwamt52c3qIEb1qf5KHyXjuOWqonBHkcinSzLVS8A==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 350,
+ "comment" : "r and s^-1 have a large Hamming weight",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc022024238e70b431b1a64efdf9032669939d4b77f249503fc6905feb7540dea3e6d2",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "041877045be25d34a1d0600f9d5c00d0645a2a54379b6ceefad2e6bf5c2a3352ce821a532cc1751ee1d36d41c3d6ab4e9b143e44ec46d73478ea6a79a5c0e54159",
+ "wx" : "1877045be25d34a1d0600f9d5c00d0645a2a54379b6ceefad2e6bf5c2a3352ce",
+ "wy" : "00821a532cc1751ee1d36d41c3d6ab4e9b143e44ec46d73478ea6a79a5c0e54159"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200041877045be25d34a1d0600f9d5c00d0645a2a54379b6ceefad2e6bf5c2a3352ce821a532cc1751ee1d36d41c3d6ab4e9b143e44ec46d73478ea6a79a5c0e54159",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEGHcEW+JdNKHQYA+dXADQZFoqVDebbO76\n0ua/XCozUs6CGlMswXUe4dNtQcPWq06bFD5E7EbXNHjqanmlwOVBWQ==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 351,
+ "comment" : "small r and s",
+ "flags" : [
+ "SmallRandS",
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3006020101020101",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "04455439fcc3d2deeceddeaece60e7bd17304f36ebb602adf5a22e0b8f1db46a50aec38fb2baf221e9a8d1887c7bf6222dd1834634e77263315af6d23609d04f77",
+ "wx" : "455439fcc3d2deeceddeaece60e7bd17304f36ebb602adf5a22e0b8f1db46a50",
+ "wy" : "00aec38fb2baf221e9a8d1887c7bf6222dd1834634e77263315af6d23609d04f77"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004455439fcc3d2deeceddeaece60e7bd17304f36ebb602adf5a22e0b8f1db46a50aec38fb2baf221e9a8d1887c7bf6222dd1834634e77263315af6d23609d04f77",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAERVQ5/MPS3uzt3q7OYOe9FzBPNuu2Aq31\noi4Ljx20alCuw4+yuvIh6ajRiHx79iIt0YNGNOdyYzFa9tI2CdBPdw==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 352,
+ "comment" : "small r and s",
+ "flags" : [
+ "SmallRandS",
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3006020101020102",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "042e1f466b024c0c3ace2437de09127fed04b706f94b19a21bb1c2acf35cece7180449ae3523d72534e964972cfd3b38af0bddd9619e5af223e4d1a40f34cf9f1d",
+ "wx" : "2e1f466b024c0c3ace2437de09127fed04b706f94b19a21bb1c2acf35cece718",
+ "wy" : "0449ae3523d72534e964972cfd3b38af0bddd9619e5af223e4d1a40f34cf9f1d"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200042e1f466b024c0c3ace2437de09127fed04b706f94b19a21bb1c2acf35cece7180449ae3523d72534e964972cfd3b38af0bddd9619e5af223e4d1a40f34cf9f1d",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAELh9GawJMDDrOJDfeCRJ/7QS3BvlLGaIb\nscKs81zs5xgESa41I9clNOlklyz9OzivC93ZYZ5a8iPk0aQPNM+fHQ==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 353,
+ "comment" : "small r and s",
+ "flags" : [
+ "SmallRandS",
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3006020101020103",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "048e7abdbbd18de7452374c1879a1c3b01d13261e7d4571c3b47a1c76c55a2337326ed897cd517a4f5349db809780f6d2f2b9f6299d8b5a89077f1119a718fd7b3",
+ "wx" : "008e7abdbbd18de7452374c1879a1c3b01d13261e7d4571c3b47a1c76c55a23373",
+ "wy" : "26ed897cd517a4f5349db809780f6d2f2b9f6299d8b5a89077f1119a718fd7b3"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200048e7abdbbd18de7452374c1879a1c3b01d13261e7d4571c3b47a1c76c55a2337326ed897cd517a4f5349db809780f6d2f2b9f6299d8b5a89077f1119a718fd7b3",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEjnq9u9GN50UjdMGHmhw7AdEyYefUVxw7\nR6HHbFWiM3Mm7Yl81Rek9TSduAl4D20vK59imdi1qJB38RGacY/Xsw==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 354,
+ "comment" : "small r and s",
+ "flags" : [
+ "SmallRandS",
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3006020102020101",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "047b333d4340d3d718dd3e6aff7de7bbf8b72bfd616c8420056052842376b9af1942117c5afeac755d6f376fc6329a7d76051b87123a4a5d0bc4a539380f03de7b",
+ "wx" : "7b333d4340d3d718dd3e6aff7de7bbf8b72bfd616c8420056052842376b9af19",
+ "wy" : "42117c5afeac755d6f376fc6329a7d76051b87123a4a5d0bc4a539380f03de7b"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200047b333d4340d3d718dd3e6aff7de7bbf8b72bfd616c8420056052842376b9af1942117c5afeac755d6f376fc6329a7d76051b87123a4a5d0bc4a539380f03de7b",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEezM9Q0DT1xjdPmr/fee7+Lcr/WFshCAF\nYFKEI3a5rxlCEXxa/qx1XW83b8Yymn12BRuHEjpKXQvEpTk4DwPeew==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 355,
+ "comment" : "small r and s",
+ "flags" : [
+ "SmallRandS",
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3006020102020102",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "04d30ca4a0ddb6616c851d30ced682c40f83c62758a1f2759988d6763a88f1c0e503a80d5415650d41239784e8e2fb1235e9fe991d112ebb81186cbf0da2de3aff",
+ "wx" : "00d30ca4a0ddb6616c851d30ced682c40f83c62758a1f2759988d6763a88f1c0e5",
+ "wy" : "03a80d5415650d41239784e8e2fb1235e9fe991d112ebb81186cbf0da2de3aff"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004d30ca4a0ddb6616c851d30ced682c40f83c62758a1f2759988d6763a88f1c0e503a80d5415650d41239784e8e2fb1235e9fe991d112ebb81186cbf0da2de3aff",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE0wykoN22YWyFHTDO1oLED4PGJ1ih8nWZ\niNZ2OojxwOUDqA1UFWUNQSOXhOji+xI16f6ZHREuu4EYbL8Not46/w==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 356,
+ "comment" : "small r and s",
+ "flags" : [
+ "SmallRandS",
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3006020102020103",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 357,
+ "comment" : "r is larger than n",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364143020103",
+ "result" : "invalid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "0448969b39991297b332a652d3ee6e01e909b39904e71fa2354a7830c7750baf24b4012d1b830d199ccb1fc972b32bfded55f09cd62d257e5e844e27e57a1594ec",
+ "wx" : "48969b39991297b332a652d3ee6e01e909b39904e71fa2354a7830c7750baf24",
+ "wy" : "00b4012d1b830d199ccb1fc972b32bfded55f09cd62d257e5e844e27e57a1594ec"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000448969b39991297b332a652d3ee6e01e909b39904e71fa2354a7830c7750baf24b4012d1b830d199ccb1fc972b32bfded55f09cd62d257e5e844e27e57a1594ec",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAESJabOZkSl7MyplLT7m4B6QmzmQTnH6I1\nSngwx3ULryS0AS0bgw0ZnMsfyXKzK/3tVfCc1i0lfl6ETiflehWU7A==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 358,
+ "comment" : "s is larger than n",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30080201020203ed2979",
+ "result" : "invalid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "0402ef4d6d6cfd5a94f1d7784226e3e2a6c0a436c55839619f38fb4472b5f9ee777eb4acd4eebda5cd72875ffd2a2f26229c2dc6b46500919a432c86739f3ae866",
+ "wx" : "02ef4d6d6cfd5a94f1d7784226e3e2a6c0a436c55839619f38fb4472b5f9ee77",
+ "wy" : "7eb4acd4eebda5cd72875ffd2a2f26229c2dc6b46500919a432c86739f3ae866"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000402ef4d6d6cfd5a94f1d7784226e3e2a6c0a436c55839619f38fb4472b5f9ee777eb4acd4eebda5cd72875ffd2a2f26229c2dc6b46500919a432c86739f3ae866",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEAu9NbWz9WpTx13hCJuPipsCkNsVYOWGf\nOPtEcrX57nd+tKzU7r2lzXKHX/0qLyYinC3GtGUAkZpDLIZznzroZg==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 359,
+ "comment" : "small r and s^-1",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30260202010102203a74e9d3a74e9d3a74e9d3a74e9d3a749f8ab3732a0a89604a09bce5b2916da4",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "04464f4ff715729cae5072ca3bd801d3195b67aec65e9b01aad20a2943dcbcb584b1afd29d31a39a11d570aa1597439b3b2d1971bf2f1abf15432d0207b10d1d08",
+ "wx" : "464f4ff715729cae5072ca3bd801d3195b67aec65e9b01aad20a2943dcbcb584",
+ "wy" : "00b1afd29d31a39a11d570aa1597439b3b2d1971bf2f1abf15432d0207b10d1d08"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004464f4ff715729cae5072ca3bd801d3195b67aec65e9b01aad20a2943dcbcb584b1afd29d31a39a11d570aa1597439b3b2d1971bf2f1abf15432d0207b10d1d08",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAERk9P9xVynK5Qcso72AHTGVtnrsZemwGq\n0gopQ9y8tYSxr9KdMaOaEdVwqhWXQ5s7LRlxvy8avxVDLQIHsQ0dCA==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 360,
+ "comment" : "smallish r and s^-1",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "302b02072d9b4d347952cc02200343aefc2f25d98b882e86eb9e30d55a6eb508b516510b34024ae4b6362330b3",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "04157f8fddf373eb5f49cfcf10d8b853cf91cbcd7d665c3522ba7dd738ddb79a4cdeadf1a5c448ea3c9f4191a8999abfcc757ac6d64567ef072c47fec613443b8f",
+ "wx" : "157f8fddf373eb5f49cfcf10d8b853cf91cbcd7d665c3522ba7dd738ddb79a4c",
+ "wy" : "00deadf1a5c448ea3c9f4191a8999abfcc757ac6d64567ef072c47fec613443b8f"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004157f8fddf373eb5f49cfcf10d8b853cf91cbcd7d665c3522ba7dd738ddb79a4cdeadf1a5c448ea3c9f4191a8999abfcc757ac6d64567ef072c47fec613443b8f",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEFX+P3fNz619Jz88Q2LhTz5HLzX1mXDUi\nun3XON23mkzerfGlxEjqPJ9BkaiZmr/MdXrG1kVn7wcsR/7GE0Q7jw==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 361,
+ "comment" : "100-bit r and small s^-1",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3031020d1033e67e37b32b445580bf4efc02206f906f906f906f906f906f906f906f8fe1cab5eefdb214061dce3b22789f1d6f",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "040934a537466c07430e2c48feb990bb19fb78cecc9cee424ea4d130291aa237f0d4f92d23b462804b5b68c52558c01c9996dbf727fccabbeedb9621a400535afa",
+ "wx" : "0934a537466c07430e2c48feb990bb19fb78cecc9cee424ea4d130291aa237f0",
+ "wy" : "00d4f92d23b462804b5b68c52558c01c9996dbf727fccabbeedb9621a400535afa"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200040934a537466c07430e2c48feb990bb19fb78cecc9cee424ea4d130291aa237f0d4f92d23b462804b5b68c52558c01c9996dbf727fccabbeedb9621a400535afa",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAECTSlN0ZsB0MOLEj+uZC7Gft4zsyc7kJO\npNEwKRqiN/DU+S0jtGKAS1toxSVYwByZltv3J/zKu+7bliGkAFNa+g==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 362,
+ "comment" : "small r and 100 bit s^-1",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3026020201010220783266e90f43dafe5cd9b3b0be86de22f9de83677d0f50713a468ec72fcf5d57",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "04d6ef20be66c893f741a9bf90d9b74675d1c2a31296397acb3ef174fd0b300c654a0c95478ca00399162d7f0f2dc89efdc2b28a30fbabe285857295a4b0c4e265",
+ "wx" : "00d6ef20be66c893f741a9bf90d9b74675d1c2a31296397acb3ef174fd0b300c65",
+ "wy" : "4a0c95478ca00399162d7f0f2dc89efdc2b28a30fbabe285857295a4b0c4e265"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004d6ef20be66c893f741a9bf90d9b74675d1c2a31296397acb3ef174fd0b300c654a0c95478ca00399162d7f0f2dc89efdc2b28a30fbabe285857295a4b0c4e265",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE1u8gvmbIk/dBqb+Q2bdGddHCoxKWOXrL\nPvF0/QswDGVKDJVHjKADmRYtfw8tyJ79wrKKMPur4oWFcpWksMTiZQ==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 363,
+ "comment" : "100-bit r and s^-1",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3031020d062522bbd3ecbe7c39e93e7c260220783266e90f43dafe5cd9b3b0be86de22f9de83677d0f50713a468ec72fcf5d57",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "04b7291d1404e0c0c07dab9372189f4bd58d2ceaa8d15ede544d9514545ba9ee0629c9a63d5e308769cc30ec276a410e6464a27eeafd9e599db10f053a4fe4a829",
+ "wx" : "00b7291d1404e0c0c07dab9372189f4bd58d2ceaa8d15ede544d9514545ba9ee06",
+ "wy" : "29c9a63d5e308769cc30ec276a410e6464a27eeafd9e599db10f053a4fe4a829"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004b7291d1404e0c0c07dab9372189f4bd58d2ceaa8d15ede544d9514545ba9ee0629c9a63d5e308769cc30ec276a410e6464a27eeafd9e599db10f053a4fe4a829",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEtykdFATgwMB9q5NyGJ9L1Y0s6qjRXt5U\nTZUUVFup7gYpyaY9XjCHacww7CdqQQ5kZKJ+6v2eWZ2xDwU6T+SoKQ==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 364,
+ "comment" : "r and s^-1 are close to n",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3045022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd03640c1022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c0",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "046e28303305d642ccb923b722ea86b2a0bc8e3735ecb26e849b19c9f76b2fdbb8186e80d64d8cab164f5238f5318461bf89d4d96ee6544c816c7566947774e0f6",
+ "wx" : "6e28303305d642ccb923b722ea86b2a0bc8e3735ecb26e849b19c9f76b2fdbb8",
+ "wy" : "186e80d64d8cab164f5238f5318461bf89d4d96ee6544c816c7566947774e0f6"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200046e28303305d642ccb923b722ea86b2a0bc8e3735ecb26e849b19c9f76b2fdbb8186e80d64d8cab164f5238f5318461bf89d4d96ee6544c816c7566947774e0f6",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEbigwMwXWQsy5I7ci6oayoLyONzXssm6E\nmxnJ92sv27gYboDWTYyrFk9SOPUxhGG/idTZbuZUTIFsdWaUd3Tg9g==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 365,
+ "comment" : "r and s are 64-bit integer",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30160209009c44febf31c3594d020900839ed28247c2b06b",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "04375bda93f6af92fb5f8f4b1b5f0534e3bafab34cb7ad9fb9d0b722e4a5c302a9a00b9f387a5a396097aa2162fc5bbcf4a5263372f681c94da51e9799120990fd",
+ "wx" : "375bda93f6af92fb5f8f4b1b5f0534e3bafab34cb7ad9fb9d0b722e4a5c302a9",
+ "wy" : "00a00b9f387a5a396097aa2162fc5bbcf4a5263372f681c94da51e9799120990fd"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004375bda93f6af92fb5f8f4b1b5f0534e3bafab34cb7ad9fb9d0b722e4a5c302a9a00b9f387a5a396097aa2162fc5bbcf4a5263372f681c94da51e9799120990fd",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEN1vak/avkvtfj0sbXwU047r6s0y3rZ+5\n0Lci5KXDAqmgC584elo5YJeqIWL8W7z0pSYzcvaByU2lHpeZEgmQ/Q==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 366,
+ "comment" : "r and s are 100-bit integer",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "301e020d09df8b682430beef6f5fd7c7cf020d0fd0a62e13778f4222a0d61c8a",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "04d75b68216babe03ae257e94b4e3bf1c52f44e3df266d1524ff8c5ea69da73197da4bff9ed1c53f44917a67d7b978598e89df359e3d5913eaea24f3ae259abc44",
+ "wx" : "00d75b68216babe03ae257e94b4e3bf1c52f44e3df266d1524ff8c5ea69da73197",
+ "wy" : "00da4bff9ed1c53f44917a67d7b978598e89df359e3d5913eaea24f3ae259abc44"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004d75b68216babe03ae257e94b4e3bf1c52f44e3df266d1524ff8c5ea69da73197da4bff9ed1c53f44917a67d7b978598e89df359e3d5913eaea24f3ae259abc44",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE11toIWur4DriV+lLTjvxxS9E498mbRUk\n/4xepp2nMZfaS/+e0cU/RJF6Z9e5eFmOid81nj1ZE+rqJPOuJZq8RA==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 367,
+ "comment" : "r and s are 128-bit integer",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "30260211008a598e563a89f526c32ebec8de26367a02110084f633e2042630e99dd0f1e16f7a04bf",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "0478bcda140aed23d430cb23c3dc0d01f423db134ee94a3a8cb483f2deac2ac653118114f6f33045d4e9ed9107085007bfbddf8f58fe7a1a2445d66a990045476e",
+ "wx" : "78bcda140aed23d430cb23c3dc0d01f423db134ee94a3a8cb483f2deac2ac653",
+ "wy" : "118114f6f33045d4e9ed9107085007bfbddf8f58fe7a1a2445d66a990045476e"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000478bcda140aed23d430cb23c3dc0d01f423db134ee94a3a8cb483f2deac2ac653118114f6f33045d4e9ed9107085007bfbddf8f58fe7a1a2445d66a990045476e",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEeLzaFArtI9QwyyPD3A0B9CPbE07pSjqM\ntIPy3qwqxlMRgRT28zBF1OntkQcIUAe/vd+PWP56GiRF1mqZAEVHbg==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 368,
+ "comment" : "r and s are 160-bit integer",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "302e021500aa6eeb5823f7fa31b466bb473797f0d0314c0bdf021500e2977c479e6d25703cebbc6bd561938cc9d1bfb9",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "04bb79f61857f743bfa1b6e7111ce4094377256969e4e15159123d9548acc3be6c1f9d9f8860dcffd3eb36dd6c31ff2e7226c2009c4c94d8d7d2b5686bf7abd677",
+ "wx" : "00bb79f61857f743bfa1b6e7111ce4094377256969e4e15159123d9548acc3be6c",
+ "wy" : "1f9d9f8860dcffd3eb36dd6c31ff2e7226c2009c4c94d8d7d2b5686bf7abd677"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004bb79f61857f743bfa1b6e7111ce4094377256969e4e15159123d9548acc3be6c1f9d9f8860dcffd3eb36dd6c31ff2e7226c2009c4c94d8d7d2b5686bf7abd677",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEu3n2GFf3Q7+htucRHOQJQ3claWnk4VFZ\nEj2VSKzDvmwfnZ+IYNz/0+s23Wwx/y5yJsIAnEyU2NfStWhr96vWdw==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 369,
+ "comment" : "s == 1",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3025022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c1020101",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 370,
+ "comment" : "s == 0",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3025022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c1020100",
+ "result" : "invalid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "0493591827d9e6713b4e9faea62c72b28dfefa68e0c05160b5d6aae88fd2e36c36073f5545ad5af410af26afff68654cf72d45e493489311203247347a890f4518",
+ "wx" : "0093591827d9e6713b4e9faea62c72b28dfefa68e0c05160b5d6aae88fd2e36c36",
+ "wy" : "073f5545ad5af410af26afff68654cf72d45e493489311203247347a890f4518"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000493591827d9e6713b4e9faea62c72b28dfefa68e0c05160b5d6aae88fd2e36c36073f5545ad5af410af26afff68654cf72d45e493489311203247347a890f4518",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEk1kYJ9nmcTtOn66mLHKyjf76aODAUWC1\n1qroj9LjbDYHP1VFrVr0EK8mr/9oZUz3LUXkk0iTESAyRzR6iQ9FGA==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 371,
+ "comment" : "edge case modular inverse",
+ "flags" : [
+ "ModularInverse",
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c10220419d981c515af8cc82545aac0c85e9e308fbb2eab6acd7ed497e0b4145a18fd9",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "0431ed3081aefe001eb6402069ee2ccc1862937b85995144dba9503943587bf0dada01b8cc4df34f5ab3b1a359615208946e5ee35f98ee775b8ccecd86ccc1650f",
+ "wx" : "31ed3081aefe001eb6402069ee2ccc1862937b85995144dba9503943587bf0da",
+ "wy" : "00da01b8cc4df34f5ab3b1a359615208946e5ee35f98ee775b8ccecd86ccc1650f"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000431ed3081aefe001eb6402069ee2ccc1862937b85995144dba9503943587bf0dada01b8cc4df34f5ab3b1a359615208946e5ee35f98ee775b8ccecd86ccc1650f",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEMe0wga7+AB62QCBp7izMGGKTe4WZUUTb\nqVA5Q1h78NraAbjMTfNPWrOxo1lhUgiUbl7jX5jud1uMzs2GzMFlDw==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 372,
+ "comment" : "edge case modular inverse",
+ "flags" : [
+ "ModularInverse",
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c102201b21717ad71d23bbac60a9ad0baf75b063c9fdf52a00ebf99d022172910993c9",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "047dff66fa98509ff3e2e51045f4390523dccda43a3bc2885e58c248090990eea854c76c2b9adeb6bb571823e07fd7c65c8639cf9d905260064c8e7675ce6d98b4",
+ "wx" : "7dff66fa98509ff3e2e51045f4390523dccda43a3bc2885e58c248090990eea8",
+ "wy" : "54c76c2b9adeb6bb571823e07fd7c65c8639cf9d905260064c8e7675ce6d98b4"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200047dff66fa98509ff3e2e51045f4390523dccda43a3bc2885e58c248090990eea854c76c2b9adeb6bb571823e07fd7c65c8639cf9d905260064c8e7675ce6d98b4",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEff9m+phQn/Pi5RBF9DkFI9zNpDo7wohe\nWMJICQmQ7qhUx2wrmt62u1cYI+B/18ZchjnPnZBSYAZMjnZ1zm2YtA==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 373,
+ "comment" : "edge case modular inverse",
+ "flags" : [
+ "ModularInverse",
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c102202f588f66018f3dd14db3e28e77996487e32486b521ed8e5a20f06591951777e9",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "044280509aab64edfc0b4a2967e4cbce849cb544e4a77313c8e6ece579fbd7420a2e89fe5cc1927d554e6a3bb14033ea7c922cd75cba2c7415fdab52f20b1860f1",
+ "wx" : "4280509aab64edfc0b4a2967e4cbce849cb544e4a77313c8e6ece579fbd7420a",
+ "wy" : "2e89fe5cc1927d554e6a3bb14033ea7c922cd75cba2c7415fdab52f20b1860f1"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200044280509aab64edfc0b4a2967e4cbce849cb544e4a77313c8e6ece579fbd7420a2e89fe5cc1927d554e6a3bb14033ea7c922cd75cba2c7415fdab52f20b1860f1",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEQoBQmqtk7fwLSiln5MvOhJy1ROSncxPI\n5uzlefvXQgouif5cwZJ9VU5qO7FAM+p8kizXXLosdBX9q1LyCxhg8Q==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 374,
+ "comment" : "edge case modular inverse",
+ "flags" : [
+ "ModularInverse",
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c10220091a08870ff4daf9123b30c20e8c4fc8505758dcf4074fcaff2170c9bfcf74f4",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "044f8df145194e3c4fc3eea26d43ce75b402d6b17472ddcbb254b8a79b0bf3d9cb2aa20d82844cb266344e71ca78f2ad27a75a09e5bc0fa57e4efd9d465a0888db",
+ "wx" : "4f8df145194e3c4fc3eea26d43ce75b402d6b17472ddcbb254b8a79b0bf3d9cb",
+ "wy" : "2aa20d82844cb266344e71ca78f2ad27a75a09e5bc0fa57e4efd9d465a0888db"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200044f8df145194e3c4fc3eea26d43ce75b402d6b17472ddcbb254b8a79b0bf3d9cb2aa20d82844cb266344e71ca78f2ad27a75a09e5bc0fa57e4efd9d465a0888db",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAET43xRRlOPE/D7qJtQ851tALWsXRy3cuy\nVLinmwvz2csqog2ChEyyZjROccp48q0np1oJ5bwPpX5O/Z1GWgiI2w==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 375,
+ "comment" : "edge case modular inverse",
+ "flags" : [
+ "ModularInverse",
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c102207c370dc0ce8c59a8b273cba44a7c1191fc3186dc03cab96b0567312df0d0b250",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "049598a57dd67ec3e16b587a338aa3a10a3a3913b41a3af32e3ed3ff01358c6b14122819edf8074bbc521f7d4cdce82fef7a516706affba1d93d9dea9ccae1a207",
+ "wx" : "009598a57dd67ec3e16b587a338aa3a10a3a3913b41a3af32e3ed3ff01358c6b14",
+ "wy" : "122819edf8074bbc521f7d4cdce82fef7a516706affba1d93d9dea9ccae1a207"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200049598a57dd67ec3e16b587a338aa3a10a3a3913b41a3af32e3ed3ff01358c6b14122819edf8074bbc521f7d4cdce82fef7a516706affba1d93d9dea9ccae1a207",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAElZilfdZ+w+FrWHoziqOhCjo5E7QaOvMu\nPtP/ATWMaxQSKBnt+AdLvFIffUzc6C/velFnBq/7odk9neqcyuGiBw==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 376,
+ "comment" : "edge case modular inverse",
+ "flags" : [
+ "ModularInverse",
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c1022070b59a7d1ee77a2f9e0491c2a7cfcd0ed04df4a35192f6132dcc668c79a6160e",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "049171fec3ca20806bc084f12f0760911b60990bd80e5b2a71ca03a048b20f837e634fd17863761b2958d2be4e149f8d3d7abbdc18be03f451ab6c17fa0a1f8330",
+ "wx" : "009171fec3ca20806bc084f12f0760911b60990bd80e5b2a71ca03a048b20f837e",
+ "wy" : "634fd17863761b2958d2be4e149f8d3d7abbdc18be03f451ab6c17fa0a1f8330"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200049171fec3ca20806bc084f12f0760911b60990bd80e5b2a71ca03a048b20f837e634fd17863761b2958d2be4e149f8d3d7abbdc18be03f451ab6c17fa0a1f8330",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEkXH+w8oggGvAhPEvB2CRG2CZC9gOWypx\nygOgSLIPg35jT9F4Y3YbKVjSvk4Un409ervcGL4D9FGrbBf6Ch+DMA==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 377,
+ "comment" : "edge case modular inverse",
+ "flags" : [
+ "ModularInverse",
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c102202736d76e412246e097148e2bf62915614eb7c428913a58eb5e9cd4674a9423de",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "04777c8930b6e1d271100fe68ce93f163fa37612c5fff67f4a62fc3bafaf3d17a9ed73d86f60a51b5ed91353a3b054edc0aa92c9ebcbd0b75d188fdc882791d68d",
+ "wx" : "777c8930b6e1d271100fe68ce93f163fa37612c5fff67f4a62fc3bafaf3d17a9",
+ "wy" : "00ed73d86f60a51b5ed91353a3b054edc0aa92c9ebcbd0b75d188fdc882791d68d"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004777c8930b6e1d271100fe68ce93f163fa37612c5fff67f4a62fc3bafaf3d17a9ed73d86f60a51b5ed91353a3b054edc0aa92c9ebcbd0b75d188fdc882791d68d",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEd3yJMLbh0nEQD+aM6T8WP6N2EsX/9n9K\nYvw7r689F6ntc9hvYKUbXtkTU6OwVO3AqpLJ68vQt10Yj9yIJ5HWjQ==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 378,
+ "comment" : "edge case modular inverse",
+ "flags" : [
+ "ModularInverse",
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c102204a1e12831fbe93627b02d6e7f24bccdd6ef4b2d0f46739eaf3b1eaf0ca117770",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "04eabc248f626e0a63e1eb81c43d461a39a1dba881eb6ee2152b07c32d71bcf4700603caa8b9d33db13af44c6efbec8a198ed6124ac9eb17eaafd2824a545ec000",
+ "wx" : "00eabc248f626e0a63e1eb81c43d461a39a1dba881eb6ee2152b07c32d71bcf470",
+ "wy" : "0603caa8b9d33db13af44c6efbec8a198ed6124ac9eb17eaafd2824a545ec000"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004eabc248f626e0a63e1eb81c43d461a39a1dba881eb6ee2152b07c32d71bcf4700603caa8b9d33db13af44c6efbec8a198ed6124ac9eb17eaafd2824a545ec000",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE6rwkj2JuCmPh64HEPUYaOaHbqIHrbuIV\nKwfDLXG89HAGA8qoudM9sTr0TG777IoZjtYSSsnrF+qv0oJKVF7AAA==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 379,
+ "comment" : "edge case modular inverse",
+ "flags" : [
+ "ModularInverse",
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c1022006c778d4dfff7dee06ed88bc4e0ed34fc553aad67caf796f2a1c6487c1b2e877",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "049f7a13ada158a55f9ddf1a45f044f073d9b80030efdcfc9f9f58418fbceaf001f8ada0175090f80d47227d6713b6740f9a0091d88a837d0a1cd77b58a8f28d73",
+ "wx" : "009f7a13ada158a55f9ddf1a45f044f073d9b80030efdcfc9f9f58418fbceaf001",
+ "wy" : "00f8ada0175090f80d47227d6713b6740f9a0091d88a837d0a1cd77b58a8f28d73"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200049f7a13ada158a55f9ddf1a45f044f073d9b80030efdcfc9f9f58418fbceaf001f8ada0175090f80d47227d6713b6740f9a0091d88a837d0a1cd77b58a8f28d73",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEn3oTraFYpV+d3xpF8ETwc9m4ADDv3Pyf\nn1hBj7zq8AH4raAXUJD4DUcifWcTtnQPmgCR2IqDfQoc13tYqPKNcw==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 380,
+ "comment" : "edge case modular inverse",
+ "flags" : [
+ "ModularInverse",
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c102204de459ef9159afa057feb3ec40fef01c45b809f4ab296ea48c206d4249a2b451",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "0411c4f3e461cd019b5c06ea0cea4c4090c3cc3e3c5d9f3c6d65b436826da9b4dbbbeb7a77e4cbfda207097c43423705f72c80476da3dac40a483b0ab0f2ead1cb",
+ "wx" : "11c4f3e461cd019b5c06ea0cea4c4090c3cc3e3c5d9f3c6d65b436826da9b4db",
+ "wy" : "00bbeb7a77e4cbfda207097c43423705f72c80476da3dac40a483b0ab0f2ead1cb"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000411c4f3e461cd019b5c06ea0cea4c4090c3cc3e3c5d9f3c6d65b436826da9b4dbbbeb7a77e4cbfda207097c43423705f72c80476da3dac40a483b0ab0f2ead1cb",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEEcTz5GHNAZtcBuoM6kxAkMPMPjxdnzxt\nZbQ2gm2ptNu763p35Mv9ogcJfENCNwX3LIBHbaPaxApIOwqw8urRyw==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 381,
+ "comment" : "edge case modular inverse",
+ "flags" : [
+ "ModularInverse",
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c10220745d294978007302033502e1acc48b63ae6500be43adbea1b258d6b423dbb416",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "04e2e18682d53123aa01a6c5d00b0c623d671b462ea80bddd65227fd5105988aa4161907b3fd25044a949ea41c8e2ea8459dc6f1654856b8b61b31543bb1b45bdb",
+ "wx" : "00e2e18682d53123aa01a6c5d00b0c623d671b462ea80bddd65227fd5105988aa4",
+ "wy" : "161907b3fd25044a949ea41c8e2ea8459dc6f1654856b8b61b31543bb1b45bdb"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004e2e18682d53123aa01a6c5d00b0c623d671b462ea80bddd65227fd5105988aa4161907b3fd25044a949ea41c8e2ea8459dc6f1654856b8b61b31543bb1b45bdb",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE4uGGgtUxI6oBpsXQCwxiPWcbRi6oC93W\nUif9UQWYiqQWGQez/SUESpSepByOLqhFncbxZUhWuLYbMVQ7sbRb2w==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 382,
+ "comment" : "edge case modular inverse",
+ "flags" : [
+ "ModularInverse",
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c102207b2a785e3896f59b2d69da57648e80ad3c133a750a2847fd2098ccd902042b6c",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "0490f8d4ca73de08a6564aaf005247b6f0ffe978504dce52605f46b7c3e56197dafadbe528eb70d9ee7ea0e70702db54f721514c7b8604ac2cb214f1decb7e383d",
+ "wx" : "0090f8d4ca73de08a6564aaf005247b6f0ffe978504dce52605f46b7c3e56197da",
+ "wy" : "00fadbe528eb70d9ee7ea0e70702db54f721514c7b8604ac2cb214f1decb7e383d"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000490f8d4ca73de08a6564aaf005247b6f0ffe978504dce52605f46b7c3e56197dafadbe528eb70d9ee7ea0e70702db54f721514c7b8604ac2cb214f1decb7e383d",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEkPjUynPeCKZWSq8AUke28P/peFBNzlJg\nX0a3w+Vhl9r62+Uo63DZ7n6g5wcC21T3IVFMe4YErCyyFPHey344PQ==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 383,
+ "comment" : "edge case modular inverse",
+ "flags" : [
+ "ModularInverse",
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c1022071ae94a72ca896875e7aa4a4c3d29afdb4b35b6996273e63c47ac519256c5eb1",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "04824c195c73cffdf038d101bce1687b5c3b6146f395c885976f7753b2376b948e3cdefa6fc347d13e4dcbc63a0b03a165180cd2be1431a0cf74ce1ea25082d2bc",
+ "wx" : "00824c195c73cffdf038d101bce1687b5c3b6146f395c885976f7753b2376b948e",
+ "wy" : "3cdefa6fc347d13e4dcbc63a0b03a165180cd2be1431a0cf74ce1ea25082d2bc"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004824c195c73cffdf038d101bce1687b5c3b6146f395c885976f7753b2376b948e3cdefa6fc347d13e4dcbc63a0b03a165180cd2be1431a0cf74ce1ea25082d2bc",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEgkwZXHPP/fA40QG84Wh7XDthRvOVyIWX\nb3dTsjdrlI483vpvw0fRPk3LxjoLA6FlGAzSvhQxoM90zh6iUILSvA==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 384,
+ "comment" : "edge case modular inverse",
+ "flags" : [
+ "ModularInverse",
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c102200fa527fa7343c0bc9ec35a6278bfbff4d83301b154fc4bd14aee7eb93445b5f9",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "042788a52f078eb3f202c4fa73e0d3386faf3df6be856003636f599922d4f5268f30b4f207c919bbdf5e67a8be4265a8174754b3aba8f16e575b77ff4d5a7eb64f",
+ "wx" : "2788a52f078eb3f202c4fa73e0d3386faf3df6be856003636f599922d4f5268f",
+ "wy" : "30b4f207c919bbdf5e67a8be4265a8174754b3aba8f16e575b77ff4d5a7eb64f"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200042788a52f078eb3f202c4fa73e0d3386faf3df6be856003636f599922d4f5268f30b4f207c919bbdf5e67a8be4265a8174754b3aba8f16e575b77ff4d5a7eb64f",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEJ4ilLweOs/ICxPpz4NM4b6899r6FYANj\nb1mZItT1Jo8wtPIHyRm7315nqL5CZagXR1Szq6jxbldbd/9NWn62Tw==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 385,
+ "comment" : "edge case modular inverse",
+ "flags" : [
+ "ModularInverse",
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c102206539c0adadd0525ff42622164ce9314348bd0863b4c80e936b23ca0414264671",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "04d533b789a4af890fa7a82a1fae58c404f9a62a50b49adafab349c513b415087401b4171b803e76b34a9861e10f7bc289a066fd01bd29f84c987a10a5fb18c2d4",
+ "wx" : "00d533b789a4af890fa7a82a1fae58c404f9a62a50b49adafab349c513b4150874",
+ "wy" : "01b4171b803e76b34a9861e10f7bc289a066fd01bd29f84c987a10a5fb18c2d4"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004d533b789a4af890fa7a82a1fae58c404f9a62a50b49adafab349c513b415087401b4171b803e76b34a9861e10f7bc289a066fd01bd29f84c987a10a5fb18c2d4",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE1TO3iaSviQ+nqCofrljEBPmmKlC0mtr6\ns0nFE7QVCHQBtBcbgD52s0qYYeEPe8KJoGb9Ab0p+EyYehCl+xjC1A==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 386,
+ "comment" : "point at infinity during verify",
+ "flags" : [
+ "PointDuplication",
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304402207fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c0",
+ "result" : "invalid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "043a3150798c8af69d1e6e981f3a45402ba1d732f4be8330c5164f49e10ec555b4221bd842bc5e4d97eff37165f60e3998a424d72a450cf95ea477c78287d0343a",
+ "wx" : "3a3150798c8af69d1e6e981f3a45402ba1d732f4be8330c5164f49e10ec555b4",
+ "wy" : "221bd842bc5e4d97eff37165f60e3998a424d72a450cf95ea477c78287d0343a"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200043a3150798c8af69d1e6e981f3a45402ba1d732f4be8330c5164f49e10ec555b4221bd842bc5e4d97eff37165f60e3998a424d72a450cf95ea477c78287d0343a",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEOjFQeYyK9p0ebpgfOkVAK6HXMvS+gzDF\nFk9J4Q7FVbQiG9hCvF5Nl+/zcWX2DjmYpCTXKkUM+V6kd8eCh9A0Og==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 387,
+ "comment" : "edge case for signature malleability",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304402207fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a002207fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "043b37df5fb347c69a0f17d85c0c7ca83736883a825e13143d0fcfc8101e851e800de3c090b6ca21ba543517330c04b12f948c6badf14a63abffdf4ef8c7537026",
+ "wx" : "3b37df5fb347c69a0f17d85c0c7ca83736883a825e13143d0fcfc8101e851e80",
+ "wy" : "0de3c090b6ca21ba543517330c04b12f948c6badf14a63abffdf4ef8c7537026"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200043b37df5fb347c69a0f17d85c0c7ca83736883a825e13143d0fcfc8101e851e800de3c090b6ca21ba543517330c04b12f948c6badf14a63abffdf4ef8c7537026",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEOzffX7NHxpoPF9hcDHyoNzaIOoJeExQ9\nD8/IEB6FHoAN48CQtsohulQ1FzMMBLEvlIxrrfFKY6v/3074x1NwJg==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 388,
+ "comment" : "edge case for signature malleability",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304402207fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a002207fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a1",
+ "result" : "invalid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "04feb5163b0ece30ff3e03c7d55c4380fa2fa81ee2c0354942ff6f08c99d0cd82ce87de05ee1bda089d3e4e248fa0f721102acfffdf50e654be281433999df897e",
+ "wx" : "00feb5163b0ece30ff3e03c7d55c4380fa2fa81ee2c0354942ff6f08c99d0cd82c",
+ "wy" : "00e87de05ee1bda089d3e4e248fa0f721102acfffdf50e654be281433999df897e"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004feb5163b0ece30ff3e03c7d55c4380fa2fa81ee2c0354942ff6f08c99d0cd82ce87de05ee1bda089d3e4e248fa0f721102acfffdf50e654be281433999df897e",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE/rUWOw7OMP8+A8fVXEOA+i+oHuLANUlC\n/28IyZ0M2CzofeBe4b2gidPk4kj6D3IRAqz//fUOZUvigUM5md+Jfg==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 389,
+ "comment" : "u1 == 1",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215b8022044a5ad0bd0636d9e12bc9e0a6bdd5e1bba77f523842193b3b82e448e05d5f11e",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "04238ced001cf22b8853e02edc89cbeca5050ba7e042a7a77f9382cd414922897640683d3094643840f295890aa4c18aa39b41d77dd0fb3bb2700e4f9ec284ffc2",
+ "wx" : "238ced001cf22b8853e02edc89cbeca5050ba7e042a7a77f9382cd4149228976",
+ "wy" : "40683d3094643840f295890aa4c18aa39b41d77dd0fb3bb2700e4f9ec284ffc2"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004238ced001cf22b8853e02edc89cbeca5050ba7e042a7a77f9382cd414922897640683d3094643840f295890aa4c18aa39b41d77dd0fb3bb2700e4f9ec284ffc2",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEI4ztABzyK4hT4C7cicvspQULp+BCp6d/\nk4LNQUkiiXZAaD0wlGQ4QPKViQqkwYqjm0HXfdD7O7JwDk+ewoT/wg==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 390,
+ "comment" : "u1 == n - 1",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215b8022044a5ad0bd0636d9e12bc9e0a6bdd5e1bba77f523842193b3b82e448e05d5f11e",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "04961cf64817c06c0e51b3c2736c922fde18bd8c4906fcd7f5ef66c4678508f35ed2c5d18168cfbe70f2f123bd7419232bb92dd69113e2941061889481c5a027bf",
+ "wx" : "00961cf64817c06c0e51b3c2736c922fde18bd8c4906fcd7f5ef66c4678508f35e",
+ "wy" : "00d2c5d18168cfbe70f2f123bd7419232bb92dd69113e2941061889481c5a027bf"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004961cf64817c06c0e51b3c2736c922fde18bd8c4906fcd7f5ef66c4678508f35ed2c5d18168cfbe70f2f123bd7419232bb92dd69113e2941061889481c5a027bf",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAElhz2SBfAbA5Rs8JzbJIv3hi9jEkG/Nf1\n72bEZ4UI817SxdGBaM++cPLxI710GSMruS3WkRPilBBhiJSBxaAnvw==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 391,
+ "comment" : "u2 == 1",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215b8022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215b8",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "0413681eae168cd4ea7cf2e2a45d052742d10a9f64e796867dbdcb829fe0b1028816528760d177376c09df79de39557c329cc1753517acffe8fa2ec298026b8384",
+ "wx" : "13681eae168cd4ea7cf2e2a45d052742d10a9f64e796867dbdcb829fe0b10288",
+ "wy" : "16528760d177376c09df79de39557c329cc1753517acffe8fa2ec298026b8384"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000413681eae168cd4ea7cf2e2a45d052742d10a9f64e796867dbdcb829fe0b1028816528760d177376c09df79de39557c329cc1753517acffe8fa2ec298026b8384",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEE2gerhaM1Op88uKkXQUnQtEKn2TnloZ9\nvcuCn+CxAogWUodg0Xc3bAnfed45VXwynMF1NRes/+j6LsKYAmuDhA==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 392,
+ "comment" : "u2 == n - 1",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215b8022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215b8",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "045aa7abfdb6b4086d543325e5d79c6e95ce42f866d2bb84909633a04bb1aa31c291c80088794905e1da33336d874e2f91ccf45cc59185bede5dd6f3f7acaae18b",
+ "wx" : "5aa7abfdb6b4086d543325e5d79c6e95ce42f866d2bb84909633a04bb1aa31c2",
+ "wy" : "0091c80088794905e1da33336d874e2f91ccf45cc59185bede5dd6f3f7acaae18b"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200045aa7abfdb6b4086d543325e5d79c6e95ce42f866d2bb84909633a04bb1aa31c291c80088794905e1da33336d874e2f91ccf45cc59185bede5dd6f3f7acaae18b",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEWqer/ba0CG1UMyXl15xulc5C+GbSu4SQ\nljOgS7GqMcKRyACIeUkF4dozM22HTi+RzPRcxZGFvt5d1vP3rKrhiw==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 393,
+ "comment" : "edge case for u1",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc022016e1e459457679df5b9434ae23f474b3e8d2a70bd6b5dbe692ba16da01f1fb0a",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "0400277791b305a45b2b39590b2f05d3392a6c8182cef4eb540120e0f5c206c3e464108233fb0b8c3ac892d79ef8e0fbf92ed133addb4554270132584dc52eef41",
+ "wx" : "277791b305a45b2b39590b2f05d3392a6c8182cef4eb540120e0f5c206c3e4",
+ "wy" : "64108233fb0b8c3ac892d79ef8e0fbf92ed133addb4554270132584dc52eef41"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000400277791b305a45b2b39590b2f05d3392a6c8182cef4eb540120e0f5c206c3e464108233fb0b8c3ac892d79ef8e0fbf92ed133addb4554270132584dc52eef41",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEACd3kbMFpFsrOVkLLwXTOSpsgYLO9OtU\nASDg9cIGw+RkEIIz+wuMOsiS15744Pv5LtEzrdtFVCcBMlhNxS7vQQ==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 394,
+ "comment" : "edge case for u1",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02201c940f313f92647be257eccd7ed08b0baef3f0478f25871b53635302c5f6314a",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "046efa092b68de9460f0bcc919005a5f6e80e19de98968be3cd2c770a9949bfb1ac75e6e5087d6550d5f9beb1e79e5029307bc255235e2d5dc99241ac3ab886c49",
+ "wx" : "6efa092b68de9460f0bcc919005a5f6e80e19de98968be3cd2c770a9949bfb1a",
+ "wy" : "00c75e6e5087d6550d5f9beb1e79e5029307bc255235e2d5dc99241ac3ab886c49"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200046efa092b68de9460f0bcc919005a5f6e80e19de98968be3cd2c770a9949bfb1ac75e6e5087d6550d5f9beb1e79e5029307bc255235e2d5dc99241ac3ab886c49",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEbvoJK2jelGDwvMkZAFpfboDhnemJaL48\n0sdwqZSb+xrHXm5Qh9ZVDV+b6x555QKTB7wlUjXi1dyZJBrDq4hsSQ==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 395,
+ "comment" : "edge case for u1",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc022015d94a85077b493f91cb7101ec63e1b01be58b594e855f45050a8c14062d689b",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "0472d4a19c4f9d2cf5848ea40445b70d4696b5f02d632c0c654cc7d7eeb0c6d058e8c4cd9943e459174c7ac01fa742198e47e6c19a6bdb0c4f6c237831c1b3f942",
+ "wx" : "72d4a19c4f9d2cf5848ea40445b70d4696b5f02d632c0c654cc7d7eeb0c6d058",
+ "wy" : "00e8c4cd9943e459174c7ac01fa742198e47e6c19a6bdb0c4f6c237831c1b3f942"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000472d4a19c4f9d2cf5848ea40445b70d4696b5f02d632c0c654cc7d7eeb0c6d058e8c4cd9943e459174c7ac01fa742198e47e6c19a6bdb0c4f6c237831c1b3f942",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEctShnE+dLPWEjqQERbcNRpa18C1jLAxl\nTMfX7rDG0FjoxM2ZQ+RZF0x6wB+nQhmOR+bBmmvbDE9sI3gxwbP5Qg==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 396,
+ "comment" : "edge case for u1",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02205b1d27a7694c146244a5ad0bd0636d9d9ef3b9fb58385418d9c982105077d1b7",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "042a8ea2f50dcced0c217575bdfa7cd47d1c6f100041ec0e35512794c1be7e740258f8c17122ed303fda7143eb58bede70295b653266013b0b0ebd3f053137f6ec",
+ "wx" : "2a8ea2f50dcced0c217575bdfa7cd47d1c6f100041ec0e35512794c1be7e7402",
+ "wy" : "58f8c17122ed303fda7143eb58bede70295b653266013b0b0ebd3f053137f6ec"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200042a8ea2f50dcced0c217575bdfa7cd47d1c6f100041ec0e35512794c1be7e740258f8c17122ed303fda7143eb58bede70295b653266013b0b0ebd3f053137f6ec",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEKo6i9Q3M7QwhdXW9+nzUfRxvEABB7A41\nUSeUwb5+dAJY+MFxIu0wP9pxQ+tYvt5wKVtlMmYBOwsOvT8FMTf27A==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 397,
+ "comment" : "edge case for u1",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02202d85896b3eb9dbb5a52f42f9c9261ed3fc46644ec65f06ade3fd78f257e43432",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "0488de689ce9af1e94be6a2089c8a8b1253ffdbb6c8e9c86249ba220001a4ad3b80c4998e54842f413b9edb1825acbb6335e81e4d184b2b01c8bebdc85d1f28946",
+ "wx" : "0088de689ce9af1e94be6a2089c8a8b1253ffdbb6c8e9c86249ba220001a4ad3b8",
+ "wy" : "0c4998e54842f413b9edb1825acbb6335e81e4d184b2b01c8bebdc85d1f28946"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000488de689ce9af1e94be6a2089c8a8b1253ffdbb6c8e9c86249ba220001a4ad3b80c4998e54842f413b9edb1825acbb6335e81e4d184b2b01c8bebdc85d1f28946",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEiN5onOmvHpS+aiCJyKixJT/9u2yOnIYk\nm6IgABpK07gMSZjlSEL0E7ntsYJay7YzXoHk0YSysByL69yF0fKJRg==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 398,
+ "comment" : "edge case for u1",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02205b0b12d67d73b76b4a5e85f3924c3da7f88cc89d8cbe0d5bc7faf1e4afc86864",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "04fea2d31f70f90d5fb3e00e186ac42ab3c1615cee714e0b4e1131b3d4d8225bf7b037a18df2ac15343f30f74067ddf29e817d5f77f8dce05714da59c094f0cda9",
+ "wx" : "00fea2d31f70f90d5fb3e00e186ac42ab3c1615cee714e0b4e1131b3d4d8225bf7",
+ "wy" : "00b037a18df2ac15343f30f74067ddf29e817d5f77f8dce05714da59c094f0cda9"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004fea2d31f70f90d5fb3e00e186ac42ab3c1615cee714e0b4e1131b3d4d8225bf7b037a18df2ac15343f30f74067ddf29e817d5f77f8dce05714da59c094f0cda9",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE/qLTH3D5DV+z4A4YasQqs8FhXO5xTgtO\nETGz1NgiW/ewN6GN8qwVND8w90Bn3fKegX1fd/jc4FcU2lnAlPDNqQ==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 399,
+ "comment" : "edge case for u1",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0220694c146244a5ad0bd0636d9e12bc9e09e60e68b90d0b5e6c5dddd0cb694d8799",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "047258911e3d423349166479dbe0b8341af7fbd03d0a7e10edccb36b6ceea5a3db17ac2b8992791128fa3b96dc2fbd4ca3bfa782ef2832fc6656943db18e7346b0",
+ "wx" : "7258911e3d423349166479dbe0b8341af7fbd03d0a7e10edccb36b6ceea5a3db",
+ "wy" : "17ac2b8992791128fa3b96dc2fbd4ca3bfa782ef2832fc6656943db18e7346b0"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200047258911e3d423349166479dbe0b8341af7fbd03d0a7e10edccb36b6ceea5a3db17ac2b8992791128fa3b96dc2fbd4ca3bfa782ef2832fc6656943db18e7346b0",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEcliRHj1CM0kWZHnb4Lg0Gvf70D0KfhDt\nzLNrbO6lo9sXrCuJknkRKPo7ltwvvUyjv6eC7ygy/GZWlD2xjnNGsA==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 400,
+ "comment" : "edge case for u1",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02203d7f487c07bfc5f30846938a3dcef696444707cf9677254a92b06c63ab867d22",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "044f28461dea64474d6bb34d1499c97d37b9e95633df1ceeeaacd45016c98b3914c8818810b8cc06ddb40e8a1261c528faa589455d5a6df93b77bc5e0e493c7470",
+ "wx" : "4f28461dea64474d6bb34d1499c97d37b9e95633df1ceeeaacd45016c98b3914",
+ "wy" : "00c8818810b8cc06ddb40e8a1261c528faa589455d5a6df93b77bc5e0e493c7470"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200044f28461dea64474d6bb34d1499c97d37b9e95633df1ceeeaacd45016c98b3914c8818810b8cc06ddb40e8a1261c528faa589455d5a6df93b77bc5e0e493c7470",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAETyhGHepkR01rs00Umcl9N7npVjPfHO7q\nrNRQFsmLORTIgYgQuMwG3bQOihJhxSj6pYlFXVpt+Tt3vF4OSTx0cA==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 401,
+ "comment" : "edge case for u1",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02206c7648fc0fbf8a06adb8b839f97b4ff7a800f11b1e37c593b261394599792ba4",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "0474f2a814fb5d8eca91a69b5e60712732b3937de32829be974ed7b68c5c2f5d66eff0f07c56f987a657f42196205f588c0f1d96fd8a63a5f238b48f478788fe3b",
+ "wx" : "74f2a814fb5d8eca91a69b5e60712732b3937de32829be974ed7b68c5c2f5d66",
+ "wy" : "00eff0f07c56f987a657f42196205f588c0f1d96fd8a63a5f238b48f478788fe3b"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000474f2a814fb5d8eca91a69b5e60712732b3937de32829be974ed7b68c5c2f5d66eff0f07c56f987a657f42196205f588c0f1d96fd8a63a5f238b48f478788fe3b",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEdPKoFPtdjsqRppteYHEnMrOTfeMoKb6X\nTte2jFwvXWbv8PB8VvmHplf0IZYgX1iMDx2W/YpjpfI4tI9Hh4j+Ow==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 402,
+ "comment" : "edge case for u1",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0220641c9c5d790dc09cdd3dfabb62cdf453e69747a7e3d7aa1a714189ef53171a99",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "04195b51a7cc4a21b8274a70a90de779814c3c8ca358328208c09a29f336b82d6ab2416b7c92fffdc29c3b1282dd2a77a4d04df7f7452047393d849989c5cee9ad",
+ "wx" : "195b51a7cc4a21b8274a70a90de779814c3c8ca358328208c09a29f336b82d6a",
+ "wy" : "00b2416b7c92fffdc29c3b1282dd2a77a4d04df7f7452047393d849989c5cee9ad"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004195b51a7cc4a21b8274a70a90de779814c3c8ca358328208c09a29f336b82d6ab2416b7c92fffdc29c3b1282dd2a77a4d04df7f7452047393d849989c5cee9ad",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEGVtRp8xKIbgnSnCpDed5gUw8jKNYMoII\nwJop8za4LWqyQWt8kv/9wpw7EoLdKnek0E3390UgRzk9hJmJxc7prQ==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 403,
+ "comment" : "edge case for u1",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc022029798c5c45bdf58b4a7b2fdc2c46ab4af1218c7eeb9f0f27a88f1267674de3b0",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "04622fc74732034bec2ddf3bc16d34b3d1f7a327dd2a8c19bab4bb4fe3a24b58aa736b2f2fae76f4dfaecc9096333b01328d51eb3fda9c9227e90d0b449983c4f0",
+ "wx" : "622fc74732034bec2ddf3bc16d34b3d1f7a327dd2a8c19bab4bb4fe3a24b58aa",
+ "wy" : "736b2f2fae76f4dfaecc9096333b01328d51eb3fda9c9227e90d0b449983c4f0"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004622fc74732034bec2ddf3bc16d34b3d1f7a327dd2a8c19bab4bb4fe3a24b58aa736b2f2fae76f4dfaecc9096333b01328d51eb3fda9c9227e90d0b449983c4f0",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEYi/HRzIDS+wt3zvBbTSz0fejJ90qjBm6\ntLtP46JLWKpzay8vrnb0367MkJYzOwEyjVHrP9qckifpDQtEmYPE8A==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 404,
+ "comment" : "edge case for u1",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02200b70f22ca2bb3cefadca1a5711fa3a59f4695385eb5aedf3495d0b6d00f8fd85",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "041f7f85caf2d7550e7af9b65023ebb4dce3450311692309db269969b834b611c70827f45b78020ecbbaf484fdd5bfaae6870f1184c21581baf6ef82bd7b530f93",
+ "wx" : "1f7f85caf2d7550e7af9b65023ebb4dce3450311692309db269969b834b611c7",
+ "wy" : "0827f45b78020ecbbaf484fdd5bfaae6870f1184c21581baf6ef82bd7b530f93"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200041f7f85caf2d7550e7af9b65023ebb4dce3450311692309db269969b834b611c70827f45b78020ecbbaf484fdd5bfaae6870f1184c21581baf6ef82bd7b530f93",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEH3+FyvLXVQ56+bZQI+u03ONFAxFpIwnb\nJplpuDS2EccIJ/RbeAIOy7r0hP3Vv6rmhw8RhMIVgbr274K9e1MPkw==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 405,
+ "comment" : "edge case for u1",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc022016e1e459457679df5b9434ae23f474b3e8d2a70bd6b5dbe692ba16da01f1fb0a",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "0449c197dc80ad1da47a4342b93893e8e1fb0bb94fc33a83e783c00b24c781377aefc20da92bac762951f72474becc734d4cc22ba81b895e282fdac4df7af0f37d",
+ "wx" : "49c197dc80ad1da47a4342b93893e8e1fb0bb94fc33a83e783c00b24c781377a",
+ "wy" : "00efc20da92bac762951f72474becc734d4cc22ba81b895e282fdac4df7af0f37d"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000449c197dc80ad1da47a4342b93893e8e1fb0bb94fc33a83e783c00b24c781377aefc20da92bac762951f72474becc734d4cc22ba81b895e282fdac4df7af0f37d",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEScGX3ICtHaR6Q0K5OJPo4fsLuU/DOoPn\ng8ALJMeBN3rvwg2pK6x2KVH3JHS+zHNNTMIrqBuJXigv2sTfevDzfQ==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 406,
+ "comment" : "edge case for u1",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02202252d685e831b6cf095e4f0535eeaf0ddd3bfa91c210c9d9dc17224702eaf88f",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "04d8cb68517b616a56400aa3868635e54b6f699598a2f6167757654980baf6acbe7ec8cf449c849aa03461a30efada41453c57c6e6fbc93bbc6fa49ada6dc0555c",
+ "wx" : "00d8cb68517b616a56400aa3868635e54b6f699598a2f6167757654980baf6acbe",
+ "wy" : "7ec8cf449c849aa03461a30efada41453c57c6e6fbc93bbc6fa49ada6dc0555c"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004d8cb68517b616a56400aa3868635e54b6f699598a2f6167757654980baf6acbe7ec8cf449c849aa03461a30efada41453c57c6e6fbc93bbc6fa49ada6dc0555c",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE2MtoUXthalZACqOGhjXlS29plZii9hZ3\nV2VJgLr2rL5+yM9EnISaoDRhow762kFFPFfG5vvJO7xvpJrabcBVXA==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 407,
+ "comment" : "edge case for u1",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc022075135abd7c425b60371a477f09ce0f274f64a8c6b061a07b5d63e93c65046c53",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "04030713fb63f2aa6fe2cadf1b20efc259c77445dafa87dac398b84065ca347df3b227818de1a39b589cb071d83e5317cccdc2338e51e312fe31d8dc34a4801750",
+ "wx" : "030713fb63f2aa6fe2cadf1b20efc259c77445dafa87dac398b84065ca347df3",
+ "wy" : "00b227818de1a39b589cb071d83e5317cccdc2338e51e312fe31d8dc34a4801750"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004030713fb63f2aa6fe2cadf1b20efc259c77445dafa87dac398b84065ca347df3b227818de1a39b589cb071d83e5317cccdc2338e51e312fe31d8dc34a4801750",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEAwcT+2Pyqm/iyt8bIO/CWcd0Rdr6h9rD\nmLhAZco0ffOyJ4GN4aObWJywcdg+UxfMzcIzjlHjEv4x2Nw0pIAXUA==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 408,
+ "comment" : "edge case for u2",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02202aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa3e3a49a23a6d8abe95461f8445676b17",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "04babb3677b0955802d8e929a41355640eaf1ea1353f8a771331c4946e3480afa7252f196c87ed3d2a59d3b1b559137fed0013fecefc19fb5a92682b9bca51b950",
+ "wx" : "00babb3677b0955802d8e929a41355640eaf1ea1353f8a771331c4946e3480afa7",
+ "wy" : "252f196c87ed3d2a59d3b1b559137fed0013fecefc19fb5a92682b9bca51b950"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004babb3677b0955802d8e929a41355640eaf1ea1353f8a771331c4946e3480afa7252f196c87ed3d2a59d3b1b559137fed0013fecefc19fb5a92682b9bca51b950",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEurs2d7CVWALY6SmkE1VkDq8eoTU/incT\nMcSUbjSAr6clLxlsh+09KlnTsbVZE3/tABP+zvwZ+1qSaCubylG5UA==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 409,
+ "comment" : "edge case for u2",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02203e888377ac6c71ac9dec3fdb9b56c9feaf0cfaca9f827fc5eb65fc3eac811210",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "041aab2018793471111a8a0e9b143fde02fc95920796d3a63de329b424396fba60bbe4130705174792441b318d3aa31dfe8577821e9b446ec573d272e036c4ebe9",
+ "wx" : "1aab2018793471111a8a0e9b143fde02fc95920796d3a63de329b424396fba60",
+ "wy" : "00bbe4130705174792441b318d3aa31dfe8577821e9b446ec573d272e036c4ebe9"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200041aab2018793471111a8a0e9b143fde02fc95920796d3a63de329b424396fba60bbe4130705174792441b318d3aa31dfe8577821e9b446ec573d272e036c4ebe9",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEGqsgGHk0cREaig6bFD/eAvyVkgeW06Y9\n4ym0JDlvumC75BMHBRdHkkQbMY06ox3+hXeCHptEbsVz0nLgNsTr6Q==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 410,
+ "comment" : "edge case for u2",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc022030bbb794db588363b40679f6c182a50d3ce9679acdd3ffbe36d7813dacbdc818",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "048cb0b909499c83ea806cd885b1dd467a0119f06a88a0276eb0cfda274535a8ff47b5428833bc3f2c8bf9d9041158cf33718a69961cd01729bc0011d1e586ab75",
+ "wx" : "008cb0b909499c83ea806cd885b1dd467a0119f06a88a0276eb0cfda274535a8ff",
+ "wy" : "47b5428833bc3f2c8bf9d9041158cf33718a69961cd01729bc0011d1e586ab75"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200048cb0b909499c83ea806cd885b1dd467a0119f06a88a0276eb0cfda274535a8ff47b5428833bc3f2c8bf9d9041158cf33718a69961cd01729bc0011d1e586ab75",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEjLC5CUmcg+qAbNiFsd1GegEZ8GqIoCdu\nsM/aJ0U1qP9HtUKIM7w/LIv52QQRWM8zcYpplhzQFym8ABHR5YardQ==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 411,
+ "comment" : "edge case for u2",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02202c37fd995622c4fb7fffffffffffffffc7cee745110cb45ab558ed7c90c15a2f",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "048f03cf1a42272bb1532723093f72e6feeac85e1700e9fbe9a6a2dd642d74bf5d3b89a7189dad8cf75fc22f6f158aa27f9c2ca00daca785be3358f2bda3862ca0",
+ "wx" : "008f03cf1a42272bb1532723093f72e6feeac85e1700e9fbe9a6a2dd642d74bf5d",
+ "wy" : "3b89a7189dad8cf75fc22f6f158aa27f9c2ca00daca785be3358f2bda3862ca0"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200048f03cf1a42272bb1532723093f72e6feeac85e1700e9fbe9a6a2dd642d74bf5d3b89a7189dad8cf75fc22f6f158aa27f9c2ca00daca785be3358f2bda3862ca0",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEjwPPGkInK7FTJyMJP3Lm/urIXhcA6fvp\npqLdZC10v107iacYna2M91/CL28ViqJ/nCygDaynhb4zWPK9o4YsoA==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 412,
+ "comment" : "edge case for u2",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02207fd995622c4fb7ffffffffffffffffff5d883ffab5b32652ccdcaa290fccb97d",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "0444de3b9c7a57a8c9e820952753421e7d987bb3d79f71f013805c897e018f8acea2460758c8f98d3fdce121a943659e372c326fff2e5fc2ae7fa3f79daae13c12",
+ "wx" : "44de3b9c7a57a8c9e820952753421e7d987bb3d79f71f013805c897e018f8ace",
+ "wy" : "00a2460758c8f98d3fdce121a943659e372c326fff2e5fc2ae7fa3f79daae13c12"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000444de3b9c7a57a8c9e820952753421e7d987bb3d79f71f013805c897e018f8acea2460758c8f98d3fdce121a943659e372c326fff2e5fc2ae7fa3f79daae13c12",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAERN47nHpXqMnoIJUnU0IefZh7s9efcfAT\ngFyJfgGPis6iRgdYyPmNP9zhIalDZZ43LDJv/y5fwq5/o/edquE8Eg==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 413,
+ "comment" : "edge case for u2",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304302207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc021f4cd53ba7608fffffffffffffffffffff9e5cf143e2539626190a3ab09cce47",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "046fb8b2b48e33031268ad6a517484dc8839ea90f6669ea0c7ac3233e2ac31394a0ac8bbe7f73c2ff4df9978727ac1dfc2fd58647d20f31f99105316b64671f204",
+ "wx" : "6fb8b2b48e33031268ad6a517484dc8839ea90f6669ea0c7ac3233e2ac31394a",
+ "wy" : "0ac8bbe7f73c2ff4df9978727ac1dfc2fd58647d20f31f99105316b64671f204"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200046fb8b2b48e33031268ad6a517484dc8839ea90f6669ea0c7ac3233e2ac31394a0ac8bbe7f73c2ff4df9978727ac1dfc2fd58647d20f31f99105316b64671f204",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEb7iytI4zAxJorWpRdITciDnqkPZmnqDH\nrDIz4qwxOUoKyLvn9zwv9N+ZeHJ6wd/C/VhkfSDzH5kQUxa2RnHyBA==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 414,
+ "comment" : "edge case for u2",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02205622c4fb7fffffffffffffffffffffff928a8f1c7ac7bec1808b9f61c01ec327",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "04bea71122a048693e905ff602b3cf9dd18af69b9fc9d8431d2b1dd26b942c95e6f43c7b8b95eb62082c12db9dbda7fe38e45cbe4a4886907fb81bdb0c5ea9246c",
+ "wx" : "00bea71122a048693e905ff602b3cf9dd18af69b9fc9d8431d2b1dd26b942c95e6",
+ "wy" : "00f43c7b8b95eb62082c12db9dbda7fe38e45cbe4a4886907fb81bdb0c5ea9246c"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004bea71122a048693e905ff602b3cf9dd18af69b9fc9d8431d2b1dd26b942c95e6f43c7b8b95eb62082c12db9dbda7fe38e45cbe4a4886907fb81bdb0c5ea9246c",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEvqcRIqBIaT6QX/YCs8+d0Yr2m5/J2EMd\nKx3Sa5Qsleb0PHuLletiCCwS2529p/445Fy+SkiGkH+4G9sMXqkkbA==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 415,
+ "comment" : "edge case for u2",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc022044104104104104104104104104104103b87853fd3b7d3f8e175125b4382f25ed",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "04da918c731ba06a20cb94ef33b778e981a404a305f1941fe33666b45b03353156e2bb2694f575b45183be78e5c9b5210bf3bf488fd4c8294516d89572ca4f5391",
+ "wx" : "00da918c731ba06a20cb94ef33b778e981a404a305f1941fe33666b45b03353156",
+ "wy" : "00e2bb2694f575b45183be78e5c9b5210bf3bf488fd4c8294516d89572ca4f5391"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004da918c731ba06a20cb94ef33b778e981a404a305f1941fe33666b45b03353156e2bb2694f575b45183be78e5c9b5210bf3bf488fd4c8294516d89572ca4f5391",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE2pGMcxugaiDLlO8zt3jpgaQEowXxlB/j\nNma0WwM1MVbiuyaU9XW0UYO+eOXJtSEL879Ij9TIKUUW2JVyyk9TkQ==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 416,
+ "comment" : "edge case for u2",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02202739ce739ce739ce739ce739ce739ce705560298d1f2f08dc419ac273a5b54d9",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "043007e92c3937dade7964dfa35b0eff031f7eb02aed0a0314411106cdeb70fe3d5a7546fc0552997b20e3d6f413e75e2cb66e116322697114b79bac734bfc4dc5",
+ "wx" : "3007e92c3937dade7964dfa35b0eff031f7eb02aed0a0314411106cdeb70fe3d",
+ "wy" : "5a7546fc0552997b20e3d6f413e75e2cb66e116322697114b79bac734bfc4dc5"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200043007e92c3937dade7964dfa35b0eff031f7eb02aed0a0314411106cdeb70fe3d5a7546fc0552997b20e3d6f413e75e2cb66e116322697114b79bac734bfc4dc5",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEMAfpLDk32t55ZN+jWw7/Ax9+sCrtCgMU\nQREGzetw/j1adUb8BVKZeyDj1vQT514stm4RYyJpcRS3m6xzS/xNxQ==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 417,
+ "comment" : "edge case for u2",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02204888888888888888888888888888888831c83ae82ebe0898776b4c69d11f88de",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "0460e734ef5624d3cbf0ddd375011bd663d6d6aebc644eb599fdf98dbdcd18ce9bd2d90b3ac31f139af832cccf6ccbbb2c6ea11fa97370dc9906da474d7d8a7567",
+ "wx" : "60e734ef5624d3cbf0ddd375011bd663d6d6aebc644eb599fdf98dbdcd18ce9b",
+ "wy" : "00d2d90b3ac31f139af832cccf6ccbbb2c6ea11fa97370dc9906da474d7d8a7567"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000460e734ef5624d3cbf0ddd375011bd663d6d6aebc644eb599fdf98dbdcd18ce9bd2d90b3ac31f139af832cccf6ccbbb2c6ea11fa97370dc9906da474d7d8a7567",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEYOc071Yk08vw3dN1ARvWY9bWrrxkTrWZ\n/fmNvc0YzpvS2Qs6wx8TmvgyzM9sy7ssbqEfqXNw3JkG2kdNfYp1Zw==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 418,
+ "comment" : "edge case for u2",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02206492492492492492492492492492492406dd3a19b8d5fb875235963c593bd2d3",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "0485a900e97858f693c0b7dfa261e380dad6ea046d1f65ddeeedd5f7d8af0ba33769744d15add4f6c0bc3b0da2aec93b34cb8c65f9340ddf74e7b0009eeeccce3c",
+ "wx" : "0085a900e97858f693c0b7dfa261e380dad6ea046d1f65ddeeedd5f7d8af0ba337",
+ "wy" : "69744d15add4f6c0bc3b0da2aec93b34cb8c65f9340ddf74e7b0009eeeccce3c"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000485a900e97858f693c0b7dfa261e380dad6ea046d1f65ddeeedd5f7d8af0ba33769744d15add4f6c0bc3b0da2aec93b34cb8c65f9340ddf74e7b0009eeeccce3c",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEhakA6XhY9pPAt9+iYeOA2tbqBG0fZd3u\n7dX32K8LozdpdE0VrdT2wLw7DaKuyTs0y4xl+TQN33TnsACe7szOPA==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 419,
+ "comment" : "edge case for u2",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02206aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa3e3a49a23a6d8abe95461f8445676b15",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "0438066f75d88efc4c93de36f49e037b234cc18b1de5608750a62cab0345401046a3e84bed8cfcb819ef4d550444f2ce4b651766b69e2e2901f88836ff90034fed",
+ "wx" : "38066f75d88efc4c93de36f49e037b234cc18b1de5608750a62cab0345401046",
+ "wy" : "00a3e84bed8cfcb819ef4d550444f2ce4b651766b69e2e2901f88836ff90034fed"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000438066f75d88efc4c93de36f49e037b234cc18b1de5608750a62cab0345401046a3e84bed8cfcb819ef4d550444f2ce4b651766b69e2e2901f88836ff90034fed",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEOAZvddiO/EyT3jb0ngN7I0zBix3lYIdQ\npiyrA0VAEEaj6EvtjPy4Ge9NVQRE8s5LZRdmtp4uKQH4iDb/kANP7Q==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 420,
+ "comment" : "edge case for u2",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02202aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa3e3a49a23a6d8abe95461f8445676b17",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "0498f68177dc95c1b4cbfa5245488ca523a7d5629470d035d621a443c72f39aabfa33d29546fa1c648f2c7d5ccf70cf1ce4ab79b5db1ac059dbecd068dbdff1b89",
+ "wx" : "0098f68177dc95c1b4cbfa5245488ca523a7d5629470d035d621a443c72f39aabf",
+ "wy" : "00a33d29546fa1c648f2c7d5ccf70cf1ce4ab79b5db1ac059dbecd068dbdff1b89"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000498f68177dc95c1b4cbfa5245488ca523a7d5629470d035d621a443c72f39aabfa33d29546fa1c648f2c7d5ccf70cf1ce4ab79b5db1ac059dbecd068dbdff1b89",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEmPaBd9yVwbTL+lJFSIylI6fVYpRw0DXW\nIaRDxy85qr+jPSlUb6HGSPLH1cz3DPHOSrebXbGsBZ2+zQaNvf8biQ==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 421,
+ "comment" : "edge case for u2",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02203ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "045c2bbfa23c9b9ad07f038aa89b4930bf267d9401e4255de9e8da0a5078ec8277e3e882a31d5e6a379e0793983ccded39b95c4353ab2ff01ea5369ba47b0c3191",
+ "wx" : "5c2bbfa23c9b9ad07f038aa89b4930bf267d9401e4255de9e8da0a5078ec8277",
+ "wy" : "00e3e882a31d5e6a379e0793983ccded39b95c4353ab2ff01ea5369ba47b0c3191"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200045c2bbfa23c9b9ad07f038aa89b4930bf267d9401e4255de9e8da0a5078ec8277e3e882a31d5e6a379e0793983ccded39b95c4353ab2ff01ea5369ba47b0c3191",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEXCu/ojybmtB/A4qom0kwvyZ9lAHkJV3p\n6NoKUHjsgnfj6IKjHV5qN54Hk5g8ze05uVxDU6sv8B6lNpukewwxkQ==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 422,
+ "comment" : "edge case for u2",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0220185ddbca6dac41b1da033cfb60c152869e74b3cd66e9ffdf1b6bc09ed65ee40c",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "042ea7133432339c69d27f9b267281bd2ddd5f19d6338d400a05cd3647b157a3853547808298448edb5e701ade84cd5fb1ac9567ba5e8fb68a6b933ec4b5cc84cc",
+ "wx" : "2ea7133432339c69d27f9b267281bd2ddd5f19d6338d400a05cd3647b157a385",
+ "wy" : "3547808298448edb5e701ade84cd5fb1ac9567ba5e8fb68a6b933ec4b5cc84cc"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200042ea7133432339c69d27f9b267281bd2ddd5f19d6338d400a05cd3647b157a3853547808298448edb5e701ade84cd5fb1ac9567ba5e8fb68a6b933ec4b5cc84cc",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAELqcTNDIznGnSf5smcoG9Ld1fGdYzjUAK\nBc02R7FXo4U1R4CCmESO215wGt6EzV+xrJVnul6Ptoprkz7EtcyEzA==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 423,
+ "comment" : "point duplication during verification",
+ "flags" : [
+ "PointDuplication"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3044022032b0d10d8d0e04bc8d4d064d270699e87cffc9b49c5c20730e1c26f6105ddcda022029ed3d67b3d505be95580d77d5b792b436881179b2b6b2e04c5fe592d38d82d9",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "042ea7133432339c69d27f9b267281bd2ddd5f19d6338d400a05cd3647b157a385cab87f7d67bb7124a18fe5217b32a04e536a9845a1704975946cc13a4a337763",
+ "wx" : "2ea7133432339c69d27f9b267281bd2ddd5f19d6338d400a05cd3647b157a385",
+ "wy" : "00cab87f7d67bb7124a18fe5217b32a04e536a9845a1704975946cc13a4a337763"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200042ea7133432339c69d27f9b267281bd2ddd5f19d6338d400a05cd3647b157a385cab87f7d67bb7124a18fe5217b32a04e536a9845a1704975946cc13a4a337763",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAELqcTNDIznGnSf5smcoG9Ld1fGdYzjUAK\nBc02R7FXo4XKuH99Z7txJKGP5SF7MqBOU2qYRaFwSXWUbME6SjN3Yw==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 424,
+ "comment" : "duplication bug",
+ "flags" : [
+ "PointDuplication"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3044022032b0d10d8d0e04bc8d4d064d270699e87cffc9b49c5c20730e1c26f6105ddcda022029ed3d67b3d505be95580d77d5b792b436881179b2b6b2e04c5fe592d38d82d9",
+ "result" : "invalid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "048aa2c64fa9c6437563abfbcbd00b2048d48c18c152a2a6f49036de7647ebe82e1ce64387995c68a060fa3bc0399b05cc06eec7d598f75041a4917e692b7f51ff",
+ "wx" : "008aa2c64fa9c6437563abfbcbd00b2048d48c18c152a2a6f49036de7647ebe82e",
+ "wy" : "1ce64387995c68a060fa3bc0399b05cc06eec7d598f75041a4917e692b7f51ff"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200048aa2c64fa9c6437563abfbcbd00b2048d48c18c152a2a6f49036de7647ebe82e1ce64387995c68a060fa3bc0399b05cc06eec7d598f75041a4917e692b7f51ff",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEiqLGT6nGQ3Vjq/vL0AsgSNSMGMFSoqb0\nkDbedkfr6C4c5kOHmVxooGD6O8A5mwXMBu7H1Zj3UEGkkX5pK39R/w==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 425,
+ "comment" : "comparison with point at infinity ",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c0022033333333333333333333333333333332f222f8faefdb533f265d461c29a47373",
+ "result" : "invalid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "04391427ff7ee78013c14aec7d96a8a062209298a783835e94fd6549d502fff71fdd6624ec343ad9fcf4d9872181e59f842f9ba4cccae09a6c0972fb6ac6b4c6bd",
+ "wx" : "391427ff7ee78013c14aec7d96a8a062209298a783835e94fd6549d502fff71f",
+ "wy" : "00dd6624ec343ad9fcf4d9872181e59f842f9ba4cccae09a6c0972fb6ac6b4c6bd"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004391427ff7ee78013c14aec7d96a8a062209298a783835e94fd6549d502fff71fdd6624ec343ad9fcf4d9872181e59f842f9ba4cccae09a6c0972fb6ac6b4c6bd",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEORQn/37ngBPBSux9lqigYiCSmKeDg16U\n/WVJ1QL/9x/dZiTsNDrZ/PTZhyGB5Z+EL5ukzMrgmmwJcvtqxrTGvQ==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 426,
+ "comment" : "extreme value for k and edgecase s",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3045022100c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c0",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "04e762b8a219b4f180219cc7a9059245e4961bd191c03899789c7a34b89e8c138ec1533ef0419bb7376e0bfde9319d10a06968791d9ea0eed9c1ce6345aed9759e",
+ "wx" : "00e762b8a219b4f180219cc7a9059245e4961bd191c03899789c7a34b89e8c138e",
+ "wy" : "00c1533ef0419bb7376e0bfde9319d10a06968791d9ea0eed9c1ce6345aed9759e"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004e762b8a219b4f180219cc7a9059245e4961bd191c03899789c7a34b89e8c138ec1533ef0419bb7376e0bfde9319d10a06968791d9ea0eed9c1ce6345aed9759e",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE52K4ohm08YAhnMepBZJF5JYb0ZHAOJl4\nnHo0uJ6ME47BUz7wQZu3N24L/ekxnRCgaWh5HZ6g7tnBzmNFrtl1ng==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 427,
+ "comment" : "extreme value for k and s^-1",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3045022100c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5022049249249249249249249249249249248c79facd43214c011123c1b03a93412a5",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "049aedb0d281db164e130000c5697fae0f305ef848be6fffb43ac593fbb950e952fa6f633359bdcd82b56b0b9f965b037789d46b9a8141b791b2aefa713f96c175",
+ "wx" : "009aedb0d281db164e130000c5697fae0f305ef848be6fffb43ac593fbb950e952",
+ "wy" : "00fa6f633359bdcd82b56b0b9f965b037789d46b9a8141b791b2aefa713f96c175"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200049aedb0d281db164e130000c5697fae0f305ef848be6fffb43ac593fbb950e952fa6f633359bdcd82b56b0b9f965b037789d46b9a8141b791b2aefa713f96c175",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEmu2w0oHbFk4TAADFaX+uDzBe+Ei+b/+0\nOsWT+7lQ6VL6b2MzWb3NgrVrC5+WWwN3idRrmoFBt5GyrvpxP5bBdQ==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 428,
+ "comment" : "extreme value for k and s^-1",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3045022100c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5022066666666666666666666666666666665e445f1f5dfb6a67e4cba8c385348e6e7",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "048ad445db62816260e4e687fd1884e48b9fc0636d031547d63315e792e19bfaee1de64f99d5f1cd8b6ec9cb0f787a654ae86993ba3db1008ef43cff0684cb22bd",
+ "wx" : "008ad445db62816260e4e687fd1884e48b9fc0636d031547d63315e792e19bfaee",
+ "wy" : "1de64f99d5f1cd8b6ec9cb0f787a654ae86993ba3db1008ef43cff0684cb22bd"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200048ad445db62816260e4e687fd1884e48b9fc0636d031547d63315e792e19bfaee1de64f99d5f1cd8b6ec9cb0f787a654ae86993ba3db1008ef43cff0684cb22bd",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEitRF22KBYmDk5of9GITki5/AY20DFUfW\nMxXnkuGb+u4d5k+Z1fHNi27Jyw94emVK6GmTuj2xAI70PP8GhMsivQ==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 429,
+ "comment" : "extreme value for k and s^-1",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3045022100c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5022066666666666666666666666666666665e445f1f5dfb6a67e4cba8c385348e6e7",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "041f5799c95be89063b24f26e40cb928c1a868a76fb0094607e8043db409c91c32e75724e813a4191e3a839007f08e2e897388b06d4a00de6de60e536d91fab566",
+ "wx" : "1f5799c95be89063b24f26e40cb928c1a868a76fb0094607e8043db409c91c32",
+ "wy" : "00e75724e813a4191e3a839007f08e2e897388b06d4a00de6de60e536d91fab566"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200041f5799c95be89063b24f26e40cb928c1a868a76fb0094607e8043db409c91c32e75724e813a4191e3a839007f08e2e897388b06d4a00de6de60e536d91fab566",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEH1eZyVvokGOyTybkDLkowahop2+wCUYH\n6AQ9tAnJHDLnVyToE6QZHjqDkAfwji6Jc4iwbUoA3m3mDlNtkfq1Zg==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 430,
+ "comment" : "extreme value for k and s^-1",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3045022100c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5022049249249249249249249249249249248c79facd43214c011123c1b03a93412a5",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "04a3331a4e1b4223ec2c027edd482c928a14ed358d93f1d4217d39abf69fcb5ccc28d684d2aaabcd6383775caa6239de26d4c6937bb603ecb4196082f4cffd509d",
+ "wx" : "00a3331a4e1b4223ec2c027edd482c928a14ed358d93f1d4217d39abf69fcb5ccc",
+ "wy" : "28d684d2aaabcd6383775caa6239de26d4c6937bb603ecb4196082f4cffd509d"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004a3331a4e1b4223ec2c027edd482c928a14ed358d93f1d4217d39abf69fcb5ccc28d684d2aaabcd6383775caa6239de26d4c6937bb603ecb4196082f4cffd509d",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEozMaThtCI+wsAn7dSCySihTtNY2T8dQh\nfTmr9p/LXMwo1oTSqqvNY4N3XKpiOd4m1MaTe7YD7LQZYIL0z/1QnQ==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 431,
+ "comment" : "extreme value for k",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3045022100c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee502200eb10e5ab95f2f275348d82ad2e4d7949c8193800d8c9c75df58e343f0ebba7b",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "043f3952199774c7cf39b38b66cb1042a6260d8680803845e4d433adba3bb248185ea495b68cbc7ed4173ee63c9042dc502625c7eb7e21fb02ca9a9114e0a3a18d",
+ "wx" : "3f3952199774c7cf39b38b66cb1042a6260d8680803845e4d433adba3bb24818",
+ "wy" : "5ea495b68cbc7ed4173ee63c9042dc502625c7eb7e21fb02ca9a9114e0a3a18d"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200043f3952199774c7cf39b38b66cb1042a6260d8680803845e4d433adba3bb248185ea495b68cbc7ed4173ee63c9042dc502625c7eb7e21fb02ca9a9114e0a3a18d",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEPzlSGZd0x885s4tmyxBCpiYNhoCAOEXk\n1DOtujuySBhepJW2jLx+1Bc+5jyQQtxQJiXH634h+wLKmpEU4KOhjQ==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 432,
+ "comment" : "extreme value for k and edgecase s",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3044022079be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c0",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "04cdfb8c0f422e144e137c2412c86c171f5fe3fa3f5bbb544e9076288f3ced786e054fd0721b77c11c79beacb3c94211b0a19bda08652efeaf92513a3b0a163698",
+ "wx" : "00cdfb8c0f422e144e137c2412c86c171f5fe3fa3f5bbb544e9076288f3ced786e",
+ "wy" : "054fd0721b77c11c79beacb3c94211b0a19bda08652efeaf92513a3b0a163698"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004cdfb8c0f422e144e137c2412c86c171f5fe3fa3f5bbb544e9076288f3ced786e054fd0721b77c11c79beacb3c94211b0a19bda08652efeaf92513a3b0a163698",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEzfuMD0IuFE4TfCQSyGwXH1/j+j9bu1RO\nkHYojzzteG4FT9ByG3fBHHm+rLPJQhGwoZvaCGUu/q+SUTo7ChY2mA==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 433,
+ "comment" : "extreme value for k and s^-1",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3044022079be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798022049249249249249249249249249249248c79facd43214c011123c1b03a93412a5",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "0473598a6a1c68278fa6bfd0ce4064e68235bc1c0f6b20a928108be336730f87e3cbae612519b5032ecc85aed811271a95fe7939d5d3460140ba318f4d14aba31d",
+ "wx" : "73598a6a1c68278fa6bfd0ce4064e68235bc1c0f6b20a928108be336730f87e3",
+ "wy" : "00cbae612519b5032ecc85aed811271a95fe7939d5d3460140ba318f4d14aba31d"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000473598a6a1c68278fa6bfd0ce4064e68235bc1c0f6b20a928108be336730f87e3cbae612519b5032ecc85aed811271a95fe7939d5d3460140ba318f4d14aba31d",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEc1mKahxoJ4+mv9DOQGTmgjW8HA9rIKko\nEIvjNnMPh+PLrmElGbUDLsyFrtgRJxqV/nk51dNGAUC6MY9NFKujHQ==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 434,
+ "comment" : "extreme value for k and s^-1",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3044022079be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798022066666666666666666666666666666665e445f1f5dfb6a67e4cba8c385348e6e7",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "0458debd9a7ee2c9d59132478a5440ae4d5d7ed437308369f92ea86c82183f10a16773e76f5edbf4da0e4f1bdffac0f57257e1dfa465842931309a24245fda6a5d",
+ "wx" : "58debd9a7ee2c9d59132478a5440ae4d5d7ed437308369f92ea86c82183f10a1",
+ "wy" : "6773e76f5edbf4da0e4f1bdffac0f57257e1dfa465842931309a24245fda6a5d"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000458debd9a7ee2c9d59132478a5440ae4d5d7ed437308369f92ea86c82183f10a16773e76f5edbf4da0e4f1bdffac0f57257e1dfa465842931309a24245fda6a5d",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEWN69mn7iydWRMkeKVECuTV1+1Dcwg2n5\nLqhsghg/EKFnc+dvXtv02g5PG9/6wPVyV+HfpGWEKTEwmiQkX9pqXQ==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 435,
+ "comment" : "extreme value for k and s^-1",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3044022079be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798022066666666666666666666666666666665e445f1f5dfb6a67e4cba8c385348e6e7",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "048b904de47967340c5f8c3572a720924ef7578637feab1949acb241a5a6ac3f5b950904496f9824b1d63f3313bae21b89fae89afdfc811b5ece03fd5aa301864f",
+ "wx" : "008b904de47967340c5f8c3572a720924ef7578637feab1949acb241a5a6ac3f5b",
+ "wy" : "00950904496f9824b1d63f3313bae21b89fae89afdfc811b5ece03fd5aa301864f"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200048b904de47967340c5f8c3572a720924ef7578637feab1949acb241a5a6ac3f5b950904496f9824b1d63f3313bae21b89fae89afdfc811b5ece03fd5aa301864f",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEi5BN5HlnNAxfjDVypyCSTvdXhjf+qxlJ\nrLJBpaasP1uVCQRJb5gksdY/MxO64huJ+uia/fyBG17OA/1aowGGTw==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 436,
+ "comment" : "extreme value for k and s^-1",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3044022079be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798022049249249249249249249249249249248c79facd43214c011123c1b03a93412a5",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "04f4892b6d525c771e035f2a252708f3784e48238604b4f94dc56eaa1e546d941a346b1aa0bce68b1c50e5b52f509fb5522e5c25e028bc8f863402edb7bcad8b1b",
+ "wx" : "00f4892b6d525c771e035f2a252708f3784e48238604b4f94dc56eaa1e546d941a",
+ "wy" : "346b1aa0bce68b1c50e5b52f509fb5522e5c25e028bc8f863402edb7bcad8b1b"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004f4892b6d525c771e035f2a252708f3784e48238604b4f94dc56eaa1e546d941a346b1aa0bce68b1c50e5b52f509fb5522e5c25e028bc8f863402edb7bcad8b1b",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE9IkrbVJcdx4DXyolJwjzeE5II4YEtPlN\nxW6qHlRtlBo0axqgvOaLHFDltS9Qn7VSLlwl4Ci8j4Y0Au23vK2LGw==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 437,
+ "comment" : "extreme value for k",
+ "flags" : [
+ "ArithmeticError"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3044022079be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179802200eb10e5ab95f2f275348d82ad2e4d7949c8193800d8c9c75df58e343f0ebba7b",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8",
+ "wx" : "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
+ "wy" : "483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEeb5mfvncu6xVoGKVzocLBwKb/NstzijZ\nWfKBWxb4F5hIOtp3JqPEZV2k+/wOEQio/Re0SKaFVBmcR9CP+xDUuA==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 438,
+ "comment" : "public key shares x-coordinate with generator",
+ "flags" : [
+ "PointDuplication"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3045022100bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca60502302202492492492492492492492492492492463cfd66a190a6008891e0d81d49a0952",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 439,
+ "comment" : "public key shares x-coordinate with generator",
+ "flags" : [
+ "PointDuplication"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3044022044a5ad0bd0636d9e12bc9e0a6bdd5e1bba77f523842193b3b82e448e05d5f11e02202492492492492492492492492492492463cfd66a190a6008891e0d81d49a0952",
+ "result" : "invalid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798b7c52588d95c3b9aa25b0403f1eef75702e84bb7597aabe663b82f6f04ef2777",
+ "wx" : "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
+ "wy" : "00b7c52588d95c3b9aa25b0403f1eef75702e84bb7597aabe663b82f6f04ef2777"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798b7c52588d95c3b9aa25b0403f1eef75702e84bb7597aabe663b82f6f04ef2777",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEeb5mfvncu6xVoGKVzocLBwKb/NstzijZ\nWfKBWxb4F5i3xSWI2Vw7mqJbBAPx7vdXAuhLt1l6q+ZjuC9vBO8ndw==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 440,
+ "comment" : "public key shares x-coordinate with generator",
+ "flags" : [
+ "PointDuplication"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3045022100bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca60502302202492492492492492492492492492492463cfd66a190a6008891e0d81d49a0952",
+ "result" : "invalid"
+ },
+ {
+ "tcId" : 441,
+ "comment" : "public key shares x-coordinate with generator",
+ "flags" : [
+ "PointDuplication"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3044022044a5ad0bd0636d9e12bc9e0a6bdd5e1bba77f523842193b3b82e448e05d5f11e02202492492492492492492492492492492463cfd66a190a6008891e0d81d49a0952",
+ "result" : "invalid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "04782c8ed17e3b2a783b5464f33b09652a71c678e05ec51e84e2bcfc663a3de963af9acb4280b8c7f7c42f4ef9aba6245ec1ec1712fd38a0fa96418d8cd6aa6152",
+ "wx" : "782c8ed17e3b2a783b5464f33b09652a71c678e05ec51e84e2bcfc663a3de963",
+ "wy" : "00af9acb4280b8c7f7c42f4ef9aba6245ec1ec1712fd38a0fa96418d8cd6aa6152"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004782c8ed17e3b2a783b5464f33b09652a71c678e05ec51e84e2bcfc663a3de963af9acb4280b8c7f7c42f4ef9aba6245ec1ec1712fd38a0fa96418d8cd6aa6152",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEeCyO0X47Kng7VGTzOwllKnHGeOBexR6E\n4rz8Zjo96WOvmstCgLjH98QvTvmrpiRewewXEv04oPqWQY2M1qphUg==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 442,
+ "comment" : "pseudorandom signature",
+ "flags" : [
+ "ValidSignature"
+ ],
+ "msg" : "",
+ "sig" : "3045022100f80ae4f96cdbc9d853f83d47aae225bf407d51c56b7776cd67d0dc195d99a9dc02204cfc1d941e08cb9aceadde0f4ccead76b30d332fc442115d50e673e28686b70b",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 443,
+ "comment" : "pseudorandom signature",
+ "flags" : [
+ "ValidSignature"
+ ],
+ "msg" : "4d7367",
+ "sig" : "30440220109cd8ae0374358984a8249c0a843628f2835ffad1df1a9a69aa2fe72355545c02205390ff250ac4274e1cb25cd6ca6491f6b91281e32f5b264d87977aed4a94e77b",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 444,
+ "comment" : "pseudorandom signature",
+ "flags" : [
+ "ValidSignature"
+ ],
+ "msg" : "313233343030",
+ "sig" : "3045022100d035ee1f17fdb0b2681b163e33c359932659990af77dca632012b30b27a057b302201939d9f3b2858bc13e3474cb50e6a82be44faa71940f876c1cba4c3e989202b6",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 445,
+ "comment" : "pseudorandom signature",
+ "flags" : [
+ "ValidSignature"
+ ],
+ "msg" : "0000000000000000000000000000000000000000",
+ "sig" : "304402204f053f563ad34b74fd8c9934ce59e79c2eb8e6eca0fef5b323ca67d5ac7ed23802204d4b05daa0719e773d8617dce5631c5fd6f59c9bdc748e4b55c970040af01be5",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "046e823555452914099182c6b2c1d6f0b5d28d50ccd005af2ce1bba541aa40caff00000001060492d5a5673e0f25d8d50fb7e58c49d86d46d4216955e0aa3d40e1",
+ "wx" : "6e823555452914099182c6b2c1d6f0b5d28d50ccd005af2ce1bba541aa40caff",
+ "wy" : "01060492d5a5673e0f25d8d50fb7e58c49d86d46d4216955e0aa3d40e1"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200046e823555452914099182c6b2c1d6f0b5d28d50ccd005af2ce1bba541aa40caff00000001060492d5a5673e0f25d8d50fb7e58c49d86d46d4216955e0aa3d40e1",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEboI1VUUpFAmRgsaywdbwtdKNUMzQBa8s\n4bulQapAyv8AAAABBgSS1aVnPg8l2NUPt+WMSdhtRtQhaVXgqj1A4Q==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 446,
+ "comment" : "y-coordinate of the public key is small",
+ "flags" : [
+ "EdgeCasePublicKey"
+ ],
+ "msg" : "4d657373616765",
+ "sig" : "304402206d6a4f556ccce154e7fb9f19e76c3deca13d59cc2aeb4ecad968aab2ded45965022053b9fa74803ede0fc4441bf683d56c564d3e274e09ccf47390badd1471c05fb7",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 447,
+ "comment" : "y-coordinate of the public key is small",
+ "flags" : [
+ "EdgeCasePublicKey"
+ ],
+ "msg" : "4d657373616765",
+ "sig" : "3044022100aad503de9b9fd66b948e9acf596f0a0e65e700b28b26ec56e6e45e846489b3c4021f0ddc3a2f89abb817bb85c062ce02f823c63fc26b269e0bc9b84d81a5aa123d",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 448,
+ "comment" : "y-coordinate of the public key is small",
+ "flags" : [
+ "EdgeCasePublicKey"
+ ],
+ "msg" : "4d657373616765",
+ "sig" : "30450221009182cebd3bb8ab572e167174397209ef4b1d439af3b200cdf003620089e43225022054477c982ea019d2e1000497fc25fcee1bccae55f2ac27530ae53b29c4b356a4",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "046e823555452914099182c6b2c1d6f0b5d28d50ccd005af2ce1bba541aa40cafffffffffef9fb6d2a5a98c1f0da272af0481a73b62792b92bde96aa1e55c2bb4e",
+ "wx" : "6e823555452914099182c6b2c1d6f0b5d28d50ccd005af2ce1bba541aa40caff",
+ "wy" : "00fffffffef9fb6d2a5a98c1f0da272af0481a73b62792b92bde96aa1e55c2bb4e"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200046e823555452914099182c6b2c1d6f0b5d28d50ccd005af2ce1bba541aa40cafffffffffef9fb6d2a5a98c1f0da272af0481a73b62792b92bde96aa1e55c2bb4e",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEboI1VUUpFAmRgsaywdbwtdKNUMzQBa8s\n4bulQapAyv/////++fttKlqYwfDaJyrwSBpztieSuSvelqoeVcK7Tg==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 449,
+ "comment" : "y-coordinate of the public key is large",
+ "flags" : [
+ "EdgeCasePublicKey"
+ ],
+ "msg" : "4d657373616765",
+ "sig" : "304402203854a3998aebdf2dbc28adac4181462ccac7873907ab7f212c42db0e69b56ed802203ed3f6b8a388d02f3e4df9f2ae9c1bd2c3916a686460dffcd42909cd7f82058e",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 450,
+ "comment" : "y-coordinate of the public key is large",
+ "flags" : [
+ "EdgeCasePublicKey"
+ ],
+ "msg" : "4d657373616765",
+ "sig" : "3045022100e94dbdc38795fe5c904d8f16d969d3b587f0a25d2de90b6d8c5c53ff887e360702207a947369c164972521bb8af406813b2d9f94d2aeaa53d4c215aaa0a2578a2c5d",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 451,
+ "comment" : "y-coordinate of the public key is large",
+ "flags" : [
+ "EdgeCasePublicKey"
+ ],
+ "msg" : "4d657373616765",
+ "sig" : "3044022049fc102a08ca47b60e0858cd0284d22cddd7233f94aaffbb2db1dd2cf08425e102205b16fca5a12cdb39701697ad8e39ffd6bdec0024298afaa2326aea09200b14d6",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "04000000013fd22248d64d95f73c29b48ab48631850be503fd00f8468b5f0f70e0f6ee7aa43bc2c6fd25b1d8269241cbdd9dbb0dac96dc96231f430705f838717d",
+ "wx" : "013fd22248d64d95f73c29b48ab48631850be503fd00f8468b5f0f70e0",
+ "wy" : "00f6ee7aa43bc2c6fd25b1d8269241cbdd9dbb0dac96dc96231f430705f838717d"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004000000013fd22248d64d95f73c29b48ab48631850be503fd00f8468b5f0f70e0f6ee7aa43bc2c6fd25b1d8269241cbdd9dbb0dac96dc96231f430705f838717d",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEAAAAAT/SIkjWTZX3PCm0irSGMYUL5QP9\nAPhGi18PcOD27nqkO8LG/SWx2CaSQcvdnbsNrJbcliMfQwcF+DhxfQ==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 452,
+ "comment" : "x-coordinate of the public key is small",
+ "flags" : [
+ "EdgeCasePublicKey"
+ ],
+ "msg" : "4d657373616765",
+ "sig" : "3044022041efa7d3f05a0010675fcb918a45c693da4b348df21a59d6f9cd73e0d831d67a02204454ada693e5e26b7bd693236d340f80545c834577b6f73d378c7bcc534244da",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 453,
+ "comment" : "x-coordinate of the public key is small",
+ "flags" : [
+ "EdgeCasePublicKey"
+ ],
+ "msg" : "4d657373616765",
+ "sig" : "3045022100b615698c358b35920dd883eca625a6c5f7563970cdfc378f8fe0cee17092144c022025f47b326b5be1fb610b885153ea84d41eb4716be66a994e8779989df1c863d4",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 454,
+ "comment" : "x-coordinate of the public key is small",
+ "flags" : [
+ "EdgeCasePublicKey"
+ ],
+ "msg" : "4d657373616765",
+ "sig" : "304502210087cf8c0eb82d44f69c60a2ff5457d3aaa322e7ec61ae5aecfd678ae1c1932b0e02203add3b115815047d6eb340a3e008989eaa0f8708d1794814729094d08d2460d3",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "0425afd689acabaed67c1f296de59406f8c550f57146a0b4ec2c97876dfffffffffa46a76e520322dfbc491ec4f0cc197420fc4ea5883d8f6dd53c354bc4f67c35",
+ "wx" : "25afd689acabaed67c1f296de59406f8c550f57146a0b4ec2c97876dffffffff",
+ "wy" : "00fa46a76e520322dfbc491ec4f0cc197420fc4ea5883d8f6dd53c354bc4f67c35"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000425afd689acabaed67c1f296de59406f8c550f57146a0b4ec2c97876dfffffffffa46a76e520322dfbc491ec4f0cc197420fc4ea5883d8f6dd53c354bc4f67c35",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEJa/WiayrrtZ8Hylt5ZQG+MVQ9XFGoLTs\nLJeHbf/////6RqduUgMi37xJHsTwzBl0IPxOpYg9j23VPDVLxPZ8NQ==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 455,
+ "comment" : "x-coordinate of the public key has many trailing 1's",
+ "flags" : [
+ "EdgeCasePublicKey"
+ ],
+ "msg" : "4d657373616765",
+ "sig" : "3044022062f48ef71ace27bf5a01834de1f7e3f948b9dce1ca1e911d5e13d3b104471d8202205ea8f33f0c778972c4582080deda9b341857dd64514f0849a05f6964c2e34022",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 456,
+ "comment" : "x-coordinate of the public key has many trailing 1's",
+ "flags" : [
+ "EdgeCasePublicKey"
+ ],
+ "msg" : "4d657373616765",
+ "sig" : "3045022100f6b0e2f6fe020cf7c0c20137434344ed7add6c4be51861e2d14cbda472a6ffb402206416c8dd3e5c5282b306e8dc8ff34ab64cc99549232d678d714402eb6ca7aa0f",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 457,
+ "comment" : "x-coordinate of the public key has many trailing 1's",
+ "flags" : [
+ "EdgeCasePublicKey"
+ ],
+ "msg" : "4d657373616765",
+ "sig" : "3045022100db09d8460f05eff23bc7e436b67da563fa4b4edb58ac24ce201fa8a358125057022046da116754602940c8999c8d665f786c50f5772c0a3cdbda075e77eabc64df16",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "04d12e6c66b67734c3c84d2601cf5d35dc097e27637f0aca4a4fdb74b6aadd3bb93f5bdff88bd5736df898e699006ed750f11cf07c5866cd7ad70c7121ffffffff",
+ "wx" : "00d12e6c66b67734c3c84d2601cf5d35dc097e27637f0aca4a4fdb74b6aadd3bb9",
+ "wy" : "3f5bdff88bd5736df898e699006ed750f11cf07c5866cd7ad70c7121ffffffff"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004d12e6c66b67734c3c84d2601cf5d35dc097e27637f0aca4a4fdb74b6aadd3bb93f5bdff88bd5736df898e699006ed750f11cf07c5866cd7ad70c7121ffffffff",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE0S5sZrZ3NMPITSYBz1013Al+J2N/CspK\nT9t0tqrdO7k/W9/4i9VzbfiY5pkAbtdQ8RzwfFhmzXrXDHEh/////w==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 458,
+ "comment" : "y-coordinate of the public key has many trailing 1's",
+ "flags" : [
+ "EdgeCasePublicKey"
+ ],
+ "msg" : "4d657373616765",
+ "sig" : "30440220592c41e16517f12fcabd98267674f974b588e9f35d35406c1a7bb2ed1d19b7b802203e65a06bd9f83caaeb7b00f2368d7e0dece6b12221269a9b5b765198f840a3a1",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 459,
+ "comment" : "y-coordinate of the public key has many trailing 1's",
+ "flags" : [
+ "EdgeCasePublicKey"
+ ],
+ "msg" : "4d657373616765",
+ "sig" : "3045022100be0d70887d5e40821a61b68047de4ea03debfdf51cdf4d4b195558b959a032b202207d994b2d8f1dbbeb13534eb3f6e5dccd85f5c4133c27d9e64271b1826ce1f67d",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 460,
+ "comment" : "y-coordinate of the public key has many trailing 1's",
+ "flags" : [
+ "EdgeCasePublicKey"
+ ],
+ "msg" : "4d657373616765",
+ "sig" : "3045022100fae92dfcb2ee392d270af3a5739faa26d4f97bfd39ed3cbee4d29e26af3b206a02206c9ba37f9faa6a1fd3f65f23b4e853d4692a7274240a12db7ba3884830630d16",
+ "result" : "valid"
+ }
+ ]
+ },
+ {
+ "type" : "EcdsaBitcoinVerify",
+ "publicKey" : {
+ "type" : "EcPublicKey",
+ "curve" : "secp256k1",
+ "keySize" : 256,
+ "uncompressed" : "046d4a7f60d4774a4f0aa8bbdedb953c7eea7909407e3164755664bc2800000000e659d34e4df38d9e8c9eaadfba36612c769195be86c77aac3f36e78b538680fb",
+ "wx" : "6d4a7f60d4774a4f0aa8bbdedb953c7eea7909407e3164755664bc2800000000",
+ "wy" : "00e659d34e4df38d9e8c9eaadfba36612c769195be86c77aac3f36e78b538680fb"
+ },
+ "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200046d4a7f60d4774a4f0aa8bbdedb953c7eea7909407e3164755664bc2800000000e659d34e4df38d9e8c9eaadfba36612c769195be86c77aac3f36e78b538680fb",
+ "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEbUp/YNR3Sk8KqLve25U8fup5CUB+MWR1\nVmS8KAAAAADmWdNOTfONnoyeqt+6NmEsdpGVvobHeqw/NueLU4aA+w==\n-----END PUBLIC KEY-----\n",
+ "sha" : "SHA-256",
+ "tests" : [
+ {
+ "tcId" : 461,
+ "comment" : "x-coordinate of the public key has many trailing 0's",
+ "flags" : [
+ "EdgeCasePublicKey"
+ ],
+ "msg" : "4d657373616765",
+ "sig" : "30440220176a2557566ffa518b11226694eb9802ed2098bfe278e5570fe1d5d7af18a94302201291df6a0ed5fc0d15098e70bcf13a009284dfd0689d3bb4be6ceeb9be1487c4",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 462,
+ "comment" : "x-coordinate of the public key has many trailing 0's",
+ "flags" : [
+ "EdgeCasePublicKey"
+ ],
+ "msg" : "4d657373616765",
+ "sig" : "3044022060be20c3dbc162dd34d26780621c104bbe5dace630171b2daef0d826409ee5c20220427f7e4d889d549170bda6a9409fb1cb8b0e763d13eea7bd97f64cf41dc6e497",
+ "result" : "valid"
+ },
+ {
+ "tcId" : 463,
+ "comment" : "x-coordinate of the public key has many trailing 0's",
+ "flags" : [
+ "EdgeCasePublicKey"
+ ],
+ "msg" : "4d657373616765",
+ "sig" : "3045022100edf03cf63f658883289a1a593d1007895b9f236d27c9c1f1313089aaed6b16ae02201a4dd6fc0814dc523d1fefa81c64fbf5e618e651e7096fccadbb94cd48e5e0cd",
+ "result" : "valid"
+ }
+ ]
+ }
+ ]
+}
diff --git a/src/secp256k1/tools/tests_wycheproof_generate.py b/src/secp256k1/tools/tests_wycheproof_generate.py
new file mode 100755
index 0000000000..333f6fbef0
--- /dev/null
+++ b/src/secp256k1/tools/tests_wycheproof_generate.py
@@ -0,0 +1,114 @@
+#!/usr/bin/env python3
+# Copyright (c) 2023 Random "Randy" Lattice and Sean Andersen
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or https://www.opensource.org/licenses/mit-license.php.
+'''
+Generate a C file with ECDSA testvectors from the Wycheproof project.
+'''
+
+import json
+import hashlib
+import urllib.request
+import sys
+
+filename_input = sys.argv[1]
+
+with open(filename_input) as f:
+ doc = json.load(f)
+
+num_groups = len(doc['testGroups'])
+
+def to_c_array(x):
+ if x == "": return ""
+ s = ',0x'.join(a+b for a,b in zip(x[::2], x[1::2]))
+ return "0x" + s
+
+
+num_vectors = 0
+offset_msg_running, offset_pk_running, offset_sig = 0, 0, 0
+out = ""
+messages = ""
+signatures = ""
+public_keys = ""
+cache_msgs = {}
+cache_public_keys = {}
+
+for i in range(num_groups):
+ group = doc['testGroups'][i]
+ num_tests = len(group['tests'])
+ public_key = group['publicKey']
+ for j in range(num_tests):
+ test_vector = group['tests'][j]
+ # // 2 to convert hex to byte length
+ sig_size = len(test_vector['sig']) // 2
+ msg_size = len(test_vector['msg']) // 2
+
+ if test_vector['result'] == "invalid": expected_verify = 0
+ elif test_vector['result'] == "valid": expected_verify = 1
+ else: raise ValueError("invalid result field")
+
+ if num_vectors != 0 and sig_size != 0: signatures += ",\n "
+
+ new_msg = False
+ msg = to_c_array(test_vector['msg'])
+ msg_offset = offset_msg_running
+ # check for repeated msg
+ if msg not in cache_msgs.keys():
+ if num_vectors != 0 and msg_size != 0: messages += ",\n "
+ cache_msgs[msg] = offset_msg_running
+ messages += msg
+ new_msg = True
+ else:
+ msg_offset = cache_msgs[msg]
+
+ new_pk = False
+ pk = to_c_array(public_key['uncompressed'])
+ pk_offset = offset_pk_running
+ # check for repeated pk
+ if pk not in cache_public_keys.keys():
+ if num_vectors != 0: public_keys += ",\n "
+ cache_public_keys[pk] = offset_pk_running
+ public_keys += pk
+ new_pk = True
+ else:
+ pk_offset = cache_public_keys[pk]
+
+ signatures += to_c_array(test_vector['sig'])
+
+ out += " /" + "* tcId: " + str(test_vector['tcId']) + ". " + test_vector['comment'] + " *" + "/\n"
+ out += " {" + "{0}, {1}, {2}, {3}, {4}, {5}".format(
+ pk_offset,
+ msg_offset,
+ msg_size,
+ offset_sig,
+ sig_size,
+ expected_verify) + " },\n"
+ if new_msg: offset_msg_running += msg_size
+ if new_pk: offset_pk_running += 65
+ offset_sig += sig_size
+ num_vectors += 1
+
+struct_definition = """
+typedef struct {
+ size_t pk_offset;
+ size_t msg_offset;
+ size_t msg_len;
+ size_t sig_offset;
+ size_t sig_len;
+ int expected_verify;
+} wycheproof_ecdsa_testvector;
+"""
+
+
+print("/* Note: this file was autogenerated using tests_wycheproof_generate.py. Do not edit. */")
+print("#define SECP256K1_ECDSA_WYCHEPROOF_NUMBER_TESTVECTORS ({})".format(num_vectors))
+
+print(struct_definition)
+
+print("static const unsigned char wycheproof_ecdsa_messages[] = { " + messages + "};\n")
+print("static const unsigned char wycheproof_ecdsa_public_keys[] = { " + public_keys + "};\n")
+print("static const unsigned char wycheproof_ecdsa_signatures[] = { " + signatures + "};\n")
+
+print("static const wycheproof_ecdsa_testvector testvectors[SECP256K1_ECDSA_WYCHEPROOF_NUMBER_TESTVECTORS] = {")
+print(out)
+print("};")
diff --git a/src/signet.cpp b/src/signet.cpp
index 747bd1b0a8..b76b1e342f 100644
--- a/src/signet.cpp
+++ b/src/signet.cpp
@@ -13,15 +13,16 @@
#include <consensus/validation.h>
#include <core_io.h>
#include <hash.h>
+#include <logging.h>
#include <primitives/block.h>
#include <primitives/transaction.h>
-#include <span.h>
#include <script/interpreter.h>
#include <script/standard.h>
+#include <span.h>
#include <streams.h>
+#include <uint256.h>
#include <util/strencodings.h>
#include <util/system.h>
-#include <uint256.h>
static constexpr uint8_t SIGNET_HEADER[4] = {0xec, 0xc7, 0xda, 0xa2};
diff --git a/src/support/allocators/pool.h b/src/support/allocators/pool.h
new file mode 100644
index 0000000000..c8e70ebacf
--- /dev/null
+++ b/src/support/allocators/pool.h
@@ -0,0 +1,349 @@
+// Copyright (c) 2022 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_SUPPORT_ALLOCATORS_POOL_H
+#define BITCOIN_SUPPORT_ALLOCATORS_POOL_H
+
+#include <array>
+#include <cassert>
+#include <cstddef>
+#include <list>
+#include <memory>
+#include <new>
+#include <type_traits>
+#include <utility>
+
+/**
+ * A memory resource similar to std::pmr::unsynchronized_pool_resource, but
+ * optimized for node-based containers. It has the following properties:
+ *
+ * * Owns the allocated memory and frees it on destruction, even when deallocate
+ * has not been called on the allocated blocks.
+ *
+ * * Consists of a number of pools, each one for a different block size.
+ * Each pool holds blocks of uniform size in a freelist.
+ *
+ * * Exhausting memory in a freelist causes a new allocation of a fixed size chunk.
+ * This chunk is used to carve out blocks.
+ *
+ * * Block sizes or alignments that can not be served by the pools are allocated
+ * and deallocated by operator new().
+ *
+ * PoolResource is not thread-safe. It is intended to be used by PoolAllocator.
+ *
+ * @tparam MAX_BLOCK_SIZE_BYTES Maximum size to allocate with the pool. If larger
+ * sizes are requested, allocation falls back to new().
+ *
+ * @tparam ALIGN_BYTES Required alignment for the allocations.
+ *
+ * An example: If you create a PoolResource<128, 8>(262144) and perform a bunch of
+ * allocations and deallocate 2 blocks with size 8 bytes, and 3 blocks with size 16,
+ * the members will look like this:
+ *
+ * m_free_lists m_allocated_chunks
+ * ┌───┐ ┌───┐ ┌────────────-------──────┐
+ * │ │ blocks │ ├─►│ 262144 B │
+ * │ │ ┌─────┐ ┌─────┐ └─┬─┘ └────────────-------──────┘
+ * │ 1 ├─►│ 8 B ├─►│ 8 B │ │
+ * │ │ └─────┘ └─────┘ :
+ * │ │ │
+ * │ │ ┌─────┐ ┌─────┐ ┌─────┐ ▼
+ * │ 2 ├─►│16 B ├─►│16 B ├─►│16 B │ ┌───┐ ┌─────────────────────────┐
+ * │ │ └─────┘ └─────┘ └─────┘ │ ├─►│ ▲ │ ▲
+ * │ │ └───┘ └──────────┬──────────────┘ │
+ * │ . │ │ m_available_memory_end
+ * │ . │ m_available_memory_it
+ * │ . │
+ * │ │
+ * │ │
+ * │16 │
+ * └───┘
+ *
+ * Here m_free_lists[1] holds the 2 blocks of size 8 bytes, and m_free_lists[2]
+ * holds the 3 blocks of size 16. The blocks came from the data stored in the
+ * m_allocated_chunks list. Each chunk has bytes 262144. The last chunk has still
+ * some memory available for the blocks, and when m_available_memory_it is at the
+ * end, a new chunk will be allocated and added to the list.
+ */
+template <std::size_t MAX_BLOCK_SIZE_BYTES, std::size_t ALIGN_BYTES>
+class PoolResource final
+{
+ static_assert(ALIGN_BYTES > 0, "ALIGN_BYTES must be nonzero");
+ static_assert((ALIGN_BYTES & (ALIGN_BYTES - 1)) == 0, "ALIGN_BYTES must be a power of two");
+
+ /**
+ * In-place linked list of the allocations, used for the freelist.
+ */
+ struct ListNode {
+ ListNode* m_next;
+
+ explicit ListNode(ListNode* next) : m_next(next) {}
+ };
+ static_assert(std::is_trivially_destructible_v<ListNode>, "Make sure we don't need to manually call a destructor");
+
+ /**
+ * Internal alignment value. The larger of the requested ALIGN_BYTES and alignof(FreeList).
+ */
+ static constexpr std::size_t ELEM_ALIGN_BYTES = std::max(alignof(ListNode), ALIGN_BYTES);
+ static_assert((ELEM_ALIGN_BYTES & (ELEM_ALIGN_BYTES - 1)) == 0, "ELEM_ALIGN_BYTES must be a power of two");
+ static_assert(sizeof(ListNode) <= ELEM_ALIGN_BYTES, "Units of size ELEM_SIZE_ALIGN need to be able to store a ListNode");
+ static_assert((MAX_BLOCK_SIZE_BYTES & (ELEM_ALIGN_BYTES - 1)) == 0, "MAX_BLOCK_SIZE_BYTES needs to be a multiple of the alignment.");
+
+ /**
+ * Size in bytes to allocate per chunk
+ */
+ const size_t m_chunk_size_bytes;
+
+ /**
+ * Contains all allocated pools of memory, used to free the data in the destructor.
+ */
+ std::list<std::byte*> m_allocated_chunks{};
+
+ /**
+ * Single linked lists of all data that came from deallocating.
+ * m_free_lists[n] will serve blocks of size n*ELEM_ALIGN_BYTES.
+ */
+ std::array<ListNode*, MAX_BLOCK_SIZE_BYTES / ELEM_ALIGN_BYTES + 1> m_free_lists{};
+
+ /**
+ * Points to the beginning of available memory for carving out allocations.
+ */
+ std::byte* m_available_memory_it = nullptr;
+
+ /**
+ * Points to the end of available memory for carving out allocations.
+ *
+ * That member variable is redundant, and is always equal to `m_allocated_chunks.back() + m_chunk_size_bytes`
+ * whenever it is accessed, but `m_available_memory_end` caches this for clarity and efficiency.
+ */
+ std::byte* m_available_memory_end = nullptr;
+
+ /**
+ * How many multiple of ELEM_ALIGN_BYTES are necessary to fit bytes. We use that result directly as an index
+ * into m_free_lists. Round up for the special case when bytes==0.
+ */
+ [[nodiscard]] static constexpr std::size_t NumElemAlignBytes(std::size_t bytes)
+ {
+ return (bytes + ELEM_ALIGN_BYTES - 1) / ELEM_ALIGN_BYTES + (bytes == 0);
+ }
+
+ /**
+ * True when it is possible to make use of the freelist
+ */
+ [[nodiscard]] static constexpr bool IsFreeListUsable(std::size_t bytes, std::size_t alignment)
+ {
+ return alignment <= ELEM_ALIGN_BYTES && bytes <= MAX_BLOCK_SIZE_BYTES;
+ }
+
+ /**
+ * Replaces node with placement constructed ListNode that points to the previous node
+ */
+ void PlacementAddToList(void* p, ListNode*& node)
+ {
+ node = new (p) ListNode{node};
+ }
+
+ /**
+ * Allocate one full memory chunk which will be used to carve out allocations.
+ * Also puts any leftover bytes into the freelist.
+ *
+ * Precondition: leftover bytes are either 0 or few enough to fit into a place in the freelist
+ */
+ void AllocateChunk()
+ {
+ // if there is still any available memory left, put it into the freelist.
+ size_t remaining_available_bytes = std::distance(m_available_memory_it, m_available_memory_end);
+ if (0 != remaining_available_bytes) {
+ PlacementAddToList(m_available_memory_it, m_free_lists[remaining_available_bytes / ELEM_ALIGN_BYTES]);
+ }
+
+ void* storage = ::operator new (m_chunk_size_bytes, std::align_val_t{ELEM_ALIGN_BYTES});
+ m_available_memory_it = new (storage) std::byte[m_chunk_size_bytes];
+ m_available_memory_end = m_available_memory_it + m_chunk_size_bytes;
+ m_allocated_chunks.emplace_back(m_available_memory_it);
+ }
+
+ /**
+ * Access to internals for testing purpose only
+ */
+ friend class PoolResourceTester;
+
+public:
+ /**
+ * Construct a new PoolResource object which allocates the first chunk.
+ * chunk_size_bytes will be rounded up to next multiple of ELEM_ALIGN_BYTES.
+ */
+ explicit PoolResource(std::size_t chunk_size_bytes)
+ : m_chunk_size_bytes(NumElemAlignBytes(chunk_size_bytes) * ELEM_ALIGN_BYTES)
+ {
+ assert(m_chunk_size_bytes >= MAX_BLOCK_SIZE_BYTES);
+ AllocateChunk();
+ }
+
+ /**
+ * Construct a new Pool Resource object, defaults to 2^18=262144 chunk size.
+ */
+ PoolResource() : PoolResource(262144) {}
+
+ /**
+ * Disable copy & move semantics, these are not supported for the resource.
+ */
+ PoolResource(const PoolResource&) = delete;
+ PoolResource& operator=(const PoolResource&) = delete;
+ PoolResource(PoolResource&&) = delete;
+ PoolResource& operator=(PoolResource&&) = delete;
+
+ /**
+ * Deallocates all memory allocated associated with the memory resource.
+ */
+ ~PoolResource()
+ {
+ for (std::byte* chunk : m_allocated_chunks) {
+ std::destroy(chunk, chunk + m_chunk_size_bytes);
+ ::operator delete ((void*)chunk, std::align_val_t{ELEM_ALIGN_BYTES});
+ }
+ }
+
+ /**
+ * Allocates a block of bytes. If possible the freelist is used, otherwise allocation
+ * is forwarded to ::operator new().
+ */
+ void* Allocate(std::size_t bytes, std::size_t alignment)
+ {
+ if (IsFreeListUsable(bytes, alignment)) {
+ const std::size_t num_alignments = NumElemAlignBytes(bytes);
+ if (nullptr != m_free_lists[num_alignments]) {
+ // we've already got data in the pool's freelist, unlink one element and return the pointer
+ // to the unlinked memory. Since FreeList is trivially destructible we can just treat it as
+ // uninitialized memory.
+ return std::exchange(m_free_lists[num_alignments], m_free_lists[num_alignments]->m_next);
+ }
+
+ // freelist is empty: get one allocation from allocated chunk memory.
+ const std::ptrdiff_t round_bytes = static_cast<std::ptrdiff_t>(num_alignments * ELEM_ALIGN_BYTES);
+ if (round_bytes > m_available_memory_end - m_available_memory_it) {
+ // slow path, only happens when a new chunk needs to be allocated
+ AllocateChunk();
+ }
+
+ // Make sure we use the right amount of bytes for that freelist (might be rounded up),
+ return std::exchange(m_available_memory_it, m_available_memory_it + round_bytes);
+ }
+
+ // Can't use the pool => use operator new()
+ return ::operator new (bytes, std::align_val_t{alignment});
+ }
+
+ /**
+ * Returns a block to the freelists, or deletes the block when it did not come from the chunks.
+ */
+ void Deallocate(void* p, std::size_t bytes, std::size_t alignment) noexcept
+ {
+ if (IsFreeListUsable(bytes, alignment)) {
+ const std::size_t num_alignments = NumElemAlignBytes(bytes);
+ // put the memory block into the linked list. We can placement construct the FreeList
+ // into the memory since we can be sure the alignment is correct.
+ PlacementAddToList(p, m_free_lists[num_alignments]);
+ } else {
+ // Can't use the pool => forward deallocation to ::operator delete().
+ ::operator delete (p, std::align_val_t{alignment});
+ }
+ }
+
+ /**
+ * Number of allocated chunks
+ */
+ [[nodiscard]] std::size_t NumAllocatedChunks() const
+ {
+ return m_allocated_chunks.size();
+ }
+
+ /**
+ * Size in bytes to allocate per chunk, currently hardcoded to a fixed size.
+ */
+ [[nodiscard]] size_t ChunkSizeBytes() const
+ {
+ return m_chunk_size_bytes;
+ }
+};
+
+
+/**
+ * Forwards all allocations/deallocations to the PoolResource.
+ */
+template <class T, std::size_t MAX_BLOCK_SIZE_BYTES, std::size_t ALIGN_BYTES>
+class PoolAllocator
+{
+ PoolResource<MAX_BLOCK_SIZE_BYTES, ALIGN_BYTES>* m_resource;
+
+ template <typename U, std::size_t M, std::size_t A>
+ friend class PoolAllocator;
+
+public:
+ using value_type = T;
+ using ResourceType = PoolResource<MAX_BLOCK_SIZE_BYTES, ALIGN_BYTES>;
+
+ /**
+ * Not explicit so we can easily construct it with the correct resource
+ */
+ PoolAllocator(ResourceType* resource) noexcept
+ : m_resource(resource)
+ {
+ }
+
+ PoolAllocator(const PoolAllocator& other) noexcept = default;
+ PoolAllocator& operator=(const PoolAllocator& other) noexcept = default;
+
+ template <class U>
+ PoolAllocator(const PoolAllocator<U, MAX_BLOCK_SIZE_BYTES, ALIGN_BYTES>& other) noexcept
+ : m_resource(other.resource())
+ {
+ }
+
+ /**
+ * The rebind struct here is mandatory because we use non type template arguments for
+ * PoolAllocator. See https://en.cppreference.com/w/cpp/named_req/Allocator#cite_note-2
+ */
+ template <typename U>
+ struct rebind {
+ using other = PoolAllocator<U, MAX_BLOCK_SIZE_BYTES, ALIGN_BYTES>;
+ };
+
+ /**
+ * Forwards each call to the resource.
+ */
+ T* allocate(size_t n)
+ {
+ return static_cast<T*>(m_resource->Allocate(n * sizeof(T), alignof(T)));
+ }
+
+ /**
+ * Forwards each call to the resource.
+ */
+ void deallocate(T* p, size_t n) noexcept
+ {
+ m_resource->Deallocate(p, n * sizeof(T), alignof(T));
+ }
+
+ ResourceType* resource() const noexcept
+ {
+ return m_resource;
+ }
+};
+
+template <class T1, class T2, std::size_t MAX_BLOCK_SIZE_BYTES, std::size_t ALIGN_BYTES>
+bool operator==(const PoolAllocator<T1, MAX_BLOCK_SIZE_BYTES, ALIGN_BYTES>& a,
+ const PoolAllocator<T2, MAX_BLOCK_SIZE_BYTES, ALIGN_BYTES>& b) noexcept
+{
+ return a.resource() == b.resource();
+}
+
+template <class T1, class T2, std::size_t MAX_BLOCK_SIZE_BYTES, std::size_t ALIGN_BYTES>
+bool operator!=(const PoolAllocator<T1, MAX_BLOCK_SIZE_BYTES, ALIGN_BYTES>& a,
+ const PoolAllocator<T2, MAX_BLOCK_SIZE_BYTES, ALIGN_BYTES>& b) noexcept
+{
+ return !(a == b);
+}
+
+#endif // BITCOIN_SUPPORT_ALLOCATORS_POOL_H
diff --git a/src/test/addrman_tests.cpp b/src/test/addrman_tests.cpp
index 758691cfde..54d923e4a4 100644
--- a/src/test/addrman_tests.cpp
+++ b/src/test/addrman_tests.cpp
@@ -127,46 +127,45 @@ BOOST_AUTO_TEST_CASE(addrman_ports)
// the specified port to tried, but not the other.
addrman->Good(CAddress(addr1_port, NODE_NONE));
BOOST_CHECK_EQUAL(addrman->Size(), 2U);
- bool newOnly = true;
- auto addr_ret3 = addrman->Select(newOnly).first;
+ bool new_only = true;
+ auto addr_ret3 = addrman->Select(new_only).first;
BOOST_CHECK_EQUAL(addr_ret3.ToStringAddrPort(), "250.1.1.1:8333");
}
-
BOOST_AUTO_TEST_CASE(addrman_select)
{
auto addrman = std::make_unique<AddrMan>(EMPTY_NETGROUPMAN, DETERMINISTIC, GetCheckRatio(m_node));
+ BOOST_CHECK(!addrman->Select(false).first.IsValid());
+ BOOST_CHECK(!addrman->Select(true).first.IsValid());
CNetAddr source = ResolveIP("252.2.2.2");
- // Test: Select from new with 1 addr in new.
+ // Add 1 address to the new table
CService addr1 = ResolveService("250.1.1.1", 8333);
BOOST_CHECK(addrman->Add({CAddress(addr1, NODE_NONE)}, source));
BOOST_CHECK_EQUAL(addrman->Size(), 1U);
- bool newOnly = true;
- auto addr_ret1 = addrman->Select(newOnly).first;
- BOOST_CHECK_EQUAL(addr_ret1.ToStringAddrPort(), "250.1.1.1:8333");
+ BOOST_CHECK(addrman->Select(/*new_only=*/true).first == addr1);
+ BOOST_CHECK(addrman->Select(/*new_only=*/false).first == addr1);
- // Test: move addr to tried, select from new expected nothing returned.
+ // Move address to the tried table
BOOST_CHECK(addrman->Good(CAddress(addr1, NODE_NONE)));
- BOOST_CHECK_EQUAL(addrman->Size(), 1U);
- auto addr_ret2 = addrman->Select(newOnly).first;
- BOOST_CHECK_EQUAL(addr_ret2.ToStringAddrPort(), "[::]:0");
-
- auto addr_ret3 = addrman->Select().first;
- BOOST_CHECK_EQUAL(addr_ret3.ToStringAddrPort(), "250.1.1.1:8333");
BOOST_CHECK_EQUAL(addrman->Size(), 1U);
+ BOOST_CHECK(!addrman->Select(/*new_only=*/true).first.IsValid());
+ BOOST_CHECK(addrman->Select().first == addr1);
+ BOOST_CHECK_EQUAL(addrman->Size(), 1U);
-
- // Add three addresses to new table.
+ // Add one address to the new table
CService addr2 = ResolveService("250.3.1.1", 8333);
+ BOOST_CHECK(addrman->Add({CAddress(addr2, NODE_NONE)}, addr2));
+ BOOST_CHECK(addrman->Select(/*new_only=*/true).first == addr2);
+
+ // Add two more addresses to the new table
CService addr3 = ResolveService("250.3.2.2", 9999);
CService addr4 = ResolveService("250.3.3.3", 9999);
- BOOST_CHECK(addrman->Add({CAddress(addr2, NODE_NONE)}, ResolveService("250.3.1.1", 8333)));
- BOOST_CHECK(addrman->Add({CAddress(addr3, NODE_NONE)}, ResolveService("250.3.1.1", 8333)));
+ BOOST_CHECK(addrman->Add({CAddress(addr3, NODE_NONE)}, addr2));
BOOST_CHECK(addrman->Add({CAddress(addr4, NODE_NONE)}, ResolveService("250.4.1.1", 8333)));
// Add three addresses to tried table.
@@ -174,17 +173,17 @@ BOOST_AUTO_TEST_CASE(addrman_select)
CService addr6 = ResolveService("250.4.5.5", 7777);
CService addr7 = ResolveService("250.4.6.6", 8333);
- BOOST_CHECK(addrman->Add({CAddress(addr5, NODE_NONE)}, ResolveService("250.3.1.1", 8333)));
+ BOOST_CHECK(addrman->Add({CAddress(addr5, NODE_NONE)}, addr3));
BOOST_CHECK(addrman->Good(CAddress(addr5, NODE_NONE)));
- BOOST_CHECK(addrman->Add({CAddress(addr6, NODE_NONE)}, ResolveService("250.3.1.1", 8333)));
+ BOOST_CHECK(addrman->Add({CAddress(addr6, NODE_NONE)}, addr3));
BOOST_CHECK(addrman->Good(CAddress(addr6, NODE_NONE)));
BOOST_CHECK(addrman->Add({CAddress(addr7, NODE_NONE)}, ResolveService("250.1.1.3", 8333)));
BOOST_CHECK(addrman->Good(CAddress(addr7, NODE_NONE)));
- // Test: 6 addrs + 1 addr from last test = 7.
+ // 6 addrs + 1 addr from last test = 7.
BOOST_CHECK_EQUAL(addrman->Size(), 7U);
- // Test: Select pulls from new and tried regardless of port number.
+ // Select pulls from new and tried regardless of port number.
std::set<uint16_t> ports;
for (int i = 0; i < 20; ++i) {
ports.insert(addrman->Select().first.GetPort());
@@ -192,6 +191,89 @@ BOOST_AUTO_TEST_CASE(addrman_select)
BOOST_CHECK_EQUAL(ports.size(), 3U);
}
+BOOST_AUTO_TEST_CASE(addrman_select_by_network)
+{
+ auto addrman = std::make_unique<AddrMan>(EMPTY_NETGROUPMAN, DETERMINISTIC, GetCheckRatio(m_node));
+ BOOST_CHECK(!addrman->Select(/*new_only=*/true, NET_IPV4).first.IsValid());
+ BOOST_CHECK(!addrman->Select(/*new_only=*/false, NET_IPV4).first.IsValid());
+
+ // add ipv4 address to the new table
+ CNetAddr source = ResolveIP("252.2.2.2");
+ CService addr1 = ResolveService("250.1.1.1", 8333);
+ BOOST_CHECK(addrman->Add({CAddress(addr1, NODE_NONE)}, source));
+
+ BOOST_CHECK(addrman->Select(/*new_only=*/true, NET_IPV4).first == addr1);
+ BOOST_CHECK(addrman->Select(/*new_only=*/false, NET_IPV4).first == addr1);
+ BOOST_CHECK(!addrman->Select(/*new_only=*/false, NET_IPV6).first.IsValid());
+ BOOST_CHECK(!addrman->Select(/*new_only=*/false, NET_ONION).first.IsValid());
+ BOOST_CHECK(!addrman->Select(/*new_only=*/false, NET_I2P).first.IsValid());
+ BOOST_CHECK(!addrman->Select(/*new_only=*/false, NET_CJDNS).first.IsValid());
+ BOOST_CHECK(!addrman->Select(/*new_only=*/true, NET_CJDNS).first.IsValid());
+ BOOST_CHECK(addrman->Select(/*new_only=*/false).first == addr1);
+
+ // add I2P address to the new table
+ CAddress i2p_addr;
+ i2p_addr.SetSpecial("udhdrtrcetjm5sxzskjyr5ztpeszydbh4dpl3pl4utgqqw2v4jna.b32.i2p");
+ BOOST_CHECK(addrman->Add({i2p_addr}, source));
+
+ BOOST_CHECK(addrman->Select(/*new_only=*/true, NET_I2P).first == i2p_addr);
+ BOOST_CHECK(addrman->Select(/*new_only=*/false, NET_I2P).first == i2p_addr);
+ BOOST_CHECK(addrman->Select(/*new_only=*/false, NET_IPV4).first == addr1);
+ BOOST_CHECK(!addrman->Select(/*new_only=*/false, NET_IPV6).first.IsValid());
+ BOOST_CHECK(!addrman->Select(/*new_only=*/false, NET_ONION).first.IsValid());
+ BOOST_CHECK(!addrman->Select(/*new_only=*/false, NET_CJDNS).first.IsValid());
+
+ // bump I2P address to tried table
+ BOOST_CHECK(addrman->Good(i2p_addr));
+
+ BOOST_CHECK(!addrman->Select(/*new_only=*/true, NET_I2P).first.IsValid());
+ BOOST_CHECK(addrman->Select(/*new_only=*/false, NET_I2P).first == i2p_addr);
+
+ // add another I2P address to the new table
+ CAddress i2p_addr2;
+ i2p_addr2.SetSpecial("c4gfnttsuwqomiygupdqqqyy5y5emnk5c73hrfvatri67prd7vyq.b32.i2p");
+ BOOST_CHECK(addrman->Add({i2p_addr2}, source));
+
+ BOOST_CHECK(addrman->Select(/*new_only=*/true, NET_I2P).first == i2p_addr2);
+
+ // ensure that both new and tried table are selected from
+ bool new_selected{false};
+ bool tried_selected{false};
+
+ while (!new_selected || !tried_selected) {
+ const CAddress selected{addrman->Select(/*new_only=*/false, NET_I2P).first};
+ BOOST_REQUIRE(selected == i2p_addr || selected == i2p_addr2);
+ if (selected == i2p_addr) {
+ tried_selected = true;
+ } else {
+ new_selected = true;
+ }
+ }
+}
+
+BOOST_AUTO_TEST_CASE(addrman_select_special)
+{
+ // use a non-deterministic addrman to ensure a passing test isn't due to setup
+ auto addrman = std::make_unique<AddrMan>(EMPTY_NETGROUPMAN, /*deterministic=*/false, GetCheckRatio(m_node));
+
+ CNetAddr source = ResolveIP("252.2.2.2");
+
+ // add I2P address to the tried table
+ CAddress i2p_addr;
+ i2p_addr.SetSpecial("udhdrtrcetjm5sxzskjyr5ztpeszydbh4dpl3pl4utgqqw2v4jna.b32.i2p");
+ BOOST_CHECK(addrman->Add({i2p_addr}, source));
+ BOOST_CHECK(addrman->Good(i2p_addr));
+
+ // add ipv4 address to the new table
+ CService addr1 = ResolveService("250.1.1.3", 8333);
+ BOOST_CHECK(addrman->Add({CAddress(addr1, NODE_NONE)}, source));
+
+ // since the only ipv4 address is on the new table, ensure that the new
+ // table gets selected even if new_only is false. if the table was being
+ // selected at random, this test will sporadically fail
+ BOOST_CHECK(addrman->Select(/*new_only=*/false, NET_IPV4).first == addr1);
+}
+
BOOST_AUTO_TEST_CASE(addrman_new_collisions)
{
auto addrman = std::make_unique<AddrMan>(EMPTY_NETGROUPMAN, DETERMINISTIC, GetCheckRatio(m_node));
diff --git a/src/test/allocator_tests.cpp b/src/test/allocator_tests.cpp
index 715ce0a5b4..f74e50a890 100644
--- a/src/test/allocator_tests.cpp
+++ b/src/test/allocator_tests.cpp
@@ -77,6 +77,7 @@ BOOST_AUTO_TEST_CASE(arena_tests)
b.walk();
#endif
// Sweeping allocate all memory
+ addr.reserve(2048);
for (int x=0; x<1024; ++x)
addr.push_back(b.alloc(1024));
BOOST_CHECK(b.stats().free == 0);
diff --git a/src/test/argsman_tests.cpp b/src/test/argsman_tests.cpp
index d00876bc70..6a0925f0bb 100644
--- a/src/test/argsman_tests.cpp
+++ b/src/test/argsman_tests.cpp
@@ -2,14 +2,14 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include <util/system.h>
-#include <fs.h>
+#include <common/args.h>
#include <sync.h>
#include <test/util/logging.h>
#include <test/util/setup_common.h>
#include <test/util/str.h>
-#include <util/strencodings.h>
#include <univalue.h>
+#include <util/fs.h>
+#include <util/strencodings.h>
#include <array>
#include <optional>
diff --git a/src/test/checkqueue_tests.cpp b/src/test/checkqueue_tests.cpp
index 6bc4770f9b..9011e703e8 100644
--- a/src/test/checkqueue_tests.cpp
+++ b/src/test/checkqueue_tests.cpp
@@ -3,10 +3,10 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <checkqueue.h>
+#include <common/args.h>
#include <sync.h>
#include <test/util/random.h>
#include <test/util/setup_common.h>
-#include <util/system.h>
#include <util/time.h>
#include <boost/test/unit_test.hpp>
diff --git a/src/test/coins_tests.cpp b/src/test/coins_tests.cpp
index e082800fc3..853dc6dc1e 100644
--- a/src/test/coins_tests.cpp
+++ b/src/test/coins_tests.cpp
@@ -6,6 +6,7 @@
#include <coins.h>
#include <script/standard.h>
#include <streams.h>
+#include <test/util/poolresourcetester.h>
#include <test/util/random.h>
#include <test/util/setup_common.h>
#include <txdb.h>
@@ -612,7 +613,8 @@ void GetCoinsMapEntry(const CCoinsMap& map, CAmount& value, char& flags, const C
void WriteCoinsViewEntry(CCoinsView& view, CAmount value, char flags)
{
- CCoinsMap map;
+ CCoinsMapMemoryResource resource;
+ CCoinsMap map{0, CCoinsMap::hasher{}, CCoinsMap::key_equal{}, &resource};
InsertCoinsMapEntry(map, value, flags);
BOOST_CHECK(view.BatchWrite(map, {}));
}
@@ -911,6 +913,7 @@ void TestFlushBehavior(
CAmount value;
char flags;
size_t cache_usage;
+ size_t cache_size;
auto flush_all = [&all_caches](bool erase) {
// Flush in reverse order to ensure that flushes happen from children up.
@@ -935,6 +938,8 @@ void TestFlushBehavior(
view->AddCoin(outp, Coin(coin), false);
cache_usage = view->DynamicMemoryUsage();
+ cache_size = view->map().size();
+
// `base` shouldn't have coin (no flush yet) but `view` should have cached it.
BOOST_CHECK(!base.HaveCoin(outp));
BOOST_CHECK(view->HaveCoin(outp));
@@ -949,6 +954,7 @@ void TestFlushBehavior(
// CoinsMap usage should be unchanged since we didn't erase anything.
BOOST_CHECK_EQUAL(cache_usage, view->DynamicMemoryUsage());
+ BOOST_CHECK_EQUAL(cache_size, view->map().size());
// --- 3. Ensuring the entry still exists in the cache and has been written to parent
//
@@ -965,8 +971,10 @@ void TestFlushBehavior(
//
flush_all(/*erase=*/ true);
- // Memory usage should have gone down.
- BOOST_CHECK(view->DynamicMemoryUsage() < cache_usage);
+ // Memory does not necessarily go down due to the map using a memory pool
+ BOOST_TEST(view->DynamicMemoryUsage() <= cache_usage);
+ // Size of the cache must go down though
+ BOOST_TEST(view->map().size() < cache_size);
// --- 5. Ensuring the entry is no longer in the cache
//
@@ -1076,4 +1084,29 @@ BOOST_AUTO_TEST_CASE(ccoins_flush_behavior)
}
}
+BOOST_AUTO_TEST_CASE(coins_resource_is_used)
+{
+ CCoinsMapMemoryResource resource;
+ PoolResourceTester::CheckAllDataAccountedFor(resource);
+
+ {
+ CCoinsMap map{0, CCoinsMap::hasher{}, CCoinsMap::key_equal{}, &resource};
+ BOOST_TEST(memusage::DynamicUsage(map) >= resource.ChunkSizeBytes());
+
+ map.reserve(1000);
+
+ // The resource has preallocated a chunk, so we should have space for at several nodes without the need to allocate anything else.
+ const auto usage_before = memusage::DynamicUsage(map);
+
+ COutPoint out_point{};
+ for (size_t i = 0; i < 1000; ++i) {
+ out_point.n = i;
+ map[out_point];
+ }
+ BOOST_TEST(usage_before == memusage::DynamicUsage(map));
+ }
+
+ PoolResourceTester::CheckAllDataAccountedFor(resource);
+}
+
BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/denialofservice_tests.cpp b/src/test/denialofservice_tests.cpp
index aca2b8eff0..1a06f16155 100644
--- a/src/test/denialofservice_tests.cpp
+++ b/src/test/denialofservice_tests.cpp
@@ -6,6 +6,7 @@
#include <banman.h>
#include <chainparams.h>
+#include <common/args.h>
#include <net.h>
#include <net_processing.h>
#include <pubkey.h>
@@ -17,7 +18,6 @@
#include <test/util/setup_common.h>
#include <timedata.h>
#include <util/string.h>
-#include <util/system.h>
#include <util/time.h>
#include <validation.h>
diff --git a/src/test/flatfile_tests.cpp b/src/test/flatfile_tests.cpp
index 54c30ed314..3874b38f61 100644
--- a/src/test/flatfile_tests.cpp
+++ b/src/test/flatfile_tests.cpp
@@ -3,10 +3,10 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <clientversion.h>
+#include <common/args.h>
#include <flatfile.h>
#include <streams.h>
#include <test/util/setup_common.h>
-#include <util/system.h>
#include <boost/test/unit_test.hpp>
diff --git a/src/test/fs_tests.cpp b/src/test/fs_tests.cpp
index 7e7d630daa..7cfecb2b22 100644
--- a/src/test/fs_tests.cpp
+++ b/src/test/fs_tests.cpp
@@ -2,9 +2,9 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
//
-#include <fs.h>
#include <test/util/setup_common.h>
-#include <util/system.h>
+#include <util/fs.h>
+#include <util/fs_helpers.h>
#include <util/getuniquepath.h>
#include <boost/test/unit_test.hpp>
diff --git a/src/test/fuzz/addrman.cpp b/src/test/fuzz/addrman.cpp
index a59e41dbb5..5ad7a25c53 100644
--- a/src/test/fuzz/addrman.cpp
+++ b/src/test/fuzz/addrman.cpp
@@ -6,6 +6,7 @@
#include <addrman.h>
#include <addrman_impl.h>
#include <chainparams.h>
+#include <common/args.h>
#include <merkleblock.h>
#include <random.h>
#include <test/fuzz/FuzzedDataProvider.h>
@@ -15,7 +16,6 @@
#include <test/util/setup_common.h>
#include <time.h>
#include <util/asmap.h>
-#include <util/system.h>
#include <cassert>
#include <cstdint>
diff --git a/src/test/fuzz/banman.cpp b/src/test/fuzz/banman.cpp
index 273dcfd850..cb5d29d9b8 100644
--- a/src/test/fuzz/banman.cpp
+++ b/src/test/fuzz/banman.cpp
@@ -3,15 +3,15 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <banman.h>
-#include <fs.h>
+#include <common/args.h>
#include <netaddress.h>
#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
#include <test/fuzz/util.h>
#include <test/fuzz/util/net.h>
#include <test/util/setup_common.h>
+#include <util/fs.h>
#include <util/readwritefile.h>
-#include <util/system.h>
#include <cassert>
#include <cstdint>
diff --git a/src/test/fuzz/coins_view.cpp b/src/test/fuzz/coins_view.cpp
index e80c772aa4..5843b80c0a 100644
--- a/src/test/fuzz/coins_view.cpp
+++ b/src/test/fuzz/coins_view.cpp
@@ -115,7 +115,8 @@ FUZZ_TARGET_INIT(coins_view, initialize_coins_view)
random_mutable_transaction = *opt_mutable_transaction;
},
[&] {
- CCoinsMap coins_map;
+ CCoinsMapMemoryResource resource;
+ CCoinsMap coins_map{0, SaltedOutpointHasher{/*deterministic=*/true}, CCoinsMap::key_equal{}, &resource};
LIMITED_WHILE(fuzzed_data_provider.ConsumeBool(), 10000) {
CCoinsCacheEntry coins_cache_entry;
coins_cache_entry.flags = fuzzed_data_provider.ConsumeIntegral<unsigned char>();
diff --git a/src/test/fuzz/connman.cpp b/src/test/fuzz/connman.cpp
index 798c14030c..0f3c850e66 100644
--- a/src/test/fuzz/connman.cpp
+++ b/src/test/fuzz/connman.cpp
@@ -5,6 +5,7 @@
#include <addrman.h>
#include <chainparams.h>
#include <chainparamsbase.h>
+#include <common/args.h>
#include <net.h>
#include <netaddress.h>
#include <protocol.h>
@@ -13,7 +14,6 @@
#include <test/fuzz/util.h>
#include <test/fuzz/util/net.h>
#include <test/util/setup_common.h>
-#include <util/system.h>
#include <util/translation.h>
#include <cstdint>
@@ -125,7 +125,6 @@ FUZZ_TARGET_INIT(connman, initialize_connman)
std::vector<CNodeStats> stats;
connman.GetNodeStats(stats);
(void)connman.GetOutboundTargetBytesLeft();
- (void)connman.GetReceiveFloodSize();
(void)connman.GetTotalBytesRecv();
(void)connman.GetTotalBytesSent();
(void)connman.GetTryNewOutboundPeer();
diff --git a/src/test/fuzz/deserialize.cpp b/src/test/fuzz/deserialize.cpp
index 7cd78e0461..177711c6e4 100644
--- a/src/test/fuzz/deserialize.cpp
+++ b/src/test/fuzz/deserialize.cpp
@@ -9,6 +9,7 @@
#include <blockfilter.h>
#include <chain.h>
#include <coins.h>
+#include <common/args.h>
#include <compressor.h>
#include <consensus/merkle.h>
#include <key.h>
@@ -25,7 +26,6 @@
#include <streams.h>
#include <test/util/setup_common.h>
#include <undo.h>
-#include <util/system.h>
#include <version.h>
#include <exception>
diff --git a/src/test/fuzz/fuzz.cpp b/src/test/fuzz/fuzz.cpp
index 9683f32d84..0bbfb206d5 100644
--- a/src/test/fuzz/fuzz.cpp
+++ b/src/test/fuzz/fuzz.cpp
@@ -4,11 +4,11 @@
#include <test/fuzz/fuzz.h>
-#include <fs.h>
#include <netaddress.h>
#include <netbase.h>
#include <test/util/setup_common.h>
#include <util/check.h>
+#include <util/fs.h>
#include <util/sock.h>
#include <util/time.h>
diff --git a/src/test/fuzz/headerssync.cpp b/src/test/fuzz/headerssync.cpp
new file mode 100644
index 0000000000..521afadb51
--- /dev/null
+++ b/src/test/fuzz/headerssync.cpp
@@ -0,0 +1,117 @@
+#include <arith_uint256.h>
+#include <chain.h>
+#include <chainparams.h>
+#include <headerssync.h>
+#include <test/fuzz/fuzz.h>
+#include <test/fuzz/util.h>
+#include <test/util/setup_common.h>
+#include <uint256.h>
+#include <util/time.h>
+#include <validation.h>
+
+#include <iterator>
+#include <vector>
+
+static void initialize_headers_sync_state_fuzz()
+{
+ static const auto testing_setup = MakeNoLogFileContext<>(
+ /*chain_name=*/CBaseChainParams::MAIN);
+}
+
+void MakeHeadersContinuous(
+ const CBlockHeader& genesis_header,
+ const std::vector<CBlockHeader>& all_headers,
+ std::vector<CBlockHeader>& new_headers)
+{
+ Assume(!new_headers.empty());
+
+ const CBlockHeader* prev_header{
+ all_headers.empty() ? &genesis_header : &all_headers.back()};
+
+ for (auto& header : new_headers) {
+ header.hashPrevBlock = prev_header->GetHash();
+
+ prev_header = &header;
+ }
+}
+
+class FuzzedHeadersSyncState : public HeadersSyncState
+{
+public:
+ FuzzedHeadersSyncState(const unsigned commit_offset, const CBlockIndex* chain_start, const arith_uint256& minimum_required_work)
+ : HeadersSyncState(/*id=*/0, Params().GetConsensus(), chain_start, minimum_required_work)
+ {
+ const_cast<unsigned&>(m_commit_offset) = commit_offset;
+ }
+};
+
+FUZZ_TARGET_INIT(headers_sync_state, initialize_headers_sync_state_fuzz)
+{
+ FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
+ auto mock_time{ConsumeTime(fuzzed_data_provider)};
+
+ CBlockHeader genesis_header{Params().GenesisBlock()};
+ CBlockIndex start_index(genesis_header);
+
+ if (mock_time < start_index.GetMedianTimePast()) return;
+ SetMockTime(mock_time);
+
+ const uint256 genesis_hash = genesis_header.GetHash();
+ start_index.phashBlock = &genesis_hash;
+
+ arith_uint256 min_work{UintToArith256(ConsumeUInt256(fuzzed_data_provider))};
+ FuzzedHeadersSyncState headers_sync(
+ /*commit_offset=*/fuzzed_data_provider.ConsumeIntegralInRange<unsigned>(1, 1024),
+ /*chain_start=*/&start_index,
+ /*minimum_required_work=*/min_work);
+
+ // Store headers for potential redownload phase.
+ std::vector<CBlockHeader> all_headers;
+ std::vector<CBlockHeader>::const_iterator redownloaded_it;
+ bool presync{true};
+ bool requested_more{true};
+
+ while (requested_more) {
+ std::vector<CBlockHeader> headers;
+
+ // Consume headers from fuzzer or maybe replay headers if we got to the
+ // redownload phase.
+ if (presync || fuzzed_data_provider.ConsumeBool()) {
+ auto deser_headers = ConsumeDeserializable<std::vector<CBlockHeader>>(fuzzed_data_provider);
+ if (!deser_headers || deser_headers->empty()) return;
+
+ if (fuzzed_data_provider.ConsumeBool()) {
+ MakeHeadersContinuous(genesis_header, all_headers, *deser_headers);
+ }
+
+ headers.swap(*deser_headers);
+ } else if (auto num_headers_left{std::distance(redownloaded_it, all_headers.cend())}; num_headers_left > 0) {
+ // Consume some headers from the redownload buffer (At least one
+ // header is consumed).
+ auto begin_it{redownloaded_it};
+ std::advance(redownloaded_it, fuzzed_data_provider.ConsumeIntegralInRange<int>(1, num_headers_left));
+ headers.insert(headers.cend(), begin_it, redownloaded_it);
+ }
+
+ if (headers.empty()) return;
+ auto result = headers_sync.ProcessNextHeaders(headers, fuzzed_data_provider.ConsumeBool());
+ requested_more = result.request_more;
+
+ if (result.request_more) {
+ if (presync) {
+ all_headers.insert(all_headers.cend(), headers.cbegin(), headers.cend());
+
+ if (headers_sync.GetState() == HeadersSyncState::State::REDOWNLOAD) {
+ presync = false;
+ redownloaded_it = all_headers.cbegin();
+
+ // If we get to redownloading, the presynced headers need
+ // to have the min amount of work on them.
+ assert(CalculateHeadersWork(all_headers) >= min_work);
+ }
+ }
+
+ (void)headers_sync.NextHeadersRequestLocator();
+ }
+ }
+}
diff --git a/src/test/fuzz/i2p.cpp b/src/test/fuzz/i2p.cpp
index 6c2321cd68..3c6db96446 100644
--- a/src/test/fuzz/i2p.cpp
+++ b/src/test/fuzz/i2p.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 <common/args.h>
#include <i2p.h>
#include <netaddress.h>
#include <netbase.h>
@@ -10,7 +11,6 @@
#include <test/fuzz/util.h>
#include <test/fuzz/util/net.h>
#include <test/util/setup_common.h>
-#include <util/system.h>
#include <util/threadinterrupt.h>
void initialize_i2p()
diff --git a/src/test/fuzz/integer.cpp b/src/test/fuzz/integer.cpp
index c0aefe6067..ead877fe05 100644
--- a/src/test/fuzz/integer.cpp
+++ b/src/test/fuzz/integer.cpp
@@ -3,6 +3,7 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <arith_uint256.h>
+#include <common/args.h>
#include <compressor.h>
#include <consensus/amount.h>
#include <consensus/merkle.h>
diff --git a/src/test/fuzz/miniscript.cpp b/src/test/fuzz/miniscript.cpp
index 6ea8a3f185..81c6f076b2 100644
--- a/src/test/fuzz/miniscript.cpp
+++ b/src/test/fuzz/miniscript.cpp
@@ -248,8 +248,6 @@ using Fragment = miniscript::Fragment;
using NodeRef = miniscript::NodeRef<CPubKey>;
using Node = miniscript::Node<CPubKey>;
using Type = miniscript::Type;
-// https://github.com/llvm/llvm-project/issues/53444
-// NOLINTNEXTLINE(misc-unused-using-decls)
using miniscript::operator"" _mst;
//! Construct a miniscript node as a shared_ptr.
diff --git a/src/test/fuzz/poolresource.cpp b/src/test/fuzz/poolresource.cpp
new file mode 100644
index 0000000000..ce64ef6472
--- /dev/null
+++ b/src/test/fuzz/poolresource.cpp
@@ -0,0 +1,174 @@
+// Copyright (c) 2022 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 <span.h>
+#include <support/allocators/pool.h>
+#include <test/fuzz/FuzzedDataProvider.h>
+#include <test/fuzz/fuzz.h>
+#include <test/fuzz/util.h>
+#include <test/util/poolresourcetester.h>
+#include <test/util/xoroshiro128plusplus.h>
+
+#include <cstdint>
+#include <tuple>
+#include <vector>
+
+namespace {
+
+template <std::size_t MAX_BLOCK_SIZE_BYTES, std::size_t ALIGN_BYTES>
+class PoolResourceFuzzer
+{
+ FuzzedDataProvider& m_provider;
+ PoolResource<MAX_BLOCK_SIZE_BYTES, ALIGN_BYTES> m_test_resource;
+ uint64_t m_sequence{0};
+ size_t m_total_allocated{};
+
+ struct Entry {
+ Span<std::byte> span;
+ size_t alignment;
+ uint64_t seed;
+
+ Entry(Span<std::byte> s, size_t a, uint64_t se) : span(s), alignment(a), seed(se) {}
+ };
+
+ std::vector<Entry> m_entries;
+
+public:
+ PoolResourceFuzzer(FuzzedDataProvider& provider)
+ : m_provider{provider},
+ m_test_resource{provider.ConsumeIntegralInRange<size_t>(MAX_BLOCK_SIZE_BYTES, 262144)}
+ {
+ }
+
+ void Allocate(size_t size, size_t alignment)
+ {
+ assert(size > 0); // Must allocate at least 1 byte.
+ assert(alignment > 0); // Alignment must be at least 1.
+ assert((alignment & (alignment - 1)) == 0); // Alignment must be power of 2.
+ assert((size & (alignment - 1)) == 0); // Size must be a multiple of alignment.
+
+ auto span = Span(static_cast<std::byte*>(m_test_resource.Allocate(size, alignment)), size);
+ m_total_allocated += size;
+
+ auto ptr_val = reinterpret_cast<std::uintptr_t>(span.data());
+ assert((ptr_val & (alignment - 1)) == 0);
+
+ uint64_t seed = m_sequence++;
+ RandomContentFill(m_entries.emplace_back(span, alignment, seed));
+ }
+
+ void
+ Allocate()
+ {
+ if (m_total_allocated > 0x1000000) return;
+ size_t alignment_bits = m_provider.ConsumeIntegralInRange<size_t>(0, 7);
+ size_t alignment = 1 << alignment_bits;
+ size_t size_bits = m_provider.ConsumeIntegralInRange<size_t>(0, 16 - alignment_bits);
+ size_t size = m_provider.ConsumeIntegralInRange<size_t>(1U << size_bits, (1U << (size_bits + 1)) - 1U) << alignment_bits;
+ Allocate(size, alignment);
+ }
+
+ void RandomContentFill(Entry& entry)
+ {
+ XoRoShiRo128PlusPlus rng(entry.seed);
+ auto ptr = entry.span.data();
+ auto size = entry.span.size();
+
+ while (size >= 8) {
+ auto r = rng();
+ std::memcpy(ptr, &r, 8);
+ size -= 8;
+ ptr += 8;
+ }
+ if (size > 0) {
+ auto r = rng();
+ std::memcpy(ptr, &r, size);
+ }
+ }
+
+ void RandomContentCheck(const Entry& entry)
+ {
+ XoRoShiRo128PlusPlus rng(entry.seed);
+ auto ptr = entry.span.data();
+ auto size = entry.span.size();
+
+ std::byte buf[8];
+ while (size >= 8) {
+ auto r = rng();
+ std::memcpy(buf, &r, 8);
+ assert(std::memcmp(buf, ptr, 8) == 0);
+ size -= 8;
+ ptr += 8;
+ }
+ if (size > 0) {
+ auto r = rng();
+ std::memcpy(buf, &r, size);
+ assert(std::memcmp(buf, ptr, size) == 0);
+ }
+ }
+
+ void Deallocate(const Entry& entry)
+ {
+ auto ptr_val = reinterpret_cast<std::uintptr_t>(entry.span.data());
+ assert((ptr_val & (entry.alignment - 1)) == 0);
+ RandomContentCheck(entry);
+ m_total_allocated -= entry.span.size();
+ m_test_resource.Deallocate(entry.span.data(), entry.span.size(), entry.alignment);
+ }
+
+ void Deallocate()
+ {
+ if (m_entries.empty()) {
+ return;
+ }
+
+ size_t idx = m_provider.ConsumeIntegralInRange<size_t>(0, m_entries.size() - 1);
+ Deallocate(m_entries[idx]);
+ if (idx != m_entries.size() - 1) {
+ m_entries[idx] = std::move(m_entries.back());
+ }
+ m_entries.pop_back();
+ }
+
+ void Clear()
+ {
+ while (!m_entries.empty()) {
+ Deallocate();
+ }
+
+ PoolResourceTester::CheckAllDataAccountedFor(m_test_resource);
+ }
+
+ void Fuzz()
+ {
+ LIMITED_WHILE(m_provider.ConsumeBool(), 10000)
+ {
+ CallOneOf(
+ m_provider,
+ [&] { Allocate(); },
+ [&] { Deallocate(); });
+ }
+ Clear();
+ }
+};
+
+
+} // namespace
+
+FUZZ_TARGET(pool_resource)
+{
+ FuzzedDataProvider provider(buffer.data(), buffer.size());
+ CallOneOf(
+ provider,
+ [&] { PoolResourceFuzzer<128, 1>{provider}.Fuzz(); },
+ [&] { PoolResourceFuzzer<128, 2>{provider}.Fuzz(); },
+ [&] { PoolResourceFuzzer<128, 4>{provider}.Fuzz(); },
+ [&] { PoolResourceFuzzer<128, 8>{provider}.Fuzz(); },
+
+ [&] { PoolResourceFuzzer<8, 8>{provider}.Fuzz(); },
+ [&] { PoolResourceFuzzer<16, 16>{provider}.Fuzz(); },
+
+ [&] { PoolResourceFuzzer<256, alignof(max_align_t)>{provider}.Fuzz(); },
+ [&] { PoolResourceFuzzer<256, 64>{provider}.Fuzz(); });
+}
diff --git a/src/test/fuzz/rpc.cpp b/src/test/fuzz/rpc.cpp
index 2578137471..1c6140c66a 100644
--- a/src/test/fuzz/rpc.cpp
+++ b/src/test/fuzz/rpc.cpp
@@ -70,7 +70,6 @@ const std::vector<std::string> RPC_COMMANDS_NOT_SAFE_FOR_FUZZING{
"addconnection", // avoid DNS lookups
"addnode", // avoid DNS lookups
"addpeeraddress", // avoid DNS lookups
- "analyzepsbt", // avoid signed integer overflow in CFeeRate::GetFee(unsigned long) (https://github.com/bitcoin/bitcoin/issues/20607)
"dumptxoutset", // avoid writing to disk
"dumpwallet", // avoid writing to disk
"echoipc", // avoid assertion failure (Assertion `"EnsureAnyNodeContext(request.context).init" && check' failed.)
@@ -79,7 +78,6 @@ const std::vector<std::string> RPC_COMMANDS_NOT_SAFE_FOR_FUZZING{
"gettxoutproof", // avoid prohibitively slow execution
"importwallet", // avoid reading from disk
"loadwallet", // avoid reading from disk
- "prioritisetransaction", // avoid signed integer overflow in CTxMemPool::PrioritiseTransaction(uint256 const&, long const&) (https://github.com/bitcoin/bitcoin/issues/20626)
"savemempool", // disabled as a precautionary measure: may take a file path argument in the future
"setban", // avoid DNS lookups
"stop", // avoid shutdown state
@@ -87,6 +85,7 @@ const std::vector<std::string> RPC_COMMANDS_NOT_SAFE_FOR_FUZZING{
// RPC commands which are safe for fuzzing.
const std::vector<std::string> RPC_COMMANDS_SAFE_FOR_FUZZING{
+ "analyzepsbt",
"clearbanned",
"combinepsbt",
"combinerawtransaction",
@@ -112,9 +111,9 @@ const std::vector<std::string> RPC_COMMANDS_SAFE_FOR_FUZZING{
"getblockchaininfo",
"getblockcount",
"getblockfilter",
+ "getblockfrompeer", // when no peers are connected, no p2p message is sent
"getblockhash",
"getblockheader",
- "getblockfrompeer", // when no peers are connected, no p2p message is sent
"getblockstats",
"getblocktemplate",
"getchaintips",
@@ -128,7 +127,6 @@ const std::vector<std::string> RPC_COMMANDS_SAFE_FOR_FUZZING{
"getmempoolancestors",
"getmempooldescendants",
"getmempoolentry",
- "gettxspendingprevout",
"getmempoolinfo",
"getmininginfo",
"getnettotals",
@@ -141,6 +139,7 @@ const std::vector<std::string> RPC_COMMANDS_SAFE_FOR_FUZZING{
"getrpcinfo",
"gettxout",
"gettxoutsetinfo",
+ "gettxspendingprevout",
"help",
"invalidateblock",
"joinpsbts",
@@ -149,6 +148,7 @@ const std::vector<std::string> RPC_COMMANDS_SAFE_FOR_FUZZING{
"mockscheduler",
"ping",
"preciousblock",
+ "prioritisetransaction",
"pruneblockchain",
"reconsiderblock",
"scanblocks",
diff --git a/src/test/fuzz/string.cpp b/src/test/fuzz/string.cpp
index 9890e4c0e5..5de24a939d 100644
--- a/src/test/fuzz/string.cpp
+++ b/src/test/fuzz/string.cpp
@@ -4,9 +4,8 @@
#include <blockfilter.h>
#include <clientversion.h>
+#include <common/args.h>
#include <common/url.h>
-#include <logging.h>
-#include <netaddress.h>
#include <netbase.h>
#include <outputtype.h>
#include <rpc/client.h>
@@ -22,113 +21,21 @@
#include <test/fuzz/util.h>
#include <util/error.h>
#include <util/fees.h>
-#include <util/message.h>
#include <util/settings.h>
#include <util/strencodings.h>
#include <util/string.h>
#include <util/system.h>
#include <util/translation.h>
-#include <version.h>
+#include <cassert>
#include <cstdint>
#include <cstdlib>
+#include <ios>
+#include <stdexcept>
#include <string>
#include <vector>
-namespace {
-bool LegacyParsePrechecks(const std::string& str)
-{
- if (str.empty()) // No empty string allowed
- return false;
- if (str.size() >= 1 && (IsSpace(str[0]) || IsSpace(str[str.size() - 1]))) // No padding allowed
- return false;
- if (!ContainsNoNUL(str)) // No embedded NUL characters allowed
- return false;
- return true;
-}
-
-bool LegacyParseInt32(const std::string& str, int32_t* out)
-{
- if (!LegacyParsePrechecks(str))
- return false;
- char* endp = nullptr;
- errno = 0; // strtol will not set errno if valid
- long int n = strtol(str.c_str(), &endp, 10);
- if (out) *out = (int32_t)n;
- // Note that strtol returns a *long int*, so even if strtol doesn't report an over/underflow
- // we still have to check that the returned value is within the range of an *int32_t*. On 64-bit
- // platforms the size of these types may be different.
- return endp && *endp == 0 && !errno &&
- n >= std::numeric_limits<int32_t>::min() &&
- n <= std::numeric_limits<int32_t>::max();
-}
-
-bool LegacyParseInt64(const std::string& str, int64_t* out)
-{
- if (!LegacyParsePrechecks(str))
- return false;
- char* endp = nullptr;
- errno = 0; // strtoll will not set errno if valid
- long long int n = strtoll(str.c_str(), &endp, 10);
- if (out) *out = (int64_t)n;
- // Note that strtoll returns a *long long int*, so even if strtol doesn't report an over/underflow
- // we still have to check that the returned value is within the range of an *int64_t*.
- return endp && *endp == 0 && !errno &&
- n >= std::numeric_limits<int64_t>::min() &&
- n <= std::numeric_limits<int64_t>::max();
-}
-
-bool LegacyParseUInt32(const std::string& str, uint32_t* out)
-{
- if (!LegacyParsePrechecks(str))
- return false;
- if (str.size() >= 1 && str[0] == '-') // Reject negative values, unfortunately strtoul accepts these by default if they fit in the range
- return false;
- char* endp = nullptr;
- errno = 0; // strtoul will not set errno if valid
- unsigned long int n = strtoul(str.c_str(), &endp, 10);
- if (out) *out = (uint32_t)n;
- // Note that strtoul returns a *unsigned long int*, so even if it doesn't report an over/underflow
- // we still have to check that the returned value is within the range of an *uint32_t*. On 64-bit
- // platforms the size of these types may be different.
- return endp && *endp == 0 && !errno &&
- n <= std::numeric_limits<uint32_t>::max();
-}
-
-bool LegacyParseUInt8(const std::string& str, uint8_t* out)
-{
- uint32_t u32;
- if (!LegacyParseUInt32(str, &u32) || u32 > std::numeric_limits<uint8_t>::max()) {
- return false;
- }
- if (out != nullptr) {
- *out = static_cast<uint8_t>(u32);
- }
- return true;
-}
-
-bool LegacyParseUInt64(const std::string& str, uint64_t* out)
-{
- if (!LegacyParsePrechecks(str))
- return false;
- if (str.size() >= 1 && str[0] == '-') // Reject negative values, unfortunately strtoull accepts these by default if they fit in the range
- return false;
- char* endp = nullptr;
- errno = 0; // strtoull will not set errno if valid
- unsigned long long int n = strtoull(str.c_str(), &endp, 10);
- if (out) *out = (uint64_t)n;
- // Note that strtoull returns a *unsigned long long int*, so even if it doesn't report an over/underflow
- // we still have to check that the returned value is within the range of an *uint64_t*.
- return endp && *endp == 0 && !errno &&
- n <= std::numeric_limits<uint64_t>::max();
-}
-
-// For backwards compatibility checking.
-int64_t atoi64_legacy(const std::string& str)
-{
- return strtoll(str.c_str(), nullptr, 10);
-}
-}; // namespace
+enum class FeeEstimateMode;
FUZZ_TARGET(string)
{
@@ -236,61 +143,4 @@ FUZZ_TARGET(string)
const bilingual_str bs2{random_string_2, random_string_1};
(void)(bs1 + bs2);
}
- {
- int32_t i32;
- int64_t i64;
- uint32_t u32;
- uint64_t u64;
- uint8_t u8;
- const bool ok_i32 = ParseInt32(random_string_1, &i32);
- const bool ok_i64 = ParseInt64(random_string_1, &i64);
- const bool ok_u32 = ParseUInt32(random_string_1, &u32);
- const bool ok_u64 = ParseUInt64(random_string_1, &u64);
- const bool ok_u8 = ParseUInt8(random_string_1, &u8);
-
- int32_t i32_legacy;
- int64_t i64_legacy;
- uint32_t u32_legacy;
- uint64_t u64_legacy;
- uint8_t u8_legacy;
- const bool ok_i32_legacy = LegacyParseInt32(random_string_1, &i32_legacy);
- const bool ok_i64_legacy = LegacyParseInt64(random_string_1, &i64_legacy);
- const bool ok_u32_legacy = LegacyParseUInt32(random_string_1, &u32_legacy);
- const bool ok_u64_legacy = LegacyParseUInt64(random_string_1, &u64_legacy);
- const bool ok_u8_legacy = LegacyParseUInt8(random_string_1, &u8_legacy);
-
- assert(ok_i32 == ok_i32_legacy);
- assert(ok_i64 == ok_i64_legacy);
- assert(ok_u32 == ok_u32_legacy);
- assert(ok_u64 == ok_u64_legacy);
- assert(ok_u8 == ok_u8_legacy);
-
- if (ok_i32) {
- assert(i32 == i32_legacy);
- }
- if (ok_i64) {
- assert(i64 == i64_legacy);
- }
- if (ok_u32) {
- assert(u32 == u32_legacy);
- }
- if (ok_u64) {
- assert(u64 == u64_legacy);
- }
- if (ok_u8) {
- assert(u8 == u8_legacy);
- }
- }
-
- {
- const int locale_independent_atoi_result = LocaleIndependentAtoi<int>(random_string_1);
- const int64_t atoi64_result = atoi64_legacy(random_string_1);
- assert(locale_independent_atoi_result == std::clamp<int64_t>(atoi64_result, std::numeric_limits<int>::min(), std::numeric_limits<int>::max()));
- }
-
- {
- const int64_t atoi64_result = atoi64_legacy(random_string_1);
- const int64_t locale_independent_atoi_result = LocaleIndependentAtoi<int64_t>(random_string_1);
- assert(atoi64_result == locale_independent_atoi_result);
- }
}
diff --git a/src/test/fuzz/system.cpp b/src/test/fuzz/system.cpp
index dc3f9c8b8f..935f0c21e1 100644
--- a/src/test/fuzz/system.cpp
+++ b/src/test/fuzz/system.cpp
@@ -2,11 +2,11 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#include <common/args.h>
#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
#include <test/fuzz/util.h>
#include <test/util/setup_common.h>
-#include <util/system.h>
#include <cstdint>
#include <string>
diff --git a/src/test/fuzz/tx_pool.cpp b/src/test/fuzz/tx_pool.cpp
index 0cabaf323b..a055705575 100644
--- a/src/test/fuzz/tx_pool.cpp
+++ b/src/test/fuzz/tx_pool.cpp
@@ -316,6 +316,7 @@ FUZZ_TARGET_INIT(tx_pool, initialize_tx_pool)
MockTime(fuzzed_data_provider, chainstate);
std::vector<uint256> txids;
+ txids.reserve(g_outpoints_coinbase_init_mature.size());
for (const auto& outpoint : g_outpoints_coinbase_init_mature) {
txids.push_back(outpoint.hash);
}
diff --git a/src/test/fuzz/utxo_snapshot.cpp b/src/test/fuzz/utxo_snapshot.cpp
index 7119643b45..be34906025 100644
--- a/src/test/fuzz/utxo_snapshot.cpp
+++ b/src/test/fuzz/utxo_snapshot.cpp
@@ -4,13 +4,13 @@
#include <chainparams.h>
#include <consensus/validation.h>
-#include <fs.h>
#include <node/utxo_snapshot.h>
#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
#include <test/fuzz/util.h>
#include <test/util/mining.h>
#include <test/util/setup_common.h>
+#include <util/fs.h>
#include <validation.h>
#include <validationinterface.h>
diff --git a/src/test/fuzz/versionbits.cpp b/src/test/fuzz/versionbits.cpp
index 143027662f..e6a19d6e91 100644
--- a/src/test/fuzz/versionbits.cpp
+++ b/src/test/fuzz/versionbits.cpp
@@ -4,9 +4,9 @@
#include <chain.h>
#include <chainparams.h>
+#include <common/args.h>
#include <consensus/params.h>
#include <primitives/block.h>
-#include <util/system.h>
#include <versionbits.h>
#include <test/fuzz/FuzzedDataProvider.h>
diff --git a/src/test/getarg_tests.cpp b/src/test/getarg_tests.cpp
index 9c2d8a4dad..715b6885f5 100644
--- a/src/test/getarg_tests.cpp
+++ b/src/test/getarg_tests.cpp
@@ -2,11 +2,12 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#include <common/args.h>
+#include <logging.h>
#include <test/util/setup_common.h>
#include <univalue.h>
#include <util/settings.h>
#include <util/strencodings.h>
-#include <util/system.h>
#include <limits>
#include <string>
@@ -29,6 +30,7 @@ void ResetArgs(ArgsManager& local_args, const std::string& strArg)
// Convert to char*:
std::vector<const char*> vecChar;
+ vecChar.reserve(vecArg.size());
for (const std::string& s : vecArg)
vecChar.push_back(s.c_str());
diff --git a/src/test/httpserver_tests.cpp b/src/test/httpserver_tests.cpp
index ee59ec6967..c95a777e80 100644
--- a/src/test/httpserver_tests.cpp
+++ b/src/test/httpserver_tests.cpp
@@ -34,5 +34,9 @@ BOOST_AUTO_TEST_CASE(test_query_parameters)
// Invalid query string syntax is the same as not having parameters
uri = "/rest/endpoint/someresource.json&p1=v1&p2=v2";
BOOST_CHECK(!GetQueryParameterFromUri(uri.c_str(), "p1").has_value());
+
+ // URI with invalid characters (%) raises a runtime error regardless of which query parameter is queried
+ uri = "/rest/endpoint/someresource.json&p1=v1&p2=v2%";
+ BOOST_CHECK_EXCEPTION(GetQueryParameterFromUri(uri.c_str(), "p1"), std::runtime_error, HasReason("URI parsing failed, it likely contained RFC 3986 invalid characters"));
}
BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/i2p_tests.cpp b/src/test/i2p_tests.cpp
index 3e20b527b5..b2e1ae43be 100644
--- a/src/test/i2p_tests.cpp
+++ b/src/test/i2p_tests.cpp
@@ -2,13 +2,13 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#include <common/args.h>
#include <i2p.h>
#include <logging.h>
#include <netaddress.h>
#include <test/util/logging.h>
#include <test/util/net.h>
#include <test/util/setup_common.h>
-#include <util/system.h>
#include <util/threadinterrupt.h>
#include <boost/test/unit_test.hpp>
diff --git a/src/test/miniscript_tests.cpp b/src/test/miniscript_tests.cpp
index 655d6d7828..42e441c41a 100644
--- a/src/test/miniscript_tests.cpp
+++ b/src/test/miniscript_tests.cpp
@@ -241,8 +241,6 @@ const KeyConverter CONVERTER{};
using Fragment = miniscript::Fragment;
using NodeRef = miniscript::NodeRef<CPubKey>;
-// https://github.com/llvm/llvm-project/issues/53444
-// NOLINTNEXTLINE(misc-unused-using-decls)
using miniscript::operator"" _mst;
using Node = miniscript::Node<CPubKey>;
diff --git a/src/test/net_tests.cpp b/src/test/net_tests.cpp
index 4fbd9b3a6e..631c213627 100644
--- a/src/test/net_tests.cpp
+++ b/src/test/net_tests.cpp
@@ -4,6 +4,7 @@
#include <chainparams.h>
#include <clientversion.h>
+#include <common/args.h>
#include <compat/compat.h>
#include <cstdint>
#include <net.h>
@@ -19,7 +20,6 @@
#include <timedata.h>
#include <util/strencodings.h>
#include <util/string.h>
-#include <util/system.h>
#include <validation.h>
#include <version.h>
diff --git a/src/test/policyestimator_tests.cpp b/src/test/policyestimator_tests.cpp
index 75ba9972f6..bc9c672560 100644
--- a/src/test/policyestimator_tests.cpp
+++ b/src/test/policyestimator_tests.cpp
@@ -24,6 +24,7 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates)
CAmount basefee(2000);
CAmount deltaFee(100);
std::vector<CAmount> feeV;
+ feeV.reserve(10);
// Populate vectors of increasing fees
for (int j = 0; j < 10; j++) {
diff --git a/src/test/pool_tests.cpp b/src/test/pool_tests.cpp
new file mode 100644
index 0000000000..8a07e09a44
--- /dev/null
+++ b/src/test/pool_tests.cpp
@@ -0,0 +1,190 @@
+// Copyright (c) 2022 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 <memusage.h>
+#include <support/allocators/pool.h>
+#include <test/util/poolresourcetester.h>
+#include <test/util/random.h>
+#include <test/util/setup_common.h>
+
+#include <boost/test/unit_test.hpp>
+
+#include <cstddef>
+#include <cstdint>
+#include <unordered_map>
+#include <vector>
+
+BOOST_FIXTURE_TEST_SUITE(pool_tests, BasicTestingSetup)
+
+BOOST_AUTO_TEST_CASE(basic_allocating)
+{
+ auto resource = PoolResource<8, 8>();
+ PoolResourceTester::CheckAllDataAccountedFor(resource);
+
+ // first chunk is already allocated
+ size_t expected_bytes_available = resource.ChunkSizeBytes();
+ BOOST_TEST(expected_bytes_available == PoolResourceTester::AvailableMemoryFromChunk(resource));
+
+ // chunk is used, no more allocation
+ void* block = resource.Allocate(8, 8);
+ expected_bytes_available -= 8;
+ BOOST_TEST(expected_bytes_available == PoolResourceTester::AvailableMemoryFromChunk(resource));
+
+ BOOST_TEST(0 == PoolResourceTester::FreeListSizes(resource)[1]);
+ resource.Deallocate(block, 8, 8);
+ PoolResourceTester::CheckAllDataAccountedFor(resource);
+ BOOST_TEST(1 == PoolResourceTester::FreeListSizes(resource)[1]);
+
+ // alignment is too small, but the best fitting freelist is used. Nothing is allocated.
+ void* b = resource.Allocate(8, 1);
+ BOOST_TEST(b == block); // we got the same block of memory as before
+ BOOST_TEST(0 == PoolResourceTester::FreeListSizes(resource)[1]);
+ BOOST_TEST(expected_bytes_available == PoolResourceTester::AvailableMemoryFromChunk(resource));
+
+ resource.Deallocate(block, 8, 1);
+ PoolResourceTester::CheckAllDataAccountedFor(resource);
+ BOOST_TEST(1 == PoolResourceTester::FreeListSizes(resource)[1]);
+ BOOST_TEST(expected_bytes_available == PoolResourceTester::AvailableMemoryFromChunk(resource));
+
+ // can't use resource because alignment is too big, allocate system memory
+ b = resource.Allocate(8, 16);
+ BOOST_TEST(b != block);
+ block = b;
+ PoolResourceTester::CheckAllDataAccountedFor(resource);
+ BOOST_TEST(1 == PoolResourceTester::FreeListSizes(resource)[1]);
+ BOOST_TEST(expected_bytes_available == PoolResourceTester::AvailableMemoryFromChunk(resource));
+
+ resource.Deallocate(block, 8, 16);
+ PoolResourceTester::CheckAllDataAccountedFor(resource);
+ BOOST_TEST(1 == PoolResourceTester::FreeListSizes(resource)[1]);
+ BOOST_TEST(expected_bytes_available == PoolResourceTester::AvailableMemoryFromChunk(resource));
+
+ // can't use chunk because size is too big
+ block = resource.Allocate(16, 8);
+ PoolResourceTester::CheckAllDataAccountedFor(resource);
+ BOOST_TEST(1 == PoolResourceTester::FreeListSizes(resource)[1]);
+ BOOST_TEST(expected_bytes_available == PoolResourceTester::AvailableMemoryFromChunk(resource));
+
+ resource.Deallocate(block, 16, 8);
+ PoolResourceTester::CheckAllDataAccountedFor(resource);
+ BOOST_TEST(1 == PoolResourceTester::FreeListSizes(resource)[1]);
+ BOOST_TEST(expected_bytes_available == PoolResourceTester::AvailableMemoryFromChunk(resource));
+
+ // it's possible that 0 bytes are allocated, make sure this works. In that case the call is forwarded to operator new
+ // 0 bytes takes one entry from the first freelist
+ void* p = resource.Allocate(0, 1);
+ BOOST_TEST(0 == PoolResourceTester::FreeListSizes(resource)[1]);
+ BOOST_TEST(expected_bytes_available == PoolResourceTester::AvailableMemoryFromChunk(resource));
+
+ resource.Deallocate(p, 0, 1);
+ PoolResourceTester::CheckAllDataAccountedFor(resource);
+ BOOST_TEST(1 == PoolResourceTester::FreeListSizes(resource)[1]);
+ BOOST_TEST(expected_bytes_available == PoolResourceTester::AvailableMemoryFromChunk(resource));
+}
+
+// Allocates from 0 to n bytes were n > the PoolResource's data, and each should work
+BOOST_AUTO_TEST_CASE(allocate_any_byte)
+{
+ auto resource = PoolResource<128, 8>(1024);
+
+ uint8_t num_allocs = 200;
+
+ auto data = std::vector<Span<uint8_t>>();
+
+ // allocate an increasing number of bytes
+ for (uint8_t num_bytes = 0; num_bytes < num_allocs; ++num_bytes) {
+ uint8_t* bytes = new (resource.Allocate(num_bytes, 1)) uint8_t[num_bytes];
+ BOOST_TEST(bytes != nullptr);
+ data.emplace_back(bytes, num_bytes);
+
+ // set each byte to num_bytes
+ std::fill(bytes, bytes + num_bytes, num_bytes);
+ }
+
+ // now that we got all allocated, test if all still have the correct values, and give everything back to the allocator
+ uint8_t val = 0;
+ for (auto const& span : data) {
+ for (auto x : span) {
+ BOOST_TEST(val == x);
+ }
+ std::destroy(span.data(), span.data() + span.size());
+ resource.Deallocate(span.data(), span.size(), 1);
+ ++val;
+ }
+
+ PoolResourceTester::CheckAllDataAccountedFor(resource);
+}
+
+BOOST_AUTO_TEST_CASE(random_allocations)
+{
+ struct PtrSizeAlignment {
+ void* ptr;
+ size_t bytes;
+ size_t alignment;
+ };
+
+ // makes a bunch of random allocations and gives all of them back in random order.
+ auto resource = PoolResource<128, 8>(65536);
+ std::vector<PtrSizeAlignment> ptr_size_alignment{};
+ for (size_t i = 0; i < 1000; ++i) {
+ // make it a bit more likely to allocate than deallocate
+ if (ptr_size_alignment.empty() || 0 != InsecureRandRange(4)) {
+ // allocate a random item
+ std::size_t alignment = std::size_t{1} << InsecureRandRange(8); // 1, 2, ..., 128
+ std::size_t size = (InsecureRandRange(200) / alignment + 1) * alignment; // multiple of alignment
+ void* ptr = resource.Allocate(size, alignment);
+ BOOST_TEST(ptr != nullptr);
+ BOOST_TEST((reinterpret_cast<uintptr_t>(ptr) & (alignment - 1)) == 0);
+ ptr_size_alignment.push_back({ptr, size, alignment});
+ } else {
+ // deallocate a random item
+ auto& x = ptr_size_alignment[InsecureRandRange(ptr_size_alignment.size())];
+ resource.Deallocate(x.ptr, x.bytes, x.alignment);
+ x = ptr_size_alignment.back();
+ ptr_size_alignment.pop_back();
+ }
+ }
+
+ // deallocate all the rest
+ for (auto const& x : ptr_size_alignment) {
+ resource.Deallocate(x.ptr, x.bytes, x.alignment);
+ }
+
+ PoolResourceTester::CheckAllDataAccountedFor(resource);
+}
+
+BOOST_AUTO_TEST_CASE(memusage_test)
+{
+ auto std_map = std::unordered_map<int, int>{};
+
+ using Map = std::unordered_map<int,
+ int,
+ std::hash<int>,
+ std::equal_to<int>,
+ PoolAllocator<std::pair<const int, int>,
+ sizeof(std::pair<const int, int>) + sizeof(void*) * 4,
+ alignof(void*)>>;
+ auto resource = Map::allocator_type::ResourceType(1024);
+
+ PoolResourceTester::CheckAllDataAccountedFor(resource);
+
+ {
+ auto resource_map = Map{0, std::hash<int>{}, std::equal_to<int>{}, &resource};
+
+ // can't have the same resource usage
+ BOOST_TEST(memusage::DynamicUsage(std_map) != memusage::DynamicUsage(resource_map));
+
+ for (size_t i = 0; i < 10000; ++i) {
+ std_map[i];
+ resource_map[i];
+ }
+
+ // Eventually the resource_map should have a much lower memory usage because it has less malloc overhead
+ BOOST_TEST(memusage::DynamicUsage(resource_map) <= memusage::DynamicUsage(std_map) * 90 / 100);
+ }
+
+ PoolResourceTester::CheckAllDataAccountedFor(resource);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/random_tests.cpp b/src/test/random_tests.cpp
index e5cf767614..414e4509f5 100644
--- a/src/test/random_tests.cpp
+++ b/src/test/random_tests.cpp
@@ -5,6 +5,7 @@
#include <random.h>
#include <test/util/setup_common.h>
+#include <util/time.h>
#include <boost/test/unit_test.hpp>
diff --git a/src/test/scheduler_tests.cpp b/src/test/scheduler_tests.cpp
index 1301a1b219..3fb3378598 100644
--- a/src/test/scheduler_tests.cpp
+++ b/src/test/scheduler_tests.cpp
@@ -71,6 +71,7 @@ BOOST_AUTO_TEST_CASE(manythreads)
// As soon as these are created they will start running and servicing the queue
std::vector<std::thread> microThreads;
+ microThreads.reserve(10);
for (int i = 0; i < 5; i++)
microThreads.emplace_back(std::bind(&CScheduler::serviceQueue, &microTasks));
@@ -136,6 +137,7 @@ BOOST_AUTO_TEST_CASE(singlethreadedscheduler_ordered)
// the extra threads should effectively be doing nothing
// if they don't we'll get out of order behaviour
std::vector<std::thread> threads;
+ threads.reserve(5);
for (int i = 0; i < 5; ++i) {
threads.emplace_back([&] { scheduler.serviceQueue(); });
}
diff --git a/src/test/script_p2sh_tests.cpp b/src/test/script_p2sh_tests.cpp
index c9f002b324..739ab75de3 100644
--- a/src/test/script_p2sh_tests.cpp
+++ b/src/test/script_p2sh_tests.cpp
@@ -156,6 +156,7 @@ BOOST_AUTO_TEST_CASE(set)
FillableSigningProvider keystore;
CKey key[4];
std::vector<CPubKey> keys;
+ keys.reserve(4);
for (int i = 0; i < 4; i++)
{
key[i].MakeNewKey(true);
@@ -270,12 +271,13 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard)
CCoinsViewCache coins(&coinsDummy);
FillableSigningProvider keystore;
CKey key[6];
- std::vector<CPubKey> keys;
for (int i = 0; i < 6; i++)
{
key[i].MakeNewKey(true);
BOOST_CHECK(keystore.AddKey(key[i]));
}
+ std::vector<CPubKey> keys;
+ keys.reserve(3);
for (int i = 0; i < 3; i++)
keys.push_back(key[i].GetPubKey());
diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp
index 45d9f2cf29..d8898743b0 100644
--- a/src/test/script_tests.cpp
+++ b/src/test/script_tests.cpp
@@ -6,7 +6,6 @@
#include <test/data/bip341_wallet_vectors.json.h>
#include <core_io.h>
-#include <fs.h>
#include <key.h>
#include <rpc/util.h>
#include <script/script.h>
@@ -19,6 +18,7 @@
#include <test/util/random.h>
#include <test/util/setup_common.h>
#include <test/util/transaction_utils.h>
+#include <util/fs.h>
#include <util/strencodings.h>
#include <util/system.h>
diff --git a/src/test/settings_tests.cpp b/src/test/settings_tests.cpp
index ad12c46561..604eb48df6 100644
--- a/src/test/settings_tests.cpp
+++ b/src/test/settings_tests.cpp
@@ -4,16 +4,16 @@
#include <util/settings.h>
-#include <fs.h>
#include <test/util/setup_common.h>
#include <test/util/str.h>
+#include <util/fs.h>
#include <boost/test/unit_test.hpp>
+#include <common/args.h>
#include <univalue.h>
#include <util/strencodings.h>
#include <util/string.h>
-#include <util/system.h>
#include <fstream>
#include <map>
diff --git a/src/test/streams_tests.cpp b/src/test/streams_tests.cpp
index a9b5251ad3..a0392570f1 100644
--- a/src/test/streams_tests.cpp
+++ b/src/test/streams_tests.cpp
@@ -2,10 +2,10 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include <fs.h>
#include <streams.h>
#include <test/util/random.h>
#include <test/util/setup_common.h>
+#include <util/fs.h>
#include <boost/test/unit_test.hpp>
diff --git a/src/test/txpackage_tests.cpp b/src/test/txpackage_tests.cpp
index 024526497c..c08d2748a6 100644
--- a/src/test/txpackage_tests.cpp
+++ b/src/test/txpackage_tests.cpp
@@ -16,6 +16,9 @@
#include <boost/test/unit_test.hpp>
BOOST_AUTO_TEST_SUITE(txpackage_tests)
+// A fee amount that is above 1sat/vB but below 5sat/vB for most transactions created within these
+// unit tests.
+static const CAmount low_fee_amt{200};
// Create placeholder transactions that have no meaning.
inline CTransactionRef create_placeholder_tx(size_t num_inputs, size_t num_outputs)
@@ -373,6 +376,7 @@ BOOST_FIXTURE_TEST_CASE(package_witness_swap_tests, TestChain100Setup)
{
// Mine blocks to mature coinbases.
mineBlocks(5);
+ MockMempoolMinFee(CFeeRate(5000));
LOCK(cs_main);
// Transactions with a same-txid-different-witness transaction in the mempool should be ignored,
@@ -560,13 +564,15 @@ BOOST_FIXTURE_TEST_CASE(package_witness_swap_tests, TestChain100Setup)
BOOST_CHECK(parent2_v2_result.m_result_type == MempoolAcceptResult::ResultType::VALID);
package_mixed.push_back(ptx_parent2_v1);
- // parent3 will be a new transaction. Put 0 fees on it to make it invalid on its own.
+ // parent3 will be a new transaction. Put a low feerate to make it invalid on its own.
auto mtx_parent3 = CreateValidMempoolTransaction(/*input_transaction=*/m_coinbase_txns[3], /*input_vout=*/0,
/*input_height=*/0, /*input_signing_key=*/coinbaseKey,
/*output_destination=*/acs_spk,
- /*output_amount=*/CAmount(50 * COIN), /*submit=*/false);
+ /*output_amount=*/CAmount(50 * COIN - low_fee_amt), /*submit=*/false);
CTransactionRef ptx_parent3 = MakeTransactionRef(mtx_parent3);
package_mixed.push_back(ptx_parent3);
+ BOOST_CHECK(m_node.mempool->GetMinFee().GetFee(GetVirtualTransactionSize(*ptx_parent3)) > low_fee_amt);
+ BOOST_CHECK(m_node.mempool->m_min_relay_feerate.GetFee(GetVirtualTransactionSize(*ptx_parent3)) <= low_fee_amt);
// child spends parent1, parent2, and parent3
CKey mixed_grandchild_key;
@@ -627,6 +633,7 @@ BOOST_FIXTURE_TEST_CASE(package_witness_swap_tests, TestChain100Setup)
BOOST_FIXTURE_TEST_CASE(package_cpfp_tests, TestChain100Setup)
{
mineBlocks(5);
+ MockMempoolMinFee(CFeeRate(5000));
LOCK(::cs_main);
size_t expected_pool_size = m_node.mempool->size();
CKey child_key;
@@ -636,9 +643,9 @@ BOOST_FIXTURE_TEST_CASE(package_cpfp_tests, TestChain100Setup)
grandchild_key.MakeNewKey(true);
CScript child_spk = GetScriptForDestination(WitnessV0KeyHash(grandchild_key.GetPubKey()));
- // zero-fee parent and high-fee child package
+ // low-fee parent and high-fee child package
const CAmount coinbase_value{50 * COIN};
- const CAmount parent_value{coinbase_value - 0};
+ const CAmount parent_value{coinbase_value - low_fee_amt};
const CAmount child_value{parent_value - COIN};
Package package_cpfp;
@@ -657,17 +664,20 @@ BOOST_FIXTURE_TEST_CASE(package_cpfp_tests, TestChain100Setup)
package_cpfp.push_back(tx_child);
// Package feerate is calculated using modified fees, and prioritisetransaction accepts negative
- // fee deltas. This should be taken into account. De-prioritise the parent transaction by -1BTC,
- // bringing the package feerate to 0.
- m_node.mempool->PrioritiseTransaction(tx_parent->GetHash(), -1 * COIN);
+ // fee deltas. This should be taken into account. De-prioritise the parent transaction
+ // to bring the package feerate to 0.
+ m_node.mempool->PrioritiseTransaction(tx_parent->GetHash(), child_value - coinbase_value);
{
BOOST_CHECK_EQUAL(m_node.mempool->size(), expected_pool_size);
const auto submit_cpfp_deprio = ProcessNewPackage(m_node.chainman->ActiveChainstate(), *m_node.mempool,
package_cpfp, /*test_accept=*/ false);
- BOOST_CHECK_EQUAL(submit_cpfp_deprio.m_state.GetResult(), PackageValidationResult::PCKG_POLICY);
- BOOST_CHECK_MESSAGE(submit_cpfp_deprio.m_state.IsInvalid(),
- "Package validation unexpectedly succeeded: " << submit_cpfp_deprio.m_state.GetRejectReason());
- BOOST_CHECK(submit_cpfp_deprio.m_tx_results.empty());
+ BOOST_CHECK_EQUAL(submit_cpfp_deprio.m_state.GetResult(), PackageValidationResult::PCKG_TX);
+ BOOST_CHECK(submit_cpfp_deprio.m_state.IsInvalid());
+ BOOST_CHECK_EQUAL(submit_cpfp_deprio.m_tx_results.find(tx_parent->GetWitnessHash())->second.m_state.GetResult(),
+ TxValidationResult::TX_MEMPOOL_POLICY);
+ BOOST_CHECK_EQUAL(submit_cpfp_deprio.m_tx_results.find(tx_child->GetWitnessHash())->second.m_state.GetResult(),
+ TxValidationResult::TX_MISSING_INPUTS);
+ BOOST_CHECK(submit_cpfp_deprio.m_tx_results.find(tx_parent->GetWitnessHash())->second.m_state.GetRejectReason() == "min relay fee not met");
BOOST_CHECK_EQUAL(m_node.mempool->size(), expected_pool_size);
const CFeeRate expected_feerate(0, GetVirtualTransactionSize(*tx_parent) + GetVirtualTransactionSize(*tx_child));
}
@@ -675,8 +685,8 @@ BOOST_FIXTURE_TEST_CASE(package_cpfp_tests, TestChain100Setup)
// Clear the prioritisation of the parent transaction.
WITH_LOCK(m_node.mempool->cs, m_node.mempool->ClearPrioritisation(tx_parent->GetHash()));
- // Package CPFP: Even though the parent pays 0 absolute fees, the child pays 1 BTC which is
- // enough for the package feerate to meet the threshold.
+ // Package CPFP: Even though the parent's feerate is below the mempool minimum feerate, the
+ // child pays enough for the package feerate to meet the threshold.
{
BOOST_CHECK_EQUAL(m_node.mempool->size(), expected_pool_size);
const auto submit_cpfp = ProcessNewPackage(m_node.chainman->ActiveChainstate(), *m_node.mempool,
@@ -689,7 +699,7 @@ BOOST_FIXTURE_TEST_CASE(package_cpfp_tests, TestChain100Setup)
auto it_child = submit_cpfp.m_tx_results.find(tx_child->GetWitnessHash());
BOOST_CHECK(it_parent != submit_cpfp.m_tx_results.end());
BOOST_CHECK(it_parent->second.m_result_type == MempoolAcceptResult::ResultType::VALID);
- BOOST_CHECK(it_parent->second.m_base_fees.value() == 0);
+ BOOST_CHECK(it_parent->second.m_base_fees.value() == coinbase_value - parent_value);
BOOST_CHECK(it_child != submit_cpfp.m_tx_results.end());
BOOST_CHECK(it_child->second.m_result_type == MempoolAcceptResult::ResultType::VALID);
BOOST_CHECK(it_child->second.m_base_fees.value() == COIN);
@@ -709,22 +719,28 @@ BOOST_FIXTURE_TEST_CASE(package_cpfp_tests, TestChain100Setup)
}
// Just because we allow low-fee parents doesn't mean we allow low-feerate packages.
- // This package just pays 200 satoshis total. This would be enough to pay for the child alone,
- // but isn't enough for the entire package to meet the 1sat/vbyte minimum.
+ // The mempool minimum feerate is 5sat/vB, but this package just pays 800 satoshis total.
+ // The child fees would be able to pay for itself, but isn't enough for the entire package.
Package package_still_too_low;
+ const CAmount parent_fee{200};
+ const CAmount child_fee{600};
auto mtx_parent_cheap = CreateValidMempoolTransaction(/*input_transaction=*/m_coinbase_txns[1], /*input_vout=*/0,
/*input_height=*/0, /*input_signing_key=*/coinbaseKey,
/*output_destination=*/parent_spk,
- /*output_amount=*/coinbase_value, /*submit=*/false);
+ /*output_amount=*/coinbase_value - parent_fee, /*submit=*/false);
CTransactionRef tx_parent_cheap = MakeTransactionRef(mtx_parent_cheap);
package_still_too_low.push_back(tx_parent_cheap);
+ BOOST_CHECK(m_node.mempool->GetMinFee().GetFee(GetVirtualTransactionSize(*tx_parent_cheap)) > parent_fee);
+ BOOST_CHECK(m_node.mempool->m_min_relay_feerate.GetFee(GetVirtualTransactionSize(*tx_parent_cheap)) <= parent_fee);
auto mtx_child_cheap = CreateValidMempoolTransaction(/*input_transaction=*/tx_parent_cheap, /*input_vout=*/0,
/*input_height=*/101, /*input_signing_key=*/child_key,
/*output_destination=*/child_spk,
- /*output_amount=*/coinbase_value - 200, /*submit=*/false);
+ /*output_amount=*/coinbase_value - parent_fee - child_fee, /*submit=*/false);
CTransactionRef tx_child_cheap = MakeTransactionRef(mtx_child_cheap);
package_still_too_low.push_back(tx_child_cheap);
+ BOOST_CHECK(m_node.mempool->GetMinFee().GetFee(GetVirtualTransactionSize(*tx_child_cheap)) <= child_fee);
+ BOOST_CHECK(m_node.mempool->GetMinFee().GetFee(GetVirtualTransactionSize(*tx_parent_cheap) + GetVirtualTransactionSize(*tx_child_cheap)) > parent_fee + child_fee);
// Cheap package should fail with package-fee-too-low.
{
@@ -735,11 +751,6 @@ BOOST_FIXTURE_TEST_CASE(package_cpfp_tests, TestChain100Setup)
BOOST_CHECK_EQUAL(submit_package_too_low.m_state.GetResult(), PackageValidationResult::PCKG_POLICY);
BOOST_CHECK_EQUAL(submit_package_too_low.m_state.GetRejectReason(), "package-fee-too-low");
BOOST_CHECK_EQUAL(m_node.mempool->size(), expected_pool_size);
- const CFeeRate child_feerate(200, GetVirtualTransactionSize(*tx_child_cheap));
- BOOST_CHECK(child_feerate.GetFeePerK() > 1000);
- const CFeeRate expected_feerate(200,
- GetVirtualTransactionSize(*tx_parent_cheap) + GetVirtualTransactionSize(*tx_child_cheap));
- BOOST_CHECK(expected_feerate.GetFeePerK() < 1000);
}
// Package feerate includes the modified fees of the transactions.
@@ -752,18 +763,18 @@ BOOST_FIXTURE_TEST_CASE(package_cpfp_tests, TestChain100Setup)
expected_pool_size += 2;
BOOST_CHECK_MESSAGE(submit_prioritised_package.m_state.IsValid(),
"Package validation unexpectedly failed" << submit_prioritised_package.m_state.GetRejectReason());
- const CFeeRate expected_feerate(1 * COIN + 200,
+ const CFeeRate expected_feerate(1 * COIN + parent_fee + child_fee,
GetVirtualTransactionSize(*tx_parent_cheap) + GetVirtualTransactionSize(*tx_child_cheap));
BOOST_CHECK_EQUAL(submit_prioritised_package.m_tx_results.size(), package_still_too_low.size());
auto it_parent = submit_prioritised_package.m_tx_results.find(tx_parent_cheap->GetWitnessHash());
auto it_child = submit_prioritised_package.m_tx_results.find(tx_child_cheap->GetWitnessHash());
BOOST_CHECK(it_parent != submit_prioritised_package.m_tx_results.end());
BOOST_CHECK(it_parent->second.m_result_type == MempoolAcceptResult::ResultType::VALID);
- BOOST_CHECK(it_parent->second.m_base_fees.value() == 0);
+ BOOST_CHECK(it_parent->second.m_base_fees.value() == parent_fee);
BOOST_CHECK(it_parent->second.m_effective_feerate.value() == expected_feerate);
BOOST_CHECK(it_child != submit_prioritised_package.m_tx_results.end());
BOOST_CHECK(it_child->second.m_result_type == MempoolAcceptResult::ResultType::VALID);
- BOOST_CHECK(it_child->second.m_base_fees.value() == 200);
+ BOOST_CHECK(it_child->second.m_base_fees.value() == child_fee);
BOOST_CHECK(it_child->second.m_effective_feerate.value() == expected_feerate);
std::vector<uint256> expected_wtxids({tx_parent_cheap->GetWitnessHash(), tx_child_cheap->GetWitnessHash()});
BOOST_CHECK(it_parent->second.m_wtxids_fee_calculations.value() == expected_wtxids);
@@ -800,8 +811,8 @@ BOOST_FIXTURE_TEST_CASE(package_cpfp_tests, TestChain100Setup)
BOOST_CHECK_MESSAGE(submit_rich_parent.m_state.IsInvalid(), "Package validation unexpectedly succeeded");
// The child would have been validated on its own and failed, then submitted as a "package" of 1.
- BOOST_CHECK_EQUAL(submit_rich_parent.m_state.GetResult(), PackageValidationResult::PCKG_POLICY);
- BOOST_CHECK_EQUAL(submit_rich_parent.m_state.GetRejectReason(), "package-fee-too-low");
+ BOOST_CHECK_EQUAL(submit_rich_parent.m_state.GetResult(), PackageValidationResult::PCKG_TX);
+ BOOST_CHECK_EQUAL(submit_rich_parent.m_state.GetRejectReason(), "transaction failed");
auto it_parent = submit_rich_parent.m_tx_results.find(tx_parent_rich->GetWitnessHash());
BOOST_CHECK(it_parent != submit_rich_parent.m_tx_results.end());
@@ -810,6 +821,11 @@ BOOST_FIXTURE_TEST_CASE(package_cpfp_tests, TestChain100Setup)
BOOST_CHECK_MESSAGE(it_parent->second.m_base_fees.value() == high_parent_fee,
strprintf("rich parent: expected fee %s, got %s", high_parent_fee, it_parent->second.m_base_fees.value()));
BOOST_CHECK(it_parent->second.m_effective_feerate == CFeeRate(high_parent_fee, GetVirtualTransactionSize(*tx_parent_rich)));
+ auto it_child = submit_rich_parent.m_tx_results.find(tx_child_poor->GetWitnessHash());
+ BOOST_CHECK(it_child != submit_rich_parent.m_tx_results.end());
+ BOOST_CHECK_EQUAL(it_child->second.m_result_type, MempoolAcceptResult::ResultType::INVALID);
+ BOOST_CHECK_EQUAL(it_child->second.m_state.GetResult(), TxValidationResult::TX_MEMPOOL_POLICY);
+ BOOST_CHECK(it_child->second.m_state.GetRejectReason() == "min relay fee not met");
BOOST_CHECK_EQUAL(m_node.mempool->size(), expected_pool_size);
BOOST_CHECK(m_node.mempool->exists(GenTxid::Txid(tx_parent_rich->GetHash())));
diff --git a/src/test/txrequest_tests.cpp b/src/test/txrequest_tests.cpp
index 17a55d5ab5..dc257a0d51 100644
--- a/src/test/txrequest_tests.cpp
+++ b/src/test/txrequest_tests.cpp
@@ -386,6 +386,7 @@ void BuildBigPriorityTest(Scenario& scenario, int peers)
}
// Make a list of all peers, in order of intended request order (concatenation of pref_peers and npref_peers).
std::vector<NodeId> request_order;
+ request_order.reserve(num_pref + num_npref);
for (int i = 0; i < num_pref; ++i) request_order.push_back(pref_peers[i]);
for (int i = 0; i < num_npref; ++i) request_order.push_back(npref_peers[i]);
diff --git a/src/test/util/chainstate.h b/src/test/util/chainstate.h
index e664435e03..bf8f8b5819 100644
--- a/src/test/util/chainstate.h
+++ b/src/test/util/chainstate.h
@@ -6,12 +6,12 @@
#define BITCOIN_TEST_UTIL_CHAINSTATE_H
#include <clientversion.h>
-#include <fs.h>
#include <logging.h>
#include <node/context.h>
#include <node/utxo_snapshot.h>
#include <rpc/blockchain.h>
#include <test/util/setup_common.h>
+#include <util/fs.h>
#include <validation.h>
#include <univalue.h>
diff --git a/src/test/util/net.cpp b/src/test/util/net.cpp
index 070a6a1c50..3f72384b3b 100644
--- a/src/test/util/net.cpp
+++ b/src/test/util/net.cpp
@@ -66,7 +66,7 @@ void ConnmanTestMsg::NodeReceiveMsgBytes(CNode& node, Span<const uint8_t> msg_by
{
assert(node.ReceiveMsgBytes(msg_bytes, complete));
if (complete) {
- node.MarkReceivedMsgsForProcessing(nReceiveFloodSize);
+ node.MarkReceivedMsgsForProcessing();
}
}
@@ -84,6 +84,7 @@ bool ConnmanTestMsg::ReceiveMsgFrom(CNode& node, CSerializedNetMsg& ser_msg) con
std::vector<NodeEvictionCandidate> GetRandomNodeEvictionCandidates(int n_candidates, FastRandomContext& random_context)
{
std::vector<NodeEvictionCandidate> candidates;
+ candidates.reserve(n_candidates);
for (int id = 0; id < n_candidates; ++id) {
candidates.push_back({
/*id=*/id,
diff --git a/src/test/util/poolresourcetester.h b/src/test/util/poolresourcetester.h
new file mode 100644
index 0000000000..93f62eb2a9
--- /dev/null
+++ b/src/test/util/poolresourcetester.h
@@ -0,0 +1,129 @@
+// Copyright (c) 2022 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_TEST_UTIL_POOLRESOURCETESTER_H
+#define BITCOIN_TEST_UTIL_POOLRESOURCETESTER_H
+
+#include <support/allocators/pool.h>
+
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <vector>
+
+/**
+ * Helper to get access to private parts of PoolResource. Used in unit tests and in the fuzzer
+ */
+class PoolResourceTester
+{
+ struct PtrAndBytes {
+ uintptr_t ptr;
+ std::size_t size;
+
+ PtrAndBytes(const void* p, std::size_t s)
+ : ptr(reinterpret_cast<uintptr_t>(p)), size(s)
+ {
+ }
+
+ /**
+ * defines a sort ordering by the pointer value
+ */
+ friend bool operator<(PtrAndBytes const& a, PtrAndBytes const& b)
+ {
+ return a.ptr < b.ptr;
+ }
+ };
+
+public:
+ /**
+ * Extracts the number of elements per freelist
+ */
+ template <std::size_t MAX_BLOCK_SIZE_BYTES, std::size_t ALIGN_BYTES>
+ static std::vector<std::size_t> FreeListSizes(const PoolResource<MAX_BLOCK_SIZE_BYTES, ALIGN_BYTES>& resource)
+ {
+ auto sizes = std::vector<std::size_t>();
+ for (const auto* ptr : resource.m_free_lists) {
+ size_t size = 0;
+ while (ptr != nullptr) {
+ ++size;
+ ptr = ptr->m_next;
+ }
+ sizes.push_back(size);
+ }
+ return sizes;
+ }
+
+ /**
+ * How many bytes are still available from the last allocated chunk
+ */
+ template <std::size_t MAX_BLOCK_SIZE_BYTES, std::size_t ALIGN_BYTES>
+ static std::size_t AvailableMemoryFromChunk(const PoolResource<MAX_BLOCK_SIZE_BYTES, ALIGN_BYTES>& resource)
+ {
+ return resource.m_available_memory_end - resource.m_available_memory_it;
+ }
+
+ /**
+ * Once all blocks are given back to the resource, tests that the freelists are consistent:
+ *
+ * * All data in the freelists must come from the chunks
+ * * Memory doesn't overlap
+ * * Each byte in the chunks can be accounted for in either the freelist or as available bytes.
+ */
+ template <std::size_t MAX_BLOCK_SIZE_BYTES, std::size_t ALIGN_BYTES>
+ static void CheckAllDataAccountedFor(const PoolResource<MAX_BLOCK_SIZE_BYTES, ALIGN_BYTES>& resource)
+ {
+ // collect all free blocks by iterating all freelists
+ std::vector<PtrAndBytes> free_blocks;
+ for (std::size_t freelist_idx = 0; freelist_idx < resource.m_free_lists.size(); ++freelist_idx) {
+ std::size_t bytes = freelist_idx * resource.ELEM_ALIGN_BYTES;
+ auto* ptr = resource.m_free_lists[freelist_idx];
+ while (ptr != nullptr) {
+ free_blocks.emplace_back(ptr, bytes);
+ ptr = ptr->m_next;
+ }
+ }
+ // also add whatever has not yet been used for blocks
+ auto num_available_bytes = resource.m_available_memory_end - resource.m_available_memory_it;
+ if (num_available_bytes > 0) {
+ free_blocks.emplace_back(resource.m_available_memory_it, num_available_bytes);
+ }
+
+ // collect all chunks
+ std::vector<PtrAndBytes> chunks;
+ for (const std::byte* ptr : resource.m_allocated_chunks) {
+ chunks.emplace_back(ptr, resource.ChunkSizeBytes());
+ }
+
+ // now we have all the data from all freelists on the one hand side, and all chunks on the other hand side.
+ // To check if all of them match, sort by address and iterate.
+ std::sort(free_blocks.begin(), free_blocks.end());
+ std::sort(chunks.begin(), chunks.end());
+
+ auto chunk_it = chunks.begin();
+ auto chunk_ptr_remaining = chunk_it->ptr;
+ auto chunk_size_remaining = chunk_it->size;
+ for (const auto& free_block : free_blocks) {
+ if (chunk_size_remaining == 0) {
+ assert(chunk_it != chunks.end());
+ ++chunk_it;
+ assert(chunk_it != chunks.end());
+ chunk_ptr_remaining = chunk_it->ptr;
+ chunk_size_remaining = chunk_it->size;
+ }
+ assert(free_block.ptr == chunk_ptr_remaining); // ensure addresses match
+ assert(free_block.size <= chunk_size_remaining); // ensure no overflow
+ assert((free_block.ptr & (resource.ELEM_ALIGN_BYTES - 1)) == 0); // ensure correct alignment
+ chunk_ptr_remaining += free_block.size;
+ chunk_size_remaining -= free_block.size;
+ }
+ // ensure we are at the end of the chunks
+ assert(chunk_ptr_remaining == chunk_it->ptr + chunk_it->size);
+ ++chunk_it;
+ assert(chunk_it == chunks.end());
+ assert(chunk_size_remaining == 0);
+ }
+};
+
+#endif // BITCOIN_TEST_UTIL_POOLRESOURCETESTER_H
diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp
index 58593c9d5b..ddc1e7ab37 100644
--- a/src/test/util/setup_common.cpp
+++ b/src/test/util/setup_common.cpp
@@ -44,6 +44,7 @@
#include <txmempool.h>
#include <util/strencodings.h>
#include <util/string.h>
+#include <util/system.h>
#include <util/thread.h>
#include <util/threadnames.h>
#include <util/time.h>
@@ -432,6 +433,33 @@ std::vector<CTransactionRef> TestChain100Setup::PopulateMempool(FastRandomContex
return mempool_transactions;
}
+void TestChain100Setup::MockMempoolMinFee(const CFeeRate& target_feerate)
+{
+ LOCK2(cs_main, m_node.mempool->cs);
+ // Transactions in the mempool will affect the new minimum feerate.
+ assert(m_node.mempool->size() == 0);
+ // The target feerate cannot be too low...
+ // ...otherwise the transaction's feerate will need to be negative.
+ assert(target_feerate > m_node.mempool->m_incremental_relay_feerate);
+ // ...otherwise this is not meaningful. The feerate policy uses the maximum of both feerates.
+ assert(target_feerate > m_node.mempool->m_min_relay_feerate);
+
+ // Manually create an invalid transaction. Manually set the fee in the CTxMemPoolEntry to
+ // achieve the exact target feerate.
+ CMutableTransaction mtx = CMutableTransaction();
+ mtx.vin.push_back(CTxIn{COutPoint{g_insecure_rand_ctx.rand256(), 0}});
+ mtx.vout.push_back(CTxOut(1 * COIN, GetScriptForDestination(WitnessV0ScriptHash(CScript() << OP_TRUE))));
+ const auto tx{MakeTransactionRef(mtx)};
+ LockPoints lp;
+ // The new mempool min feerate is equal to the removed package's feerate + incremental feerate.
+ const auto tx_fee = target_feerate.GetFee(GetVirtualTransactionSize(*tx)) -
+ m_node.mempool->m_incremental_relay_feerate.GetFee(GetVirtualTransactionSize(*tx));
+ m_node.mempool->addUnchecked(CTxMemPoolEntry(tx, /*fee=*/tx_fee,
+ /*time=*/0, /*entry_height=*/1,
+ /*spends_coinbase=*/true, /*sigops_cost=*/1, lp));
+ m_node.mempool->TrimToSize(0);
+ assert(m_node.mempool->GetMinFee() == target_feerate);
+}
/**
* @returns a real block (0000000000013b8ab2cd513b0261a14096412195a72a0c4827d229dcc7e0f7af)
* with 9 txs.
diff --git a/src/test/util/setup_common.h b/src/test/util/setup_common.h
index 8874db7e75..750f010fb0 100644
--- a/src/test/util/setup_common.h
+++ b/src/test/util/setup_common.h
@@ -6,7 +6,7 @@
#define BITCOIN_TEST_UTIL_SETUP_COMMON_H
#include <chainparamsbase.h>
-#include <fs.h>
+#include <common/args.h>
#include <key.h>
#include <node/caches.h>
#include <node/context.h>
@@ -15,14 +15,15 @@
#include <random.h>
#include <stdexcept>
#include <util/check.h>
+#include <util/fs.h>
#include <util/string.h>
-#include <util/system.h>
#include <util/vector.h>
#include <functional>
#include <type_traits>
#include <vector>
+class CFeeRate;
class Chainstate;
/** This is connected to the logger. Can be used to redirect logs to any other log */
@@ -185,6 +186,17 @@ struct TestChain100Setup : public TestingSetup {
*/
std::vector<CTransactionRef> PopulateMempool(FastRandomContext& det_rand, size_t num_transactions, bool submit);
+ /** Mock the mempool minimum feerate by adding a transaction and calling TrimToSize(0),
+ * simulating the mempool "reaching capacity" and evicting by descendant feerate. Note that
+ * this clears the mempool, and the new minimum feerate will depend on the maximum feerate of
+ * transactions removed, so this must be called while the mempool is empty.
+ *
+ * @param target_feerate The new mempool minimum feerate after this function returns.
+ * Must be above max(incremental feerate, min relay feerate),
+ * or 1sat/vB with default settings.
+ */
+ void MockMempoolMinFee(const CFeeRate& target_feerate);
+
std::vector<CTransactionRef> m_coinbase_txns; // For convenience, coinbase transactions
CKey coinbaseKey; // private/public key needed to spend coinbase transactions
};
diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp
index a13552653e..812737429d 100644
--- a/src/test/util_tests.cpp
+++ b/src/test/util_tests.cpp
@@ -2,16 +2,16 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include <util/system.h>
-
#include <clientversion.h>
-#include <fs.h>
#include <hash.h> // For Hash()
#include <key.h> // For CKey
#include <sync.h>
#include <test/util/random.h>
#include <test/util/setup_common.h>
#include <uint256.h>
+#include <util/bitdeque.h>
+#include <util/fs.h>
+#include <util/fs_helpers.h>
#include <util/getuniquepath.h>
#include <util/message.h> // For MessageSign(), MessageVerify(), MESSAGE_MAGIC
#include <util/moneystr.h>
@@ -22,7 +22,6 @@
#include <util/string.h>
#include <util/time.h>
#include <util/vector.h>
-#include <util/bitdeque.h>
#include <array>
#include <cmath>
@@ -36,9 +35,11 @@
#include <univalue.h>
#include <utility>
#include <vector>
+
+#include <sys/types.h>
+
#ifndef WIN32
#include <signal.h>
-#include <sys/types.h>
#include <sys/wait.h>
#endif
diff --git a/src/test/util_threadnames_tests.cpp b/src/test/util_threadnames_tests.cpp
index dbb5423a77..ae913939e8 100644
--- a/src/test/util_threadnames_tests.cpp
+++ b/src/test/util_threadnames_tests.cpp
@@ -38,6 +38,7 @@ std::set<std::string> RenameEnMasse(int num_threads)
names.insert(util::ThreadGetInternalName());
};
+ threads.reserve(num_threads);
for (int i = 0; i < num_threads; ++i) {
threads.push_back(std::thread(RenameThisThread, i));
}
diff --git a/src/test/validation_block_tests.cpp b/src/test/validation_block_tests.cpp
index 4c8687ce69..e08f2c98c2 100644
--- a/src/test/validation_block_tests.cpp
+++ b/src/test/validation_block_tests.cpp
@@ -174,6 +174,7 @@ BOOST_AUTO_TEST_CASE(processnewblock_signals_ordering)
// this will create parallelism and randomness inside validation - the ValidationInterface
// will subscribe to events generated during block validation and assert on ordering invariance
std::vector<std::thread> threads;
+ threads.reserve(10);
for (int i = 0; i < 10; i++) {
threads.emplace_back([&]() {
bool ignored;
diff --git a/src/test/validation_chainstatemanager_tests.cpp b/src/test/validation_chainstatemanager_tests.cpp
index 688aafdd46..edc7e4b70a 100644
--- a/src/test/validation_chainstatemanager_tests.cpp
+++ b/src/test/validation_chainstatemanager_tests.cpp
@@ -367,10 +367,13 @@ struct SnapshotTestSetup : TestChain100Setup {
BOOST_TEST_MESSAGE("Simulating node restart");
{
- LOCK(::cs_main);
for (Chainstate* cs : chainman.GetAll()) {
+ LOCK(::cs_main);
cs->ForceFlushStateToDisk();
}
+ // Process all callbacks referring to the old manager before wiping it.
+ SyncWithValidationInterfaceQueue();
+ LOCK(::cs_main);
chainman.ResetChainstates();
BOOST_CHECK_EQUAL(chainman.GetAll().size(), 0);
const ChainstateManager::Options chainman_opts{
diff --git a/src/test/validation_flush_tests.cpp b/src/test/validation_flush_tests.cpp
index 26c48eb0e0..7398091215 100644
--- a/src/test/validation_flush_tests.cpp
+++ b/src/test/validation_flush_tests.cpp
@@ -36,12 +36,12 @@ BOOST_AUTO_TEST_CASE(getcoinscachesizestate)
BOOST_TEST_MESSAGE("CCoinsViewCache memory usage: " << view.DynamicMemoryUsage());
};
- constexpr size_t MAX_COINS_CACHE_BYTES = 1024;
+ // PoolResource defaults to 256 KiB that will be allocated, so we'll take that and make it a bit larger.
+ constexpr size_t MAX_COINS_CACHE_BYTES = 262144 + 512;
// Without any coins in the cache, we shouldn't need to flush.
- BOOST_CHECK_EQUAL(
- chainstate.GetCoinsCacheSizeState(MAX_COINS_CACHE_BYTES, /*max_mempool_size_bytes=*/0),
- CoinsCacheSizeState::OK);
+ BOOST_TEST(
+ chainstate.GetCoinsCacheSizeState(MAX_COINS_CACHE_BYTES, /*max_mempool_size_bytes=*/ 0) != CoinsCacheSizeState::CRITICAL);
// If the initial memory allocations of cacheCoins don't match these common
// cases, we can't really continue to make assertions about memory usage.
@@ -71,13 +71,21 @@ BOOST_AUTO_TEST_CASE(getcoinscachesizestate)
// cacheCoins (unordered_map) preallocates.
constexpr int COINS_UNTIL_CRITICAL{3};
+ // no coin added, so we have plenty of space left.
+ BOOST_CHECK_EQUAL(
+ chainstate.GetCoinsCacheSizeState(MAX_COINS_CACHE_BYTES, /*max_mempool_size_bytes*/ 0),
+ CoinsCacheSizeState::OK);
+
for (int i{0}; i < COINS_UNTIL_CRITICAL; ++i) {
const COutPoint res = AddTestCoin(view);
print_view_mem_usage(view);
BOOST_CHECK_EQUAL(view.AccessCoin(res).DynamicMemoryUsage(), COIN_SIZE);
+
+ // adding first coin causes the MemoryResource to allocate one 256 KiB chunk of memory,
+ // pushing us immediately over to LARGE
BOOST_CHECK_EQUAL(
- chainstate.GetCoinsCacheSizeState(MAX_COINS_CACHE_BYTES, /*max_mempool_size_bytes=*/0),
- CoinsCacheSizeState::OK);
+ chainstate.GetCoinsCacheSizeState(MAX_COINS_CACHE_BYTES, /*max_mempool_size_bytes=*/ 0),
+ CoinsCacheSizeState::LARGE);
}
// Adding some additional coins will push us over the edge to CRITICAL.
@@ -94,16 +102,16 @@ BOOST_AUTO_TEST_CASE(getcoinscachesizestate)
chainstate.GetCoinsCacheSizeState(MAX_COINS_CACHE_BYTES, /*max_mempool_size_bytes=*/0),
CoinsCacheSizeState::CRITICAL);
- // Passing non-zero max mempool usage should allow us more headroom.
+ // Passing non-zero max mempool usage (512 KiB) should allow us more headroom.
BOOST_CHECK_EQUAL(
- chainstate.GetCoinsCacheSizeState(MAX_COINS_CACHE_BYTES, /*max_mempool_size_bytes=*/1 << 10),
+ chainstate.GetCoinsCacheSizeState(MAX_COINS_CACHE_BYTES, /*max_mempool_size_bytes=*/ 1 << 19),
CoinsCacheSizeState::OK);
for (int i{0}; i < 3; ++i) {
AddTestCoin(view);
print_view_mem_usage(view);
BOOST_CHECK_EQUAL(
- chainstate.GetCoinsCacheSizeState(MAX_COINS_CACHE_BYTES, /*max_mempool_size_bytes=*/1 << 10),
+ chainstate.GetCoinsCacheSizeState(MAX_COINS_CACHE_BYTES, /*max_mempool_size_bytes=*/ 1 << 19),
CoinsCacheSizeState::OK);
}
@@ -119,7 +127,7 @@ BOOST_AUTO_TEST_CASE(getcoinscachesizestate)
BOOST_CHECK(usage_percentage >= 0.9);
BOOST_CHECK(usage_percentage < 1);
BOOST_CHECK_EQUAL(
- chainstate.GetCoinsCacheSizeState(MAX_COINS_CACHE_BYTES, 1 << 10),
+ chainstate.GetCoinsCacheSizeState(MAX_COINS_CACHE_BYTES, /*max_mempool_size_bytes*/ 1 << 10), // 1024
CoinsCacheSizeState::LARGE);
}
@@ -131,8 +139,7 @@ BOOST_AUTO_TEST_CASE(getcoinscachesizestate)
CoinsCacheSizeState::OK);
}
- // Flushing the view doesn't take us back to OK because cacheCoins has
- // preallocated memory that doesn't get reclaimed even after flush.
+ // Flushing the view does take us back to OK because ReallocateCache() is called
BOOST_CHECK_EQUAL(
chainstate.GetCoinsCacheSizeState(MAX_COINS_CACHE_BYTES, 0),
@@ -144,7 +151,7 @@ BOOST_AUTO_TEST_CASE(getcoinscachesizestate)
BOOST_CHECK_EQUAL(
chainstate.GetCoinsCacheSizeState(MAX_COINS_CACHE_BYTES, 0),
- CoinsCacheSizeState::CRITICAL);
+ CoinsCacheSizeState::OK);
}
BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/validation_tests.cpp b/src/test/validation_tests.cpp
index 6ea49cb4ee..0b4c491615 100644
--- a/src/test/validation_tests.cpp
+++ b/src/test/validation_tests.cpp
@@ -127,7 +127,7 @@ BOOST_AUTO_TEST_CASE(test_assumeutxo)
const auto params = CreateChainParams(*m_node.args, CBaseChainParams::REGTEST);
// These heights don't have assumeutxo configurations associated, per the contents
- // of chainparams.cpp.
+ // of kernel/chainparams.cpp.
std::vector<int> bad_heights{0, 100, 111, 115, 209, 211};
for (auto empty : bad_heights) {
diff --git a/src/test/validationinterface_tests.cpp b/src/test/validationinterface_tests.cpp
index ceba689e52..576768a625 100644
--- a/src/test/validationinterface_tests.cpp
+++ b/src/test/validationinterface_tests.cpp
@@ -10,6 +10,8 @@
#include <util/check.h>
#include <validationinterface.h>
+#include <atomic>
+
BOOST_FIXTURE_TEST_SUITE(validationinterface_tests, TestingSetup)
struct TestSubscriberNoop final : public CValidationInterface {
diff --git a/src/timedata.cpp b/src/timedata.cpp
index a0646b4707..15ca90ee6a 100644
--- a/src/timedata.cpp
+++ b/src/timedata.cpp
@@ -8,11 +8,12 @@
#include <timedata.h>
+#include <common/args.h>
+#include <logging.h>
#include <netaddress.h>
#include <node/interface_ui.h>
#include <sync.h>
#include <tinyformat.h>
-#include <util/system.h>
#include <util/translation.h>
#include <warnings.h>
diff --git a/src/torcontrol.cpp b/src/torcontrol.cpp
index d4daeacd3e..92b55f9fc4 100644
--- a/src/torcontrol.cpp
+++ b/src/torcontrol.cpp
@@ -7,15 +7,16 @@
#include <chainparams.h>
#include <chainparamsbase.h>
+#include <common/args.h>
#include <compat/compat.h>
#include <crypto/hmac_sha256.h>
+#include <logging.h>
#include <net.h>
#include <netaddress.h>
#include <netbase.h>
#include <util/readwritefile.h>
#include <util/strencodings.h>
#include <util/syscall_sandbox.h>
-#include <util/system.h>
#include <util/thread.h>
#include <util/time.h>
diff --git a/src/torcontrol.h b/src/torcontrol.h
index 6563a2ef42..afc5413db0 100644
--- a/src/torcontrol.h
+++ b/src/torcontrol.h
@@ -8,8 +8,8 @@
#ifndef BITCOIN_TORCONTROL_H
#define BITCOIN_TORCONTROL_H
-#include <fs.h>
#include <netaddress.h>
+#include <util/fs.h>
#include <boost/signals2/signal.hpp>
diff --git a/src/txdb.h b/src/txdb.h
index 8a876349fb..63c7152097 100644
--- a/src/txdb.h
+++ b/src/txdb.h
@@ -10,7 +10,7 @@
#include <dbwrapper.h>
#include <kernel/cs_main.h>
#include <sync.h>
-#include <fs.h>
+#include <util/fs.h>
#include <memory>
#include <optional>
diff --git a/src/txmempool.cpp b/src/txmempool.cpp
index 032dfee3ea..da875c271e 100644
--- a/src/txmempool.cpp
+++ b/src/txmempool.cpp
@@ -10,6 +10,7 @@
#include <consensus/consensus.h>
#include <consensus/tx_verify.h>
#include <consensus/validation.h>
+#include <logging.h>
#include <policy/fees.h>
#include <policy/policy.h>
#include <policy/settings.h>
diff --git a/src/util/asmap.cpp b/src/util/asmap.cpp
index 4b548c5a4d..360573cbae 100644
--- a/src/util/asmap.cpp
+++ b/src/util/asmap.cpp
@@ -6,10 +6,10 @@
#include <clientversion.h>
#include <crypto/common.h>
-#include <fs.h>
#include <logging.h>
#include <serialize.h>
#include <streams.h>
+#include <util/fs.h>
#include <algorithm>
#include <cassert>
diff --git a/src/util/asmap.h b/src/util/asmap.h
index 844037f816..08a88f1b3c 100644
--- a/src/util/asmap.h
+++ b/src/util/asmap.h
@@ -5,7 +5,7 @@
#ifndef BITCOIN_UTIL_ASMAP_H
#define BITCOIN_UTIL_ASMAP_H
-#include <fs.h>
+#include <util/fs.h>
#include <cstdint>
#include <vector>
diff --git a/src/util/bip32.cpp b/src/util/bip32.cpp
index c4b7120394..c0ad9257ce 100644
--- a/src/util/bip32.cpp
+++ b/src/util/bip32.cpp
@@ -25,7 +25,7 @@ bool ParseHDKeypath(const std::string& keypath_str, std::vector<uint32_t>& keypa
}
// Finds whether it is hardened
uint32_t path = 0;
- size_t pos = item.find("'");
+ size_t pos = item.find('\'');
if (pos != std::string::npos) {
// The hardened tick can only be in the last index of the string
if (pos != item.size() - 1) {
diff --git a/src/fs.cpp b/src/util/fs.cpp
index 64411fe41f..e8fb72670f 100644
--- a/src/fs.cpp
+++ b/src/util/fs.cpp
@@ -2,7 +2,7 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include <fs.h>
+#include <util/fs.h>
#include <util/syserror.h>
#ifndef WIN32
diff --git a/src/fs.h b/src/util/fs.h
index 0ece256acb..886a30394e 100644
--- a/src/fs.h
+++ b/src/util/fs.h
@@ -2,8 +2,8 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#ifndef BITCOIN_FS_H
-#define BITCOIN_FS_H
+#ifndef BITCOIN_UTIL_FS_H
+#define BITCOIN_UTIL_FS_H
#include <tinyformat.h>
@@ -248,4 +248,4 @@ template<> inline void formatValue(std::ostream&, const char*, const char*, int,
template<> inline void formatValue(std::ostream&, const char*, const char*, int, const fs::path&) = delete;
} // namespace tinyformat
-#endif // BITCOIN_FS_H
+#endif // BITCOIN_UTIL_FS_H
diff --git a/src/util/fs_helpers.cpp b/src/util/fs_helpers.cpp
new file mode 100644
index 0000000000..d05cb8a63d
--- /dev/null
+++ b/src/util/fs_helpers.cpp
@@ -0,0 +1,295 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2023 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 <util/fs_helpers.h>
+
+#if defined(HAVE_CONFIG_H)
+#include <config/bitcoin-config.h>
+#endif
+
+#include <logging.h>
+#include <sync.h>
+#include <tinyformat.h>
+#include <util/fs.h>
+#include <util/getuniquepath.h>
+
+#include <cerrno>
+#include <filesystem>
+#include <fstream>
+#include <map>
+#include <memory>
+#include <string>
+#include <system_error>
+#include <utility>
+
+#ifndef WIN32
+// for posix_fallocate, in configure.ac we check if it is present after this
+#ifdef __linux__
+
+#ifdef _POSIX_C_SOURCE
+#undef _POSIX_C_SOURCE
+#endif
+
+#define _POSIX_C_SOURCE 200112L
+
+#endif // __linux__
+
+#include <fcntl.h>
+#include <sys/resource.h>
+#include <unistd.h>
+#else
+#include <io.h> /* For _get_osfhandle, _chsize */
+#include <shlobj.h> /* For SHGetSpecialFolderPathW */
+#endif // WIN32
+
+/** Mutex to protect dir_locks. */
+static GlobalMutex cs_dir_locks;
+/** A map that contains all the currently held directory locks. After
+ * successful locking, these will be held here until the global destructor
+ * cleans them up and thus automatically unlocks them, or ReleaseDirectoryLocks
+ * is called.
+ */
+static std::map<std::string, std::unique_ptr<fsbridge::FileLock>> dir_locks GUARDED_BY(cs_dir_locks);
+
+bool LockDirectory(const fs::path& directory, const fs::path& lockfile_name, bool probe_only)
+{
+ LOCK(cs_dir_locks);
+ fs::path pathLockFile = directory / lockfile_name;
+
+ // If a lock for this directory already exists in the map, don't try to re-lock it
+ if (dir_locks.count(fs::PathToString(pathLockFile))) {
+ return true;
+ }
+
+ // Create empty lock file if it doesn't exist.
+ FILE* file = fsbridge::fopen(pathLockFile, "a");
+ if (file) fclose(file);
+ auto lock = std::make_unique<fsbridge::FileLock>(pathLockFile);
+ if (!lock->TryLock()) {
+ return error("Error while attempting to lock directory %s: %s", fs::PathToString(directory), lock->GetReason());
+ }
+ if (!probe_only) {
+ // Lock successful and we're not just probing, put it into the map
+ dir_locks.emplace(fs::PathToString(pathLockFile), std::move(lock));
+ }
+ return true;
+}
+
+void UnlockDirectory(const fs::path& directory, const fs::path& lockfile_name)
+{
+ LOCK(cs_dir_locks);
+ dir_locks.erase(fs::PathToString(directory / lockfile_name));
+}
+
+void ReleaseDirectoryLocks()
+{
+ LOCK(cs_dir_locks);
+ dir_locks.clear();
+}
+
+bool DirIsWritable(const fs::path& directory)
+{
+ fs::path tmpFile = GetUniquePath(directory);
+
+ FILE* file = fsbridge::fopen(tmpFile, "a");
+ if (!file) return false;
+
+ fclose(file);
+ remove(tmpFile);
+
+ return true;
+}
+
+bool CheckDiskSpace(const fs::path& dir, uint64_t additional_bytes)
+{
+ constexpr uint64_t min_disk_space = 52428800; // 50 MiB
+
+ uint64_t free_bytes_available = fs::space(dir).available;
+ return free_bytes_available >= min_disk_space + additional_bytes;
+}
+
+std::streampos GetFileSize(const char* path, std::streamsize max)
+{
+ std::ifstream file{path, std::ios::binary};
+ file.ignore(max);
+ return file.gcount();
+}
+
+bool FileCommit(FILE* file)
+{
+ if (fflush(file) != 0) { // harmless if redundantly called
+ LogPrintf("%s: fflush failed: %d\n", __func__, errno);
+ return false;
+ }
+#ifdef WIN32
+ HANDLE hFile = (HANDLE)_get_osfhandle(_fileno(file));
+ if (FlushFileBuffers(hFile) == 0) {
+ LogPrintf("%s: FlushFileBuffers failed: %d\n", __func__, GetLastError());
+ return false;
+ }
+#elif defined(MAC_OSX) && defined(F_FULLFSYNC)
+ if (fcntl(fileno(file), F_FULLFSYNC, 0) == -1) { // Manpage says "value other than -1" is returned on success
+ LogPrintf("%s: fcntl F_FULLFSYNC failed: %d\n", __func__, errno);
+ return false;
+ }
+#elif HAVE_FDATASYNC
+ if (fdatasync(fileno(file)) != 0 && errno != EINVAL) { // Ignore EINVAL for filesystems that don't support sync
+ LogPrintf("%s: fdatasync failed: %d\n", __func__, errno);
+ return false;
+ }
+#else
+ if (fsync(fileno(file)) != 0 && errno != EINVAL) {
+ LogPrintf("%s: fsync failed: %d\n", __func__, errno);
+ return false;
+ }
+#endif
+ return true;
+}
+
+void DirectoryCommit(const fs::path& dirname)
+{
+#ifndef WIN32
+ FILE* file = fsbridge::fopen(dirname, "r");
+ if (file) {
+ fsync(fileno(file));
+ fclose(file);
+ }
+#endif
+}
+
+bool TruncateFile(FILE* file, unsigned int length)
+{
+#if defined(WIN32)
+ return _chsize(_fileno(file), length) == 0;
+#else
+ return ftruncate(fileno(file), length) == 0;
+#endif
+}
+
+/**
+ * this function tries to raise the file descriptor limit to the requested number.
+ * It returns the actual file descriptor limit (which may be more or less than nMinFD)
+ */
+int RaiseFileDescriptorLimit(int nMinFD)
+{
+#if defined(WIN32)
+ return 2048;
+#else
+ struct rlimit limitFD;
+ if (getrlimit(RLIMIT_NOFILE, &limitFD) != -1) {
+ if (limitFD.rlim_cur < (rlim_t)nMinFD) {
+ limitFD.rlim_cur = nMinFD;
+ if (limitFD.rlim_cur > limitFD.rlim_max)
+ limitFD.rlim_cur = limitFD.rlim_max;
+ setrlimit(RLIMIT_NOFILE, &limitFD);
+ getrlimit(RLIMIT_NOFILE, &limitFD);
+ }
+ return limitFD.rlim_cur;
+ }
+ return nMinFD; // getrlimit failed, assume it's fine
+#endif
+}
+
+/**
+ * this function tries to make a particular range of a file allocated (corresponding to disk space)
+ * it is advisory, and the range specified in the arguments will never contain live data
+ */
+void AllocateFileRange(FILE* file, unsigned int offset, unsigned int length)
+{
+#if defined(WIN32)
+ // Windows-specific version
+ HANDLE hFile = (HANDLE)_get_osfhandle(_fileno(file));
+ LARGE_INTEGER nFileSize;
+ int64_t nEndPos = (int64_t)offset + length;
+ nFileSize.u.LowPart = nEndPos & 0xFFFFFFFF;
+ nFileSize.u.HighPart = nEndPos >> 32;
+ SetFilePointerEx(hFile, nFileSize, 0, FILE_BEGIN);
+ SetEndOfFile(hFile);
+#elif defined(MAC_OSX)
+ // OSX specific version
+ // NOTE: Contrary to other OS versions, the OSX version assumes that
+ // NOTE: offset is the size of the file.
+ fstore_t fst;
+ fst.fst_flags = F_ALLOCATECONTIG;
+ fst.fst_posmode = F_PEOFPOSMODE;
+ fst.fst_offset = 0;
+ fst.fst_length = length; // mac os fst_length takes the # of free bytes to allocate, not desired file size
+ fst.fst_bytesalloc = 0;
+ if (fcntl(fileno(file), F_PREALLOCATE, &fst) == -1) {
+ fst.fst_flags = F_ALLOCATEALL;
+ fcntl(fileno(file), F_PREALLOCATE, &fst);
+ }
+ ftruncate(fileno(file), static_cast<off_t>(offset) + length);
+#else
+#if defined(HAVE_POSIX_FALLOCATE)
+ // Version using posix_fallocate
+ off_t nEndPos = (off_t)offset + length;
+ if (0 == posix_fallocate(fileno(file), 0, nEndPos)) return;
+#endif
+ // Fallback version
+ // TODO: just write one byte per block
+ static const char buf[65536] = {};
+ if (fseek(file, offset, SEEK_SET)) {
+ return;
+ }
+ while (length > 0) {
+ unsigned int now = 65536;
+ if (length < now)
+ now = length;
+ fwrite(buf, 1, now, file); // allowed to fail; this function is advisory anyway
+ length -= now;
+ }
+#endif
+}
+
+#ifdef WIN32
+fs::path GetSpecialFolderPath(int nFolder, bool fCreate)
+{
+ WCHAR pszPath[MAX_PATH] = L"";
+
+ if (SHGetSpecialFolderPathW(nullptr, pszPath, nFolder, fCreate)) {
+ return fs::path(pszPath);
+ }
+
+ LogPrintf("SHGetSpecialFolderPathW() failed, could not obtain requested path.\n");
+ return fs::path("");
+}
+#endif
+
+bool RenameOver(fs::path src, fs::path dest)
+{
+#ifdef __MINGW64__
+ // This is a workaround for a bug in libstdc++ which
+ // implements std::filesystem::rename with _wrename function.
+ // This bug has been fixed in upstream:
+ // - GCC 10.3: 8dd1c1085587c9f8a21bb5e588dfe1e8cdbba79e
+ // - GCC 11.1: 1dfd95f0a0ca1d9e6cbc00e6cbfd1fa20a98f312
+ // For more details see the commits mentioned above.
+ return MoveFileExW(src.wstring().c_str(), dest.wstring().c_str(),
+ MOVEFILE_REPLACE_EXISTING) != 0;
+#else
+ std::error_code error;
+ fs::rename(src, dest, error);
+ return !error;
+#endif
+}
+
+/**
+ * Ignores exceptions thrown by create_directories if the requested directory exists.
+ * Specifically handles case where path p exists, but it wasn't possible for the user to
+ * write to the parent directory.
+ */
+bool TryCreateDirectories(const fs::path& p)
+{
+ try {
+ return fs::create_directories(p);
+ } catch (const fs::filesystem_error&) {
+ if (!fs::exists(p) || !fs::is_directory(p))
+ throw;
+ }
+
+ // create_directories didn't create the directory, it had to have existed already
+ return false;
+}
diff --git a/src/util/fs_helpers.h b/src/util/fs_helpers.h
new file mode 100644
index 0000000000..e7db01a89b
--- /dev/null
+++ b/src/util/fs_helpers.h
@@ -0,0 +1,63 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2023 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_UTIL_FS_HELPERS_H
+#define BITCOIN_UTIL_FS_HELPERS_H
+
+#include <util/fs.h>
+
+#include <cstdint>
+#include <cstdio>
+#include <iosfwd>
+#include <limits>
+
+/**
+ * Ensure file contents are fully committed to disk, using a platform-specific
+ * feature analogous to fsync().
+ */
+bool FileCommit(FILE* file);
+
+/**
+ * Sync directory contents. This is required on some environments to ensure that
+ * newly created files are committed to disk.
+ */
+void DirectoryCommit(const fs::path& dirname);
+
+bool TruncateFile(FILE* file, unsigned int length);
+int RaiseFileDescriptorLimit(int nMinFD);
+void AllocateFileRange(FILE* file, unsigned int offset, unsigned int length);
+
+/**
+ * Rename src to dest.
+ * @return true if the rename was successful.
+ */
+[[nodiscard]] bool RenameOver(fs::path src, fs::path dest);
+
+bool LockDirectory(const fs::path& directory, const fs::path& lockfile_name, bool probe_only = false);
+void UnlockDirectory(const fs::path& directory, const fs::path& lockfile_name);
+bool DirIsWritable(const fs::path& directory);
+bool CheckDiskSpace(const fs::path& dir, uint64_t additional_bytes = 0);
+
+/** Get the size of a file by scanning it.
+ *
+ * @param[in] path The file path
+ * @param[in] max Stop seeking beyond this limit
+ * @return The file size or max
+ */
+std::streampos GetFileSize(const char* path, std::streamsize max = std::numeric_limits<std::streamsize>::max());
+
+/** Release all directory locks. This is used for unit testing only, at runtime
+ * the global destructor will take care of the locks.
+ */
+void ReleaseDirectoryLocks();
+
+bool TryCreateDirectories(const fs::path& p);
+fs::path GetDefaultDataDir();
+
+#ifdef WIN32
+fs::path GetSpecialFolderPath(int nFolder, bool fCreate = true);
+#endif
+
+#endif // BITCOIN_UTIL_FS_HELPERS_H
diff --git a/src/util/getuniquepath.cpp b/src/util/getuniquepath.cpp
index 42c5dee0ed..105b4d52d2 100644
--- a/src/util/getuniquepath.cpp
+++ b/src/util/getuniquepath.cpp
@@ -3,7 +3,7 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <random.h>
-#include <fs.h>
+#include <util/fs.h>
#include <util/strencodings.h>
fs::path GetUniquePath(const fs::path& base)
diff --git a/src/util/getuniquepath.h b/src/util/getuniquepath.h
index e0c6147876..1563652300 100644
--- a/src/util/getuniquepath.h
+++ b/src/util/getuniquepath.h
@@ -5,7 +5,7 @@
#ifndef BITCOIN_UTIL_GETUNIQUEPATH_H
#define BITCOIN_UTIL_GETUNIQUEPATH_H
-#include <fs.h>
+#include <util/fs.h>
/**
* Helper function for getting a unique path
diff --git a/src/util/readwritefile.cpp b/src/util/readwritefile.cpp
index cc555adf45..773d7ad1cc 100644
--- a/src/util/readwritefile.cpp
+++ b/src/util/readwritefile.cpp
@@ -5,7 +5,7 @@
#include <util/readwritefile.h>
-#include <fs.h>
+#include <util/fs.h>
#include <algorithm>
#include <cstdio>
diff --git a/src/util/readwritefile.h b/src/util/readwritefile.h
index 73437baf1b..6ddfcb4f35 100644
--- a/src/util/readwritefile.h
+++ b/src/util/readwritefile.h
@@ -5,7 +5,7 @@
#ifndef BITCOIN_UTIL_READWRITEFILE_H
#define BITCOIN_UTIL_READWRITEFILE_H
-#include <fs.h>
+#include <util/fs.h>
#include <limits>
#include <string>
diff --git a/src/util/settings.cpp b/src/util/settings.cpp
index a2e30098dc..bb257c0584 100644
--- a/src/util/settings.cpp
+++ b/src/util/settings.cpp
@@ -2,7 +2,7 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include <fs.h>
+#include <util/fs.h>
#include <util/settings.h>
#include <tinyformat.h>
diff --git a/src/util/settings.h b/src/util/settings.h
index b0d8acb711..27e87a4751 100644
--- a/src/util/settings.h
+++ b/src/util/settings.h
@@ -5,7 +5,7 @@
#ifndef BITCOIN_UTIL_SETTINGS_H
#define BITCOIN_UTIL_SETTINGS_H
-#include <fs.h>
+#include <util/fs.h>
#include <map>
#include <string>
diff --git a/src/util/system.cpp b/src/util/system.cpp
index 98e89f82e7..598e6adb88 100644
--- a/src/util/system.cpp
+++ b/src/util/system.cpp
@@ -5,16 +5,10 @@
#include <util/system.h>
-#include <chainparamsbase.h>
-#include <fs.h>
-#include <sync.h>
-#include <util/check.h>
-#include <util/getuniquepath.h>
-#include <util/strencodings.h>
+#include <logging.h>
#include <util/string.h>
#include <util/syserror.h>
-#include <util/translation.h>
-
+#include <util/time.h>
#if (defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__))
#include <pthread.h>
@@ -22,1251 +16,25 @@
#endif
#ifndef WIN32
-// for posix_fallocate, in configure.ac we check if it is present after this
-#ifdef __linux__
-
-#ifdef _POSIX_C_SOURCE
-#undef _POSIX_C_SOURCE
-#endif
-
-#define _POSIX_C_SOURCE 200112L
-
-#endif // __linux__
-
-#include <algorithm>
-#include <cassert>
-#include <fcntl.h>
#include <sched.h>
-#include <sys/resource.h>
#include <sys/stat.h>
-
#else
-
#include <codecvt>
-
-#include <io.h> /* for _commit */
-#include <shellapi.h>
-#include <shlobj.h>
#endif
#ifdef HAVE_MALLOPT_ARENA_MAX
#include <malloc.h>
#endif
-#include <univalue.h>
-
-#include <fstream>
-#include <map>
-#include <memory>
-#include <optional>
+#include <cstdlib>
+#include <locale>
+#include <stdexcept>
#include <string>
-#include <system_error>
#include <thread>
-#include <typeinfo>
// Application startup time (used for uptime calculation)
const int64_t nStartupTime = GetTime();
-const char * const BITCOIN_CONF_FILENAME = "bitcoin.conf";
-const char * const BITCOIN_SETTINGS_FILENAME = "settings.json";
-
-ArgsManager gArgs;
-
-/** Mutex to protect dir_locks. */
-static GlobalMutex cs_dir_locks;
-/** A map that contains all the currently held directory locks. After
- * successful locking, these will be held here until the global destructor
- * cleans them up and thus automatically unlocks them, or ReleaseDirectoryLocks
- * is called.
- */
-static std::map<std::string, std::unique_ptr<fsbridge::FileLock>> dir_locks GUARDED_BY(cs_dir_locks);
-
-bool LockDirectory(const fs::path& directory, const fs::path& lockfile_name, bool probe_only)
-{
- LOCK(cs_dir_locks);
- fs::path pathLockFile = directory / lockfile_name;
-
- // If a lock for this directory already exists in the map, don't try to re-lock it
- if (dir_locks.count(fs::PathToString(pathLockFile))) {
- return true;
- }
-
- // Create empty lock file if it doesn't exist.
- FILE* file = fsbridge::fopen(pathLockFile, "a");
- if (file) fclose(file);
- auto lock = std::make_unique<fsbridge::FileLock>(pathLockFile);
- if (!lock->TryLock()) {
- return error("Error while attempting to lock directory %s: %s", fs::PathToString(directory), lock->GetReason());
- }
- if (!probe_only) {
- // Lock successful and we're not just probing, put it into the map
- dir_locks.emplace(fs::PathToString(pathLockFile), std::move(lock));
- }
- return true;
-}
-
-void UnlockDirectory(const fs::path& directory, const fs::path& lockfile_name)
-{
- LOCK(cs_dir_locks);
- dir_locks.erase(fs::PathToString(directory / lockfile_name));
-}
-
-void ReleaseDirectoryLocks()
-{
- LOCK(cs_dir_locks);
- dir_locks.clear();
-}
-
-bool DirIsWritable(const fs::path& directory)
-{
- fs::path tmpFile = GetUniquePath(directory);
-
- FILE* file = fsbridge::fopen(tmpFile, "a");
- if (!file) return false;
-
- fclose(file);
- remove(tmpFile);
-
- return true;
-}
-
-bool CheckDiskSpace(const fs::path& dir, uint64_t additional_bytes)
-{
- constexpr uint64_t min_disk_space = 52428800; // 50 MiB
-
- uint64_t free_bytes_available = fs::space(dir).available;
- return free_bytes_available >= min_disk_space + additional_bytes;
-}
-
-std::streampos GetFileSize(const char* path, std::streamsize max) {
- std::ifstream file{path, std::ios::binary};
- file.ignore(max);
- return file.gcount();
-}
-
-/**
- * Interpret a string argument as a boolean.
- *
- * The definition of LocaleIndependentAtoi<int>() requires that non-numeric string values
- * like "foo", return 0. This means that if a user unintentionally supplies a
- * non-integer argument here, the return value is always false. This means that
- * -foo=false does what the user probably expects, but -foo=true is well defined
- * but does not do what they probably expected.
- *
- * The return value of LocaleIndependentAtoi<int>(...) is zero when given input not
- * representable as an int.
- *
- * For a more extensive discussion of this topic (and a wide range of opinions
- * on the Right Way to change this code), see PR12713.
- */
-static bool InterpretBool(const std::string& strValue)
-{
- if (strValue.empty())
- return true;
- return (LocaleIndependentAtoi<int>(strValue) != 0);
-}
-
-static std::string SettingName(const std::string& arg)
-{
- return arg.size() > 0 && arg[0] == '-' ? arg.substr(1) : arg;
-}
-
-struct KeyInfo {
- std::string name;
- std::string section;
- bool negated{false};
-};
-
-/**
- * Parse "name", "section.name", "noname", "section.noname" settings keys.
- *
- * @note Where an option was negated can be later checked using the
- * IsArgNegated() method. One use case for this is to have a way to disable
- * options that are not normally boolean (e.g. using -nodebuglogfile to request
- * that debug log output is not sent to any file at all).
- */
-KeyInfo InterpretKey(std::string key)
-{
- KeyInfo result;
- // Split section name from key name for keys like "testnet.foo" or "regtest.bar"
- size_t option_index = key.find('.');
- if (option_index != std::string::npos) {
- result.section = key.substr(0, option_index);
- key.erase(0, option_index + 1);
- }
- if (key.substr(0, 2) == "no") {
- key.erase(0, 2);
- result.negated = true;
- }
- result.name = key;
- return result;
-}
-
-/**
- * Interpret settings value based on registered flags.
- *
- * @param[in] key key information to know if key was negated
- * @param[in] value string value of setting to be parsed
- * @param[in] flags ArgsManager registered argument flags
- * @param[out] error Error description if settings value is not valid
- *
- * @return parsed settings value if it is valid, otherwise nullopt accompanied
- * by a descriptive error string
- */
-static std::optional<util::SettingsValue> InterpretValue(const KeyInfo& key, const std::string* value,
- unsigned int flags, std::string& error)
-{
- // Return negated settings as false values.
- if (key.negated) {
- if (flags & ArgsManager::DISALLOW_NEGATION) {
- error = strprintf("Negating of -%s is meaningless and therefore forbidden", key.name);
- return std::nullopt;
- }
- // Double negatives like -nofoo=0 are supported (but discouraged)
- if (value && !InterpretBool(*value)) {
- LogPrintf("Warning: parsed potentially confusing double-negative -%s=%s\n", key.name, *value);
- return true;
- }
- return false;
- }
- if (!value && (flags & ArgsManager::DISALLOW_ELISION)) {
- error = strprintf("Can not set -%s with no value. Please specify value with -%s=value.", key.name, key.name);
- return std::nullopt;
- }
- return value ? *value : "";
-}
-
-// Define default constructor and destructor that are not inline, so code instantiating this class doesn't need to
-// #include class definitions for all members.
-// For example, m_settings has an internal dependency on univalue.
-ArgsManager::ArgsManager() = default;
-ArgsManager::~ArgsManager() = default;
-
-std::set<std::string> ArgsManager::GetUnsuitableSectionOnlyArgs() const
-{
- std::set<std::string> unsuitables;
-
- LOCK(cs_args);
-
- // if there's no section selected, don't worry
- if (m_network.empty()) return std::set<std::string> {};
-
- // if it's okay to use the default section for this network, don't worry
- if (m_network == CBaseChainParams::MAIN) return std::set<std::string> {};
-
- for (const auto& arg : m_network_only_args) {
- if (OnlyHasDefaultSectionSetting(m_settings, m_network, SettingName(arg))) {
- unsuitables.insert(arg);
- }
- }
- return unsuitables;
-}
-
-std::list<SectionInfo> ArgsManager::GetUnrecognizedSections() const
-{
- // Section names to be recognized in the config file.
- static const std::set<std::string> available_sections{
- CBaseChainParams::REGTEST,
- CBaseChainParams::SIGNET,
- CBaseChainParams::TESTNET,
- CBaseChainParams::MAIN
- };
-
- LOCK(cs_args);
- std::list<SectionInfo> unrecognized = m_config_sections;
- unrecognized.remove_if([](const SectionInfo& appeared){ return available_sections.find(appeared.m_name) != available_sections.end(); });
- return unrecognized;
-}
-
-void ArgsManager::SelectConfigNetwork(const std::string& network)
-{
- LOCK(cs_args);
- m_network = network;
-}
-
-bool ArgsManager::ParseParameters(int argc, const char* const argv[], std::string& error)
-{
- LOCK(cs_args);
- m_settings.command_line_options.clear();
-
- for (int i = 1; i < argc; i++) {
- std::string key(argv[i]);
-
-#ifdef MAC_OSX
- // At the first time when a user gets the "App downloaded from the
- // internet" warning, and clicks the Open button, macOS passes
- // a unique process serial number (PSN) as -psn_... command-line
- // argument, which we filter out.
- if (key.substr(0, 5) == "-psn_") continue;
-#endif
-
- if (key == "-") break; //bitcoin-tx using stdin
- std::optional<std::string> val;
- size_t is_index = key.find('=');
- if (is_index != std::string::npos) {
- val = key.substr(is_index + 1);
- key.erase(is_index);
- }
-#ifdef WIN32
- key = ToLower(key);
- if (key[0] == '/')
- key[0] = '-';
-#endif
-
- if (key[0] != '-') {
- if (!m_accept_any_command && m_command.empty()) {
- // The first non-dash arg is a registered command
- std::optional<unsigned int> flags = GetArgFlags(key);
- if (!flags || !(*flags & ArgsManager::COMMAND)) {
- error = strprintf("Invalid command '%s'", argv[i]);
- return false;
- }
- }
- m_command.push_back(key);
- while (++i < argc) {
- // The remaining args are command args
- m_command.push_back(argv[i]);
- }
- break;
- }
-
- // Transform --foo to -foo
- if (key.length() > 1 && key[1] == '-')
- key.erase(0, 1);
-
- // Transform -foo to foo
- key.erase(0, 1);
- KeyInfo keyinfo = InterpretKey(key);
- std::optional<unsigned int> flags = GetArgFlags('-' + keyinfo.name);
-
- // Unknown command line options and command line options with dot
- // characters (which are returned from InterpretKey with nonempty
- // section strings) are not valid.
- if (!flags || !keyinfo.section.empty()) {
- error = strprintf("Invalid parameter %s", argv[i]);
- return false;
- }
-
- std::optional<util::SettingsValue> value = InterpretValue(keyinfo, val ? &*val : nullptr, *flags, error);
- if (!value) return false;
-
- m_settings.command_line_options[keyinfo.name].push_back(*value);
- }
-
- // we do not allow -includeconf from command line, only -noincludeconf
- if (auto* includes = util::FindKey(m_settings.command_line_options, "includeconf")) {
- const util::SettingsSpan values{*includes};
- // Range may be empty if -noincludeconf was passed
- if (!values.empty()) {
- error = "-includeconf cannot be used from commandline; -includeconf=" + values.begin()->write();
- return false; // pick first value as example
- }
- }
- return true;
-}
-
-std::optional<unsigned int> ArgsManager::GetArgFlags(const std::string& name) const
-{
- LOCK(cs_args);
- for (const auto& arg_map : m_available_args) {
- const auto search = arg_map.second.find(name);
- if (search != arg_map.second.end()) {
- return search->second.m_flags;
- }
- }
- return std::nullopt;
-}
-
-fs::path ArgsManager::GetPathArg(std::string arg, const fs::path& default_value) const
-{
- if (IsArgNegated(arg)) return fs::path{};
- std::string path_str = GetArg(arg, "");
- if (path_str.empty()) return default_value;
- fs::path result = fs::PathFromString(path_str).lexically_normal();
- // Remove trailing slash, if present.
- return result.has_filename() ? result : result.parent_path();
-}
-
-const fs::path& ArgsManager::GetBlocksDirPath() const
-{
- LOCK(cs_args);
- fs::path& path = m_cached_blocks_path;
-
- // Cache the path to avoid calling fs::create_directories on every call of
- // this function
- if (!path.empty()) return path;
-
- if (IsArgSet("-blocksdir")) {
- path = fs::absolute(GetPathArg("-blocksdir"));
- if (!fs::is_directory(path)) {
- path = "";
- return path;
- }
- } else {
- path = GetDataDirBase();
- }
-
- path /= fs::PathFromString(BaseParams().DataDir());
- path /= "blocks";
- fs::create_directories(path);
- return path;
-}
-
-const fs::path& ArgsManager::GetDataDir(bool net_specific) const
-{
- LOCK(cs_args);
- fs::path& path = net_specific ? m_cached_network_datadir_path : m_cached_datadir_path;
-
- // Used cached path if available
- if (!path.empty()) return path;
-
- const fs::path datadir{GetPathArg("-datadir")};
- if (!datadir.empty()) {
- path = fs::absolute(datadir);
- if (!fs::is_directory(path)) {
- path = "";
- return path;
- }
- } else {
- path = GetDefaultDataDir();
- }
-
- if (net_specific && !BaseParams().DataDir().empty()) {
- path /= fs::PathFromString(BaseParams().DataDir());
- }
-
- return path;
-}
-
-void ArgsManager::ClearPathCache()
-{
- LOCK(cs_args);
-
- m_cached_datadir_path = fs::path();
- m_cached_network_datadir_path = fs::path();
- m_cached_blocks_path = fs::path();
-}
-
-std::optional<const ArgsManager::Command> ArgsManager::GetCommand() const
-{
- Command ret;
- LOCK(cs_args);
- auto it = m_command.begin();
- if (it == m_command.end()) {
- // No command was passed
- return std::nullopt;
- }
- if (!m_accept_any_command) {
- // The registered command
- ret.command = *(it++);
- }
- while (it != m_command.end()) {
- // The unregistered command and args (if any)
- ret.args.push_back(*(it++));
- }
- return ret;
-}
-
-std::vector<std::string> ArgsManager::GetArgs(const std::string& strArg) const
-{
- std::vector<std::string> result;
- for (const util::SettingsValue& value : GetSettingsList(strArg)) {
- result.push_back(value.isFalse() ? "0" : value.isTrue() ? "1" : value.get_str());
- }
- return result;
-}
-
-bool ArgsManager::IsArgSet(const std::string& strArg) const
-{
- return !GetSetting(strArg).isNull();
-}
-
-bool ArgsManager::GetSettingsPath(fs::path* filepath, bool temp, bool backup) const
-{
- fs::path settings = GetPathArg("-settings", BITCOIN_SETTINGS_FILENAME);
- if (settings.empty()) {
- return false;
- }
- if (backup) {
- settings += ".bak";
- }
- if (filepath) {
- *filepath = fsbridge::AbsPathJoin(GetDataDirNet(), temp ? settings + ".tmp" : settings);
- }
- return true;
-}
-
-static void SaveErrors(const std::vector<std::string> errors, std::vector<std::string>* error_out)
-{
- for (const auto& error : errors) {
- if (error_out) {
- error_out->emplace_back(error);
- } else {
- LogPrintf("%s\n", error);
- }
- }
-}
-
-bool ArgsManager::ReadSettingsFile(std::vector<std::string>* errors)
-{
- fs::path path;
- if (!GetSettingsPath(&path, /* temp= */ false)) {
- return true; // Do nothing if settings file disabled.
- }
-
- LOCK(cs_args);
- m_settings.rw_settings.clear();
- std::vector<std::string> read_errors;
- if (!util::ReadSettings(path, m_settings.rw_settings, read_errors)) {
- SaveErrors(read_errors, errors);
- return false;
- }
- for (const auto& setting : m_settings.rw_settings) {
- KeyInfo key = InterpretKey(setting.first); // Split setting key into section and argname
- if (!GetArgFlags('-' + key.name)) {
- LogPrintf("Ignoring unknown rw_settings value %s\n", setting.first);
- }
- }
- return true;
-}
-
-bool ArgsManager::WriteSettingsFile(std::vector<std::string>* errors, bool backup) const
-{
- fs::path path, path_tmp;
- if (!GetSettingsPath(&path, /*temp=*/false, backup) || !GetSettingsPath(&path_tmp, /*temp=*/true, backup)) {
- throw std::logic_error("Attempt to write settings file when dynamic settings are disabled.");
- }
-
- LOCK(cs_args);
- std::vector<std::string> write_errors;
- if (!util::WriteSettings(path_tmp, m_settings.rw_settings, write_errors)) {
- SaveErrors(write_errors, errors);
- return false;
- }
- if (!RenameOver(path_tmp, path)) {
- SaveErrors({strprintf("Failed renaming settings file %s to %s\n", fs::PathToString(path_tmp), fs::PathToString(path))}, errors);
- return false;
- }
- return true;
-}
-
-util::SettingsValue ArgsManager::GetPersistentSetting(const std::string& name) const
-{
- LOCK(cs_args);
- return util::GetSetting(m_settings, m_network, name, !UseDefaultSection("-" + name),
- /*ignore_nonpersistent=*/true, /*get_chain_name=*/false);
-}
-
-bool ArgsManager::IsArgNegated(const std::string& strArg) const
-{
- return GetSetting(strArg).isFalse();
-}
-
-std::string ArgsManager::GetArg(const std::string& strArg, const std::string& strDefault) const
-{
- return GetArg(strArg).value_or(strDefault);
-}
-
-std::optional<std::string> ArgsManager::GetArg(const std::string& strArg) const
-{
- const util::SettingsValue value = GetSetting(strArg);
- return SettingToString(value);
-}
-
-std::optional<std::string> SettingToString(const util::SettingsValue& value)
-{
- if (value.isNull()) return std::nullopt;
- if (value.isFalse()) return "0";
- if (value.isTrue()) return "1";
- if (value.isNum()) return value.getValStr();
- return value.get_str();
-}
-
-std::string SettingToString(const util::SettingsValue& value, const std::string& strDefault)
-{
- return SettingToString(value).value_or(strDefault);
-}
-
-int64_t ArgsManager::GetIntArg(const std::string& strArg, int64_t nDefault) const
-{
- return GetIntArg(strArg).value_or(nDefault);
-}
-
-std::optional<int64_t> ArgsManager::GetIntArg(const std::string& strArg) const
-{
- const util::SettingsValue value = GetSetting(strArg);
- return SettingToInt(value);
-}
-
-std::optional<int64_t> SettingToInt(const util::SettingsValue& value)
-{
- if (value.isNull()) return std::nullopt;
- if (value.isFalse()) return 0;
- if (value.isTrue()) return 1;
- if (value.isNum()) return value.getInt<int64_t>();
- return LocaleIndependentAtoi<int64_t>(value.get_str());
-}
-
-int64_t SettingToInt(const util::SettingsValue& value, int64_t nDefault)
-{
- return SettingToInt(value).value_or(nDefault);
-}
-
-bool ArgsManager::GetBoolArg(const std::string& strArg, bool fDefault) const
-{
- return GetBoolArg(strArg).value_or(fDefault);
-}
-
-std::optional<bool> ArgsManager::GetBoolArg(const std::string& strArg) const
-{
- const util::SettingsValue value = GetSetting(strArg);
- return SettingToBool(value);
-}
-
-std::optional<bool> SettingToBool(const util::SettingsValue& value)
-{
- if (value.isNull()) return std::nullopt;
- if (value.isBool()) return value.get_bool();
- return InterpretBool(value.get_str());
-}
-
-bool SettingToBool(const util::SettingsValue& value, bool fDefault)
-{
- return SettingToBool(value).value_or(fDefault);
-}
-
-bool ArgsManager::SoftSetArg(const std::string& strArg, const std::string& strValue)
-{
- LOCK(cs_args);
- if (IsArgSet(strArg)) return false;
- ForceSetArg(strArg, strValue);
- return true;
-}
-
-bool ArgsManager::SoftSetBoolArg(const std::string& strArg, bool fValue)
-{
- if (fValue)
- return SoftSetArg(strArg, std::string("1"));
- else
- return SoftSetArg(strArg, std::string("0"));
-}
-
-void ArgsManager::ForceSetArg(const std::string& strArg, const std::string& strValue)
-{
- LOCK(cs_args);
- m_settings.forced_settings[SettingName(strArg)] = strValue;
-}
-
-void ArgsManager::AddCommand(const std::string& cmd, const std::string& help)
-{
- Assert(cmd.find('=') == std::string::npos);
- Assert(cmd.at(0) != '-');
-
- LOCK(cs_args);
- m_accept_any_command = false; // latch to false
- std::map<std::string, Arg>& arg_map = m_available_args[OptionsCategory::COMMANDS];
- auto ret = arg_map.emplace(cmd, Arg{"", help, ArgsManager::COMMAND});
- Assert(ret.second); // Fail on duplicate commands
-}
-
-void ArgsManager::AddArg(const std::string& name, const std::string& help, unsigned int flags, const OptionsCategory& cat)
-{
- Assert((flags & ArgsManager::COMMAND) == 0); // use AddCommand
-
- // Split arg name from its help param
- size_t eq_index = name.find('=');
- if (eq_index == std::string::npos) {
- eq_index = name.size();
- }
- std::string arg_name = name.substr(0, eq_index);
-
- LOCK(cs_args);
- std::map<std::string, Arg>& arg_map = m_available_args[cat];
- auto ret = arg_map.emplace(arg_name, Arg{name.substr(eq_index, name.size() - eq_index), help, flags});
- assert(ret.second); // Make sure an insertion actually happened
-
- if (flags & ArgsManager::NETWORK_ONLY) {
- m_network_only_args.emplace(arg_name);
- }
-}
-
-void ArgsManager::AddHiddenArgs(const std::vector<std::string>& names)
-{
- for (const std::string& name : names) {
- AddArg(name, "", ArgsManager::ALLOW_ANY, OptionsCategory::HIDDEN);
- }
-}
-
-std::string ArgsManager::GetHelpMessage() const
-{
- const bool show_debug = GetBoolArg("-help-debug", false);
-
- std::string usage;
- LOCK(cs_args);
- for (const auto& arg_map : m_available_args) {
- switch(arg_map.first) {
- case OptionsCategory::OPTIONS:
- usage += HelpMessageGroup("Options:");
- break;
- case OptionsCategory::CONNECTION:
- usage += HelpMessageGroup("Connection options:");
- break;
- case OptionsCategory::ZMQ:
- usage += HelpMessageGroup("ZeroMQ notification options:");
- break;
- case OptionsCategory::DEBUG_TEST:
- usage += HelpMessageGroup("Debugging/Testing options:");
- break;
- case OptionsCategory::NODE_RELAY:
- usage += HelpMessageGroup("Node relay options:");
- break;
- case OptionsCategory::BLOCK_CREATION:
- usage += HelpMessageGroup("Block creation options:");
- break;
- case OptionsCategory::RPC:
- usage += HelpMessageGroup("RPC server options:");
- break;
- case OptionsCategory::WALLET:
- usage += HelpMessageGroup("Wallet options:");
- break;
- case OptionsCategory::WALLET_DEBUG_TEST:
- if (show_debug) usage += HelpMessageGroup("Wallet debugging/testing options:");
- break;
- case OptionsCategory::CHAINPARAMS:
- usage += HelpMessageGroup("Chain selection options:");
- break;
- case OptionsCategory::GUI:
- usage += HelpMessageGroup("UI Options:");
- break;
- case OptionsCategory::COMMANDS:
- usage += HelpMessageGroup("Commands:");
- break;
- case OptionsCategory::REGISTER_COMMANDS:
- usage += HelpMessageGroup("Register Commands:");
- break;
- default:
- break;
- }
-
- // When we get to the hidden options, stop
- if (arg_map.first == OptionsCategory::HIDDEN) break;
-
- for (const auto& arg : arg_map.second) {
- if (show_debug || !(arg.second.m_flags & ArgsManager::DEBUG_ONLY)) {
- std::string name;
- if (arg.second.m_help_param.empty()) {
- name = arg.first;
- } else {
- name = arg.first + arg.second.m_help_param;
- }
- usage += HelpMessageOpt(name, arg.second.m_help_text);
- }
- }
- }
- return usage;
-}
-
-bool HelpRequested(const ArgsManager& args)
-{
- return args.IsArgSet("-?") || args.IsArgSet("-h") || args.IsArgSet("-help") || args.IsArgSet("-help-debug");
-}
-
-void SetupHelpOptions(ArgsManager& args)
-{
- args.AddArg("-?", "Print this help message and exit", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
- args.AddHiddenArgs({"-h", "-help"});
-}
-
-static const int screenWidth = 79;
-static const int optIndent = 2;
-static const int msgIndent = 7;
-
-std::string HelpMessageGroup(const std::string &message) {
- return std::string(message) + std::string("\n\n");
-}
-
-std::string HelpMessageOpt(const std::string &option, const std::string &message) {
- return std::string(optIndent,' ') + std::string(option) +
- std::string("\n") + std::string(msgIndent,' ') +
- FormatParagraph(message, screenWidth - msgIndent, msgIndent) +
- std::string("\n\n");
-}
-
-fs::path GetDefaultDataDir()
-{
- // Windows: C:\Users\Username\AppData\Roaming\Bitcoin
- // macOS: ~/Library/Application Support/Bitcoin
- // Unix-like: ~/.bitcoin
-#ifdef WIN32
- // Windows
- return GetSpecialFolderPath(CSIDL_APPDATA) / "Bitcoin";
-#else
- fs::path pathRet;
- char* pszHome = getenv("HOME");
- if (pszHome == nullptr || strlen(pszHome) == 0)
- pathRet = fs::path("/");
- else
- pathRet = fs::path(pszHome);
-#ifdef MAC_OSX
- // macOS
- return pathRet / "Library/Application Support/Bitcoin";
-#else
- // Unix-like
- return pathRet / ".bitcoin";
-#endif
-#endif
-}
-
-bool CheckDataDirOption(const ArgsManager& args)
-{
- const fs::path datadir{args.GetPathArg("-datadir")};
- return datadir.empty() || fs::is_directory(fs::absolute(datadir));
-}
-
-fs::path GetConfigFile(const ArgsManager& args, const fs::path& configuration_file_path)
-{
- return AbsPathForConfigVal(args, configuration_file_path, /*net_specific=*/false);
-}
-
-static bool GetConfigOptions(std::istream& stream, const std::string& filepath, std::string& error, std::vector<std::pair<std::string, std::string>>& options, std::list<SectionInfo>& sections)
-{
- std::string str, prefix;
- std::string::size_type pos;
- int linenr = 1;
- while (std::getline(stream, str)) {
- bool used_hash = false;
- if ((pos = str.find('#')) != std::string::npos) {
- str = str.substr(0, pos);
- used_hash = true;
- }
- const static std::string pattern = " \t\r\n";
- str = TrimString(str, pattern);
- if (!str.empty()) {
- if (*str.begin() == '[' && *str.rbegin() == ']') {
- const std::string section = str.substr(1, str.size() - 2);
- sections.emplace_back(SectionInfo{section, filepath, linenr});
- prefix = section + '.';
- } else if (*str.begin() == '-') {
- error = strprintf("parse error on line %i: %s, options in configuration file must be specified without leading -", linenr, str);
- return false;
- } else if ((pos = str.find('=')) != std::string::npos) {
- std::string name = prefix + TrimString(std::string_view{str}.substr(0, pos), pattern);
- std::string_view value = TrimStringView(std::string_view{str}.substr(pos + 1), pattern);
- if (used_hash && name.find("rpcpassword") != std::string::npos) {
- error = strprintf("parse error on line %i, using # in rpcpassword can be ambiguous and should be avoided", linenr);
- return false;
- }
- options.emplace_back(name, value);
- if ((pos = name.rfind('.')) != std::string::npos && prefix.length() <= pos) {
- sections.emplace_back(SectionInfo{name.substr(0, pos), filepath, linenr});
- }
- } else {
- error = strprintf("parse error on line %i: %s", linenr, str);
- if (str.size() >= 2 && str.substr(0, 2) == "no") {
- error += strprintf(", if you intended to specify a negated option, use %s=1 instead", str);
- }
- return false;
- }
- }
- ++linenr;
- }
- return true;
-}
-
-bool IsConfSupported(KeyInfo& key, std::string& error) {
- if (key.name == "conf") {
- error = "conf cannot be set in the configuration file; use includeconf= if you want to include additional config files";
- return false;
- }
- if (key.name == "reindex") {
- // reindex can be set in a config file but it is strongly discouraged as this will cause the node to reindex on
- // every restart. Allow the config but throw a warning
- LogPrintf("Warning: reindex=1 is set in the configuration file, which will significantly slow down startup. Consider removing or commenting out this option for better performance, unless there is currently a condition which makes rebuilding the indexes necessary\n");
- return true;
- }
- return true;
-}
-
-bool ArgsManager::ReadConfigStream(std::istream& stream, const std::string& filepath, std::string& error, bool ignore_invalid_keys)
-{
- LOCK(cs_args);
- std::vector<std::pair<std::string, std::string>> options;
- if (!GetConfigOptions(stream, filepath, error, options, m_config_sections)) {
- return false;
- }
- for (const std::pair<std::string, std::string>& option : options) {
- KeyInfo key = InterpretKey(option.first);
- std::optional<unsigned int> flags = GetArgFlags('-' + key.name);
- if (!IsConfSupported(key, error)) return false;
- if (flags) {
- std::optional<util::SettingsValue> value = InterpretValue(key, &option.second, *flags, error);
- if (!value) {
- return false;
- }
- m_settings.ro_config[key.section][key.name].push_back(*value);
- } else {
- if (ignore_invalid_keys) {
- LogPrintf("Ignoring unknown configuration value %s\n", option.first);
- } else {
- error = strprintf("Invalid configuration value %s", option.first);
- return false;
- }
- }
- }
- return true;
-}
-
-fs::path ArgsManager::GetConfigFilePath() const
-{
- return GetConfigFile(*this, GetPathArg("-conf", BITCOIN_CONF_FILENAME));
-}
-
-bool ArgsManager::ReadConfigFiles(std::string& error, bool ignore_invalid_keys)
-{
- {
- LOCK(cs_args);
- m_settings.ro_config.clear();
- m_config_sections.clear();
- }
-
- const auto conf_path{GetConfigFilePath()};
- std::ifstream stream{conf_path};
-
- // not ok to have a config file specified that cannot be opened
- if (IsArgSet("-conf") && !stream.good()) {
- error = strprintf("specified config file \"%s\" could not be opened.", fs::PathToString(conf_path));
- return false;
- }
- // ok to not have a config file
- if (stream.good()) {
- if (!ReadConfigStream(stream, fs::PathToString(conf_path), error, ignore_invalid_keys)) {
- return false;
- }
- // `-includeconf` cannot be included in the command line arguments except
- // as `-noincludeconf` (which indicates that no included conf file should be used).
- bool use_conf_file{true};
- {
- LOCK(cs_args);
- if (auto* includes = util::FindKey(m_settings.command_line_options, "includeconf")) {
- // ParseParameters() fails if a non-negated -includeconf is passed on the command-line
- assert(util::SettingsSpan(*includes).last_negated());
- use_conf_file = false;
- }
- }
- if (use_conf_file) {
- std::string chain_id = GetChainName();
- std::vector<std::string> conf_file_names;
-
- auto add_includes = [&](const std::string& network, size_t skip = 0) {
- size_t num_values = 0;
- LOCK(cs_args);
- if (auto* section = util::FindKey(m_settings.ro_config, network)) {
- if (auto* values = util::FindKey(*section, "includeconf")) {
- for (size_t i = std::max(skip, util::SettingsSpan(*values).negated()); i < values->size(); ++i) {
- conf_file_names.push_back((*values)[i].get_str());
- }
- num_values = values->size();
- }
- }
- return num_values;
- };
-
- // We haven't set m_network yet (that happens in SelectParams()), so manually check
- // for network.includeconf args.
- const size_t chain_includes = add_includes(chain_id);
- const size_t default_includes = add_includes({});
-
- for (const std::string& conf_file_name : conf_file_names) {
- std::ifstream conf_file_stream{GetConfigFile(*this, fs::PathFromString(conf_file_name))};
- if (conf_file_stream.good()) {
- if (!ReadConfigStream(conf_file_stream, conf_file_name, error, ignore_invalid_keys)) {
- return false;
- }
- LogPrintf("Included configuration file %s\n", conf_file_name);
- } else {
- error = "Failed to include configuration file " + conf_file_name;
- return false;
- }
- }
-
- // Warn about recursive -includeconf
- conf_file_names.clear();
- add_includes(chain_id, /* skip= */ chain_includes);
- add_includes({}, /* skip= */ default_includes);
- std::string chain_id_final = GetChainName();
- if (chain_id_final != chain_id) {
- // Also warn about recursive includeconf for the chain that was specified in one of the includeconfs
- add_includes(chain_id_final);
- }
- for (const std::string& conf_file_name : conf_file_names) {
- tfm::format(std::cerr, "warning: -includeconf cannot be used from included files; ignoring -includeconf=%s\n", conf_file_name);
- }
- }
- }
-
- // If datadir is changed in .conf file:
- ClearPathCache();
- if (!CheckDataDirOption(*this)) {
- error = strprintf("specified data directory \"%s\" does not exist.", GetArg("-datadir", ""));
- return false;
- }
- return true;
-}
-
-std::string ArgsManager::GetChainName() const
-{
- auto get_net = [&](const std::string& arg) {
- LOCK(cs_args);
- util::SettingsValue value = util::GetSetting(m_settings, /* section= */ "", SettingName(arg),
- /* ignore_default_section_config= */ false,
- /*ignore_nonpersistent=*/false,
- /* get_chain_name= */ true);
- return value.isNull() ? false : value.isBool() ? value.get_bool() : InterpretBool(value.get_str());
- };
-
- const bool fRegTest = get_net("-regtest");
- const bool fSigNet = get_net("-signet");
- const bool fTestNet = get_net("-testnet");
- const bool is_chain_arg_set = IsArgSet("-chain");
-
- if ((int)is_chain_arg_set + (int)fRegTest + (int)fSigNet + (int)fTestNet > 1) {
- throw std::runtime_error("Invalid combination of -regtest, -signet, -testnet and -chain. Can use at most one.");
- }
- if (fRegTest)
- return CBaseChainParams::REGTEST;
- if (fSigNet) {
- return CBaseChainParams::SIGNET;
- }
- if (fTestNet)
- return CBaseChainParams::TESTNET;
-
- return GetArg("-chain", CBaseChainParams::MAIN);
-}
-
-bool ArgsManager::UseDefaultSection(const std::string& arg) const
-{
- return m_network == CBaseChainParams::MAIN || m_network_only_args.count(arg) == 0;
-}
-
-util::SettingsValue ArgsManager::GetSetting(const std::string& arg) const
-{
- LOCK(cs_args);
- return util::GetSetting(
- m_settings, m_network, SettingName(arg), !UseDefaultSection(arg),
- /*ignore_nonpersistent=*/false, /*get_chain_name=*/false);
-}
-
-std::vector<util::SettingsValue> ArgsManager::GetSettingsList(const std::string& arg) const
-{
- LOCK(cs_args);
- return util::GetSettingsList(m_settings, m_network, SettingName(arg), !UseDefaultSection(arg));
-}
-
-void ArgsManager::logArgsPrefix(
- const std::string& prefix,
- const std::string& section,
- const std::map<std::string, std::vector<util::SettingsValue>>& args) const
-{
- std::string section_str = section.empty() ? "" : "[" + section + "] ";
- for (const auto& arg : args) {
- for (const auto& value : arg.second) {
- std::optional<unsigned int> flags = GetArgFlags('-' + arg.first);
- if (flags) {
- std::string value_str = (*flags & SENSITIVE) ? "****" : value.write();
- LogPrintf("%s %s%s=%s\n", prefix, section_str, arg.first, value_str);
- }
- }
- }
-}
-
-void ArgsManager::LogArgs() const
-{
- LOCK(cs_args);
- for (const auto& section : m_settings.ro_config) {
- logArgsPrefix("Config file arg:", section.first, section.second);
- }
- for (const auto& setting : m_settings.rw_settings) {
- LogPrintf("Setting file arg: %s = %s\n", setting.first, setting.second.write());
- }
- logArgsPrefix("Command-line arg:", "", m_settings.command_line_options);
-}
-
-bool RenameOver(fs::path src, fs::path dest)
-{
-#ifdef __MINGW64__
- // This is a workaround for a bug in libstdc++ which
- // implements std::filesystem::rename with _wrename function.
- // This bug has been fixed in upstream:
- // - GCC 10.3: 8dd1c1085587c9f8a21bb5e588dfe1e8cdbba79e
- // - GCC 11.1: 1dfd95f0a0ca1d9e6cbc00e6cbfd1fa20a98f312
- // For more details see the commits mentioned above.
- return MoveFileExW(src.wstring().c_str(), dest.wstring().c_str(),
- MOVEFILE_REPLACE_EXISTING) != 0;
-#else
- std::error_code error;
- fs::rename(src, dest, error);
- return !error;
-#endif
-}
-
-/**
- * Ignores exceptions thrown by create_directories if the requested directory exists.
- * Specifically handles case where path p exists, but it wasn't possible for the user to
- * write to the parent directory.
- */
-bool TryCreateDirectories(const fs::path& p)
-{
- try
- {
- return fs::create_directories(p);
- } catch (const fs::filesystem_error&) {
- if (!fs::exists(p) || !fs::is_directory(p))
- throw;
- }
-
- // create_directories didn't create the directory, it had to have existed already
- return false;
-}
-
-bool FileCommit(FILE *file)
-{
- if (fflush(file) != 0) { // harmless if redundantly called
- LogPrintf("%s: fflush failed: %d\n", __func__, errno);
- return false;
- }
-#ifdef WIN32
- HANDLE hFile = (HANDLE)_get_osfhandle(_fileno(file));
- if (FlushFileBuffers(hFile) == 0) {
- LogPrintf("%s: FlushFileBuffers failed: %d\n", __func__, GetLastError());
- return false;
- }
-#elif defined(MAC_OSX) && defined(F_FULLFSYNC)
- if (fcntl(fileno(file), F_FULLFSYNC, 0) == -1) { // Manpage says "value other than -1" is returned on success
- LogPrintf("%s: fcntl F_FULLFSYNC failed: %d\n", __func__, errno);
- return false;
- }
-#elif HAVE_FDATASYNC
- if (fdatasync(fileno(file)) != 0 && errno != EINVAL) { // Ignore EINVAL for filesystems that don't support sync
- LogPrintf("%s: fdatasync failed: %d\n", __func__, errno);
- return false;
- }
-#else
- if (fsync(fileno(file)) != 0 && errno != EINVAL) {
- LogPrintf("%s: fsync failed: %d\n", __func__, errno);
- return false;
- }
-#endif
- return true;
-}
-
-void DirectoryCommit(const fs::path &dirname)
-{
-#ifndef WIN32
- FILE* file = fsbridge::fopen(dirname, "r");
- if (file) {
- fsync(fileno(file));
- fclose(file);
- }
-#endif
-}
-
-bool TruncateFile(FILE *file, unsigned int length) {
-#if defined(WIN32)
- return _chsize(_fileno(file), length) == 0;
-#else
- return ftruncate(fileno(file), length) == 0;
-#endif
-}
-
-/**
- * this function tries to raise the file descriptor limit to the requested number.
- * It returns the actual file descriptor limit (which may be more or less than nMinFD)
- */
-int RaiseFileDescriptorLimit(int nMinFD) {
-#if defined(WIN32)
- return 2048;
-#else
- struct rlimit limitFD;
- if (getrlimit(RLIMIT_NOFILE, &limitFD) != -1) {
- if (limitFD.rlim_cur < (rlim_t)nMinFD) {
- limitFD.rlim_cur = nMinFD;
- if (limitFD.rlim_cur > limitFD.rlim_max)
- limitFD.rlim_cur = limitFD.rlim_max;
- setrlimit(RLIMIT_NOFILE, &limitFD);
- getrlimit(RLIMIT_NOFILE, &limitFD);
- }
- return limitFD.rlim_cur;
- }
- return nMinFD; // getrlimit failed, assume it's fine
-#endif
-}
-
-/**
- * this function tries to make a particular range of a file allocated (corresponding to disk space)
- * it is advisory, and the range specified in the arguments will never contain live data
- */
-void AllocateFileRange(FILE *file, unsigned int offset, unsigned int length) {
-#if defined(WIN32)
- // Windows-specific version
- HANDLE hFile = (HANDLE)_get_osfhandle(_fileno(file));
- LARGE_INTEGER nFileSize;
- int64_t nEndPos = (int64_t)offset + length;
- nFileSize.u.LowPart = nEndPos & 0xFFFFFFFF;
- nFileSize.u.HighPart = nEndPos >> 32;
- SetFilePointerEx(hFile, nFileSize, 0, FILE_BEGIN);
- SetEndOfFile(hFile);
-#elif defined(MAC_OSX)
- // OSX specific version
- // NOTE: Contrary to other OS versions, the OSX version assumes that
- // NOTE: offset is the size of the file.
- fstore_t fst;
- fst.fst_flags = F_ALLOCATECONTIG;
- fst.fst_posmode = F_PEOFPOSMODE;
- fst.fst_offset = 0;
- fst.fst_length = length; // mac os fst_length takes the # of free bytes to allocate, not desired file size
- fst.fst_bytesalloc = 0;
- if (fcntl(fileno(file), F_PREALLOCATE, &fst) == -1) {
- fst.fst_flags = F_ALLOCATEALL;
- fcntl(fileno(file), F_PREALLOCATE, &fst);
- }
- ftruncate(fileno(file), static_cast<off_t>(offset) + length);
-#else
- #if defined(HAVE_POSIX_FALLOCATE)
- // Version using posix_fallocate
- off_t nEndPos = (off_t)offset + length;
- if (0 == posix_fallocate(fileno(file), 0, nEndPos)) return;
- #endif
- // Fallback version
- // TODO: just write one byte per block
- static const char buf[65536] = {};
- if (fseek(file, offset, SEEK_SET)) {
- return;
- }
- while (length > 0) {
- unsigned int now = 65536;
- if (length < now)
- now = length;
- fwrite(buf, 1, now, file); // allowed to fail; this function is advisory anyway
- length -= now;
- }
-#endif
-}
-
-#ifdef WIN32
-fs::path GetSpecialFolderPath(int nFolder, bool fCreate)
-{
- WCHAR pszPath[MAX_PATH] = L"";
-
- if(SHGetSpecialFolderPathW(nullptr, pszPath, nFolder, fCreate))
- {
- return fs::path(pszPath);
- }
-
- LogPrintf("SHGetSpecialFolderPathW() failed, could not obtain requested path.\n");
- return fs::path("");
-}
-#endif
-
#ifndef WIN32
std::string ShellEscape(const std::string& arg)
{
@@ -1290,7 +58,6 @@ void runCommand(const std::string& strCommand)
}
#endif
-
void SetupEnvironment()
{
#ifdef HAVE_MALLOPT_ARENA_MAX
@@ -1346,14 +113,6 @@ int64_t GetStartupTime()
return nStartupTime;
}
-fs::path AbsPathForConfigVal(const ArgsManager& args, const fs::path& path, bool net_specific)
-{
- if (path.is_absolute()) {
- return path;
- }
- return fsbridge::AbsPathJoin(net_specific ? args.GetDataDirNet() : args.GetDataDirBase(), path);
-}
-
void ScheduleBatchPriority()
{
#ifdef SCHED_BATCH
@@ -1364,30 +123,3 @@ void ScheduleBatchPriority()
}
#endif
}
-
-namespace util {
-#ifdef WIN32
-WinCmdLineArgs::WinCmdLineArgs()
-{
- wchar_t** wargv = CommandLineToArgvW(GetCommandLineW(), &argc);
- std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t> utf8_cvt;
- argv = new char*[argc];
- args.resize(argc);
- for (int i = 0; i < argc; i++) {
- args[i] = utf8_cvt.to_bytes(wargv[i]);
- argv[i] = &*args[i].begin();
- }
- LocalFree(wargv);
-}
-
-WinCmdLineArgs::~WinCmdLineArgs()
-{
- delete[] argv;
-}
-
-std::pair<int, char**> WinCmdLineArgs::get()
-{
- return std::make_pair(argc, argv);
-}
-#endif
-} // namespace util
diff --git a/src/util/system.h b/src/util/system.h
index 7292262bea..e2fc3450f6 100644
--- a/src/util/system.h
+++ b/src/util/system.h
@@ -3,10 +3,6 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-/**
- * Server/client environment: argument handling, config file parsing,
- * thread wrappers, startup time
- */
#ifndef BITCOIN_UTIL_SYSTEM_H
#define BITCOIN_UTIL_SYSTEM_H
@@ -14,83 +10,19 @@
#include <config/bitcoin-config.h>
#endif
-#include <compat/compat.h>
#include <compat/assumptions.h>
-#include <fs.h>
-#include <logging.h>
-#include <sync.h>
-#include <util/settings.h>
-#include <util/time.h>
+#include <compat/compat.h>
#include <any>
-#include <map>
-#include <optional>
#include <set>
#include <stdint.h>
#include <string>
-#include <utility>
-#include <vector>
-
-class ArgsManager;
-class UniValue;
// Application startup time (used for uptime calculation)
int64_t GetStartupTime();
-extern const char * const BITCOIN_CONF_FILENAME;
-extern const char * const BITCOIN_SETTINGS_FILENAME;
-
void SetupEnvironment();
bool SetupNetworking();
-
-/**
- * Ensure file contents are fully committed to disk, using a platform-specific
- * feature analogous to fsync().
- */
-bool FileCommit(FILE *file);
-
-/**
- * Sync directory contents. This is required on some environments to ensure that
- * newly created files are committed to disk.
- */
-void DirectoryCommit(const fs::path &dirname);
-
-bool TruncateFile(FILE *file, unsigned int length);
-int RaiseFileDescriptorLimit(int nMinFD);
-void AllocateFileRange(FILE *file, unsigned int offset, unsigned int length);
-
-/**
- * Rename src to dest.
- * @return true if the rename was successful.
- */
-[[nodiscard]] bool RenameOver(fs::path src, fs::path dest);
-
-bool LockDirectory(const fs::path& directory, const fs::path& lockfile_name, bool probe_only=false);
-void UnlockDirectory(const fs::path& directory, const fs::path& lockfile_name);
-bool DirIsWritable(const fs::path& directory);
-bool CheckDiskSpace(const fs::path& dir, uint64_t additional_bytes = 0);
-
-/** Get the size of a file by scanning it.
- *
- * @param[in] path The file path
- * @param[in] max Stop seeking beyond this limit
- * @return The file size or max
- */
-std::streampos GetFileSize(const char* path, std::streamsize max = std::numeric_limits<std::streamsize>::max());
-
-/** Release all directory locks. This is used for unit testing only, at runtime
- * the global destructor will take care of the locks.
- */
-void ReleaseDirectoryLocks();
-
-bool TryCreateDirectories(const fs::path& p);
-fs::path GetDefaultDataDir();
-// Return true if -datadir option points to a valid directory or is not specified.
-bool CheckDataDirOption(const ArgsManager& args);
-fs::path GetConfigFile(const ArgsManager& args, const fs::path& configuration_file_path);
-#ifdef WIN32
-fs::path GetSpecialFolderPath(int nFolder, bool fCreate = true);
-#endif
#ifndef WIN32
std::string ShellEscape(const std::string& arg);
#endif
@@ -99,413 +31,6 @@ void runCommand(const std::string& strCommand);
#endif
/**
- * Most paths passed as configuration arguments are treated as relative to
- * the datadir if they are not absolute.
- *
- * @param args Parsed arguments and settings.
- * @param path The path to be conditionally prefixed with datadir.
- * @param net_specific Use network specific datadir variant
- * @return The normalized path.
- */
-fs::path AbsPathForConfigVal(const ArgsManager& args, const fs::path& path, bool net_specific = true);
-
-inline bool IsSwitchChar(char c)
-{
-#ifdef WIN32
- return c == '-' || c == '/';
-#else
- return c == '-';
-#endif
-}
-
-enum class OptionsCategory {
- OPTIONS,
- CONNECTION,
- WALLET,
- WALLET_DEBUG_TEST,
- ZMQ,
- DEBUG_TEST,
- CHAINPARAMS,
- NODE_RELAY,
- BLOCK_CREATION,
- RPC,
- GUI,
- COMMANDS,
- REGISTER_COMMANDS,
-
- HIDDEN // Always the last option to avoid printing these in the help
-};
-
-struct SectionInfo
-{
- std::string m_name;
- std::string m_file;
- int m_line;
-};
-
-std::string SettingToString(const util::SettingsValue&, const std::string&);
-std::optional<std::string> SettingToString(const util::SettingsValue&);
-
-int64_t SettingToInt(const util::SettingsValue&, int64_t);
-std::optional<int64_t> SettingToInt(const util::SettingsValue&);
-
-bool SettingToBool(const util::SettingsValue&, bool);
-std::optional<bool> SettingToBool(const util::SettingsValue&);
-
-class ArgsManager
-{
-public:
- /**
- * Flags controlling how config and command line arguments are validated and
- * interpreted.
- */
- enum Flags : uint32_t {
- ALLOW_ANY = 0x01, //!< disable validation
- // ALLOW_BOOL = 0x02, //!< unimplemented, draft implementation in #16545
- // ALLOW_INT = 0x04, //!< unimplemented, draft implementation in #16545
- // ALLOW_STRING = 0x08, //!< unimplemented, draft implementation in #16545
- // ALLOW_LIST = 0x10, //!< unimplemented, draft implementation in #16545
- DISALLOW_NEGATION = 0x20, //!< disallow -nofoo syntax
- DISALLOW_ELISION = 0x40, //!< disallow -foo syntax that doesn't assign any value
-
- DEBUG_ONLY = 0x100,
- /* Some options would cause cross-contamination if values for
- * mainnet were used while running on regtest/testnet (or vice-versa).
- * Setting them as NETWORK_ONLY ensures that sharing a config file
- * between mainnet and regtest/testnet won't cause problems due to these
- * parameters by accident. */
- NETWORK_ONLY = 0x200,
- // This argument's value is sensitive (such as a password).
- SENSITIVE = 0x400,
- COMMAND = 0x800,
- };
-
-protected:
- struct Arg
- {
- std::string m_help_param;
- std::string m_help_text;
- unsigned int m_flags;
- };
-
- mutable RecursiveMutex cs_args;
- util::Settings m_settings GUARDED_BY(cs_args);
- std::vector<std::string> m_command GUARDED_BY(cs_args);
- std::string m_network GUARDED_BY(cs_args);
- std::set<std::string> m_network_only_args GUARDED_BY(cs_args);
- std::map<OptionsCategory, std::map<std::string, Arg>> m_available_args GUARDED_BY(cs_args);
- bool m_accept_any_command GUARDED_BY(cs_args){true};
- std::list<SectionInfo> m_config_sections GUARDED_BY(cs_args);
- mutable fs::path m_cached_blocks_path GUARDED_BY(cs_args);
- mutable fs::path m_cached_datadir_path GUARDED_BY(cs_args);
- mutable fs::path m_cached_network_datadir_path GUARDED_BY(cs_args);
-
- [[nodiscard]] bool ReadConfigStream(std::istream& stream, const std::string& filepath, std::string& error, bool ignore_invalid_keys = false);
-
- /**
- * Returns true if settings values from the default section should be used,
- * depending on the current network and whether the setting is
- * network-specific.
- */
- bool UseDefaultSection(const std::string& arg) const EXCLUSIVE_LOCKS_REQUIRED(cs_args);
-
- public:
- /**
- * Get setting value.
- *
- * Result will be null if setting was unset, true if "-setting" argument was passed
- * false if "-nosetting" argument was passed, and a string if a "-setting=value"
- * argument was passed.
- */
- util::SettingsValue GetSetting(const std::string& arg) const;
-
- /**
- * Get list of setting values.
- */
- std::vector<util::SettingsValue> GetSettingsList(const std::string& arg) const;
-
- ArgsManager();
- ~ArgsManager();
-
- /**
- * Select the network in use
- */
- void SelectConfigNetwork(const std::string& network);
-
- [[nodiscard]] bool ParseParameters(int argc, const char* const argv[], std::string& error);
-
- /**
- * Return config file path (read-only)
- */
- fs::path GetConfigFilePath() const;
- [[nodiscard]] bool ReadConfigFiles(std::string& error, bool ignore_invalid_keys = false);
-
- /**
- * Log warnings for options in m_section_only_args when
- * they are specified in the default section but not overridden
- * on the command line or in a network-specific section in the
- * config file.
- */
- std::set<std::string> GetUnsuitableSectionOnlyArgs() const;
-
- /**
- * Log warnings for unrecognized section names in the config file.
- */
- std::list<SectionInfo> GetUnrecognizedSections() const;
-
- struct Command {
- /** The command (if one has been registered with AddCommand), or empty */
- std::string command;
- /**
- * If command is non-empty: Any args that followed it
- * If command is empty: The unregistered command and any args that followed it
- */
- std::vector<std::string> args;
- };
- /**
- * Get the command and command args (returns std::nullopt if no command provided)
- */
- std::optional<const Command> GetCommand() const;
-
- /**
- * Get blocks directory path
- *
- * @return Blocks path which is network specific
- */
- const fs::path& GetBlocksDirPath() const;
-
- /**
- * Get data directory path
- *
- * @return Absolute path on success, otherwise an empty path when a non-directory path would be returned
- */
- const fs::path& GetDataDirBase() const { return GetDataDir(false); }
-
- /**
- * Get data directory path with appended network identifier
- *
- * @return Absolute path on success, otherwise an empty path when a non-directory path would be returned
- */
- const fs::path& GetDataDirNet() const { return GetDataDir(true); }
-
- /**
- * Clear cached directory paths
- */
- void ClearPathCache();
-
- /**
- * Return a vector of strings of the given argument
- *
- * @param strArg Argument to get (e.g. "-foo")
- * @return command-line arguments
- */
- std::vector<std::string> GetArgs(const std::string& strArg) const;
-
- /**
- * Return true if the given argument has been manually set
- *
- * @param strArg Argument to get (e.g. "-foo")
- * @return true if the argument has been set
- */
- bool IsArgSet(const std::string& strArg) const;
-
- /**
- * Return true if the argument was originally passed as a negated option,
- * i.e. -nofoo.
- *
- * @param strArg Argument to get (e.g. "-foo")
- * @return true if the argument was passed negated
- */
- bool IsArgNegated(const std::string& strArg) const;
-
- /**
- * Return string argument or default value
- *
- * @param strArg Argument to get (e.g. "-foo")
- * @param strDefault (e.g. "1")
- * @return command-line argument or default value
- */
- std::string GetArg(const std::string& strArg, const std::string& strDefault) const;
- std::optional<std::string> GetArg(const std::string& strArg) const;
-
- /**
- * Return path argument or default value
- *
- * @param arg Argument to get a path from (e.g., "-datadir", "-blocksdir" or "-walletdir")
- * @param default_value Optional default value to return instead of the empty path.
- * @return normalized path if argument is set, with redundant "." and ".."
- * path components and trailing separators removed (see patharg unit test
- * for examples or implementation for details). If argument is empty or not
- * set, default_value is returned unchanged.
- */
- fs::path GetPathArg(std::string arg, const fs::path& default_value = {}) const;
-
- /**
- * Return integer argument or default value
- *
- * @param strArg Argument to get (e.g. "-foo")
- * @param nDefault (e.g. 1)
- * @return command-line argument (0 if invalid number) or default value
- */
- int64_t GetIntArg(const std::string& strArg, int64_t nDefault) const;
- std::optional<int64_t> GetIntArg(const std::string& strArg) const;
-
- /**
- * Return boolean argument or default value
- *
- * @param strArg Argument to get (e.g. "-foo")
- * @param fDefault (true or false)
- * @return command-line argument or default value
- */
- bool GetBoolArg(const std::string& strArg, bool fDefault) const;
- std::optional<bool> GetBoolArg(const std::string& strArg) const;
-
- /**
- * Set an argument if it doesn't already have a value
- *
- * @param strArg Argument to set (e.g. "-foo")
- * @param strValue Value (e.g. "1")
- * @return true if argument gets set, false if it already had a value
- */
- bool SoftSetArg(const std::string& strArg, const std::string& strValue);
-
- /**
- * Set a boolean argument if it doesn't already have a value
- *
- * @param strArg Argument to set (e.g. "-foo")
- * @param fValue Value (e.g. false)
- * @return true if argument gets set, false if it already had a value
- */
- bool SoftSetBoolArg(const std::string& strArg, bool fValue);
-
- // Forces an arg setting. Called by SoftSetArg() if the arg hasn't already
- // been set. Also called directly in testing.
- void ForceSetArg(const std::string& strArg, const std::string& strValue);
-
- /**
- * Returns the appropriate chain name from the program arguments.
- * @return CBaseChainParams::MAIN by default; raises runtime error if an invalid combination is given.
- */
- std::string GetChainName() const;
-
- /**
- * Add argument
- */
- void AddArg(const std::string& name, const std::string& help, unsigned int flags, const OptionsCategory& cat);
-
- /**
- * Add subcommand
- */
- void AddCommand(const std::string& cmd, const std::string& help);
-
- /**
- * Add many hidden arguments
- */
- void AddHiddenArgs(const std::vector<std::string>& args);
-
- /**
- * Clear available arguments
- */
- void ClearArgs() {
- LOCK(cs_args);
- m_available_args.clear();
- m_network_only_args.clear();
- }
-
- /**
- * Get the help string
- */
- std::string GetHelpMessage() const;
-
- /**
- * Return Flags for known arg.
- * Return nullopt for unknown arg.
- */
- std::optional<unsigned int> GetArgFlags(const std::string& name) const;
-
- /**
- * Get settings file path, or return false if read-write settings were
- * disabled with -nosettings.
- */
- bool GetSettingsPath(fs::path* filepath = nullptr, bool temp = false, bool backup = false) const;
-
- /**
- * Read settings file. Push errors to vector, or log them if null.
- */
- bool ReadSettingsFile(std::vector<std::string>* errors = nullptr);
-
- /**
- * Write settings file or backup settings file. Push errors to vector, or
- * log them if null.
- */
- bool WriteSettingsFile(std::vector<std::string>* errors = nullptr, bool backup = false) const;
-
- /**
- * Get current setting from config file or read/write settings file,
- * ignoring nonpersistent command line or forced settings values.
- */
- util::SettingsValue GetPersistentSetting(const std::string& name) const;
-
- /**
- * Access settings with lock held.
- */
- template <typename Fn>
- void LockSettings(Fn&& fn)
- {
- LOCK(cs_args);
- fn(m_settings);
- }
-
- /**
- * Log the config file options and the command line arguments,
- * useful for troubleshooting.
- */
- void LogArgs() const;
-
-private:
- /**
- * Get data directory path
- *
- * @param net_specific Append network identifier to the returned path
- * @return Absolute path on success, otherwise an empty path when a non-directory path would be returned
- */
- const fs::path& GetDataDir(bool net_specific) const;
-
- // Helper function for LogArgs().
- void logArgsPrefix(
- const std::string& prefix,
- const std::string& section,
- const std::map<std::string, std::vector<util::SettingsValue>>& args) const;
-};
-
-extern ArgsManager gArgs;
-
-/**
- * @return true if help has been requested via a command-line arg
- */
-bool HelpRequested(const ArgsManager& args);
-
-/** Add help options to the args manager */
-void SetupHelpOptions(ArgsManager& args);
-
-/**
- * Format a string to be used as group of options in help messages
- *
- * @param message Group name (e.g. "RPC server options:")
- * @return the formatted string
- */
-std::string HelpMessageGroup(const std::string& message);
-
-/**
- * Format a string to be used as option description in help messages
- *
- * @param option Option message (e.g. "-rpcuser=<user>")
- * @param message Option description (e.g. "Username for JSON-RPC connections")
- * @return the formatted string
- */
-std::string HelpMessageOpt(const std::string& option, const std::string& message);
-
-/**
* Return the number of cores available on the current system.
* @note This does count virtual cores, such as those provided by HyperThreading.
*/
@@ -542,21 +67,6 @@ T* AnyPtr(const std::any& any) noexcept
return ptr ? *ptr : nullptr;
}
-#ifdef WIN32
-class WinCmdLineArgs
-{
-public:
- WinCmdLineArgs();
- ~WinCmdLineArgs();
- std::pair<int, char**> get();
-
-private:
- int argc;
- char** argv;
- std::vector<std::string> args;
-};
-#endif
-
} // namespace util
#endif // BITCOIN_UTIL_SYSTEM_H
diff --git a/src/validation.cpp b/src/validation.cpp
index e82fead89e..0b46854902 100644
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -11,6 +11,7 @@
#include <arith_uint256.h>
#include <chain.h>
#include <checkqueue.h>
+#include <common/args.h>
#include <consensus/amount.h>
#include <consensus/consensus.h>
#include <consensus/merkle.h>
@@ -19,7 +20,6 @@
#include <consensus/validation.h>
#include <cuckoocache.h>
#include <flatfile.h>
-#include <fs.h>
#include <hash.h>
#include <kernel/chainparams.h>
#include <kernel/mempool_entry.h>
@@ -46,6 +46,8 @@
#include <uint256.h>
#include <undo.h>
#include <util/check.h> // For NDEBUG compile time check
+#include <util/fs.h>
+#include <util/fs_helpers.h>
#include <util/hasher.h>
#include <util/moneystr.h>
#include <util/rbf.h>
@@ -844,9 +846,18 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
return state.Invalid(TxValidationResult::TX_NOT_STANDARD, "bad-txns-too-many-sigops",
strprintf("%d", nSigOpsCost));
- // No individual transactions are allowed below the min relay feerate and mempool min feerate except from
- // disconnected blocks and transactions in a package. Package transactions will be checked using
- // package feerate later.
+ // No individual transactions are allowed below the min relay feerate except from disconnected blocks.
+ // This requirement, unlike CheckFeeRate, cannot be bypassed using m_package_feerates because,
+ // while a tx could be package CPFP'd when entering the mempool, we do not have a DoS-resistant
+ // method of ensuring the tx remains bumped. For example, the fee-bumping child could disappear
+ // due to a replacement.
+ if (!bypass_limits && ws.m_modified_fees < m_pool.m_min_relay_feerate.GetFee(ws.m_vsize)) {
+ return state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, "min relay fee not met",
+ strprintf("%d < %d", ws.m_modified_fees, m_pool.m_min_relay_feerate.GetFee(ws.m_vsize)));
+ }
+ // No individual transactions are allowed below the mempool min feerate except from disconnected
+ // blocks and transactions in a package. Package transactions will be checked using package
+ // feerate later.
if (!bypass_limits && !args.m_package_feerates && !CheckFeeRate(ws.m_vsize, ws.m_modified_fees, state)) return false;
ws.m_iters_conflicting = m_pool.GetIterSet(ws.m_conflicts);
@@ -1190,6 +1201,7 @@ bool MemPoolAccept::SubmitPackage(const ATMPArgs& args, std::vector<Workspace>&
} else {
all_submitted = false;
ws.m_state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, "mempool full");
+ package_state.Invalid(PackageValidationResult::PCKG_TX, "transaction failed");
results.emplace(ws.m_ptx->GetWitnessHash(), MempoolAcceptResult::Failure(ws.m_state));
}
}
@@ -4581,6 +4593,9 @@ void Chainstate::LoadExternalBlockFile(
// next block, but it's still possible to rewind to the start of the current block (without a disk read).
nRewind = nBlockPos + nSize;
blkdat.SkipTo(nRewind);
+
+ std::shared_ptr<CBlock> pblock{}; // needs to remain available after the cs_main lock is released to avoid duplicate reads from disk
+
{
LOCK(cs_main);
// detect out of order blocks, and store them for later
@@ -4598,7 +4613,7 @@ void Chainstate::LoadExternalBlockFile(
if (!pindex || (pindex->nStatus & BLOCK_HAVE_DATA) == 0) {
// This block can be processed immediately; rewind to its start, read and deserialize it.
blkdat.SetPos(nBlockPos);
- std::shared_ptr<CBlock> pblock{std::make_shared<CBlock>()};
+ pblock = std::make_shared<CBlock>();
blkdat >> *pblock;
nRewind = blkdat.GetPos();
@@ -4622,6 +4637,21 @@ void Chainstate::LoadExternalBlockFile(
}
}
+ if (m_blockman.IsPruneMode() && !fReindex && pblock) {
+ // must update the tip for pruning to work while importing with -loadblock.
+ // this is a tradeoff to conserve disk space at the expense of time
+ // spent updating the tip to be able to prune.
+ // otherwise, ActivateBestChain won't be called by the import process
+ // until after all of the block files are loaded. ActivateBestChain can be
+ // called by concurrent network message processing. but, that is not
+ // reliable for the purpose of pruning while importing.
+ BlockValidationState state;
+ if (!ActivateBestChain(state, pblock)) {
+ LogPrint(BCLog::REINDEX, "failed to activate chain (%s)\n", state.ToString());
+ break;
+ }
+ }
+
NotifyHeaderTip(*this);
if (!blocks_with_unknown_parent) continue;
@@ -4930,7 +4960,6 @@ bool Chainstate::ResizeCoinsCaches(size_t coinstip_size, size_t coinsdb_size)
} else {
// Otherwise, flush state to disk and deallocate the in-memory coins map.
ret = FlushStateToDisk(state, FlushStateMode::ALWAYS);
- CoinsTip().ReallocateCache();
}
return ret;
}
diff --git a/src/validation.h b/src/validation.h
index aba863db09..fd0e2115f7 100644
--- a/src/validation.h
+++ b/src/validation.h
@@ -15,7 +15,6 @@
#include <chain.h>
#include <consensus/amount.h>
#include <deploymentstatus.h>
-#include <fs.h>
#include <kernel/chainparams.h>
#include <kernel/chainstatemanager_opts.h>
#include <kernel/cs_main.h> // IWYU pragma: export
@@ -30,6 +29,7 @@
#include <txmempool.h> // For CTxMemPool::cs
#include <uint256.h>
#include <util/check.h>
+#include <util/fs.h>
#include <util/hasher.h>
#include <util/translation.h>
#include <versionbits.h>
@@ -997,7 +997,7 @@ public:
std::set<CBlockIndex*> m_failed_blocks;
/** Best header we've seen so far (used for getheaders queries' starting points). */
- CBlockIndex* m_best_header = nullptr;
+ CBlockIndex* m_best_header GUARDED_BY(::cs_main){nullptr};
//! The total number of bytes available for us to use across all in-memory
//! coins caches. This will be split somehow across chainstates.
diff --git a/src/wallet/bdb.cpp b/src/wallet/bdb.cpp
index 653115aa81..fa6e56c6e4 100644
--- a/src/wallet/bdb.cpp
+++ b/src/wallet/bdb.cpp
@@ -4,18 +4,29 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <compat/compat.h>
-#include <fs.h>
+#include <logging.h>
+#include <util/fs.h>
+#include <util/time.h>
#include <wallet/bdb.h>
#include <wallet/db.h>
+#include <sync.h>
#include <util/check.h>
+#include <util/fs_helpers.h>
#include <util/strencodings.h>
#include <util/translation.h>
#include <stdint.h>
-#ifndef WIN32
#include <sys/stat.h>
+
+// Windows may not define S_IRUSR or S_IWUSR. We define both
+// here, with the same values as glibc (see stat.h).
+#ifdef WIN32
+#ifndef S_IRUSR
+#define S_IRUSR 0400
+#define S_IWUSR 0200
+#endif
#endif
namespace wallet {
@@ -432,6 +443,7 @@ void BerkeleyEnvironment::ReloadDbEnv()
});
std::vector<fs::path> filenames;
+ filenames.reserve(m_databases.size());
for (const auto& it : m_databases) {
filenames.push_back(it.first);
}
@@ -656,12 +668,14 @@ void BerkeleyDatabase::ReloadDbEnv()
env->ReloadDbEnv();
}
-BerkeleyCursor::BerkeleyCursor(BerkeleyDatabase& database)
+BerkeleyCursor::BerkeleyCursor(BerkeleyDatabase& database, BerkeleyBatch* batch)
{
if (!database.m_db.get()) {
throw std::runtime_error(STR_INTERNAL_BUG("BerkeleyDatabase does not exist"));
}
- int ret = database.m_db->cursor(nullptr, &m_cursor, 0);
+ // Transaction argument to cursor is only needed when using the cursor to
+ // write to the database. Read-only cursors do not need a txn pointer.
+ int ret = database.m_db->cursor(batch ? batch->txn() : nullptr, &m_cursor, 0);
if (ret != 0) {
throw std::runtime_error(STR_INTERNAL_BUG(strprintf("BDB Cursor could not be created. Returned %d", ret)));
}
@@ -808,6 +822,25 @@ bool BerkeleyBatch::HasKey(DataStream&& key)
return ret == 0;
}
+bool BerkeleyBatch::ErasePrefix(Span<const std::byte> prefix)
+{
+ if (!TxnBegin()) return false;
+ auto cursor{std::make_unique<BerkeleyCursor>(m_database, this)};
+ // const_cast is safe below even though prefix_key is an in/out parameter,
+ // because we are not using the DB_DBT_USERMEM flag, so BDB will allocate
+ // and return a different output data pointer
+ Dbt prefix_key{const_cast<std::byte*>(prefix.data()), static_cast<uint32_t>(prefix.size())}, prefix_value{};
+ int ret{cursor->dbc()->get(&prefix_key, &prefix_value, DB_SET_RANGE)};
+ for (int flag{DB_CURRENT}; ret == 0; flag = DB_NEXT) {
+ SafeDbt key, value;
+ ret = cursor->dbc()->get(key, value, flag);
+ if (ret != 0 || key.get_size() < prefix.size() || memcmp(key.get_data(), prefix.data(), prefix.size()) != 0) break;
+ ret = cursor->dbc()->del(0);
+ }
+ cursor.reset();
+ return TxnCommit() && (ret == 0 || ret == DB_NOTFOUND);
+}
+
void BerkeleyDatabase::AddRef()
{
LOCK(cs_db);
diff --git a/src/wallet/bdb.h b/src/wallet/bdb.h
index 06c98972b0..4fac128bf1 100644
--- a/src/wallet/bdb.h
+++ b/src/wallet/bdb.h
@@ -7,13 +7,14 @@
#define BITCOIN_WALLET_BDB_H
#include <clientversion.h>
-#include <fs.h>
#include <serialize.h>
#include <streams.h>
+#include <util/fs.h>
#include <util/system.h>
#include <wallet/db.h>
#include <atomic>
+#include <condition_variable>
#include <map>
#include <memory>
#include <string>
@@ -191,10 +192,11 @@ private:
Dbc* m_cursor;
public:
- explicit BerkeleyCursor(BerkeleyDatabase& database);
+ explicit BerkeleyCursor(BerkeleyDatabase& database, BerkeleyBatch* batch=nullptr);
~BerkeleyCursor() override;
Status Next(DataStream& key, DataStream& value) override;
+ Dbc* dbc() const { return m_cursor; }
};
/** RAII class that provides access to a Berkeley database */
@@ -205,6 +207,7 @@ private:
bool WriteKey(DataStream&& key, DataStream&& value, bool overwrite = true) override;
bool EraseKey(DataStream&& key) override;
bool HasKey(DataStream&& key) override;
+ bool ErasePrefix(Span<const std::byte> prefix) override;
protected:
Db* pdb{nullptr};
@@ -229,6 +232,7 @@ public:
bool TxnBegin() override;
bool TxnCommit() override;
bool TxnAbort() override;
+ DbTxn* txn() const { return activeTxn; }
};
std::string BerkeleyDatabaseVersion();
diff --git a/src/wallet/coincontrol.cpp b/src/wallet/coincontrol.cpp
index 3b3c1f8da4..2087119db9 100644
--- a/src/wallet/coincontrol.cpp
+++ b/src/wallet/coincontrol.cpp
@@ -4,11 +4,79 @@
#include <wallet/coincontrol.h>
-#include <util/system.h>
+#include <common/args.h>
namespace wallet {
CCoinControl::CCoinControl()
{
m_avoid_partial_spends = gArgs.GetBoolArg("-avoidpartialspends", DEFAULT_AVOIDPARTIALSPENDS);
}
+
+bool CCoinControl::HasSelected() const
+{
+ return !m_selected_inputs.empty();
+}
+
+bool CCoinControl::IsSelected(const COutPoint& output) const
+{
+ return m_selected_inputs.count(output) > 0;
+}
+
+bool CCoinControl::IsExternalSelected(const COutPoint& output) const
+{
+ return m_external_txouts.count(output) > 0;
+}
+
+std::optional<CTxOut> CCoinControl::GetExternalOutput(const COutPoint& outpoint) const
+{
+ const auto ext_it = m_external_txouts.find(outpoint);
+ if (ext_it == m_external_txouts.end()) {
+ return std::nullopt;
+ }
+
+ return std::make_optional(ext_it->second);
+}
+
+void CCoinControl::Select(const COutPoint& output)
+{
+ m_selected_inputs.insert(output);
+}
+
+void CCoinControl::SelectExternal(const COutPoint& outpoint, const CTxOut& txout)
+{
+ m_selected_inputs.insert(outpoint);
+ m_external_txouts.emplace(outpoint, txout);
+}
+
+void CCoinControl::UnSelect(const COutPoint& output)
+{
+ m_selected_inputs.erase(output);
+}
+
+void CCoinControl::UnSelectAll()
+{
+ m_selected_inputs.clear();
+}
+
+std::vector<COutPoint> CCoinControl::ListSelected() const
+{
+ return {m_selected_inputs.begin(), m_selected_inputs.end()};
+}
+
+void CCoinControl::SetInputWeight(const COutPoint& outpoint, int64_t weight)
+{
+ m_input_weights[outpoint] = weight;
+}
+
+bool CCoinControl::HasInputWeight(const COutPoint& outpoint) const
+{
+ return m_input_weights.count(outpoint) > 0;
+}
+
+int64_t CCoinControl::GetInputWeight(const COutPoint& outpoint) const
+{
+ auto it = m_input_weights.find(outpoint);
+ assert(it != m_input_weights.end());
+ return it->second;
+}
} // namespace wallet
diff --git a/src/wallet/coincontrol.h b/src/wallet/coincontrol.h
index cb6f0a1635..7ff8fee5bc 100644
--- a/src/wallet/coincontrol.h
+++ b/src/wallet/coincontrol.h
@@ -13,9 +13,9 @@
#include <script/signingprovider.h>
#include <script/standard.h>
-#include <optional>
#include <algorithm>
#include <map>
+#include <optional>
#include <set>
namespace wallet {
@@ -63,76 +63,62 @@ public:
CCoinControl();
- bool HasSelected() const
- {
- return (setSelected.size() > 0);
- }
-
- bool IsSelected(const COutPoint& output) const
- {
- return (setSelected.count(output) > 0);
- }
-
- bool IsExternalSelected(const COutPoint& output) const
- {
- return (m_external_txouts.count(output) > 0);
- }
-
- bool GetExternalOutput(const COutPoint& outpoint, CTxOut& txout) const
- {
- const auto ext_it = m_external_txouts.find(outpoint);
- if (ext_it == m_external_txouts.end()) {
- return false;
- }
- txout = ext_it->second;
- return true;
- }
-
- void Select(const COutPoint& output)
- {
- setSelected.insert(output);
- }
-
- void SelectExternal(const COutPoint& outpoint, const CTxOut& txout)
- {
- setSelected.insert(outpoint);
- m_external_txouts.emplace(outpoint, txout);
- }
-
- void UnSelect(const COutPoint& output)
- {
- setSelected.erase(output);
- }
-
- void UnSelectAll()
- {
- setSelected.clear();
- }
-
- void ListSelected(std::vector<COutPoint>& vOutpoints) const
- {
- vOutpoints.assign(setSelected.begin(), setSelected.end());
- }
-
- void SetInputWeight(const COutPoint& outpoint, int64_t weight)
- {
- m_input_weights[outpoint] = weight;
- }
-
- bool HasInputWeight(const COutPoint& outpoint) const
- {
- return m_input_weights.count(outpoint) > 0;
- }
-
- int64_t GetInputWeight(const COutPoint& outpoint) const
- {
- auto it = m_input_weights.find(outpoint);
- assert(it != m_input_weights.end());
- return it->second;
- }
+ /**
+ * Returns true if there are pre-selected inputs.
+ */
+ bool HasSelected() const;
+ /**
+ * Returns true if the given output is pre-selected.
+ */
+ bool IsSelected(const COutPoint& output) const;
+ /**
+ * Returns true if the given output is selected as an external input.
+ */
+ bool IsExternalSelected(const COutPoint& output) const;
+ /**
+ * Returns the external output for the given outpoint if it exists.
+ */
+ std::optional<CTxOut> GetExternalOutput(const COutPoint& outpoint) const;
+ /**
+ * Lock-in the given output for spending.
+ * The output will be included in the transaction even if it's not the most optimal choice.
+ */
+ void Select(const COutPoint& output);
+ /**
+ * Lock-in the given output as an external input for spending because it is not in the wallet.
+ * The output will be included in the transaction even if it's not the most optimal choice.
+ */
+ void SelectExternal(const COutPoint& outpoint, const CTxOut& txout);
+ /**
+ * Unselects the given output.
+ */
+ void UnSelect(const COutPoint& output);
+ /**
+ * Unselects all outputs.
+ */
+ void UnSelectAll();
+ /**
+ * List the selected inputs.
+ */
+ std::vector<COutPoint> ListSelected() const;
+ /**
+ * Set an input's weight.
+ */
+ void SetInputWeight(const COutPoint& outpoint, int64_t weight);
+ /**
+ * Returns true if the input weight is set.
+ */
+ bool HasInputWeight(const COutPoint& outpoint) const;
+ /**
+ * Returns the input weight.
+ */
+ int64_t GetInputWeight(const COutPoint& outpoint) const;
private:
- std::set<COutPoint> setSelected;
+ //! Selected inputs (inputs that will be used, regardless of whether they're optimal or not)
+ std::set<COutPoint> m_selected_inputs;
+ //! Map of external inputs to include in the transaction
+ //! These are not in the wallet, so we need to track them separately
std::map<COutPoint, CTxOut> m_external_txouts;
//! Map of COutPoints to the maximum weight for that input
std::map<COutPoint, int64_t> m_input_weights;
diff --git a/src/wallet/coinselection.cpp b/src/wallet/coinselection.cpp
index 9cf61dbe51..832d24746f 100644
--- a/src/wallet/coinselection.cpp
+++ b/src/wallet/coinselection.cpp
@@ -6,15 +6,24 @@
#include <consensus/amount.h>
#include <consensus/consensus.h>
+#include <logging.h>
#include <policy/feerate.h>
#include <util/check.h>
-#include <util/system.h>
#include <util/moneystr.h>
+#include <util/system.h>
#include <numeric>
#include <optional>
+#include <queue>
namespace wallet {
+// Common selection error across the algorithms
+static util::Result<SelectionResult> ErrorMaxWeightExceeded()
+{
+ return util::Error{_("The inputs size exceeds the maximum weight. "
+ "Please try sending a smaller amount or manually consolidating your wallet's UTXOs")};
+}
+
// Descending order comparator
struct {
bool operator()(const OutputGroup& a, const OutputGroup& b) const
@@ -63,11 +72,13 @@ struct {
static const size_t TOTAL_TRIES = 100000;
-std::optional<SelectionResult> SelectCoinsBnB(std::vector<OutputGroup>& utxo_pool, const CAmount& selection_target, const CAmount& cost_of_change)
+util::Result<SelectionResult> SelectCoinsBnB(std::vector<OutputGroup>& utxo_pool, const CAmount& selection_target, const CAmount& cost_of_change,
+ int max_weight)
{
SelectionResult result(selection_target, SelectionAlgorithm::BNB);
CAmount curr_value = 0;
std::vector<size_t> curr_selection; // selected utxo indexes
+ int curr_selection_weight = 0; // sum of selected utxo weight
// Calculate curr_available_value
CAmount curr_available_value = 0;
@@ -78,7 +89,7 @@ std::optional<SelectionResult> SelectCoinsBnB(std::vector<OutputGroup>& utxo_poo
curr_available_value += utxo.GetSelectionAmount();
}
if (curr_available_value < selection_target) {
- return std::nullopt;
+ return util::Error();
}
// Sort the utxo_pool
@@ -89,6 +100,7 @@ std::optional<SelectionResult> SelectCoinsBnB(std::vector<OutputGroup>& utxo_poo
CAmount best_waste = MAX_MONEY;
bool is_feerate_high = utxo_pool.at(0).fee > utxo_pool.at(0).long_term_fee;
+ bool max_tx_weight_exceeded = false;
// Depth First search loop for choosing the UTXOs
for (size_t curr_try = 0, utxo_pool_index = 0; curr_try < TOTAL_TRIES; ++curr_try, ++utxo_pool_index) {
@@ -98,6 +110,9 @@ std::optional<SelectionResult> SelectCoinsBnB(std::vector<OutputGroup>& utxo_poo
curr_value > selection_target + cost_of_change || // Selected value is out of range, go back and try other branch
(curr_waste > best_waste && is_feerate_high)) { // Don't select things which we know will be more wasteful if the waste is increasing
backtrack = true;
+ } else if (curr_selection_weight > max_weight) { // Exceeding weight for standard tx, cannot find more solutions by adding more inputs
+ max_tx_weight_exceeded = true; // at least one selection attempt exceeded the max weight
+ backtrack = true;
} else if (curr_value >= selection_target) { // Selected value is within range
curr_waste += (curr_value - selection_target); // This is the excess value which is added to the waste for the below comparison
// Adding another UTXO after this check could bring the waste down if the long term fee is higher than the current fee.
@@ -127,6 +142,7 @@ std::optional<SelectionResult> SelectCoinsBnB(std::vector<OutputGroup>& utxo_poo
OutputGroup& utxo = utxo_pool.at(utxo_pool_index);
curr_value -= utxo.GetSelectionAmount();
curr_waste -= utxo.fee - utxo.long_term_fee;
+ curr_selection_weight -= utxo.m_weight;
curr_selection.pop_back();
} else { // Moving forwards, continuing down this branch
OutputGroup& utxo = utxo_pool.at(utxo_pool_index);
@@ -146,13 +162,14 @@ std::optional<SelectionResult> SelectCoinsBnB(std::vector<OutputGroup>& utxo_poo
curr_selection.push_back(utxo_pool_index);
curr_value += utxo.GetSelectionAmount();
curr_waste += utxo.fee - utxo.long_term_fee;
+ curr_selection_weight += utxo.m_weight;
}
}
}
// Check for solution
if (best_selection.empty()) {
- return std::nullopt;
+ return max_tx_weight_exceeded ? ErrorMaxWeightExceeded() : util::Error();
}
// Set output set
@@ -165,9 +182,20 @@ std::optional<SelectionResult> SelectCoinsBnB(std::vector<OutputGroup>& utxo_poo
return result;
}
-std::optional<SelectionResult> SelectCoinsSRD(const std::vector<OutputGroup>& utxo_pool, CAmount target_value, FastRandomContext& rng)
+class MinOutputGroupComparator
+{
+public:
+ int operator() (const OutputGroup& group1, const OutputGroup& group2) const
+ {
+ return group1.GetSelectionAmount() > group2.GetSelectionAmount();
+ }
+};
+
+util::Result<SelectionResult> SelectCoinsSRD(const std::vector<OutputGroup>& utxo_pool, CAmount target_value, FastRandomContext& rng,
+ int max_weight)
{
SelectionResult result(target_value, SelectionAlgorithm::SRD);
+ std::priority_queue<OutputGroup, std::vector<OutputGroup>, MinOutputGroupComparator> heap;
// Include change for SRD as we want to avoid making really small change if the selection just
// barely meets the target. Just use the lower bound change target instead of the randomly
@@ -181,16 +209,40 @@ std::optional<SelectionResult> SelectCoinsSRD(const std::vector<OutputGroup>& ut
Shuffle(indexes.begin(), indexes.end(), rng);
CAmount selected_eff_value = 0;
+ int weight = 0;
+ bool max_tx_weight_exceeded = false;
for (const size_t i : indexes) {
const OutputGroup& group = utxo_pool.at(i);
Assume(group.GetSelectionAmount() > 0);
+
+ // Add group to selection
+ heap.push(group);
selected_eff_value += group.GetSelectionAmount();
- result.AddInput(group);
+ weight += group.m_weight;
+
+ // If the selection weight exceeds the maximum allowed size, remove the least valuable inputs until we
+ // are below max weight.
+ if (weight > max_weight) {
+ max_tx_weight_exceeded = true; // mark it in case we don't find any useful result.
+ do {
+ const OutputGroup& to_remove_group = heap.top();
+ selected_eff_value -= to_remove_group.GetSelectionAmount();
+ weight -= to_remove_group.m_weight;
+ heap.pop();
+ } while (!heap.empty() && weight > max_weight);
+ }
+
+ // Now check if we are above the target
if (selected_eff_value >= target_value) {
+ // Result found, add it.
+ while (!heap.empty()) {
+ result.AddInput(heap.top());
+ heap.pop();
+ }
return result;
}
}
- return std::nullopt;
+ return max_tx_weight_exceeded ? ErrorMaxWeightExceeded() : util::Error();
}
/** Find a subset of the OutputGroups that is at least as large as, but as close as possible to, the
@@ -252,8 +304,8 @@ static void ApproximateBestSubset(FastRandomContext& insecure_rand, const std::v
}
}
-std::optional<SelectionResult> KnapsackSolver(std::vector<OutputGroup>& groups, const CAmount& nTargetValue,
- CAmount change_target, FastRandomContext& rng)
+util::Result<SelectionResult> KnapsackSolver(std::vector<OutputGroup>& groups, const CAmount& nTargetValue,
+ CAmount change_target, FastRandomContext& rng, int max_weight)
{
SelectionResult result(nTargetValue, SelectionAlgorithm::KNAPSACK);
@@ -286,7 +338,7 @@ std::optional<SelectionResult> KnapsackSolver(std::vector<OutputGroup>& groups,
}
if (nTotalLower < nTargetValue) {
- if (!lowest_larger) return std::nullopt;
+ if (!lowest_larger) return util::Error();
result.AddInput(*lowest_larger);
return result;
}
@@ -313,6 +365,16 @@ std::optional<SelectionResult> KnapsackSolver(std::vector<OutputGroup>& groups,
}
}
+ // If the result exceeds the maximum allowed size, return closest UTXO above the target
+ if (result.GetWeight() > max_weight) {
+ // No coin above target, nothing to do.
+ if (!lowest_larger) return ErrorMaxWeightExceeded();
+
+ // Return closest UTXO above target
+ result.Clear();
+ result.AddInput(*lowest_larger);
+ }
+
if (LogAcceptCategory(BCLog::SELECTCOINS, BCLog::Level::Debug)) {
std::string log_message{"Coin selection best subset: "};
for (unsigned int i = 0; i < applicable_groups.size(); i++) {
diff --git a/src/wallet/coinselection.h b/src/wallet/coinselection.h
index 5a7b748be1..723f5bbfb3 100644
--- a/src/wallet/coinselection.h
+++ b/src/wallet/coinselection.h
@@ -13,6 +13,7 @@
#include <random.h>
#include <util/system.h>
#include <util/check.h>
+#include <util/result.h>
#include <optional>
@@ -408,20 +409,24 @@ public:
int GetWeight() const { return m_weight; }
};
-std::optional<SelectionResult> SelectCoinsBnB(std::vector<OutputGroup>& utxo_pool, const CAmount& selection_target, const CAmount& cost_of_change);
+util::Result<SelectionResult> SelectCoinsBnB(std::vector<OutputGroup>& utxo_pool, const CAmount& selection_target, const CAmount& cost_of_change,
+ int max_weight);
/** Select coins by Single Random Draw. OutputGroups are selected randomly from the eligible
* outputs until the target is satisfied
*
* @param[in] utxo_pool The positive effective value OutputGroups eligible for selection
* @param[in] target_value The target value to select for
- * @returns If successful, a SelectionResult, otherwise, std::nullopt
+ * @param[in] rng The randomness source to shuffle coins
+ * @param[in] max_weight The maximum allowed weight for a selection result to be valid
+ * @returns If successful, a valid SelectionResult, otherwise, util::Error
*/
-std::optional<SelectionResult> SelectCoinsSRD(const std::vector<OutputGroup>& utxo_pool, CAmount target_value, FastRandomContext& rng);
+util::Result<SelectionResult> SelectCoinsSRD(const std::vector<OutputGroup>& utxo_pool, CAmount target_value, FastRandomContext& rng,
+ int max_weight);
// Original coin selection algorithm as a fallback
-std::optional<SelectionResult> KnapsackSolver(std::vector<OutputGroup>& groups, const CAmount& nTargetValue,
- CAmount change_target, FastRandomContext& rng);
+util::Result<SelectionResult> KnapsackSolver(std::vector<OutputGroup>& groups, const CAmount& nTargetValue,
+ CAmount change_target, FastRandomContext& rng, int max_weight);
} // namespace wallet
#endif // BITCOIN_WALLET_COINSELECTION_H
diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp
index 8e79ee678e..0c24920516 100644
--- a/src/wallet/db.cpp
+++ b/src/wallet/db.cpp
@@ -4,9 +4,9 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <chainparams.h>
-#include <fs.h>
+#include <common/args.h>
#include <logging.h>
-#include <util/system.h>
+#include <util/fs.h>
#include <wallet/db.h>
#include <exception>
diff --git a/src/wallet/db.h b/src/wallet/db.h
index d4c590fac7..6834ba6963 100644
--- a/src/wallet/db.h
+++ b/src/wallet/db.h
@@ -7,9 +7,9 @@
#define BITCOIN_WALLET_DB_H
#include <clientversion.h>
-#include <fs.h>
#include <streams.h>
#include <support/allocators/secure.h>
+#include <util/fs.h>
#include <atomic>
#include <memory>
@@ -110,6 +110,7 @@ public:
return HasKey(std::move(ssKey));
}
+ virtual bool ErasePrefix(Span<const std::byte> prefix) = 0;
virtual std::unique_ptr<DatabaseCursor> GetNewCursor() = 0;
virtual bool TxnBegin() = 0;
@@ -186,6 +187,7 @@ private:
bool WriteKey(DataStream&& key, DataStream&& value, bool overwrite = true) override { return true; }
bool EraseKey(DataStream&& key) override { return true; }
bool HasKey(DataStream&& key) override { return true; }
+ bool ErasePrefix(Span<const std::byte> prefix) override { return true; }
public:
void Flush() override {}
diff --git a/src/wallet/dump.cpp b/src/wallet/dump.cpp
index 69208c19dc..865af0bb23 100644
--- a/src/wallet/dump.cpp
+++ b/src/wallet/dump.cpp
@@ -4,8 +4,8 @@
#include <wallet/dump.h>
-#include <fs.h>
-#include <util/system.h>
+#include <common/args.h>
+#include <util/fs.h>
#include <util/translation.h>
#include <wallet/wallet.h>
diff --git a/src/wallet/dump.h b/src/wallet/dump.h
index ff0d94e4b2..5034f95479 100644
--- a/src/wallet/dump.h
+++ b/src/wallet/dump.h
@@ -5,7 +5,7 @@
#ifndef BITCOIN_WALLET_DUMP_H
#define BITCOIN_WALLET_DUMP_H
-#include <fs.h>
+#include <util/fs.h>
#include <string>
#include <vector>
diff --git a/src/wallet/external_signer_scriptpubkeyman.cpp b/src/wallet/external_signer_scriptpubkeyman.cpp
index cb861d835e..079e3baa4e 100644
--- a/src/wallet/external_signer_scriptpubkeyman.cpp
+++ b/src/wallet/external_signer_scriptpubkeyman.cpp
@@ -3,7 +3,9 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <chainparams.h>
+#include <common/args.h>
#include <external_signer.h>
+#include <util/system.h>
#include <wallet/external_signer_scriptpubkeyman.h>
#include <iostream>
diff --git a/src/wallet/feebumper.cpp b/src/wallet/feebumper.cpp
index 37a704bfa4..b6b1fa1d3e 100644
--- a/src/wallet/feebumper.cpp
+++ b/src/wallet/feebumper.cpp
@@ -63,7 +63,7 @@ static feebumper::Result PreconditionChecks(const CWallet& wallet, const CWallet
}
//! Check if the user provided a valid feeRate
-static feebumper::Result CheckFeeRate(const CWallet& wallet, const CWalletTx& wtx, const CFeeRate& newFeerate, const int64_t maxTxSize, CAmount old_fee, std::vector<bilingual_str>& errors)
+static feebumper::Result CheckFeeRate(const CWallet& wallet, const CFeeRate& newFeerate, const int64_t maxTxSize, CAmount old_fee, std::vector<bilingual_str>& errors)
{
// check that fee rate is higher than mempool's minimum fee
// (no point in bumping fee if we know that the new tx won't be accepted to the mempool)
@@ -84,15 +84,12 @@ static feebumper::Result CheckFeeRate(const CWallet& wallet, const CWalletTx& wt
CFeeRate incrementalRelayFee = std::max(wallet.chain().relayIncrementalFee(), CFeeRate(WALLET_INCREMENTAL_RELAY_FEE));
- // Given old total fee and transaction size, calculate the old feeRate
- const int64_t txSize = GetVirtualTransactionSize(*(wtx.tx));
- CFeeRate nOldFeeRate(old_fee, txSize);
// Min total fee is old fee + relay fee
- CAmount minTotalFee = nOldFeeRate.GetFee(maxTxSize) + incrementalRelayFee.GetFee(maxTxSize);
+ CAmount minTotalFee = old_fee + incrementalRelayFee.GetFee(maxTxSize);
if (new_total_fee < minTotalFee) {
errors.push_back(strprintf(Untranslated("Insufficient total fee %s, must be at least %s (oldFee %s + incrementalFee %s)"),
- FormatMoney(new_total_fee), FormatMoney(minTotalFee), FormatMoney(nOldFeeRate.GetFee(maxTxSize)), FormatMoney(incrementalRelayFee.GetFee(maxTxSize))));
+ FormatMoney(new_total_fee), FormatMoney(minTotalFee), FormatMoney(old_fee), FormatMoney(incrementalRelayFee.GetFee(maxTxSize))));
return feebumper::Result::INVALID_PARAMETER;
}
@@ -234,7 +231,9 @@ Result CreateRateBumpTransaction(CWallet& wallet, const uint256& txid, const CCo
// is one). If outputs vector is non-empty, replace original
// outputs with its contents, otherwise use original outputs.
std::vector<CRecipient> recipients;
- for (const auto& output : outputs.empty() ? wtx.tx->vout : outputs) {
+ CAmount new_outputs_value = 0;
+ const auto& txouts = outputs.empty() ? wtx.tx->vout : outputs;
+ for (const auto& output : txouts) {
if (!OutputIsChange(wallet, output)) {
CRecipient recipient = {output.scriptPubKey, output.nValue, false};
recipients.push_back(recipient);
@@ -243,19 +242,35 @@ Result CreateRateBumpTransaction(CWallet& wallet, const uint256& txid, const CCo
ExtractDestination(output.scriptPubKey, change_dest);
new_coin_control.destChange = change_dest;
}
+ new_outputs_value += output.nValue;
+ }
+
+ // If no recipients, means that we are sending coins to a change address
+ if (recipients.empty()) {
+ // Just as a sanity check, ensure that the change address exist
+ if (std::get_if<CNoDestination>(&new_coin_control.destChange)) {
+ errors.emplace_back(Untranslated("Unable to create transaction. Transaction must have at least one recipient"));
+ return Result::INVALID_PARAMETER;
+ }
+
+ // Add change as recipient with SFFO flag enabled, so fees are deduced from it.
+ // If the output differs from the original tx output (because the user customized it) a new change output will be created.
+ recipients.emplace_back(CRecipient{GetScriptForDestination(new_coin_control.destChange), new_outputs_value, /*fSubtractFeeFromAmount=*/true});
+ new_coin_control.destChange = CNoDestination();
}
if (coin_control.m_feerate) {
// The user provided a feeRate argument.
// We calculate this here to avoid compiler warning on the cs_wallet lock
// We need to make a temporary transaction with no input witnesses as the dummy signer expects them to be empty for external inputs
- CMutableTransaction mtx{*wtx.tx};
- for (auto& txin : mtx.vin) {
+ CMutableTransaction temp_mtx{*wtx.tx};
+ for (auto& txin : temp_mtx.vin) {
txin.scriptSig.clear();
txin.scriptWitness.SetNull();
}
- const int64_t maxTxSize{CalculateMaximumSignedTxSize(CTransaction(mtx), &wallet, &new_coin_control).vsize};
- Result res = CheckFeeRate(wallet, wtx, *new_coin_control.m_feerate, maxTxSize, old_fee, errors);
+ temp_mtx.vout = txouts;
+ const int64_t maxTxSize{CalculateMaximumSignedTxSize(CTransaction(temp_mtx), &wallet, &new_coin_control).vsize};
+ Result res = CheckFeeRate(wallet, *new_coin_control.m_feerate, maxTxSize, old_fee, errors);
if (res != Result::OK) {
return res;
}
diff --git a/src/wallet/init.cpp b/src/wallet/init.cpp
index 5403e38950..0d0a8650ac 100644
--- a/src/wallet/init.cpp
+++ b/src/wallet/init.cpp
@@ -3,6 +3,7 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#include <common/args.h>
#include <init.h>
#include <interfaces/chain.h>
#include <interfaces/init.h>
@@ -14,7 +15,6 @@
#include <univalue.h>
#include <util/check.h>
#include <util/moneystr.h>
-#include <util/system.h>
#include <util/translation.h>
#ifdef USE_BDB
#include <wallet/bdb.h>
diff --git a/src/wallet/interfaces.cpp b/src/wallet/interfaces.cpp
index 1a76e46c54..cd438cfe2f 100644
--- a/src/wallet/interfaces.cpp
+++ b/src/wallet/interfaces.cpp
@@ -4,6 +4,7 @@
#include <interfaces/wallet.h>
+#include <common/args.h>
#include <consensus/amount.h>
#include <interfaces/chain.h>
#include <interfaces/handler.h>
@@ -15,13 +16,13 @@
#include <sync.h>
#include <uint256.h>
#include <util/check.h>
-#include <util/system.h>
#include <util/translation.h>
#include <util/ui_change_type.h>
+#include <wallet/coincontrol.h>
#include <wallet/context.h>
#include <wallet/feebumper.h>
#include <wallet/fees.h>
-#include <wallet/ismine.h>
+#include <wallet/types.h>
#include <wallet/load.h>
#include <wallet/receive.h>
#include <wallet/rpc/wallet.h>
@@ -178,7 +179,7 @@ public:
}
return false;
};
- bool setAddressBook(const CTxDestination& dest, const std::string& name, const std::string& purpose) override
+ bool setAddressBook(const CTxDestination& dest, const std::string& name, const std::optional<AddressPurpose>& purpose) override
{
return m_wallet->SetAddressBook(dest, name, purpose);
}
@@ -189,7 +190,7 @@ public:
bool getAddress(const CTxDestination& dest,
std::string* name,
isminetype* is_mine,
- std::string* purpose) override
+ AddressPurpose* purpose) override
{
LOCK(m_wallet->cs_wallet);
const auto& entry = m_wallet->FindAddressBookEntry(dest, /*allow_change=*/false);
@@ -197,11 +198,16 @@ public:
if (name) {
*name = entry->GetLabel();
}
+ std::optional<isminetype> dest_is_mine;
+ if (is_mine || purpose) {
+ dest_is_mine = m_wallet->IsMine(dest);
+ }
if (is_mine) {
- *is_mine = m_wallet->IsMine(dest);
+ *is_mine = *dest_is_mine;
}
if (purpose) {
- *purpose = entry->purpose;
+ // In very old wallets, address purpose may not be recorded so we derive it from IsMine
+ *purpose = entry->purpose.value_or(*dest_is_mine ? AddressPurpose::RECEIVE : AddressPurpose::SEND);
}
return true;
}
@@ -209,9 +215,11 @@ public:
{
LOCK(m_wallet->cs_wallet);
std::vector<WalletAddress> result;
- m_wallet->ForEachAddrBookEntry([&](const CTxDestination& dest, const std::string& label, const std::string& purpose, bool is_change) EXCLUSIVE_LOCKS_REQUIRED(m_wallet->cs_wallet) {
+ m_wallet->ForEachAddrBookEntry([&](const CTxDestination& dest, const std::string& label, bool is_change, const std::optional<AddressPurpose>& purpose) EXCLUSIVE_LOCKS_REQUIRED(m_wallet->cs_wallet) {
if (is_change) return;
- result.emplace_back(dest, m_wallet->IsMine(dest), label, purpose);
+ isminetype is_mine = m_wallet->IsMine(dest);
+ // In very old wallets, address purpose may not be recorded so we derive it from IsMine
+ result.emplace_back(dest, is_mine, purpose.value_or(is_mine ? AddressPurpose::RECEIVE : AddressPurpose::SEND), label);
});
return result;
}
@@ -220,9 +228,22 @@ public:
return m_wallet->GetAddressReceiveRequests();
}
bool setAddressReceiveRequest(const CTxDestination& dest, const std::string& id, const std::string& value) override {
+ // Note: The setAddressReceiveRequest interface used by the GUI to store
+ // receive requests is a little awkward and could be improved in the
+ // future:
+ //
+ // - The same method is used to save requests and erase them, but
+ // having separate methods could be clearer and prevent bugs.
+ //
+ // - Request ids are passed as strings even though they are generated as
+ // integers.
+ //
+ // - Multiple requests can be stored for the same address, but it might
+ // be better to only allow one request or only keep the current one.
LOCK(m_wallet->cs_wallet);
WalletBatch batch{m_wallet->GetDatabase()};
- return m_wallet->SetAddressReceiveRequest(batch, dest, id, value);
+ return value.empty() ? m_wallet->EraseAddressReceiveRequest(batch, dest, id)
+ : m_wallet->SetAddressReceiveRequest(batch, dest, id, value);
}
bool displayAddress(const CTxDestination& dest) override
{
@@ -403,7 +424,24 @@ public:
CAmount getBalance() override { return GetBalance(*m_wallet).m_mine_trusted; }
CAmount getAvailableBalance(const CCoinControl& coin_control) override
{
- return GetAvailableBalance(*m_wallet, &coin_control);
+ LOCK(m_wallet->cs_wallet);
+ CAmount total_amount = 0;
+ // Fetch selected coins total amount
+ if (coin_control.HasSelected()) {
+ FastRandomContext rng{};
+ CoinSelectionParams params(rng);
+ // Note: for now, swallow any error.
+ if (auto res = FetchSelectedInputs(*m_wallet, coin_control, params)) {
+ total_amount += res->total_amount;
+ }
+ }
+
+ // And fetch the wallet available coins
+ if (coin_control.m_allow_other_inputs) {
+ total_amount += AvailableCoins(*m_wallet, &coin_control).GetTotalAmount();
+ }
+
+ return total_amount;
}
isminetype txinIsMine(const CTxIn& txin) override
{
@@ -501,7 +539,7 @@ public:
{
return MakeSignalHandler(m_wallet->NotifyAddressBookChanged.connect(
[fn](const CTxDestination& address, const std::string& label, bool is_mine,
- const std::string& purpose, ChangeType status) { fn(address, label, is_mine, purpose, status); }));
+ AddressPurpose purpose, ChangeType status) { fn(address, label, is_mine, purpose, status); }));
}
std::unique_ptr<Handler> handleTransactionChanged(TransactionChangedFn fn) override
{
diff --git a/src/wallet/load.cpp b/src/wallet/load.cpp
index 8c60a2da72..2560dda87c 100644
--- a/src/wallet/load.cpp
+++ b/src/wallet/load.cpp
@@ -5,12 +5,12 @@
#include <wallet/load.h>
-#include <fs.h>
+#include <common/args.h>
#include <interfaces/chain.h>
#include <scheduler.h>
#include <util/check.h>
+#include <util/fs.h>
#include <util/string.h>
-#include <util/system.h>
#include <util/translation.h>
#include <wallet/context.h>
#include <wallet/spend.h>
diff --git a/src/wallet/receive.h b/src/wallet/receive.h
index 87be0fc2ae..d50644b4cf 100644
--- a/src/wallet/receive.h
+++ b/src/wallet/receive.h
@@ -6,8 +6,8 @@
#define BITCOIN_WALLET_RECEIVE_H
#include <consensus/amount.h>
-#include <wallet/ismine.h>
#include <wallet/transaction.h>
+#include <wallet/types.h>
#include <wallet/wallet.h>
namespace wallet {
diff --git a/src/wallet/rpc/addresses.cpp b/src/wallet/rpc/addresses.cpp
index da63d45d11..a5be0739a9 100644
--- a/src/wallet/rpc/addresses.cpp
+++ b/src/wallet/rpc/addresses.cpp
@@ -141,9 +141,9 @@ RPCHelpMan setlabel()
const std::string label{LabelFromValue(request.params[1])};
if (pwallet->IsMine(dest)) {
- pwallet->SetAddressBook(dest, label, "receive");
+ pwallet->SetAddressBook(dest, label, AddressPurpose::RECEIVE);
} else {
- pwallet->SetAddressBook(dest, label, "send");
+ pwallet->SetAddressBook(dest, label, AddressPurpose::SEND);
}
return UniValue::VNULL;
@@ -218,7 +218,8 @@ RPCHelpMan addmultisigaddress()
"Each key is a Bitcoin address or hex-encoded public key.\n"
"This functionality is only intended for use with non-watchonly addresses.\n"
"See `importaddress` for watchonly p2sh address support.\n"
- "If 'label' is specified, assign address to that label.\n",
+ "If 'label' is specified, assign address to that label.\n"
+ "Note: This command is only compatible with legacy wallets.\n",
{
{"nrequired", RPCArg::Type::NUM, RPCArg::Optional::NO, "The number of required signatures out of the n keys or addresses."},
{"keys", RPCArg::Type::ARR, RPCArg::Optional::NO, "The bitcoin addresses or hex-encoded public keys",
@@ -285,7 +286,7 @@ RPCHelpMan addmultisigaddress()
// Construct using pay-to-script-hash:
CScript inner;
CTxDestination dest = AddAndGetMultisigDestination(required, pubkeys, output_type, spk_man, inner);
- pwallet->SetAddressBook(dest, label, "send");
+ pwallet->SetAddressBook(dest, label, AddressPurpose::SEND);
// Make the descriptor
std::unique_ptr<Descriptor> descriptor = InferDescriptor(GetScriptForDestination(dest), spk_man);
@@ -300,7 +301,7 @@ RPCHelpMan addmultisigaddress()
// Only warns if the user has explicitly chosen an address type we cannot generate
warnings.push_back("Unable to make chosen address type, please ensure no uncompressed public keys are present.");
}
- if (!warnings.empty()) result.pushKV("warnings", warnings);
+ PushWarnings(warnings, result);
return result;
},
@@ -663,7 +664,7 @@ RPCHelpMan getaddressesbylabel()
// Find all addresses that have the given label
UniValue ret(UniValue::VOBJ);
std::set<std::string> addresses;
- pwallet->ForEachAddrBookEntry([&](const CTxDestination& _dest, const std::string& _label, const std::string& _purpose, bool _is_change) {
+ pwallet->ForEachAddrBookEntry([&](const CTxDestination& _dest, const std::string& _label, bool _is_change, const std::optional<AddressPurpose>& _purpose) {
if (_is_change) return;
if (_label == label) {
std::string address = EncodeDestination(_dest);
@@ -677,7 +678,7 @@ RPCHelpMan getaddressesbylabel()
// std::set in O(log(N))), UniValue::__pushKV is used instead,
// which currently is O(1).
UniValue value(UniValue::VOBJ);
- value.pushKV("purpose", _purpose);
+ value.pushKV("purpose", _purpose ? PurposeToString(*_purpose) : "unknown");
ret.__pushKV(address, value);
}
});
@@ -721,9 +722,15 @@ RPCHelpMan listlabels()
LOCK(pwallet->cs_wallet);
- std::string purpose;
+ std::optional<AddressPurpose> purpose;
if (!request.params[0].isNull()) {
- purpose = request.params[0].get_str();
+ std::string purpose_str = request.params[0].get_str();
+ if (!purpose_str.empty()) {
+ purpose = PurposeFromString(purpose_str);
+ if (!purpose) {
+ throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid 'purpose' argument, must be a known purpose string, typically 'send', or 'receive'.");
+ }
+ }
}
// Add to a set to sort by label name, then insert into Univalue array
diff --git a/src/wallet/rpc/backup.cpp b/src/wallet/rpc/backup.cpp
index 09cfc07bc2..553bbfb62f 100644
--- a/src/wallet/rpc/backup.cpp
+++ b/src/wallet/rpc/backup.cpp
@@ -5,7 +5,6 @@
#include <chain.h>
#include <clientversion.h>
#include <core_io.h>
-#include <fs.h>
#include <hash.h>
#include <interfaces/chain.h>
#include <key_io.h>
@@ -17,6 +16,7 @@
#include <sync.h>
#include <uint256.h>
#include <util/bip32.h>
+#include <util/fs.h>
#include <util/time.h>
#include <util/translation.h>
#include <wallet/rpc/util.h>
@@ -119,7 +119,8 @@ RPCHelpMan importprivkey()
"may report that the imported key exists but related transactions are still missing, leading to temporarily incorrect/bogus balances and unspent outputs until rescan completes.\n"
"The rescan parameter can be set to false if the key was never used to create transactions. If it is set to false,\n"
"but the key was used to create transactions, rescanblockchain needs to be called with the appropriate block range.\n"
- "Note: Use \"getwalletinfo\" to query the scanning progress.\n",
+ "Note: Use \"getwalletinfo\" to query the scanning progress.\n"
+ "Note: This command is only compatible with legacy wallets. Use \"importdescriptors\" with \"combo(X)\" for descriptor wallets.\n",
{
{"privkey", RPCArg::Type::STR, RPCArg::Optional::NO, "The private key (see dumpprivkey)"},
{"label", RPCArg::Type::STR, RPCArg::DefaultHint{"current label if address exists, otherwise \"\""}, "An optional label"},
@@ -188,7 +189,7 @@ RPCHelpMan importprivkey()
// label was passed.
for (const auto& dest : GetAllDestinationsForKey(pubkey)) {
if (!request.params[1].isNull() || !pwallet->FindAddressBookEntry(dest)) {
- pwallet->SetAddressBook(dest, strLabel, "receive");
+ pwallet->SetAddressBook(dest, strLabel, AddressPurpose::RECEIVE);
}
}
@@ -225,7 +226,7 @@ RPCHelpMan importaddress()
"\nNote: If you import a non-standard raw script in hex form, outputs sending to it will be treated\n"
"as change, and not show up in many RPCs.\n"
"Note: Use \"getwalletinfo\" to query the scanning progress.\n"
- "Note: This command is only compatible with legacy wallets. Use \"importdescriptors\" with \"addr(X)\" for descriptor wallets.\n",
+ "Note: This command is only compatible with legacy wallets. Use \"importdescriptors\" for descriptor wallets.\n",
{
{"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The Bitcoin address (or hex-encoded script)"},
{"label", RPCArg::Type::STR, RPCArg::Default{""}, "An optional label"},
@@ -417,7 +418,8 @@ RPCHelpMan importpubkey()
"may report that the imported pubkey exists but related transactions are still missing, leading to temporarily incorrect/bogus balances and unspent outputs until rescan completes.\n"
"The rescan parameter can be set to false if the key was never used to create transactions. If it is set to false,\n"
"but the key was used to create transactions, rescanblockchain needs to be called with the appropriate block range.\n"
- "Note: Use \"getwalletinfo\" to query the scanning progress.\n",
+ "Note: Use \"getwalletinfo\" to query the scanning progress.\n"
+ "Note: This command is only compatible with legacy wallets. Use \"importdescriptors\" with \"combo(X)\" for descriptor wallets.\n",
{
{"pubkey", RPCArg::Type::STR, RPCArg::Optional::NO, "The hex-encoded public key"},
{"label", RPCArg::Type::STR, RPCArg::Default{""}, "An optional label"},
@@ -495,7 +497,8 @@ RPCHelpMan importwallet()
{
return RPCHelpMan{"importwallet",
"\nImports keys from a wallet dump file (see dumpwallet). Requires a new wallet backup to include imported keys.\n"
- "Note: Blockchain and Mempool will be rescanned after a successful import. Use \"getwalletinfo\" to query the scanning progress.\n",
+ "Note: Blockchain and Mempool will be rescanned after a successful import. Use \"getwalletinfo\" to query the scanning progress.\n"
+ "Note: This command is only compatible with legacy wallets.\n",
{
{"filename", RPCArg::Type::STR, RPCArg::Optional::NO, "The wallet file"},
},
@@ -608,7 +611,7 @@ RPCHelpMan importwallet()
}
if (has_label)
- pwallet->SetAddressBook(PKHash(keyid), label, "receive");
+ pwallet->SetAddressBook(PKHash(keyid), label, AddressPurpose::RECEIVE);
progress++;
}
for (const auto& script_pair : scripts) {
@@ -642,7 +645,8 @@ RPCHelpMan dumpprivkey()
{
return RPCHelpMan{"dumpprivkey",
"\nReveals the private key corresponding to 'address'.\n"
- "Then the importprivkey can be used with this output\n",
+ "Then the importprivkey can be used with this output\n"
+ "Note: This command is only compatible with legacy wallets.\n",
{
{"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The bitcoin address for the private key"},
},
@@ -690,7 +694,8 @@ RPCHelpMan dumpwallet()
"\nDumps all wallet keys in a human-readable format to a server-side file. This does not allow overwriting existing files.\n"
"Imported scripts are included in the dumpfile, but corresponding BIP173 addresses, etc. may not be added automatically by importwallet.\n"
"Note that if your wallet contains keys which are not derived from your HD seed (e.g. imported keys), these are not covered by\n"
- "only backing up the seed itself, and must be backed up too (e.g. ensure you back up the whole dumpfile).\n",
+ "only backing up the seed itself, and must be backed up too (e.g. ensure you back up the whole dumpfile).\n"
+ "Note: This command is only compatible with legacy wallets.\n",
{
{"filename", RPCArg::Type::STR, RPCArg::Optional::NO, "The filename with path (absolute path recommended)"},
},
@@ -752,6 +757,7 @@ RPCHelpMan dumpwallet()
// sort time/key pairs
std::vector<std::pair<int64_t, CKeyID> > vKeyBirth;
+ vKeyBirth.reserve(mapKeyBirth.size());
for (const auto& entry : mapKeyBirth) {
vKeyBirth.push_back(std::make_pair(entry.second, entry.first));
}
@@ -1224,7 +1230,7 @@ static UniValue ProcessImport(CWallet& wallet, const UniValue& data, const int64
result.pushKV("error", JSONRPCError(RPC_MISC_ERROR, "Missing required fields"));
}
- if (warnings.size()) result.pushKV("warnings", warnings);
+ PushWarnings(warnings, result);
return result;
}
@@ -1252,7 +1258,8 @@ RPCHelpMan importmulti()
"may report that the imported keys, addresses or scripts exist but related transactions are still missing.\n"
"The rescan parameter can be set to false if the key was never used to create transactions. If it is set to false,\n"
"but the key was used to create transactions, rescanblockchain needs to be called with the appropriate block range.\n"
- "Note: Use \"getwalletinfo\" to query the scanning progress.\n",
+ "Note: Use \"getwalletinfo\" to query the scanning progress.\n"
+ "Note: This command is only compatible with legacy wallets. Use \"importdescriptors\" for descriptor wallets.\n",
{
{"requests", RPCArg::Type::ARR, RPCArg::Optional::NO, "Data to be imported",
{
@@ -1578,7 +1585,7 @@ static UniValue ProcessDescriptorImport(CWallet& wallet, const UniValue& data, c
result.pushKV("success", UniValue(false));
result.pushKV("error", e);
}
- if (warnings.size()) result.pushKV("warnings", warnings);
+ PushWarnings(warnings, result);
return result;
}
@@ -1902,7 +1909,11 @@ RPCHelpMan restorewallet()
RPCResult::Type::OBJ, "", "",
{
{RPCResult::Type::STR, "name", "The wallet name if restored successfully."},
- {RPCResult::Type::STR, "warning", "Warning message if wallet was not loaded cleanly."},
+ {RPCResult::Type::STR, "warning", /*optional=*/true, "Warning messages, if any, related to restoring the wallet. Multiple messages will be delimited by newlines. (DEPRECATED, returned only if config option -deprecatedrpc=walletwarningfield is passed.)"},
+ {RPCResult::Type::ARR, "warnings", /*optional=*/true, "Warning messages, if any, related to restoring the wallet.",
+ {
+ {RPCResult::Type::STR, "", ""},
+ }},
}
},
RPCExamples{
@@ -1932,7 +1943,10 @@ RPCHelpMan restorewallet()
UniValue obj(UniValue::VOBJ);
obj.pushKV("name", wallet->GetName());
- obj.pushKV("warning", Join(warnings, Untranslated("\n")).original);
+ if (wallet->chain().rpcEnableDeprecated("walletwarningfield")) {
+ obj.pushKV("warning", Join(warnings, Untranslated("\n")).original);
+ }
+ PushWarnings(warnings, obj);
return obj;
diff --git a/src/wallet/rpc/coins.cpp b/src/wallet/rpc/coins.cpp
index 4c386789f1..750ef69f6e 100644
--- a/src/wallet/rpc/coins.cpp
+++ b/src/wallet/rpc/coins.cpp
@@ -448,6 +448,7 @@ RPCHelpMan getbalances()
{RPCResult::Type::STR_AMOUNT, "untrusted_pending", "untrusted pending balance (outputs created by others that are in the mempool)"},
{RPCResult::Type::STR_AMOUNT, "immature", "balance from immature coinbase outputs"},
}},
+ RESULT_LAST_PROCESSED_BLOCK,
}
},
RPCExamples{
@@ -488,6 +489,8 @@ RPCHelpMan getbalances()
balances_watchonly.pushKV("immature", ValueFromAmount(bal.m_watchonly_immature));
balances.pushKV("watchonly", balances_watchonly);
}
+
+ AppendLastProcessedBlock(balances, wallet);
return balances;
},
};
diff --git a/src/wallet/rpc/transactions.cpp b/src/wallet/rpc/transactions.cpp
index 3bfe296d90..c34391e6e8 100644
--- a/src/wallet/rpc/transactions.cpp
+++ b/src/wallet/rpc/transactions.cpp
@@ -134,7 +134,7 @@ static UniValue ListReceived(const CWallet& wallet, const UniValue& params, cons
UniValue ret(UniValue::VARR);
std::map<std::string, tallyitem> label_tally;
- const auto& func = [&](const CTxDestination& address, const std::string& label, const std::string& purpose, bool is_change) {
+ const auto& func = [&](const CTxDestination& address, const std::string& label, bool is_change, const std::optional<AddressPurpose>& purpose) {
if (is_change) return; // no change addresses
auto it = mapTally.find(address);
@@ -175,7 +175,7 @@ static UniValue ListReceived(const CWallet& wallet, const UniValue& params, cons
if (filtered_address) {
const auto& entry = wallet.FindAddressBookEntry(*filtered_address, /*allow_change=*/false);
- if (entry) func(*filtered_address, entry->GetLabel(), entry->purpose, /*is_change=*/false);
+ if (entry) func(*filtered_address, entry->GetLabel(), entry->IsChange(), entry->purpose);
} else {
// No filtered addr, walk-through the addressbook entry
wallet.ForEachAddrBookEntry(func);
@@ -389,6 +389,7 @@ static void ListTransactions(const CWallet& wallet, const CWalletTx& wtx, int nM
entry.pushKV("label", label);
}
entry.pushKV("vout", r.vout);
+ entry.pushKV("abandoned", wtx.isAbandoned());
if (fLong)
WalletTxToJSON(wallet, wtx, entry);
ret.push_back(entry);
@@ -462,8 +463,7 @@ RPCHelpMan listtransactions()
},
TransactionDescriptionString()),
{
- {RPCResult::Type::BOOL, "abandoned", /*optional=*/true, "'true' if the transaction has been abandoned (inputs are respendable). Only available for the \n"
- "'send' category of transactions."},
+ {RPCResult::Type::BOOL, "abandoned", "'true' if the transaction has been abandoned (inputs are respendable)."},
})},
}
},
@@ -576,8 +576,7 @@ RPCHelpMan listsinceblock()
},
TransactionDescriptionString()),
{
- {RPCResult::Type::BOOL, "abandoned", /*optional=*/true, "'true' if the transaction has been abandoned (inputs are respendable). Only available for the \n"
- "'send' category of transactions."},
+ {RPCResult::Type::BOOL, "abandoned", "'true' if the transaction has been abandoned (inputs are respendable)."},
{RPCResult::Type::STR, "label", /*optional=*/true, "A comment for the address/transaction, if any"},
})},
}},
@@ -721,8 +720,7 @@ RPCHelpMan gettransaction()
{RPCResult::Type::NUM, "vout", "the vout value"},
{RPCResult::Type::STR_AMOUNT, "fee", /*optional=*/true, "The amount of the fee in " + CURRENCY_UNIT + ". This is negative and only available for the \n"
"'send' category of transactions."},
- {RPCResult::Type::BOOL, "abandoned", /*optional=*/true, "'true' if the transaction has been abandoned (inputs are respendable). Only available for the \n"
- "'send' category of transactions."},
+ {RPCResult::Type::BOOL, "abandoned", "'true' if the transaction has been abandoned (inputs are respendable)."},
{RPCResult::Type::ARR, "parent_descs", /*optional=*/true, "Only if 'category' is 'received'. List of parent descriptors for the scriptPubKey of this coin.", {
{RPCResult::Type::STR, "desc", "The descriptor string."},
}},
@@ -733,6 +731,7 @@ RPCHelpMan gettransaction()
{
{RPCResult::Type::ELISION, "", "Equivalent to the RPC decoderawtransaction method, or the RPC getrawtransaction method when `verbose` is passed."},
}},
+ RESULT_LAST_PROCESSED_BLOCK,
})
},
RPCExamples{
@@ -793,6 +792,7 @@ RPCHelpMan gettransaction()
entry.pushKV("decoded", decoded);
}
+ AppendLastProcessedBlock(entry, *pwallet);
return entry;
},
};
diff --git a/src/wallet/rpc/util.cpp b/src/wallet/rpc/util.cpp
index 4d82e0a41f..4ff44b84b0 100644
--- a/src/wallet/rpc/util.cpp
+++ b/src/wallet/rpc/util.cpp
@@ -177,4 +177,14 @@ void HandleWalletError(const std::shared_ptr<CWallet> wallet, DatabaseStatus& st
throw JSONRPCError(code, error.original);
}
}
+
+void AppendLastProcessedBlock(UniValue& entry, const CWallet& wallet) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet)
+{
+ AssertLockHeld(wallet.cs_wallet);
+ UniValue lastprocessedblock{UniValue::VOBJ};
+ lastprocessedblock.pushKV("hash", wallet.GetLastBlockHash().GetHex());
+ lastprocessedblock.pushKV("height", wallet.GetLastBlockHeight());
+ entry.pushKV("lastprocessedblock", lastprocessedblock);
+}
+
} // namespace wallet
diff --git a/src/wallet/rpc/util.h b/src/wallet/rpc/util.h
index d5d6ac0dfa..2fdba04352 100644
--- a/src/wallet/rpc/util.h
+++ b/src/wallet/rpc/util.h
@@ -5,7 +5,9 @@
#ifndef BITCOIN_WALLET_RPC_UTIL_H
#define BITCOIN_WALLET_RPC_UTIL_H
+#include <rpc/util.h>
#include <script/script.h>
+#include <wallet/wallet.h>
#include <any>
#include <memory>
@@ -17,13 +19,17 @@ class UniValue;
struct bilingual_str;
namespace wallet {
-class CWallet;
class LegacyScriptPubKeyMan;
enum class DatabaseStatus;
struct WalletContext;
extern const std::string HELP_REQUIRING_PASSPHRASE;
+static const RPCResult RESULT_LAST_PROCESSED_BLOCK { RPCResult::Type::OBJ, "lastprocessedblock", "hash and height of the block this information was generated on",{
+ {RPCResult::Type::STR_HEX, "hash", "hash of the block this information was generated on"},
+ {RPCResult::Type::NUM, "height", "height of the block this information was generated on"}}
+};
+
/**
* Figures out what wallet, if any, to use for a JSONRPCRequest.
*
@@ -45,8 +51,8 @@ std::string LabelFromValue(const UniValue& value);
void PushParentDescriptors(const CWallet& wallet, const CScript& script_pubkey, UniValue& entry);
void HandleWalletError(const std::shared_ptr<CWallet> wallet, DatabaseStatus& status, bilingual_str& error);
-
int64_t ParseISO8601DateTime(const std::string& str);
+void AppendLastProcessedBlock(UniValue& entry, const CWallet& wallet) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet);
} // namespace wallet
#endif // BITCOIN_WALLET_RPC_UTIL_H
diff --git a/src/wallet/rpc/wallet.cpp b/src/wallet/rpc/wallet.cpp
index 16595267b4..d728b2fb96 100644
--- a/src/wallet/rpc/wallet.cpp
+++ b/src/wallet/rpc/wallet.cpp
@@ -13,6 +13,7 @@
#include <wallet/rpc/wallet.h>
#include <wallet/rpc/util.h>
#include <wallet/wallet.h>
+#include <wallet/walletutil.h>
#include <optional>
@@ -20,6 +21,14 @@
namespace wallet {
+
+static const std::map<uint64_t, std::string> WALLET_FLAG_CAVEATS{
+ {WALLET_FLAG_AVOID_REUSE,
+ "You need to rescan the blockchain in order to correctly mark used "
+ "destinations in the past. Until this is done, some destinations may "
+ "be considered unused, even if the opposite is the case."},
+};
+
/** Checks if a CKey is in the given CWallet compressed or otherwise*/
bool HaveKey(const SigningProvider& wallet, const CKey& key)
{
@@ -59,6 +68,7 @@ static RPCHelpMan getwalletinfo()
}, /*skip_type_check=*/true},
{RPCResult::Type::BOOL, "descriptors", "whether this wallet uses descriptors for scriptPubKey management"},
{RPCResult::Type::BOOL, "external_signer", "whether this wallet is configured to use an external signer such as a hardware wallet"},
+ RESULT_LAST_PROCESSED_BLOCK,
}},
},
RPCExamples{
@@ -120,6 +130,8 @@ static RPCHelpMan getwalletinfo()
}
obj.pushKV("descriptors", pwallet->IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS));
obj.pushKV("external_signer", pwallet->IsWalletFlagSet(WALLET_FLAG_EXTERNAL_SIGNER));
+
+ AppendLastProcessedBlock(obj, *pwallet);
return obj;
},
};
@@ -207,7 +219,11 @@ static RPCHelpMan loadwallet()
RPCResult::Type::OBJ, "", "",
{
{RPCResult::Type::STR, "name", "The wallet name if loaded successfully."},
- {RPCResult::Type::STR, "warning", "Warning message if wallet was not loaded cleanly."},
+ {RPCResult::Type::STR, "warning", /*optional=*/true, "Warning messages, if any, related to loading the wallet. Multiple messages will be delimited by newlines. (DEPRECATED, returned only if config option -deprecatedrpc=walletwarningfield is passed.)"},
+ {RPCResult::Type::ARR, "warnings", /*optional=*/true, "Warning messages, if any, related to loading the wallet.",
+ {
+ {RPCResult::Type::STR, "", ""},
+ }},
}
},
RPCExamples{
@@ -240,7 +256,10 @@ static RPCHelpMan loadwallet()
UniValue obj(UniValue::VOBJ);
obj.pushKV("name", wallet->GetName());
- obj.pushKV("warning", Join(warnings, Untranslated("\n")).original);
+ if (wallet->chain().rpcEnableDeprecated("walletwarningfield")) {
+ obj.pushKV("warning", Join(warnings, Untranslated("\n")).original);
+ }
+ PushWarnings(warnings, obj);
return obj;
},
@@ -335,7 +354,11 @@ static RPCHelpMan createwallet()
RPCResult::Type::OBJ, "", "",
{
{RPCResult::Type::STR, "name", "The wallet name if created successfully. If the wallet was created using a full path, the wallet_name will be the full path."},
- {RPCResult::Type::STR, "warning", "Warning message if wallet was not loaded cleanly."},
+ {RPCResult::Type::STR, "warning", /*optional=*/true, "Warning messages, if any, related to creating the wallet. Multiple messages will be delimited by newlines. (DEPRECATED, returned only if config option -deprecatedrpc=walletwarningfield is passed.)"},
+ {RPCResult::Type::ARR, "warnings", /*optional=*/true, "Warning messages, if any, related to creating the wallet.",
+ {
+ {RPCResult::Type::STR, "", ""},
+ }},
}
},
RPCExamples{
@@ -405,7 +428,10 @@ static RPCHelpMan createwallet()
UniValue obj(UniValue::VOBJ);
obj.pushKV("name", wallet->GetName());
- obj.pushKV("warning", Join(warnings, Untranslated("\n")).original);
+ if (wallet->chain().rpcEnableDeprecated("walletwarningfield")) {
+ obj.pushKV("warning", Join(warnings, Untranslated("\n")).original);
+ }
+ PushWarnings(warnings, obj);
return obj;
},
@@ -422,7 +448,11 @@ static RPCHelpMan unloadwallet()
{"load_on_startup", RPCArg::Type::BOOL, RPCArg::Optional::OMITTED, "Save wallet name to persistent settings and load on startup. True to add wallet to startup list, false to remove, null to leave unchanged."},
},
RPCResult{RPCResult::Type::OBJ, "", "", {
- {RPCResult::Type::STR, "warning", "Warning message if wallet was not unloaded cleanly."},
+ {RPCResult::Type::STR, "warning", /*optional=*/true, "Warning messages, if any, related to unloading the wallet. Multiple messages will be delimited by newlines. (DEPRECATED, returned only if config option -deprecatedrpc=walletwarningfield is passed.)"},
+ {RPCResult::Type::ARR, "warnings", /*optional=*/true, "Warning messages, if any, related to unloading the wallet.",
+ {
+ {RPCResult::Type::STR, "", ""},
+ }},
}},
RPCExamples{
HelpExampleCli("unloadwallet", "wallet_name")
@@ -460,11 +490,13 @@ static RPCHelpMan unloadwallet()
throw JSONRPCError(RPC_MISC_ERROR, "Requested wallet already unloaded");
}
}
+ UniValue result(UniValue::VOBJ);
+ if (wallet->chain().rpcEnableDeprecated("walletwarningfield")) {
+ result.pushKV("warning", Join(warnings, Untranslated("\n")).original);
+ }
+ PushWarnings(warnings, result);
UnloadWallet(std::move(wallet));
-
- UniValue result(UniValue::VOBJ);
- result.pushKV("warning", Join(warnings, Untranslated("\n")).original);
return result;
},
};
@@ -475,8 +507,8 @@ static RPCHelpMan sethdseed()
return RPCHelpMan{"sethdseed",
"\nSet or generate a new HD wallet seed. Non-HD wallets will not be upgraded to being a HD wallet. Wallets that are already\n"
"HD will have a new HD seed set so that new keys added to the keypool will be derived from this new seed.\n"
- "\nNote that you will need to MAKE A NEW BACKUP of your wallet after setting the HD wallet seed." +
- HELP_REQUIRING_PASSPHRASE,
+ "\nNote that you will need to MAKE A NEW BACKUP of your wallet after setting the HD wallet seed." + HELP_REQUIRING_PASSPHRASE +
+ "Note: This command is only compatible with legacy wallets.\n",
{
{"newkeypool", RPCArg::Type::BOOL, RPCArg::Default{true}, "Whether to flush old unused addresses, including change addresses, from the keypool and regenerate it.\n"
"If true, the next address from getnewaddress and change address from getrawchangeaddress will be from this new seed.\n"
diff --git a/src/wallet/salvage.cpp b/src/wallet/salvage.cpp
index e2b4dbf4c2..06c8c8bb37 100644
--- a/src/wallet/salvage.cpp
+++ b/src/wallet/salvage.cpp
@@ -3,8 +3,8 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include <fs.h>
#include <streams.h>
+#include <util/fs.h>
#include <util/translation.h>
#include <wallet/bdb.h>
#include <wallet/salvage.h>
diff --git a/src/wallet/salvage.h b/src/wallet/salvage.h
index ce918aec2d..fbf152ec79 100644
--- a/src/wallet/salvage.h
+++ b/src/wallet/salvage.h
@@ -6,8 +6,8 @@
#ifndef BITCOIN_WALLET_SALVAGE_H
#define BITCOIN_WALLET_SALVAGE_H
-#include <fs.h>
#include <streams.h>
+#include <util/fs.h>
class ArgsManager;
struct bilingual_str;
diff --git a/src/wallet/scriptpubkeyman.cpp b/src/wallet/scriptpubkeyman.cpp
index 1589e52deb..62bd0c06cd 100644
--- a/src/wallet/scriptpubkeyman.cpp
+++ b/src/wallet/scriptpubkeyman.cpp
@@ -1385,10 +1385,10 @@ void LegacyScriptPubKeyMan::ReturnDestination(int64_t nIndex, bool fInternal, co
WalletLogPrintf("keypool return %d\n", nIndex);
}
-bool LegacyScriptPubKeyMan::GetKeyFromPool(CPubKey& result, const OutputType type, bool internal)
+bool LegacyScriptPubKeyMan::GetKeyFromPool(CPubKey& result, const OutputType type)
{
assert(type != OutputType::BECH32M);
- if (!CanGetAddresses(internal)) {
+ if (!CanGetAddresses(/*internal=*/ false)) {
return false;
}
@@ -1396,10 +1396,10 @@ bool LegacyScriptPubKeyMan::GetKeyFromPool(CPubKey& result, const OutputType typ
{
LOCK(cs_KeyStore);
int64_t nIndex;
- if (!ReserveKeyFromKeyPool(nIndex, keypool, internal) && !m_storage.IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)) {
+ if (!ReserveKeyFromKeyPool(nIndex, keypool, /*fRequestedInternal=*/ false) && !m_storage.IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)) {
if (m_storage.IsLocked()) return false;
WalletBatch batch(m_storage.GetDatabase());
- result = GenerateNewKey(batch, m_hd_chain, internal);
+ result = GenerateNewKey(batch, m_hd_chain, /*internal=*/ false);
return true;
}
KeepDestination(nIndex, type);
@@ -1507,6 +1507,7 @@ std::vector<CKeyID> GetAffectedKeys(const CScript& spk, const SigningProvider& p
FlatSigningProvider out;
InferDescriptor(spk, provider)->Expand(0, DUMMY_SIGNING_PROVIDER, dummy, out);
std::vector<CKeyID> ret;
+ ret.reserve(out.pubkeys.size());
for (const auto& entry : out.pubkeys) {
ret.push_back(entry.first);
}
@@ -2501,6 +2502,7 @@ TransactionError DescriptorScriptPubKeyMan::FillPSBT(PartiallySignedTransaction&
} else {
// Maybe there are pubkeys listed that we can sign for
std::vector<CPubKey> pubkeys;
+ pubkeys.reserve(input.hd_keypaths.size() + 2);
// ECDSA Pubkeys
for (const auto& [pk, _] : input.hd_keypaths) {
diff --git a/src/wallet/scriptpubkeyman.h b/src/wallet/scriptpubkeyman.h
index 4d14325241..22b67c88e9 100644
--- a/src/wallet/scriptpubkeyman.h
+++ b/src/wallet/scriptpubkeyman.h
@@ -14,7 +14,7 @@
#include <util/result.h>
#include <util/time.h>
#include <wallet/crypter.h>
-#include <wallet/ismine.h>
+#include <wallet/types.h>
#include <wallet/walletdb.h>
#include <wallet/walletutil.h>
@@ -334,7 +334,7 @@ private:
std::map<int64_t, CKeyID> m_index_to_reserved_key;
//! Fetches a key from the keypool
- bool GetKeyFromPool(CPubKey &key, const OutputType type, bool internal = false);
+ bool GetKeyFromPool(CPubKey &key, const OutputType type);
/**
* Reserves a key from the keypool and sets nIndex to its index
diff --git a/src/wallet/spend.cpp b/src/wallet/spend.cpp
index 4548d5f813..b14a30921b 100644
--- a/src/wallet/spend.cpp
+++ b/src/wallet/spend.cpp
@@ -3,6 +3,7 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <algorithm>
+#include <common/args.h>
#include <consensus/amount.h>
#include <consensus/validation.h>
#include <interfaces/chain.h>
@@ -14,6 +15,7 @@
#include <util/fees.h>
#include <util/moneystr.h>
#include <util/rbf.h>
+#include <util/system.h>
#include <util/trace.h>
#include <util/translation.h>
#include <wallet/coincontrol.h>
@@ -50,9 +52,7 @@ int CalculateMaximumSignedInputSize(const CTxOut& txout, const CWallet* wallet,
TxSize CalculateMaximumSignedTxSize(const CTransaction &tx, const CWallet *wallet, const std::vector<CTxOut>& txouts, const CCoinControl* coin_control)
{
CMutableTransaction txNew(tx);
- if (!wallet->DummySignTx(txNew, txouts, coin_control)) {
- return TxSize{-1, -1};
- }
+ if (!wallet->DummySignTx(txNew, txouts, coin_control)) return TxSize{-1, -1};
CTransaction ctx(txNew);
int64_t vsize = GetVirtualTransactionSize(ctx);
int64_t weight = GetTransactionWeight(ctx);
@@ -70,11 +70,9 @@ TxSize CalculateMaximumSignedTxSize(const CTransaction &tx, const CWallet *walle
assert(input.prevout.n < mi->second.tx->vout.size());
txouts.emplace_back(mi->second.tx->vout.at(input.prevout.n));
} else if (coin_control) {
- CTxOut txout;
- if (!coin_control->GetExternalOutput(input.prevout, txout)) {
- return TxSize{-1, -1};
- }
- txouts.emplace_back(txout);
+ const auto& txout{coin_control->GetExternalOutput(input.prevout)};
+ if (!txout) return TxSize{-1, -1};
+ txouts.emplace_back(*txout);
} else {
return TxSize{-1, -1};
}
@@ -161,10 +159,8 @@ util::Result<PreSelectedInputs> FetchSelectedInputs(const CWallet& wallet, const
const CoinSelectionParams& coin_selection_params) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet)
{
PreSelectedInputs result;
- std::vector<COutPoint> vPresetInputs;
- coin_control.ListSelected(vPresetInputs);
const bool can_grind_r = wallet.CanGrindR();
- for (const COutPoint& outpoint : vPresetInputs) {
+ for (const COutPoint& outpoint : coin_control.ListSelected()) {
int input_bytes = -1;
CTxOut txout;
if (auto ptr_wtx = wallet.GetWalletTx(outpoint.hash)) {
@@ -176,9 +172,12 @@ util::Result<PreSelectedInputs> FetchSelectedInputs(const CWallet& wallet, const
input_bytes = CalculateMaximumSignedInputSize(txout, &wallet, &coin_control);
} else {
// The input is external. We did not find the tx in mapWallet.
- if (!coin_control.GetExternalOutput(outpoint, txout)) {
+ const auto out{coin_control.GetExternalOutput(outpoint)};
+ if (!out) {
return util::Error{strprintf(_("Not found pre-selected input %s"), outpoint.ToString())};
}
+
+ txout = *out;
}
if (input_bytes == -1) {
@@ -356,12 +355,6 @@ CoinsResult AvailableCoinsListUnspent(const CWallet& wallet, const CCoinControl*
return AvailableCoins(wallet, coinControl, /*feerate=*/ std::nullopt, params);
}
-CAmount GetAvailableBalance(const CWallet& wallet, const CCoinControl* coinControl)
-{
- LOCK(wallet.cs_wallet);
- return AvailableCoins(wallet, coinControl).GetTotalAmount();
-}
-
const CTxOut& FindNonChangeParentOutput(const CWallet& wallet, const COutPoint& outpoint)
{
AssertLockHeld(wallet.cs_wallet);
@@ -565,42 +558,45 @@ util::Result<SelectionResult> ChooseSelectionResult(const CAmount& nTargetValue,
{
// Vector of results. We will choose the best one based on waste.
std::vector<SelectionResult> results;
+ std::vector<util::Result<SelectionResult>> errors;
+ auto append_error = [&] (const util::Result<SelectionResult>& result) {
+ // If any specific error message appears here, then something different from a simple "no selection found" happened.
+ // Let's save it, so it can be retrieved to the user if no other selection algorithm succeeded.
+ if (HasErrorMsg(result)) {
+ errors.emplace_back(result);
+ }
+ };
- if (auto bnb_result{SelectCoinsBnB(groups.positive_group, nTargetValue, coin_selection_params.m_cost_of_change)}) {
+ // Maximum allowed weight
+ int max_inputs_weight = MAX_STANDARD_TX_WEIGHT - (coin_selection_params.tx_noinputs_size * WITNESS_SCALE_FACTOR);
+
+ if (auto bnb_result{SelectCoinsBnB(groups.positive_group, nTargetValue, coin_selection_params.m_cost_of_change, max_inputs_weight)}) {
results.push_back(*bnb_result);
- }
+ } else append_error(bnb_result);
+
+ // As Knapsack and SRD can create change, also deduce change weight.
+ max_inputs_weight -= (coin_selection_params.change_output_size * WITNESS_SCALE_FACTOR);
// The knapsack solver has some legacy behavior where it will spend dust outputs. We retain this behavior, so don't filter for positive only here.
- if (auto knapsack_result{KnapsackSolver(groups.mixed_group, nTargetValue, coin_selection_params.m_min_change_target, coin_selection_params.rng_fast)}) {
+ if (auto knapsack_result{KnapsackSolver(groups.mixed_group, nTargetValue, coin_selection_params.m_min_change_target, coin_selection_params.rng_fast, max_inputs_weight)}) {
knapsack_result->ComputeAndSetWaste(coin_selection_params.min_viable_change, coin_selection_params.m_cost_of_change, coin_selection_params.m_change_fee);
results.push_back(*knapsack_result);
- }
+ } else append_error(knapsack_result);
- if (auto srd_result{SelectCoinsSRD(groups.positive_group, nTargetValue, coin_selection_params.rng_fast)}) {
+ if (auto srd_result{SelectCoinsSRD(groups.positive_group, nTargetValue, coin_selection_params.rng_fast, max_inputs_weight)}) {
srd_result->ComputeAndSetWaste(coin_selection_params.min_viable_change, coin_selection_params.m_cost_of_change, coin_selection_params.m_change_fee);
results.push_back(*srd_result);
- }
+ } else append_error(srd_result);
if (results.empty()) {
- // No solution found
- return util::Error();
- }
-
- std::vector<SelectionResult> eligible_results;
- std::copy_if(results.begin(), results.end(), std::back_inserter(eligible_results), [coin_selection_params](const SelectionResult& result) {
- const auto initWeight{coin_selection_params.tx_noinputs_size * WITNESS_SCALE_FACTOR};
- return initWeight + result.GetWeight() <= static_cast<int>(MAX_STANDARD_TX_WEIGHT);
- });
-
- if (eligible_results.empty()) {
- return util::Error{_("The inputs size exceeds the maximum weight. "
- "Please try sending a smaller amount or manually consolidating your wallet's UTXOs")};
+ // No solution found, retrieve the first explicit error (if any).
+ // future: add 'severity level' to errors so the worst one can be retrieved instead of the first one.
+ return errors.empty() ? util::Error() : errors.front();
}
// Choose the result with the least waste
// If the waste is the same, choose the one which spends more inputs.
- auto& best_result = *std::min_element(eligible_results.begin(), eligible_results.end());
- return best_result;
+ return *std::min_element(results.begin(), results.end());
}
util::Result<SelectionResult> SelectCoins(const CWallet& wallet, CoinsResult& available_coins, const PreSelectedInputs& pre_set_inputs,
diff --git a/src/wallet/spend.h b/src/wallet/spend.h
index 78c2c5f22b..cc9ccf3011 100644
--- a/src/wallet/spend.h
+++ b/src/wallet/spend.h
@@ -94,8 +94,6 @@ CoinsResult AvailableCoins(const CWallet& wallet,
*/
CoinsResult AvailableCoinsListUnspent(const CWallet& wallet, const CCoinControl* coinControl = nullptr, CoinFilterParams params = {}) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet);
-CAmount GetAvailableBalance(const CWallet& wallet, const CCoinControl* coinControl = nullptr);
-
/**
* Find non-change parent output.
*/
diff --git a/src/wallet/sqlite.cpp b/src/wallet/sqlite.cpp
index 8d8a7ab2a2..77e8a4e9c1 100644
--- a/src/wallet/sqlite.cpp
+++ b/src/wallet/sqlite.cpp
@@ -8,8 +8,8 @@
#include <crypto/common.h>
#include <logging.h>
#include <sync.h>
+#include <util/fs_helpers.h>
#include <util/strencodings.h>
-#include <util/system.h>
#include <util/translation.h>
#include <wallet/db.h>
@@ -125,6 +125,7 @@ void SQLiteBatch::SetupSQLStatements()
{&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_delete_prefix_stmt, "DELETE FROM main WHERE instr(key, ?) = 1"},
};
for (const auto& [stmt_prepared, stmt_text] : statements) {
@@ -375,6 +376,7 @@ void SQLiteBatch::Close()
{&m_insert_stmt, "insert"},
{&m_overwrite_stmt, "overwrite"},
{&m_delete_stmt, "delete"},
+ {&m_delete_prefix_stmt, "delete prefix"},
};
for (const auto& [stmt_prepared, stmt_description] : statements) {
@@ -441,24 +443,34 @@ bool SQLiteBatch::WriteKey(DataStream&& key, DataStream&& value, bool overwrite)
return res == SQLITE_DONE;
}
-bool SQLiteBatch::EraseKey(DataStream&& key)
+bool SQLiteBatch::ExecStatement(sqlite3_stmt* stmt, Span<const std::byte> blob)
{
if (!m_database.m_db) return false;
- assert(m_delete_stmt);
+ assert(stmt);
// Bind: leftmost parameter in statement is index 1
- if (!BindBlobToStatement(m_delete_stmt, 1, key, "key")) return false;
+ if (!BindBlobToStatement(stmt, 1, blob, "key")) return false;
// Execute
- int res = sqlite3_step(m_delete_stmt);
- sqlite3_clear_bindings(m_delete_stmt);
- sqlite3_reset(m_delete_stmt);
+ int res = sqlite3_step(stmt);
+ sqlite3_clear_bindings(stmt);
+ sqlite3_reset(stmt);
if (res != SQLITE_DONE) {
LogPrintf("%s: Unable to execute statement: %s\n", __func__, sqlite3_errstr(res));
}
return res == SQLITE_DONE;
}
+bool SQLiteBatch::EraseKey(DataStream&& key)
+{
+ return ExecStatement(m_delete_stmt, key);
+}
+
+bool SQLiteBatch::ErasePrefix(Span<const std::byte> prefix)
+{
+ return ExecStatement(m_delete_prefix_stmt, prefix);
+}
+
bool SQLiteBatch::HasKey(DataStream&& key)
{
if (!m_database.m_db) return false;
diff --git a/src/wallet/sqlite.h b/src/wallet/sqlite.h
index 5745a1d4cf..d9de40569b 100644
--- a/src/wallet/sqlite.h
+++ b/src/wallet/sqlite.h
@@ -36,13 +36,16 @@ private:
sqlite3_stmt* m_insert_stmt{nullptr};
sqlite3_stmt* m_overwrite_stmt{nullptr};
sqlite3_stmt* m_delete_stmt{nullptr};
+ sqlite3_stmt* m_delete_prefix_stmt{nullptr};
void SetupSQLStatements();
+ bool ExecStatement(sqlite3_stmt* stmt, Span<const std::byte> blob);
bool ReadKey(DataStream&& key, DataStream& value) override;
bool WriteKey(DataStream&& key, DataStream&& value, bool overwrite = true) override;
bool EraseKey(DataStream&& key) override;
bool HasKey(DataStream&& key) override;
+ bool ErasePrefix(Span<const std::byte> prefix) override;
public:
explicit SQLiteBatch(SQLiteDatabase& database);
diff --git a/src/wallet/test/coinselector_tests.cpp b/src/wallet/test/coinselector_tests.cpp
index 8f626addde..7f66179517 100644
--- a/src/wallet/test/coinselector_tests.cpp
+++ b/src/wallet/test/coinselector_tests.cpp
@@ -68,7 +68,7 @@ static void add_coin(const CAmount& nValue, int nInput, CoinSet& set, CAmount fe
set.insert(std::make_shared<COutput>(coin));
}
-static void add_coin(CoinsResult& available_coins, CWallet& wallet, const CAmount& nValue, CFeeRate feerate = CFeeRate(0), int nAge = 6*24, bool fIsFromMe = false, int nInput =0, bool spendable = false)
+static void add_coin(CoinsResult& available_coins, CWallet& wallet, const CAmount& nValue, CFeeRate feerate = CFeeRate(0), int nAge = 6*24, bool fIsFromMe = false, int nInput =0, bool spendable = false, int custom_size = 0)
{
CMutableTransaction tx;
tx.nLockTime = nextLockTime++; // so all transactions get different hashes
@@ -84,7 +84,21 @@ static void add_coin(CoinsResult& available_coins, CWallet& wallet, const CAmoun
assert(ret.second);
CWalletTx& wtx = (*ret.first).second;
const auto& txout = wtx.tx->vout.at(nInput);
- available_coins.Add(OutputType::BECH32, {COutPoint(wtx.GetHash(), nInput), txout, nAge, CalculateMaximumSignedInputSize(txout, &wallet, /*coin_control=*/nullptr), /*spendable=*/ true, /*solvable=*/ true, /*safe=*/ true, wtx.GetTxTime(), fIsFromMe, feerate});
+ available_coins.Add(OutputType::BECH32, {COutPoint(wtx.GetHash(), nInput), txout, nAge, custom_size == 0 ? CalculateMaximumSignedInputSize(txout, &wallet, /*coin_control=*/nullptr) : custom_size, /*spendable=*/ true, /*solvable=*/ true, /*safe=*/ true, wtx.GetTxTime(), fIsFromMe, feerate});
+}
+
+// Helpers
+std::optional<SelectionResult> KnapsackSolver(std::vector<OutputGroup>& groups, const CAmount& nTargetValue,
+ CAmount change_target, FastRandomContext& rng)
+{
+ auto res{KnapsackSolver(groups, nTargetValue, change_target, rng, MAX_STANDARD_TX_WEIGHT)};
+ return res ? std::optional<SelectionResult>(*res) : std::nullopt;
+}
+
+std::optional<SelectionResult> SelectCoinsBnB(std::vector<OutputGroup>& utxo_pool, const CAmount& selection_target, const CAmount& cost_of_change)
+{
+ auto res{SelectCoinsBnB(utxo_pool, selection_target, cost_of_change, MAX_STANDARD_TX_WEIGHT)};
+ return res ? std::optional<SelectionResult>(*res) : std::nullopt;
}
/** Check if SelectionResult a is equivalent to SelectionResult b.
@@ -128,13 +142,15 @@ static CAmount make_hard_case(int utxos, std::vector<COutput>& utxo_pool)
return target;
}
-inline std::vector<OutputGroup>& GroupCoins(const std::vector<COutput>& available_coins)
+inline std::vector<OutputGroup>& GroupCoins(const std::vector<COutput>& available_coins, bool subtract_fee_outputs = false)
{
static std::vector<OutputGroup> static_groups;
static_groups.clear();
for (auto& coin : available_coins) {
static_groups.emplace_back();
- static_groups.back().Insert(std::make_shared<COutput>(coin), /*ancestors=*/ 0, /*descendants=*/ 0);
+ OutputGroup& group = static_groups.back();
+ group.Insert(std::make_shared<COutput>(coin), /*ancestors=*/ 0, /*descendants=*/ 0);
+ group.m_subtract_fee_outputs = subtract_fee_outputs;
}
return static_groups;
}
@@ -158,6 +174,16 @@ inline std::vector<OutputGroup>& KnapsackGroupOutputs(const CoinsResult& availab
return static_groups.all_groups.mixed_group;
}
+static std::unique_ptr<CWallet> NewWallet(const node::NodeContext& m_node, const std::string& wallet_name = "")
+{
+ std::unique_ptr<CWallet> wallet = std::make_unique<CWallet>(m_node.chain.get(), wallet_name, CreateMockWalletDatabase());
+ BOOST_CHECK(wallet->LoadWallet() == DBErrors::LOAD_OK);
+ LOCK(wallet->cs_wallet);
+ wallet->SetWalletFlag(WALLET_FLAG_DESCRIPTORS);
+ wallet->SetupDescriptorScriptPubKeyMans();
+ return wallet;
+}
+
// Branch and bound coin selection tests
BOOST_AUTO_TEST_CASE(bnb_search_test)
{
@@ -294,11 +320,7 @@ BOOST_AUTO_TEST_CASE(bnb_search_test)
coin_selection_params_bnb.m_subtract_fee_outputs = true;
{
- std::unique_ptr<CWallet> wallet = std::make_unique<CWallet>(m_node.chain.get(), "", CreateMockWalletDatabase());
- wallet->LoadWallet();
- LOCK(wallet->cs_wallet);
- wallet->SetWalletFlag(WALLET_FLAG_DESCRIPTORS);
- wallet->SetupDescriptorScriptPubKeyMans();
+ std::unique_ptr<CWallet> wallet = NewWallet(m_node);
CoinsResult available_coins;
@@ -316,11 +338,7 @@ BOOST_AUTO_TEST_CASE(bnb_search_test)
}
{
- std::unique_ptr<CWallet> wallet = std::make_unique<CWallet>(m_node.chain.get(), "", CreateMockWalletDatabase());
- wallet->LoadWallet();
- LOCK(wallet->cs_wallet);
- wallet->SetWalletFlag(WALLET_FLAG_DESCRIPTORS);
- wallet->SetupDescriptorScriptPubKeyMans();
+ std::unique_ptr<CWallet> wallet = NewWallet(m_node);
CoinsResult available_coins;
@@ -335,15 +353,13 @@ BOOST_AUTO_TEST_CASE(bnb_search_test)
selected_input.Insert(select_coin, coin_selection_params_bnb.m_subtract_fee_outputs);
available_coins.Erase({available_coins.coins[OutputType::BECH32].begin()->outpoint});
coin_selection_params_bnb.m_effective_feerate = CFeeRate(0);
+ LOCK(wallet->cs_wallet);
const auto result10 = SelectCoins(*wallet, available_coins, selected_input, 10 * CENT, coin_control, coin_selection_params_bnb);
BOOST_CHECK(result10);
}
{
- std::unique_ptr<CWallet> wallet = std::make_unique<CWallet>(m_node.chain.get(), "", CreateMockWalletDatabase());
- wallet->LoadWallet();
- LOCK(wallet->cs_wallet);
- wallet->SetWalletFlag(WALLET_FLAG_DESCRIPTORS);
- wallet->SetupDescriptorScriptPubKeyMans();
+ std::unique_ptr<CWallet> wallet = NewWallet(m_node);
+ LOCK(wallet->cs_wallet); // Every 'SelectCoins' call requires it
CoinsResult available_coins;
@@ -397,6 +413,37 @@ BOOST_AUTO_TEST_CASE(bnb_search_test)
const auto result13 = SelectCoins(*wallet, available_coins, selected_input, 10 * CENT, coin_control, coin_selection_params_bnb);
BOOST_CHECK(EquivalentResult(expected_result, *result13));
}
+
+ {
+ // Test bnb max weight exceeded
+ // Inputs set [10, 9, 8, 5, 3, 1], Selection Target = 16 and coin 5 exceeding the max weight.
+
+ std::unique_ptr<CWallet> wallet = NewWallet(m_node);
+
+ CoinsResult available_coins;
+ add_coin(available_coins, *wallet, 10 * CENT, coin_selection_params_bnb.m_effective_feerate, 6 * 24, false, 0, true);
+ add_coin(available_coins, *wallet, 9 * CENT, coin_selection_params_bnb.m_effective_feerate, 6 * 24, false, 0, true);
+ add_coin(available_coins, *wallet, 8 * CENT, coin_selection_params_bnb.m_effective_feerate, 6 * 24, false, 0, true);
+ add_coin(available_coins, *wallet, 5 * CENT, coin_selection_params_bnb.m_effective_feerate, 6 * 24, false, 0, true, /*custom_size=*/MAX_STANDARD_TX_WEIGHT);
+ add_coin(available_coins, *wallet, 3 * CENT, coin_selection_params_bnb.m_effective_feerate, 6 * 24, false, 0, true);
+ add_coin(available_coins, *wallet, 1 * CENT, coin_selection_params_bnb.m_effective_feerate, 6 * 24, false, 0, true);
+
+ CAmount selection_target = 16 * CENT;
+ const auto& no_res = SelectCoinsBnB(GroupCoins(available_coins.All(), /*subtract_fee_outputs*/true),
+ selection_target, /*cost_of_change=*/0, MAX_STANDARD_TX_WEIGHT);
+ BOOST_ASSERT(!no_res);
+ BOOST_CHECK(util::ErrorString(no_res).original.find("The inputs size exceeds the maximum weight") != std::string::npos);
+
+ // Now add same coin value with a good size and check that it gets selected
+ add_coin(available_coins, *wallet, 5 * CENT, coin_selection_params_bnb.m_effective_feerate, 6 * 24, false, 0, true);
+ const auto& res = SelectCoinsBnB(GroupCoins(available_coins.All(), /*subtract_fee_outputs*/true), selection_target, /*cost_of_change=*/0);
+
+ expected_result.Clear();
+ add_coin(8 * CENT, 2, expected_result);
+ add_coin(5 * CENT, 2, expected_result);
+ add_coin(3 * CENT, 2, expected_result);
+ BOOST_CHECK(EquivalentResult(expected_result, *res));
+ }
}
BOOST_AUTO_TEST_CASE(knapsack_solver_test)
@@ -404,11 +451,7 @@ BOOST_AUTO_TEST_CASE(knapsack_solver_test)
FastRandomContext rand{};
const auto temp1{[&rand](std::vector<OutputGroup>& g, const CAmount& v, CAmount c) { return KnapsackSolver(g, v, c, rand); }};
const auto KnapsackSolver{temp1};
- std::unique_ptr<CWallet> wallet = std::make_unique<CWallet>(m_node.chain.get(), "", CreateMockWalletDatabase());
- wallet->LoadWallet();
- LOCK(wallet->cs_wallet);
- wallet->SetWalletFlag(WALLET_FLAG_DESCRIPTORS);
- wallet->SetupDescriptorScriptPubKeyMans();
+ std::unique_ptr<CWallet> wallet = NewWallet(m_node);
CoinsResult available_coins;
@@ -714,11 +757,7 @@ BOOST_AUTO_TEST_CASE(knapsack_solver_test)
BOOST_AUTO_TEST_CASE(ApproximateBestSubset)
{
FastRandomContext rand{};
- std::unique_ptr<CWallet> wallet = std::make_unique<CWallet>(m_node.chain.get(), "", CreateMockWalletDatabase());
- wallet->LoadWallet();
- LOCK(wallet->cs_wallet);
- wallet->SetWalletFlag(WALLET_FLAG_DESCRIPTORS);
- wallet->SetupDescriptorScriptPubKeyMans();
+ std::unique_ptr<CWallet> wallet = NewWallet(m_node);
CoinsResult available_coins;
@@ -736,11 +775,8 @@ BOOST_AUTO_TEST_CASE(ApproximateBestSubset)
// Tests that with the ideal conditions, the coin selector will always be able to find a solution that can pay the target value
BOOST_AUTO_TEST_CASE(SelectCoins_test)
{
- std::unique_ptr<CWallet> wallet = std::make_unique<CWallet>(m_node.chain.get(), "", CreateMockWalletDatabase());
- wallet->LoadWallet();
- LOCK(wallet->cs_wallet);
- wallet->SetWalletFlag(WALLET_FLAG_DESCRIPTORS);
- wallet->SetupDescriptorScriptPubKeyMans();
+ std::unique_ptr<CWallet> wallet = NewWallet(m_node);
+ LOCK(wallet->cs_wallet); // Every 'SelectCoins' call requires it
// Random generator stuff
std::default_random_engine generator;
@@ -921,16 +957,101 @@ BOOST_AUTO_TEST_CASE(effective_value_test)
BOOST_CHECK_EQUAL(output5.GetEffectiveValue(), nValue); // The effective value should be equal to the absolute value if input_bytes is -1
}
-static util::Result<SelectionResult> select_coins(const CAmount& target, const CoinSelectionParams& cs_params, const CCoinControl& cc, std::function<CoinsResult(CWallet&)> coin_setup, interfaces::Chain* chain)
+
+static util::Result<SelectionResult> SelectCoinsSRD(const CAmount& target,
+ const CoinSelectionParams& cs_params,
+ const node::NodeContext& m_node,
+ int max_weight,
+ std::function<CoinsResult(CWallet&)> coin_setup)
{
- std::unique_ptr<CWallet> wallet = std::make_unique<CWallet>(chain, "", CreateMockWalletDatabase());
- wallet->LoadWallet();
- LOCK(wallet->cs_wallet);
- wallet->SetWalletFlag(WALLET_FLAG_DESCRIPTORS);
- wallet->SetupDescriptorScriptPubKeyMans();
+ std::unique_ptr<CWallet> wallet = NewWallet(m_node);
+ CoinEligibilityFilter filter(0, 0, 0); // accept all coins without ancestors
+ Groups group = GroupOutputs(*wallet, coin_setup(*wallet), cs_params, {{filter}})[filter].all_groups;
+ return SelectCoinsSRD(group.positive_group, target, cs_params.rng_fast, max_weight);
+}
+
+BOOST_AUTO_TEST_CASE(srd_tests)
+{
+ // Test SRD:
+ // 1) Insufficient funds, select all provided coins and fail.
+ // 2) Exceeded max weight, coin selection always surpasses the max allowed weight.
+ // 3) Select coins without surpassing the max weight (some coins surpasses the max allowed weight, some others not)
+
+ FastRandomContext rand;
+ CoinSelectionParams dummy_params{ // Only used to provide the 'avoid_partial' flag.
+ rand,
+ /*change_output_size=*/34,
+ /*change_spend_size=*/68,
+ /*min_change_target=*/CENT,
+ /*effective_feerate=*/CFeeRate(0),
+ /*long_term_feerate=*/CFeeRate(0),
+ /*discard_feerate=*/CFeeRate(0),
+ /*tx_noinputs_size=*/10 + 34, // static header size + output size
+ /*avoid_partial=*/false,
+ };
+
+ {
+ // #########################################################
+ // 1) Insufficient funds, select all provided coins and fail
+ // #########################################################
+ CAmount target = 49.5L * COIN;
+ int max_weight = 10000; // high enough to not fail for this reason.
+ const auto& res = SelectCoinsSRD(target, dummy_params, m_node, max_weight, [&](CWallet& wallet) {
+ CoinsResult available_coins;
+ for (int j = 0; j < 10; ++j) {
+ add_coin(available_coins, wallet, CAmount(1 * COIN));
+ add_coin(available_coins, wallet, CAmount(2 * COIN));
+ }
+ return available_coins;
+ });
+ BOOST_CHECK(!res);
+ BOOST_CHECK(util::ErrorString(res).empty()); // empty means "insufficient funds"
+ }
+
+ {
+ // ###########################
+ // 2) Test max weight exceeded
+ // ###########################
+ CAmount target = 49.5L * COIN;
+ int max_weight = 3000;
+ const auto& res = SelectCoinsSRD(target, dummy_params, m_node, max_weight, [&](CWallet& wallet) {
+ CoinsResult available_coins;
+ for (int j = 0; j < 10; ++j) {
+ add_coin(available_coins, wallet, CAmount(1 * COIN), CFeeRate(0), 144, false, 0, true);
+ add_coin(available_coins, wallet, CAmount(2 * COIN), CFeeRate(0), 144, false, 0, true);
+ }
+ return available_coins;
+ });
+ BOOST_CHECK(!res);
+ BOOST_CHECK(util::ErrorString(res).original.find("The inputs size exceeds the maximum weight") != std::string::npos);
+ }
+ {
+ // ################################################################################################################
+ // 3) Test selection when some coins surpass the max allowed weight while others not. --> must find a good solution
+ // ################################################################################################################
+ CAmount target = 25.33L * COIN;
+ int max_weight = 10000; // WU
+ const auto& res = SelectCoinsSRD(target, dummy_params, m_node, max_weight, [&](CWallet& wallet) {
+ CoinsResult available_coins;
+ for (int j = 0; j < 60; ++j) { // 60 UTXO --> 19,8 BTC total --> 60 × 272 WU = 16320 WU
+ add_coin(available_coins, wallet, CAmount(0.33 * COIN), CFeeRate(0), 144, false, 0, true);
+ }
+ for (int i = 0; i < 10; i++) { // 10 UTXO --> 20 BTC total --> 10 × 272 WU = 2720 WU
+ add_coin(available_coins, wallet, CAmount(2 * COIN), CFeeRate(0), 144, false, 0, true);
+ }
+ return available_coins;
+ });
+ BOOST_CHECK(res);
+ }
+}
+
+static util::Result<SelectionResult> select_coins(const CAmount& target, const CoinSelectionParams& cs_params, const CCoinControl& cc, std::function<CoinsResult(CWallet&)> coin_setup, const node::NodeContext& m_node)
+{
+ std::unique_ptr<CWallet> wallet = NewWallet(m_node);
auto available_coins = coin_setup(*wallet);
+ LOCK(wallet->cs_wallet);
auto result = SelectCoins(*wallet, available_coins, /*pre_set_inputs=*/ {}, target, cc, cs_params);
if (result) {
const auto signedTxSize = 10 + 34 + 68 * result->GetInputSet().size(); // static header size + output size + inputs size (P2WPKH)
@@ -964,8 +1085,6 @@ BOOST_AUTO_TEST_CASE(check_max_weight)
/*avoid_partial=*/false,
};
- auto chain{m_node.chain.get()};
-
{
// Scenario 1:
// The actor starts with 1x 50.0 BTC and 1515x 0.033 BTC (~100.0 BTC total) unspent outputs
@@ -984,10 +1103,13 @@ BOOST_AUTO_TEST_CASE(check_max_weight)
add_coin(available_coins, wallet, CAmount(50 * COIN), CFeeRate(0), 144, false, 0, true);
return available_coins;
},
- chain);
+ m_node);
BOOST_CHECK(result);
- BOOST_CHECK(has_coin(result->GetInputSet(), CAmount(50 * COIN)));
+ // Verify that only the 50 BTC UTXO was selected
+ const auto& selection_res = result->GetInputSet();
+ BOOST_CHECK(selection_res.size() == 1);
+ BOOST_CHECK((*selection_res.begin())->GetEffectiveValue() == 50 * COIN);
}
{
@@ -1009,7 +1131,7 @@ BOOST_AUTO_TEST_CASE(check_max_weight)
}
return available_coins;
},
- chain);
+ m_node);
BOOST_CHECK(has_coin(result->GetInputSet(), CAmount(0.0625 * COIN)));
BOOST_CHECK(has_coin(result->GetInputSet(), CAmount(0.025 * COIN)));
@@ -1030,7 +1152,7 @@ BOOST_AUTO_TEST_CASE(check_max_weight)
}
return available_coins;
},
- chain);
+ m_node);
// No results
// 1515 inputs * 68 bytes = 103,020 bytes
@@ -1045,20 +1167,11 @@ BOOST_AUTO_TEST_CASE(SelectCoins_effective_value_test)
// This test creates a coin whose value is higher than the target but whose effective value is lower than the target.
// The coin is selected using coin control, with m_allow_other_inputs = false. SelectCoins should fail due to insufficient funds.
- std::unique_ptr<CWallet> wallet = std::make_unique<CWallet>(m_node.chain.get(), "", CreateMockWalletDatabase());
- wallet->LoadWallet();
- LOCK(wallet->cs_wallet);
- wallet->SetWalletFlag(WALLET_FLAG_DESCRIPTORS);
- wallet->SetupDescriptorScriptPubKeyMans();
+ std::unique_ptr<CWallet> wallet = NewWallet(m_node);
CoinsResult available_coins;
{
- std::unique_ptr<CWallet> dummyWallet = std::make_unique<CWallet>(m_node.chain.get(), "dummy", CreateMockWalletDatabase());
- dummyWallet->LoadWallet();
- LOCK(dummyWallet->cs_wallet);
- dummyWallet->SetWalletFlag(WALLET_FLAG_DESCRIPTORS);
- dummyWallet->SetupDescriptorScriptPubKeyMans();
-
+ std::unique_ptr<CWallet> dummyWallet = NewWallet(m_node, /*wallet_name=*/"dummy");
add_coin(available_coins, *dummyWallet, 100000); // 0.001 BTC
}
@@ -1082,6 +1195,7 @@ BOOST_AUTO_TEST_CASE(SelectCoins_effective_value_test)
cc.SetInputWeight(output.outpoint, 148);
cc.SelectExternal(output.outpoint, output.txout);
+ LOCK(wallet->cs_wallet);
const auto preset_inputs = *Assert(FetchSelectedInputs(*wallet, cc, cs_params));
available_coins.Erase({available_coins.coins[OutputType::BECH32].begin()->outpoint});
@@ -1094,11 +1208,7 @@ BOOST_FIXTURE_TEST_CASE(wallet_coinsresult_test, BasicTestingSetup)
// Test case to verify CoinsResult object sanity.
CoinsResult available_coins;
{
- std::unique_ptr<CWallet> dummyWallet = std::make_unique<CWallet>(m_node.chain.get(), "dummy", CreateMockWalletDatabase());
- BOOST_CHECK_EQUAL(dummyWallet->LoadWallet(), DBErrors::LOAD_OK);
- LOCK(dummyWallet->cs_wallet);
- dummyWallet->SetWalletFlag(WALLET_FLAG_DESCRIPTORS);
- dummyWallet->SetupDescriptorScriptPubKeyMans();
+ std::unique_ptr<CWallet> dummyWallet = NewWallet(m_node, /*wallet_name=*/"dummy");
// Add some coins to 'available_coins'
for (int i=0; i<10; i++) {
diff --git a/src/wallet/test/db_tests.cpp b/src/wallet/test/db_tests.cpp
index 7e26656b86..7761308bbc 100644
--- a/src/wallet/test/db_tests.cpp
+++ b/src/wallet/test/db_tests.cpp
@@ -4,8 +4,8 @@
#include <boost/test/unit_test.hpp>
-#include <fs.h>
#include <test/util/setup_common.h>
+#include <util/fs.h>
#include <wallet/bdb.h>
#include <fstream>
diff --git a/src/wallet/test/fuzz/coinselection.cpp b/src/wallet/test/fuzz/coinselection.cpp
index 304190eec1..9be8efab62 100644
--- a/src/wallet/test/fuzz/coinselection.cpp
+++ b/src/wallet/test/fuzz/coinselection.cpp
@@ -3,6 +3,7 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <policy/feerate.h>
+#include <policy/policy.h>
#include <primitives/transaction.h>
#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
@@ -44,6 +45,9 @@ static void GroupCoins(FuzzedDataProvider& fuzzed_data_provider, const std::vect
if (valid_outputgroup) output_groups.push_back(output_group);
}
+// Returns true if the result contains an error and the message is not empty
+static bool HasErrorMsg(const util::Result<SelectionResult>& res) { return !util::ErrorString(res).empty(); }
+
FUZZ_TARGET(coinselection)
{
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
@@ -84,18 +88,18 @@ FUZZ_TARGET(coinselection)
GroupCoins(fuzzed_data_provider, utxo_pool, coin_params, /*positive_only=*/false, group_all);
// Run coinselection algorithms
- const auto result_bnb = SelectCoinsBnB(group_pos, target, cost_of_change);
+ const auto result_bnb = SelectCoinsBnB(group_pos, target, cost_of_change, MAX_STANDARD_TX_WEIGHT);
- auto result_srd = SelectCoinsSRD(group_pos, target, fast_random_context);
+ auto result_srd = SelectCoinsSRD(group_pos, target, fast_random_context, MAX_STANDARD_TX_WEIGHT);
if (result_srd) result_srd->ComputeAndSetWaste(cost_of_change, cost_of_change, 0);
CAmount change_target{GenerateChangeTarget(target, coin_params.m_change_fee, fast_random_context)};
- auto result_knapsack = KnapsackSolver(group_all, target, change_target, fast_random_context);
+ auto result_knapsack = KnapsackSolver(group_all, target, change_target, fast_random_context, MAX_STANDARD_TX_WEIGHT);
if (result_knapsack) result_knapsack->ComputeAndSetWaste(cost_of_change, cost_of_change, 0);
// If the total balance is sufficient for the target and we are not using
- // effective values, Knapsack should always find a solution.
- if (total_balance >= target && subtract_fee_outputs) {
+ // effective values, Knapsack should always find a solution (unless the selection exceeded the max tx weight).
+ if (total_balance >= target && subtract_fee_outputs && !HasErrorMsg(result_knapsack)) {
assert(result_knapsack);
}
}
diff --git a/src/wallet/test/init_test_fixture.cpp b/src/wallet/test/init_test_fixture.cpp
index 60b1bab8ac..0adc63876c 100644
--- a/src/wallet/test/init_test_fixture.cpp
+++ b/src/wallet/test/init_test_fixture.cpp
@@ -2,10 +2,10 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include <fs.h>
+#include <common/args.h>
#include <univalue.h>
#include <util/check.h>
-#include <util/system.h>
+#include <util/fs.h>
#include <fstream>
#include <string>
diff --git a/src/wallet/test/init_tests.cpp b/src/wallet/test/init_tests.cpp
index 3dbc91fc68..10aeed49cb 100644
--- a/src/wallet/test/init_tests.cpp
+++ b/src/wallet/test/init_tests.cpp
@@ -4,10 +4,10 @@
#include <boost/test/unit_test.hpp>
+#include <common/args.h>
#include <noui.h>
#include <test/util/logging.h>
#include <test/util/setup_common.h>
-#include <util/system.h>
#include <wallet/test/init_test_fixture.h>
namespace wallet {
diff --git a/src/wallet/test/ismine_tests.cpp b/src/wallet/test/ismine_tests.cpp
index 90f369b22a..f6f2d423e4 100644
--- a/src/wallet/test/ismine_tests.cpp
+++ b/src/wallet/test/ismine_tests.cpp
@@ -8,7 +8,7 @@
#include <script/script.h>
#include <script/standard.h>
#include <test/util/setup_common.h>
-#include <wallet/ismine.h>
+#include <wallet/types.h>
#include <wallet/wallet.h>
#include <boost/test/unit_test.hpp>
diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp
index 2e95a14807..da4b553394 100644
--- a/src/wallet/test/wallet_tests.cpp
+++ b/src/wallet/test/wallet_tests.cpp
@@ -427,19 +427,63 @@ BOOST_AUTO_TEST_CASE(ComputeTimeSmart)
BOOST_CHECK_EQUAL(AddTx(*m_node.chainman, m_wallet, 5, 50, 600), 300);
}
-BOOST_AUTO_TEST_CASE(LoadReceiveRequests)
+static const DatabaseFormat DATABASE_FORMATS[] = {
+#ifdef USE_SQLITE
+ DatabaseFormat::SQLITE,
+#endif
+#ifdef USE_BDB
+ DatabaseFormat::BERKELEY,
+#endif
+};
+
+void TestLoadWallet(const std::string& name, DatabaseFormat format, std::function<void(std::shared_ptr<CWallet>)> f)
{
- CTxDestination dest = PKHash();
- LOCK(m_wallet.cs_wallet);
- WalletBatch batch{m_wallet.GetDatabase()};
- m_wallet.SetAddressUsed(batch, dest, true);
- m_wallet.SetAddressReceiveRequest(batch, dest, "0", "val_rr0");
- m_wallet.SetAddressReceiveRequest(batch, dest, "1", "val_rr1");
-
- auto values = m_wallet.GetAddressReceiveRequests();
- BOOST_CHECK_EQUAL(values.size(), 2U);
- BOOST_CHECK_EQUAL(values[0], "val_rr0");
- BOOST_CHECK_EQUAL(values[1], "val_rr1");
+ node::NodeContext node;
+ auto chain{interfaces::MakeChain(node)};
+ DatabaseOptions options;
+ options.require_format = format;
+ DatabaseStatus status;
+ bilingual_str error;
+ std::vector<bilingual_str> warnings;
+ auto database{MakeWalletDatabase(name, options, status, error)};
+ auto wallet{std::make_shared<CWallet>(chain.get(), "", std::move(database))};
+ BOOST_CHECK_EQUAL(wallet->LoadWallet(), DBErrors::LOAD_OK);
+ WITH_LOCK(wallet->cs_wallet, f(wallet));
+}
+
+BOOST_FIXTURE_TEST_CASE(LoadReceiveRequests, TestingSetup)
+{
+ for (DatabaseFormat format : DATABASE_FORMATS) {
+ const std::string name{strprintf("receive-requests-%i", format)};
+ TestLoadWallet(name, format, [](std::shared_ptr<CWallet> wallet) EXCLUSIVE_LOCKS_REQUIRED(wallet->cs_wallet) {
+ BOOST_CHECK(!wallet->IsAddressPreviouslySpent(PKHash()));
+ WalletBatch batch{wallet->GetDatabase()};
+ BOOST_CHECK(batch.WriteAddressPreviouslySpent(PKHash(), true));
+ BOOST_CHECK(batch.WriteAddressPreviouslySpent(ScriptHash(), true));
+ BOOST_CHECK(wallet->SetAddressReceiveRequest(batch, PKHash(), "0", "val_rr00"));
+ BOOST_CHECK(wallet->EraseAddressReceiveRequest(batch, PKHash(), "0"));
+ BOOST_CHECK(wallet->SetAddressReceiveRequest(batch, PKHash(), "1", "val_rr10"));
+ BOOST_CHECK(wallet->SetAddressReceiveRequest(batch, PKHash(), "1", "val_rr11"));
+ BOOST_CHECK(wallet->SetAddressReceiveRequest(batch, ScriptHash(), "2", "val_rr20"));
+ });
+ TestLoadWallet(name, format, [](std::shared_ptr<CWallet> wallet) EXCLUSIVE_LOCKS_REQUIRED(wallet->cs_wallet) {
+ BOOST_CHECK(wallet->IsAddressPreviouslySpent(PKHash()));
+ BOOST_CHECK(wallet->IsAddressPreviouslySpent(ScriptHash()));
+ auto requests = wallet->GetAddressReceiveRequests();
+ auto erequests = {"val_rr11", "val_rr20"};
+ BOOST_CHECK_EQUAL_COLLECTIONS(requests.begin(), requests.end(), std::begin(erequests), std::end(erequests));
+ WalletBatch batch{wallet->GetDatabase()};
+ BOOST_CHECK(batch.WriteAddressPreviouslySpent(PKHash(), false));
+ BOOST_CHECK(batch.EraseAddressData(ScriptHash()));
+ });
+ TestLoadWallet(name, format, [](std::shared_ptr<CWallet> wallet) EXCLUSIVE_LOCKS_REQUIRED(wallet->cs_wallet) {
+ BOOST_CHECK(!wallet->IsAddressPreviouslySpent(PKHash()));
+ BOOST_CHECK(!wallet->IsAddressPreviouslySpent(ScriptHash()));
+ auto requests = wallet->GetAddressReceiveRequests();
+ auto erequests = {"val_rr11"};
+ BOOST_CHECK_EQUAL_COLLECTIONS(requests.begin(), requests.end(), std::begin(erequests), std::end(erequests));
+ });
+ }
}
// Test some watch-only LegacyScriptPubKeyMan methods by the procedure of loading (LoadWatchOnly),
@@ -581,7 +625,7 @@ BOOST_FIXTURE_TEST_CASE(ListCoinsTest, ListCoinsTestingSetup)
BOOST_CHECK_EQUAL(list.begin()->second.size(), 1U);
// Check initial balance from one mature coinbase transaction.
- BOOST_CHECK_EQUAL(50 * COIN, GetAvailableBalance(*wallet));
+ BOOST_CHECK_EQUAL(50 * COIN, WITH_LOCK(wallet->cs_wallet, return AvailableCoins(*wallet).GetTotalAmount()));
// Add a transaction creating a change address, and confirm ListCoins still
// returns the coin associated with the change address underneath the
@@ -922,6 +966,7 @@ private:
bool WriteKey(DataStream&& key, DataStream&& value, bool overwrite = true) override { return m_pass; }
bool EraseKey(DataStream&& key) override { return m_pass; }
bool HasKey(DataStream&& key) override { return m_pass; }
+ bool ErasePrefix(Span<const std::byte> prefix) override { return m_pass; }
public:
explicit FailBatch(bool pass) : m_pass(pass) {}
diff --git a/src/wallet/transaction.h b/src/wallet/transaction.h
index 290ef4eaa9..1a79d7db4e 100644
--- a/src/wallet/transaction.h
+++ b/src/wallet/transaction.h
@@ -5,10 +5,12 @@
#ifndef BITCOIN_WALLET_TRANSACTION_H
#define BITCOIN_WALLET_TRANSACTION_H
+#include <bitset>
+#include <cstdint>
#include <consensus/amount.h>
#include <primitives/transaction.h>
#include <serialize.h>
-#include <wallet/ismine.h>
+#include <wallet/types.h>
#include <threadsafety.h>
#include <tinyformat.h>
#include <util/overloaded.h>
@@ -108,8 +110,29 @@ static inline int TxStateSerializedIndex(const TxState& state)
}
+/**
+ * Cachable amount subdivided into watchonly and spendable parts.
+ */
+struct CachableAmount
+{
+ // NO and ALL are never (supposed to be) cached
+ std::bitset<ISMINE_ENUM_ELEMENTS> m_cached;
+ CAmount m_value[ISMINE_ENUM_ELEMENTS];
+ inline void Reset()
+ {
+ m_cached.reset();
+ }
+ void Set(isminefilter filter, CAmount value)
+ {
+ m_cached.set(filter);
+ m_value[filter] = value;
+ }
+};
+
+
typedef std::map<std::string, std::string> mapValue_t;
+
/** Legacy class used for deserializing vtxPrev for backwards compatibility.
* vtxPrev was removed in commit 93a18a3650292afbb441a47d1fa1b94aeb0164e3,
* but old wallet.dat files may still contain vtxPrev vectors of CMerkleTxs.
diff --git a/src/wallet/ismine.h b/src/wallet/types.h
index 4ef4ef98ac..6198f1ae33 100644
--- a/src/wallet/ismine.h
+++ b/src/wallet/types.h
@@ -3,20 +3,19 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#ifndef BITCOIN_WALLET_ISMINE_H
-#define BITCOIN_WALLET_ISMINE_H
+//! @file Public type definitions that are used inside and outside of the wallet
+//! (e.g. by src/wallet and src/interfaces and src/qt code).
+//!
+//! File is home for simple enum and struct definitions that don't deserve
+//! separate header files. More complicated wallet public types like
+//! CCoinControl that are used externally can have separate headers.
-#include <script/standard.h>
+#ifndef BITCOIN_WALLET_TYPES_H
+#define BITCOIN_WALLET_TYPES_H
-#include <bitset>
-#include <cstdint>
#include <type_traits>
-class CScript;
-
namespace wallet {
-class CWallet;
-
/**
* IsMine() return codes, which depend on ScriptPubKeyMan implementation.
* Not every ScriptPubKeyMan covers all types, please refer to
@@ -51,23 +50,18 @@ enum isminetype : unsigned int {
using isminefilter = std::underlying_type<isminetype>::type;
/**
- * Cachable amount subdivided into watchonly and spendable parts.
+ * Address purpose field that has been been stored with wallet sending and
+ * receiving addresses since BIP70 payment protocol support was added in
+ * https://github.com/bitcoin/bitcoin/pull/2539. This field is not currently
+ * used for any logic inside the wallet, but it is still shown in RPC and GUI
+ * interfaces and saved for new addresses. It is basically redundant with an
+ * address's IsMine() result.
*/
-struct CachableAmount
-{
- // NO and ALL are never (supposed to be) cached
- std::bitset<ISMINE_ENUM_ELEMENTS> m_cached;
- CAmount m_value[ISMINE_ENUM_ELEMENTS];
- inline void Reset()
- {
- m_cached.reset();
- }
- void Set(isminefilter filter, CAmount value)
- {
- m_cached.set(filter);
- m_value[filter] = value;
- }
+enum class AddressPurpose {
+ RECEIVE,
+ SEND,
+ REFUND, //!< Never set in current code may be present in older wallet databases
};
} // namespace wallet
-#endif // BITCOIN_WALLET_ISMINE_H
+#endif // BITCOIN_WALLET_TYPES_H
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index ef8fb29e64..caf95a3f03 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -7,11 +7,11 @@
#include <blockfilter.h>
#include <chain.h>
+#include <common/args.h>
#include <consensus/amount.h>
#include <consensus/consensus.h>
#include <consensus/validation.h>
#include <external_signer.h>
-#include <fs.h>
#include <interfaces/chain.h>
#include <interfaces/wallet.h>
#include <key.h>
@@ -32,15 +32,16 @@
#include <util/check.h>
#include <util/error.h>
#include <util/fees.h>
+#include <util/fs.h>
+#include <util/fs_helpers.h>
#include <util/moneystr.h>
#include <util/rbf.h>
#include <util/string.h>
-#include <util/system.h>
#include <util/translation.h>
#include <wallet/coincontrol.h>
#include <wallet/context.h>
-#include <wallet/fees.h>
#include <wallet/external_signer_scriptpubkeyman.h>
+#include <wallet/fees.h>
#include <univalue.h>
@@ -51,13 +52,6 @@
using interfaces::FoundBlock;
namespace wallet {
-const std::map<uint64_t,std::string> WALLET_FLAG_CAVEATS{
- {WALLET_FLAG_AVOID_REUSE,
- "You need to rescan the blockchain in order to correctly mark used "
- "destinations in the past. Until this is done, some destinations may "
- "be considered unused, even if the opposite is the case."
- },
-};
bool AddWalletSetting(interfaces::Chain& chain, const std::string& wallet_name)
{
@@ -973,11 +967,11 @@ void CWallet::SetSpentKeyState(WalletBatch& batch, const uint256& hash, unsigned
CTxDestination dst;
if (ExtractDestination(srctx->tx->vout[n].scriptPubKey, dst)) {
if (IsMine(dst)) {
- if (used != IsAddressUsed(dst)) {
+ if (used != IsAddressPreviouslySpent(dst)) {
if (used) {
tx_destinations.insert(dst);
}
- SetAddressUsed(batch, dst, used);
+ SetAddressPreviouslySpent(batch, dst, used);
}
}
}
@@ -990,7 +984,7 @@ bool CWallet::IsSpentKey(const CScript& scriptPubKey) const
if (!ExtractDestination(scriptPubKey, dest)) {
return false;
}
- if (IsAddressUsed(dest)) {
+ if (IsAddressPreviouslySpent(dest)) {
return true;
}
if (IsLegacy()) {
@@ -998,15 +992,15 @@ bool CWallet::IsSpentKey(const CScript& scriptPubKey) const
assert(spk_man != nullptr);
for (const auto& keyid : GetAffectedKeys(scriptPubKey, *spk_man)) {
WitnessV0KeyHash wpkh_dest(keyid);
- if (IsAddressUsed(wpkh_dest)) {
+ if (IsAddressPreviouslySpent(wpkh_dest)) {
return true;
}
ScriptHash sh_wpkh_dest(GetScriptForDestination(wpkh_dest));
- if (IsAddressUsed(sh_wpkh_dest)) {
+ if (IsAddressPreviouslySpent(sh_wpkh_dest)) {
return true;
}
PKHash pkh_dest(keyid);
- if (IsAddressUsed(pkh_dest)) {
+ if (IsAddressPreviouslySpent(pkh_dest)) {
return true;
}
}
@@ -1228,7 +1222,7 @@ bool CWallet::AddToWalletIfInvolvingMe(const CTransactionRef& ptx, const SyncTxS
// (e.g. it wasn't generated on this node or we're restoring from backup)
// add it to the address book for proper transaction accounting
if (!*dest.internal && !FindAddressBookEntry(dest.dest, /* allow_change= */ false)) {
- SetAddressBook(dest.dest, "", "receive");
+ SetAddressBook(dest.dest, "", AddressPurpose::RECEIVE);
}
}
}
@@ -1776,7 +1770,7 @@ bool CWallet::ImportScriptPubKeys(const std::string& label, const std::set<CScri
CTxDestination dest;
ExtractDestination(script, dest);
if (IsValidDestination(dest)) {
- SetAddressBookWithDB(batch, dest, label, "receive");
+ SetAddressBookWithDB(batch, dest, label, AddressPurpose::RECEIVE);
}
}
}
@@ -2190,34 +2184,7 @@ TransactionError CWallet::FillPSBT(PartiallySignedTransaction& psbtx, bool& comp
}
}
- // Only drop non_witness_utxos if sighash_type != SIGHASH_ANYONECANPAY
- if ((sighash_type & 0x80) != SIGHASH_ANYONECANPAY) {
- // Figure out if any non_witness_utxos should be dropped
- std::vector<unsigned int> to_drop;
- for (unsigned int i = 0; i < psbtx.inputs.size(); ++i) {
- const auto& input = psbtx.inputs.at(i);
- int wit_ver;
- std::vector<unsigned char> wit_prog;
- if (input.witness_utxo.IsNull() || !input.witness_utxo.scriptPubKey.IsWitnessProgram(wit_ver, wit_prog)) {
- // There's a non-segwit input or Segwit v0, so we cannot drop any witness_utxos
- to_drop.clear();
- break;
- }
- if (wit_ver == 0) {
- // Segwit v0, so we cannot drop any non_witness_utxos
- to_drop.clear();
- break;
- }
- if (input.non_witness_utxo) {
- to_drop.push_back(i);
- }
- }
-
- // Drop the non_witness_utxos that we can drop
- for (unsigned int i : to_drop) {
- psbtx.inputs.at(i).non_witness_utxo = nullptr;
- }
- }
+ RemoveUnnecessaryTransactions(psbtx, sighash_type);
// Complete if every input is now signed
complete = true;
@@ -2399,56 +2366,56 @@ DBErrors CWallet::ZapSelectTx(std::vector<uint256>& vHashIn, std::vector<uint256
return DBErrors::LOAD_OK;
}
-bool CWallet::SetAddressBookWithDB(WalletBatch& batch, const CTxDestination& address, const std::string& strName, const std::string& strPurpose)
+bool CWallet::SetAddressBookWithDB(WalletBatch& batch, const CTxDestination& address, const std::string& strName, const std::optional<AddressPurpose>& new_purpose)
{
bool fUpdated = false;
bool is_mine;
+ std::optional<AddressPurpose> purpose;
{
LOCK(cs_wallet);
std::map<CTxDestination, CAddressBookData>::iterator mi = m_address_book.find(address);
fUpdated = (mi != m_address_book.end() && !mi->second.IsChange());
m_address_book[address].SetLabel(strName);
- if (!strPurpose.empty()) /* update purpose only if requested */
- m_address_book[address].purpose = strPurpose;
is_mine = IsMine(address) != ISMINE_NO;
+ if (new_purpose) { /* update purpose only if requested */
+ purpose = m_address_book[address].purpose = new_purpose;
+ } else {
+ purpose = m_address_book[address].purpose;
+ }
}
+ // In very old wallets, address purpose may not be recorded so we derive it from IsMine
NotifyAddressBookChanged(address, strName, is_mine,
- strPurpose, (fUpdated ? CT_UPDATED : CT_NEW));
- if (!strPurpose.empty() && !batch.WritePurpose(EncodeDestination(address), strPurpose))
+ purpose.value_or(is_mine ? AddressPurpose::RECEIVE : AddressPurpose::SEND),
+ (fUpdated ? CT_UPDATED : CT_NEW));
+ if (new_purpose && !batch.WritePurpose(EncodeDestination(address), PurposeToString(*new_purpose)))
return false;
return batch.WriteName(EncodeDestination(address), strName);
}
-bool CWallet::SetAddressBook(const CTxDestination& address, const std::string& strName, const std::string& strPurpose)
+bool CWallet::SetAddressBook(const CTxDestination& address, const std::string& strName, const std::optional<AddressPurpose>& purpose)
{
WalletBatch batch(GetDatabase());
- return SetAddressBookWithDB(batch, address, strName, strPurpose);
+ return SetAddressBookWithDB(batch, address, strName, purpose);
}
bool CWallet::DelAddressBook(const CTxDestination& address)
{
- bool is_mine;
WalletBatch batch(GetDatabase());
{
LOCK(cs_wallet);
- // If we want to delete receiving addresses, we need to take care that DestData "used" (and possibly newer DestData) gets preserved (and the "deleted" address transformed into a change entry instead of actually being deleted)
- // NOTE: This isn't a problem for sending addresses because they never have any DestData yet!
- // When adding new DestData, it should be considered here whether to retain or delete it (or move it?).
+ // If we want to delete receiving addresses, we should avoid calling EraseAddressData because it will delete the previously_spent value. Could instead just erase the label so it becomes a change address, and keep the data.
+ // NOTE: This isn't a problem for sending addresses because they don't have any data that needs to be kept.
+ // When adding new address data, it should be considered here whether to retain or delete it.
if (IsMine(address)) {
WalletLogPrintf("%s called with IsMine address, NOT SUPPORTED. Please report this bug! %s\n", __func__, PACKAGE_BUGREPORT);
return false;
}
- // Delete destdata tuples associated with address
- std::string strAddress = EncodeDestination(address);
- for (const std::pair<const std::string, std::string> &item : m_address_book[address].destdata)
- {
- batch.EraseDestData(strAddress, item.first);
- }
+ // Delete data rows associated with this address
+ batch.EraseAddressData(address);
m_address_book.erase(address);
- is_mine = IsMine(address) != ISMINE_NO;
}
- NotifyAddressBookChanged(address, "", is_mine, "", CT_DELETED);
+ NotifyAddressBookChanged(address, "", /*is_mine=*/false, AddressPurpose::SEND, CT_DELETED);
batch.ErasePurpose(EncodeDestination(address));
return batch.EraseName(EncodeDestination(address));
@@ -2502,7 +2469,7 @@ util::Result<CTxDestination> CWallet::GetNewDestination(const OutputType type, c
auto op_dest = spk_man->GetNewDestination(type);
if (op_dest) {
- SetAddressBook(*op_dest, label, "receive");
+ SetAddressBook(*op_dest, label, AddressPurpose::RECEIVE);
}
return op_dest;
@@ -2552,7 +2519,7 @@ void CWallet::ForEachAddrBookEntry(const ListAddrBookFunc& func) const
AssertLockHeld(cs_wallet);
for (const std::pair<const CTxDestination, CAddressBookData>& item : m_address_book) {
const auto& entry = item.second;
- func(item.first, entry.GetLabel(), entry.purpose, entry.IsChange());
+ func(item.first, entry.GetLabel(), entry.IsChange(), entry.purpose);
}
}
@@ -2561,7 +2528,7 @@ std::vector<CTxDestination> CWallet::ListAddrBookAddresses(const std::optional<A
AssertLockHeld(cs_wallet);
std::vector<CTxDestination> result;
AddrBookFilter filter = _filter ? *_filter : AddrBookFilter();
- ForEachAddrBookEntry([&result, &filter](const CTxDestination& dest, const std::string& label, const std::string& purpose, bool is_change) {
+ ForEachAddrBookEntry([&result, &filter](const CTxDestination& dest, const std::string& label, bool is_change, const std::optional<AddressPurpose>& purpose) {
// Filter by change
if (filter.ignore_change && is_change) return;
// Filter by label
@@ -2572,14 +2539,14 @@ std::vector<CTxDestination> CWallet::ListAddrBookAddresses(const std::optional<A
return result;
}
-std::set<std::string> CWallet::ListAddrBookLabels(const std::string& purpose) const
+std::set<std::string> CWallet::ListAddrBookLabels(const std::optional<AddressPurpose> purpose) const
{
AssertLockHeld(cs_wallet);
std::set<std::string> label_set;
ForEachAddrBookEntry([&](const CTxDestination& _dest, const std::string& _label,
- const std::string& _purpose, bool _is_change) {
+ bool _is_change, const std::optional<AddressPurpose>& _purpose) {
if (_is_change) return;
- if (purpose.empty() || _purpose == purpose) {
+ if (!purpose || purpose == _purpose) {
label_set.insert(_label);
}
});
@@ -2819,51 +2786,42 @@ unsigned int CWallet::ComputeTimeSmart(const CWalletTx& wtx, bool rescanning_old
return nTimeSmart;
}
-bool CWallet::SetAddressUsed(WalletBatch& batch, const CTxDestination& dest, bool used)
+bool CWallet::SetAddressPreviouslySpent(WalletBatch& batch, const CTxDestination& dest, bool used)
{
- const std::string key{"used"};
if (std::get_if<CNoDestination>(&dest))
return false;
if (!used) {
- if (auto* data = util::FindKey(m_address_book, dest)) data->destdata.erase(key);
- return batch.EraseDestData(EncodeDestination(dest), key);
+ if (auto* data{util::FindKey(m_address_book, dest)}) data->previously_spent = false;
+ return batch.WriteAddressPreviouslySpent(dest, false);
}
- const std::string value{"1"};
- m_address_book[dest].destdata.insert(std::make_pair(key, value));
- return batch.WriteDestData(EncodeDestination(dest), key, value);
+ LoadAddressPreviouslySpent(dest);
+ return batch.WriteAddressPreviouslySpent(dest, true);
}
-void CWallet::LoadDestData(const CTxDestination &dest, const std::string &key, const std::string &value)
+void CWallet::LoadAddressPreviouslySpent(const CTxDestination& dest)
{
- m_address_book[dest].destdata.insert(std::make_pair(key, value));
+ m_address_book[dest].previously_spent = true;
}
-bool CWallet::IsAddressUsed(const CTxDestination& dest) const
+void CWallet::LoadAddressReceiveRequest(const CTxDestination& dest, const std::string& id, const std::string& request)
{
- const std::string key{"used"};
- std::map<CTxDestination, CAddressBookData>::const_iterator i = m_address_book.find(dest);
- if(i != m_address_book.end())
- {
- CAddressBookData::StringMap::const_iterator j = i->second.destdata.find(key);
- if(j != i->second.destdata.end())
- {
- return true;
- }
- }
+ m_address_book[dest].receive_requests[id] = request;
+}
+
+bool CWallet::IsAddressPreviouslySpent(const CTxDestination& dest) const
+{
+ if (auto* data{util::FindKey(m_address_book, dest)}) return data->previously_spent;
return false;
}
std::vector<std::string> CWallet::GetAddressReceiveRequests() const
{
- const std::string prefix{"rr"};
std::vector<std::string> values;
- for (const auto& address : m_address_book) {
- for (const auto& data : address.second.destdata) {
- if (!data.first.compare(0, prefix.size(), prefix)) {
- values.emplace_back(data.second);
- }
+ for (const auto& [dest, entry] : m_address_book) {
+ for (const auto& [id, request] : entry.receive_requests) {
+ values.emplace_back(request);
}
}
return values;
@@ -2871,15 +2829,15 @@ std::vector<std::string> CWallet::GetAddressReceiveRequests() const
bool CWallet::SetAddressReceiveRequest(WalletBatch& batch, const CTxDestination& dest, const std::string& id, const std::string& value)
{
- const std::string key{"rr" + id}; // "rr" prefix = "receive request" in destdata
- CAddressBookData& data = m_address_book.at(dest);
- if (value.empty()) {
- if (!batch.EraseDestData(EncodeDestination(dest), key)) return false;
- data.destdata.erase(key);
- } else {
- if (!batch.WriteDestData(EncodeDestination(dest), key, value)) return false;
- data.destdata[key] = value;
- }
+ if (!batch.WriteAddressReceiveRequest(dest, id, value)) return false;
+ m_address_book[dest].receive_requests[id] = value;
+ return true;
+}
+
+bool CWallet::EraseAddressReceiveRequest(WalletBatch& batch, const CTxDestination& dest, const std::string& id)
+{
+ if (!batch.EraseAddressReceiveRequest(dest, id)) return false;
+ m_address_book[dest].receive_requests.erase(id);
return true;
}
@@ -3791,7 +3749,7 @@ ScriptPubKeyMan* CWallet::AddWalletDescriptor(WalletDescriptor& desc, const Flat
for (const auto& script : script_pub_keys) {
CTxDestination dest;
if (ExtractDestination(script, dest)) {
- SetAddressBook(dest, label, "receive");
+ SetAddressBook(dest, label, AddressPurpose::RECEIVE);
}
}
}
@@ -3977,7 +3935,7 @@ bool CWallet::ApplyMigrationData(MigrationData& data, bilingual_str& error)
std::vector<CTxDestination> dests_to_delete;
for (const auto& addr_pair : m_address_book) {
// Labels applied to receiving addresses should go based on IsMine
- if (addr_pair.second.purpose == "receive") {
+ if (addr_pair.second.purpose == AddressPurpose::RECEIVE) {
if (!IsMine(addr_pair.first)) {
// Check the address book data is the watchonly wallet's
if (data.watchonly_wallet) {
@@ -3985,10 +3943,7 @@ bool CWallet::ApplyMigrationData(MigrationData& data, bilingual_str& error)
if (data.watchonly_wallet->IsMine(addr_pair.first)) {
// Add to the watchonly. Preserve the labels, purpose, and change-ness
std::string label = addr_pair.second.GetLabel();
- std::string purpose = addr_pair.second.purpose;
- if (!purpose.empty()) {
- data.watchonly_wallet->m_address_book[addr_pair.first].purpose = purpose;
- }
+ data.watchonly_wallet->m_address_book[addr_pair.first].purpose = addr_pair.second.purpose;
if (!addr_pair.second.IsChange()) {
data.watchonly_wallet->m_address_book[addr_pair.first].SetLabel(label);
}
@@ -4001,10 +3956,7 @@ bool CWallet::ApplyMigrationData(MigrationData& data, bilingual_str& error)
if (data.solvable_wallet->IsMine(addr_pair.first)) {
// Add to the solvable. Preserve the labels, purpose, and change-ness
std::string label = addr_pair.second.GetLabel();
- std::string purpose = addr_pair.second.purpose;
- if (!purpose.empty()) {
- data.solvable_wallet->m_address_book[addr_pair.first].purpose = purpose;
- }
+ data.solvable_wallet->m_address_book[addr_pair.first].purpose = addr_pair.second.purpose;
if (!addr_pair.second.IsChange()) {
data.solvable_wallet->m_address_book[addr_pair.first].SetLabel(label);
}
@@ -4022,10 +3974,7 @@ bool CWallet::ApplyMigrationData(MigrationData& data, bilingual_str& error)
LOCK(data.watchonly_wallet->cs_wallet);
// Add to the watchonly. Preserve the labels, purpose, and change-ness
std::string label = addr_pair.second.GetLabel();
- std::string purpose = addr_pair.second.purpose;
- if (!purpose.empty()) {
- data.watchonly_wallet->m_address_book[addr_pair.first].purpose = purpose;
- }
+ data.watchonly_wallet->m_address_book[addr_pair.first].purpose = addr_pair.second.purpose;
if (!addr_pair.second.IsChange()) {
data.watchonly_wallet->m_address_book[addr_pair.first].SetLabel(label);
}
@@ -4035,10 +3984,7 @@ bool CWallet::ApplyMigrationData(MigrationData& data, bilingual_str& error)
LOCK(data.solvable_wallet->cs_wallet);
// Add to the solvable. Preserve the labels, purpose, and change-ness
std::string label = addr_pair.second.GetLabel();
- std::string purpose = addr_pair.second.purpose;
- if (!purpose.empty()) {
- data.solvable_wallet->m_address_book[addr_pair.first].purpose = purpose;
- }
+ data.solvable_wallet->m_address_book[addr_pair.first].purpose = addr_pair.second.purpose;
if (!addr_pair.second.IsChange()) {
data.solvable_wallet->m_address_book[addr_pair.first].SetLabel(label);
}
@@ -4053,10 +3999,9 @@ bool CWallet::ApplyMigrationData(MigrationData& data, bilingual_str& error)
WalletBatch batch{wallet.GetDatabase()};
for (const auto& [destination, addr_book_data] : wallet.m_address_book) {
auto address{EncodeDestination(destination)};
- auto purpose{addr_book_data.purpose};
auto label{addr_book_data.GetLabel()};
// don't bother writing default values (unknown purpose, empty label)
- if (purpose != "unknown") batch.WritePurpose(address, purpose);
+ if (addr_book_data.purpose) batch.WritePurpose(address, PurposeToString(*addr_book_data.purpose));
if (!label.empty()) batch.WriteName(address, label);
}
};
diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h
index e8c18dbb67..5252b46cdc 100644
--- a/src/wallet/wallet.h
+++ b/src/wallet/wallet.h
@@ -7,14 +7,15 @@
#define BITCOIN_WALLET_WALLET_H
#include <consensus/amount.h>
-#include <fs.h>
#include <interfaces/chain.h>
#include <interfaces/handler.h>
+#include <interfaces/wallet.h>
#include <logging.h>
#include <outputtype.h>
#include <policy/feerate.h>
#include <psbt.h>
#include <tinyformat.h>
+#include <util/fs.h>
#include <util/hasher.h>
#include <util/message.h>
#include <util/result.h>
@@ -145,8 +146,6 @@ static const std::map<std::string,WalletFlags> WALLET_FLAG_MAP{
{"external_signer", WALLET_FLAG_EXTERNAL_SIGNER}
};
-extern const std::map<uint64_t,std::string> WALLET_FLAG_CAVEATS;
-
/** A wrapper to reserve an address from a wallet
*
* ReserveDestination is used to reserve an address.
@@ -200,28 +199,69 @@ public:
void KeepDestination();
};
-/** Address book data */
-class CAddressBookData
+/**
+ * Address book data.
+ */
+struct CAddressBookData
{
-private:
- bool m_change{true};
- std::string m_label;
-public:
- std::string purpose;
+ /**
+ * Address label which is always nullopt for change addresses. For sending
+ * and receiving addresses, it will be set to an arbitrary label string
+ * provided by the user, or to "", which is the default label. The presence
+ * or absence of a label is used to distinguish change addresses from
+ * non-change addresses by wallet transaction listing and fee bumping code.
+ */
+ std::optional<std::string> label;
+
+ /**
+ * Address purpose which was originally recorded for payment protocol
+ * support but now serves as a cached IsMine value. Wallet code should
+ * not rely on this field being set.
+ */
+ std::optional<AddressPurpose> purpose;
- CAddressBookData() : purpose("unknown") {}
+ /**
+ * Whether coins with this address have previously been spent. Set when the
+ * the wallet avoid_reuse option is enabled and this is an IsMine address
+ * that has already received funds and spent them. This is used during coin
+ * selection to increase privacy by not creating different transactions
+ * that spend from the same addresses.
+ */
+ bool previously_spent{false};
- typedef std::map<std::string, std::string> StringMap;
- StringMap destdata;
+ /**
+ * Map containing data about previously generated receive requests
+ * requesting funds to be sent to this address. Only present for IsMine
+ * addresses. Map keys are decimal numbers uniquely identifying each
+ * request, and map values are serialized RecentRequestEntry objects
+ * containing BIP21 URI information including message and amount.
+ */
+ std::map<std::string, std::string> receive_requests{};
- bool IsChange() const { return m_change; }
- const std::string& GetLabel() const { return m_label; }
- void SetLabel(const std::string& label) {
- m_change = false;
- m_label = label;
- }
+ /** Accessor methods. */
+ bool IsChange() const { return !label.has_value(); }
+ std::string GetLabel() const { return label ? *label : std::string{}; }
+ void SetLabel(std::string name) { label = std::move(name); }
};
+inline std::string PurposeToString(AddressPurpose p)
+{
+ switch(p) {
+ case AddressPurpose::RECEIVE: return "receive";
+ case AddressPurpose::SEND: return "send";
+ case AddressPurpose::REFUND: return "refund";
+ } // no default case so the compiler will warn when a new enum as added
+ assert(false);
+}
+
+inline std::optional<AddressPurpose> PurposeFromString(std::string_view s)
+{
+ if (s == "receive") return AddressPurpose::RECEIVE;
+ else if (s == "send") return AddressPurpose::SEND;
+ else if (s == "refund") return AddressPurpose::REFUND;
+ return {};
+}
+
struct CRecipient
{
CScript scriptPubKey;
@@ -300,7 +340,7 @@ private:
/** WalletFlags set on this wallet. */
std::atomic<uint64_t> m_wallet_flags{0};
- bool SetAddressBookWithDB(WalletBatch& batch, const CTxDestination& address, const std::string& strName, const std::string& strPurpose);
+ bool SetAddressBookWithDB(WalletBatch& batch, const CTxDestination& address, const std::string& strName, const std::optional<AddressPurpose>& strPurpose);
//! Unsets a wallet flag and saves it to disk
void UnsetWalletFlagWithDB(WalletBatch& batch, uint64_t flag);
@@ -476,8 +516,10 @@ public:
bool LoadMinVersion(int nVersion) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet) { AssertLockHeld(cs_wallet); nWalletVersion = nVersion; return true; }
- //! Adds a destination data tuple to the store, without saving it to disk
- void LoadDestData(const CTxDestination& dest, const std::string& key, const std::string& value) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
+ //! Marks destination as previously spent.
+ void LoadAddressPreviouslySpent(const CTxDestination& dest) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
+ //! Appends payment request to destination.
+ void LoadAddressReceiveRequest(const CTxDestination& dest, const std::string& id, const std::string& request) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
//! Holds a timestamp at which point the wallet is scheduled (externally) to be relocked. Caller must arrange for actual relocking to occur via Lock().
int64_t nRelockTime GUARDED_BY(cs_wallet){0};
@@ -664,13 +706,13 @@ public:
/**
* Retrieve all the known labels in the address book
*/
- std::set<std::string> ListAddrBookLabels(const std::string& purpose) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
+ std::set<std::string> ListAddrBookLabels(const std::optional<AddressPurpose> purpose) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
/**
* Walk-through the address book entries.
* Stops when the provided 'ListAddrBookFunc' returns false.
*/
- using ListAddrBookFunc = std::function<void(const CTxDestination& dest, const std::string& label, const std::string& purpose, bool is_change)>;
+ using ListAddrBookFunc = std::function<void(const CTxDestination& dest, const std::string& label, bool is_change, const std::optional<AddressPurpose> purpose)>;
void ForEachAddrBookEntry(const ListAddrBookFunc& func) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
/**
@@ -700,15 +742,16 @@ public:
DBErrors LoadWallet();
DBErrors ZapSelectTx(std::vector<uint256>& vHashIn, std::vector<uint256>& vHashOut) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
- bool SetAddressBook(const CTxDestination& address, const std::string& strName, const std::string& purpose);
+ bool SetAddressBook(const CTxDestination& address, const std::string& strName, const std::optional<AddressPurpose>& purpose);
bool DelAddressBook(const CTxDestination& address);
- bool IsAddressUsed(const CTxDestination& dest) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
- bool SetAddressUsed(WalletBatch& batch, const CTxDestination& dest, bool used) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
+ bool IsAddressPreviouslySpent(const CTxDestination& dest) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
+ bool SetAddressPreviouslySpent(WalletBatch& batch, const CTxDestination& dest, bool used) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
std::vector<std::string> GetAddressReceiveRequests() const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
bool SetAddressReceiveRequest(WalletBatch& batch, const CTxDestination& dest, const std::string& id, const std::string& value) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
+ bool EraseAddressReceiveRequest(WalletBatch& batch, const CTxDestination& dest, const std::string& id) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
unsigned int GetKeyPoolSize() const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
@@ -739,7 +782,7 @@ public:
*/
boost::signals2::signal<void(const CTxDestination& address,
const std::string& label, bool isMine,
- const std::string& purpose, ChangeType status)>
+ AddressPurpose purpose, ChangeType status)>
NotifyAddressBookChanged;
/**
diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp
index 2cd35ae40e..005592d720 100644
--- a/src/wallet/walletdb.cpp
+++ b/src/wallet/walletdb.cpp
@@ -5,12 +5,12 @@
#include <wallet/walletdb.h>
-#include <fs.h>
#include <key_io.h>
#include <protocol.h>
#include <serialize.h>
#include <sync.h>
#include <util/bip32.h>
+#include <util/fs.h>
#include <util/system.h>
#include <util/time.h>
#include <util/translation.h>
@@ -347,7 +347,13 @@ ReadKeyValue(CWallet* pwallet, DataStream& ssKey, CDataStream& ssValue,
} else if (strType == DBKeys::PURPOSE) {
std::string strAddress;
ssKey >> strAddress;
- ssValue >> pwallet->m_address_book[DecodeDestination(strAddress)].purpose;
+ std::string purpose_str;
+ ssValue >> purpose_str;
+ std::optional<AddressPurpose> purpose{PurposeFromString(purpose_str)};
+ if (!purpose) {
+ pwallet->WalletLogPrintf("Warning: nonstandard purpose string '%s' for address '%s'\n", purpose_str, strAddress);
+ }
+ pwallet->m_address_book[DecodeDestination(strAddress)].purpose = purpose;
} else if (strType == DBKeys::TX) {
uint256 hash;
ssKey >> hash;
@@ -609,7 +615,20 @@ ReadKeyValue(CWallet* pwallet, DataStream& ssKey, CDataStream& ssValue,
ssKey >> strAddress;
ssKey >> strKey;
ssValue >> strValue;
- pwallet->LoadDestData(DecodeDestination(strAddress), strKey, strValue);
+ const CTxDestination& dest{DecodeDestination(strAddress)};
+ if (strKey.compare("used") == 0) {
+ // Load "used" key indicating if an IsMine address has
+ // previously been spent from with avoid_reuse option enabled.
+ // The strValue is not used for anything currently, but could
+ // hold more information in the future. Current values are just
+ // "1" or "p" for present (which was written prior to
+ // f5ba424cd44619d9b9be88b8593d69a7ba96db26).
+ pwallet->LoadAddressPreviouslySpent(dest);
+ } else if (strKey.compare(0, 2, "rr") == 0) {
+ // Load "rr##" keys where ## is a decimal number, and strValue
+ // is a serialized RecentRequestEntry object.
+ pwallet->LoadAddressReceiveRequest(dest, strKey.substr(2), strValue);
+ }
} else if (strType == DBKeys::HDCHAIN) {
CHDChain chain;
ssValue >> chain;
@@ -1082,16 +1101,28 @@ void MaybeCompactWalletDB(WalletContext& context)
fOneThread = false;
}
-bool WalletBatch::WriteDestData(const std::string &address, const std::string &key, const std::string &value)
+bool WalletBatch::WriteAddressPreviouslySpent(const CTxDestination& dest, bool previously_spent)
{
- return WriteIC(std::make_pair(DBKeys::DESTDATA, std::make_pair(address, key)), value);
+ auto key{std::make_pair(DBKeys::DESTDATA, std::make_pair(EncodeDestination(dest), std::string("used")))};
+ return previously_spent ? WriteIC(key, std::string("1")) : EraseIC(key);
}
-bool WalletBatch::EraseDestData(const std::string &address, const std::string &key)
+bool WalletBatch::WriteAddressReceiveRequest(const CTxDestination& dest, const std::string& id, const std::string& receive_request)
{
- return EraseIC(std::make_pair(DBKeys::DESTDATA, std::make_pair(address, key)));
+ return WriteIC(std::make_pair(DBKeys::DESTDATA, std::make_pair(EncodeDestination(dest), "rr" + id)), receive_request);
}
+bool WalletBatch::EraseAddressReceiveRequest(const CTxDestination& dest, const std::string& id)
+{
+ return EraseIC(std::make_pair(DBKeys::DESTDATA, std::make_pair(EncodeDestination(dest), "rr" + id)));
+}
+
+bool WalletBatch::EraseAddressData(const CTxDestination& dest)
+{
+ DataStream prefix;
+ prefix << DBKeys::DESTDATA << EncodeDestination(dest);
+ return m_batch->ErasePrefix(prefix);
+}
bool WalletBatch::WriteHDChain(const CHDChain& chain)
{
diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h
index c97356a71f..72086e950a 100644
--- a/src/wallet/walletdb.h
+++ b/src/wallet/walletdb.h
@@ -7,6 +7,7 @@
#define BITCOIN_WALLET_WALLETDB_H
#include <script/sign.h>
+#include <script/standard.h>
#include <wallet/db.h>
#include <wallet/walletutil.h>
#include <key.h>
@@ -264,10 +265,10 @@ public:
bool WriteLockedUTXO(const COutPoint& output);
bool EraseLockedUTXO(const COutPoint& output);
- /// Write destination data key,value tuple to database
- bool WriteDestData(const std::string &address, const std::string &key, const std::string &value);
- /// Erase destination data tuple from wallet database
- bool EraseDestData(const std::string &address, const std::string &key);
+ bool WriteAddressPreviouslySpent(const CTxDestination& dest, bool previously_spent);
+ bool WriteAddressReceiveRequest(const CTxDestination& dest, const std::string& id, const std::string& receive_request);
+ bool EraseAddressReceiveRequest(const CTxDestination& dest, const std::string& id);
+ bool EraseAddressData(const CTxDestination& dest);
bool WriteActiveScriptPubKeyMan(uint8_t type, const uint256& id, bool internal);
bool EraseActiveScriptPubKeyMan(uint8_t type, bool internal);
diff --git a/src/wallet/wallettool.cpp b/src/wallet/wallettool.cpp
index f389676204..2f3f8ef77d 100644
--- a/src/wallet/wallettool.cpp
+++ b/src/wallet/wallettool.cpp
@@ -8,8 +8,8 @@
#include <wallet/wallettool.h>
-#include <fs.h>
-#include <util/system.h>
+#include <common/args.h>
+#include <util/fs.h>
#include <util/translation.h>
#include <wallet/dump.h>
#include <wallet/salvage.h>
diff --git a/src/wallet/walletutil.cpp b/src/wallet/walletutil.cpp
index 299c74d01c..fdd5bc36d8 100644
--- a/src/wallet/walletutil.cpp
+++ b/src/wallet/walletutil.cpp
@@ -4,8 +4,8 @@
#include <wallet/walletutil.h>
+#include <common/args.h>
#include <logging.h>
-#include <util/system.h>
namespace wallet {
fs::path GetWalletDir()
diff --git a/src/wallet/walletutil.h b/src/wallet/walletutil.h
index 8434d64fb5..f639078de5 100644
--- a/src/wallet/walletutil.h
+++ b/src/wallet/walletutil.h
@@ -5,8 +5,8 @@
#ifndef BITCOIN_WALLET_WALLETUTIL_H
#define BITCOIN_WALLET_WALLETUTIL_H
-#include <fs.h>
#include <script/descriptor.h>
+#include <util/fs.h>
#include <vector>
diff --git a/src/zmq/zmqnotificationinterface.cpp b/src/zmq/zmqnotificationinterface.cpp
index df129c0830..9920d80a69 100644
--- a/src/zmq/zmqnotificationinterface.cpp
+++ b/src/zmq/zmqnotificationinterface.cpp
@@ -4,10 +4,10 @@
#include <zmq/zmqnotificationinterface.h>
+#include <common/args.h>
#include <logging.h>
#include <primitives/block.h>
#include <primitives/transaction.h>
-#include <util/system.h>
#include <validationinterface.h>
#include <zmq/zmqabstractnotifier.h>
#include <zmq/zmqpublishnotifier.h>
diff --git a/src/zmq/zmqpublishnotifier.cpp b/src/zmq/zmqpublishnotifier.cpp
index 6418455d19..55f3d4e934 100644
--- a/src/zmq/zmqpublishnotifier.cpp
+++ b/src/zmq/zmqpublishnotifier.cpp
@@ -96,7 +96,7 @@ static bool IsZMQAddressIPV6(const std::string &zmq_address)
{
const std::string tcp_prefix = "tcp://";
const size_t tcp_index = zmq_address.rfind(tcp_prefix);
- const size_t colon_index = zmq_address.rfind(":");
+ const size_t colon_index = zmq_address.rfind(':');
if (tcp_index == 0 && colon_index != std::string::npos) {
const std::string ip = zmq_address.substr(tcp_prefix.length(), colon_index - tcp_prefix.length());
CNetAddr addr;
diff --git a/test/functional/feature_anchors.py b/test/functional/feature_anchors.py
index 713c0826d3..468ad1eafa 100755
--- a/test/functional/feature_anchors.py
+++ b/test/functional/feature_anchors.py
@@ -63,17 +63,25 @@ class AnchorsTest(BitcoinTestFramework):
self.log.info("Check the addresses in anchors.dat")
with open(node_anchors_path, "rb") as file_handler:
- anchors = file_handler.read().hex()
+ anchors = file_handler.read()
+ anchors_hex = anchors.hex()
for port in block_relay_nodes_port:
ip_port = ip + port
- assert ip_port in anchors
+ assert ip_port in anchors_hex
for port in inbound_nodes_port:
ip_port = ip + port
- assert ip_port not in anchors
+ assert ip_port not in anchors_hex
- self.log.info("Start node")
- self.start_node(0)
+ self.log.info("Perturb anchors.dat to test it doesn't throw an error during initialization")
+ with self.nodes[0].assert_debug_log(["0 block-relay-only anchors will be tried for connections."]):
+ with open(node_anchors_path, "wb") as out_file_handler:
+ tweaked_contents = bytearray(anchors)
+ tweaked_contents[20:20] = b'1'
+ out_file_handler.write(bytes(tweaked_contents))
+
+ self.log.info("Start node")
+ self.start_node(0)
self.log.info("When node starts, check if anchors.dat doesn't exist anymore")
assert not os.path.exists(node_anchors_path)
diff --git a/test/functional/feature_dbcrash.py b/test/functional/feature_dbcrash.py
index 1f2e0936ed..3f94bbc9d1 100755
--- a/test/functional/feature_dbcrash.py
+++ b/test/functional/feature_dbcrash.py
@@ -51,9 +51,11 @@ class ChainstateWriteCrashTest(BitcoinTestFramework):
self.supports_cli = False
# Set -maxmempool=0 to turn off mempool memory sharing with dbcache
- # Set -rpcservertimeout=900 to reduce socket disconnects in this
- # long-running test
- self.base_args = ["-limitdescendantsize=0", "-maxmempool=0", "-rpcservertimeout=900", "-dbbatchsize=200000"]
+ self.base_args = [
+ "-limitdescendantsize=0",
+ "-maxmempool=0",
+ "-dbbatchsize=200000",
+ ]
# Set different crash ratios and cache sizes. Note that not all of
# -dbcache goes to the in-memory coins cache.
diff --git a/test/functional/feature_fastprune.py b/test/functional/feature_fastprune.py
new file mode 100755
index 0000000000..c913c4f93a
--- /dev/null
+++ b/test/functional/feature_fastprune.py
@@ -0,0 +1,29 @@
+#!/usr/bin/env python3
+# Copyright (c) 2023 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 fastprune mode."""
+from test_framework.test_framework import BitcoinTestFramework
+from test_framework.util import (
+ assert_equal
+)
+from test_framework.wallet import MiniWallet
+
+
+class FeatureFastpruneTest(BitcoinTestFramework):
+ def set_test_params(self):
+ self.num_nodes = 1
+ self.extra_args = [["-fastprune"]]
+
+ def run_test(self):
+ self.log.info("ensure that large blocks don't crash or freeze in -fastprune")
+ wallet = MiniWallet(self.nodes[0])
+ tx = wallet.create_self_transfer()['tx']
+ annex = b"\x50" + b"\xff" * 0x10000
+ tx.wit.vtxinwit[0].scriptWitness.stack.append(annex)
+ self.generateblock(self.nodes[0], output="raw(55)", transactions=[tx.serialize().hex()])
+ assert_equal(self.nodes[0].getblockcount(), 201)
+
+
+if __name__ == '__main__':
+ FeatureFastpruneTest().main()
diff --git a/test/functional/feature_nulldummy.py b/test/functional/feature_nulldummy.py
index d7558c830e..c95657dbbb 100755
--- a/test/functional/feature_nulldummy.py
+++ b/test/functional/feature_nulldummy.py
@@ -14,6 +14,7 @@ Generate COINBASE_MATURITY (CB) more blocks to ensure the coinbases are mature.
"""
import time
+from test_framework.address import address_to_scriptpubkey
from test_framework.blocktools import (
COINBASE_MATURITY,
NORMAL_GBT_REQUEST_PARAMS,
@@ -77,7 +78,7 @@ class NULLDUMMYTest(BitcoinTestFramework):
cms = self.nodes[0].createmultisig(1, [self.pubkey])
wms = self.nodes[0].createmultisig(1, [self.pubkey], 'p2sh-segwit')
self.ms_address = cms["address"]
- ms_unlock_details = {"scriptPubKey": self.nodes[0].validateaddress(self.ms_address)["scriptPubKey"],
+ ms_unlock_details = {"scriptPubKey": address_to_scriptpubkey(self.ms_address).hex(),
"redeemScript": cms["redeemScript"]}
self.wit_ms_address = wms['address']
diff --git a/test/functional/feature_pruning.py b/test/functional/feature_pruning.py
index 519877ac5b..b0c6138bcf 100755
--- a/test/functional/feature_pruning.py
+++ b/test/functional/feature_pruning.py
@@ -135,6 +135,10 @@ class PruneTest(BitcoinTestFramework):
extra_args=['-prune=550', '-reindex-chainstate'],
)
+ def test_rescan_blockchain(self):
+ self.restart_node(0, ["-prune=550"])
+ assert_raises_rpc_error(-1, "Can't rescan beyond pruned data. Use RPC call getblockchaininfo to determine your pruned height.", self.nodes[0].rescanblockchain)
+
def test_height_min(self):
assert os.path.isfile(os.path.join(self.prunedir, "blk00000.dat")), "blk00000.dat is missing, pruning too early"
self.log.info("Success")
@@ -469,6 +473,9 @@ class PruneTest(BitcoinTestFramework):
self.log.info("Test wallet re-scan")
self.wallet_test()
+ self.log.info("Test it's not possible to rescan beyond pruned data")
+ self.test_rescan_blockchain()
+
self.log.info("Test invalid pruning command line options")
self.test_invalid_command_line_options()
diff --git a/test/functional/feature_taproot.py b/test/functional/feature_taproot.py
index 8ac06f570d..8be2040d91 100755
--- a/test/functional/feature_taproot.py
+++ b/test/functional/feature_taproot.py
@@ -19,6 +19,7 @@ from test_framework.messages import (
CTxInWitness,
CTxOut,
SEQUENCE_FINAL,
+ tx_from_hex,
)
from test_framework.script import (
ANNEX_TAG,
@@ -109,7 +110,6 @@ from test_framework.address import (
program_to_witness,
)
from collections import OrderedDict, namedtuple
-from io import BytesIO
import json
import hashlib
import os
@@ -1386,8 +1386,7 @@ class TaprootTest(BitcoinTestFramework):
# Add change
fund_tx.vout.append(CTxOut(balance - 10000, random.choice(host_spks)))
# Ask the wallet to sign
- ss = BytesIO(bytes.fromhex(node.signrawtransactionwithwallet(fund_tx.serialize().hex())["hex"]))
- fund_tx.deserialize(ss)
+ fund_tx = tx_from_hex(node.signrawtransactionwithwallet(fund_tx.serialize().hex())["hex"])
# Construct UTXOData entries
fund_tx.rehash()
for i in range(count_this_tx):
diff --git a/test/functional/interface_rest.py b/test/functional/interface_rest.py
index aafee7e87c..5017f77d18 100755
--- a/test/functional/interface_rest.py
+++ b/test/functional/interface_rest.py
@@ -7,9 +7,7 @@
from decimal import Decimal
from enum import Enum
import http.client
-from io import BytesIO
import json
-from struct import pack, unpack
import typing
import urllib.parse
@@ -160,12 +158,11 @@ class RESTTest (BitcoinTestFramework):
bin_request = b'\x01\x02'
for txid, n in [spending, spent]:
bin_request += bytes.fromhex(txid)
- bin_request += pack("i", n)
+ bin_request += n.to_bytes(4, 'little')
bin_response = self.test_rest_request("/getutxos", http_method='POST', req_type=ReqType.BIN, body=bin_request, ret_type=RetType.BYTES)
- output = BytesIO(bin_response)
- chain_height, = unpack("<i", output.read(4))
- response_hash = output.read(32)[::-1].hex()
+ chain_height = int.from_bytes(bin_response[0:4], 'little')
+ response_hash = bin_response[4:36][::-1].hex()
assert_equal(bb_hash, response_hash) # check if getutxo's chaintip during calculation was fine
assert_equal(chain_height, 201) # chain height must be 201 (pre-mined chain [200] + generated block [1])
@@ -280,6 +277,11 @@ class RESTTest (BitcoinTestFramework):
assert_equal(len(json_obj), 1) # ensure that there is one header in the json response
assert_equal(json_obj[0]['hash'], bb_hash) # request/response hash should be the same
+ # Check invalid uri (% symbol at the end of the request)
+ for invalid_uri in [f"/headers/{bb_hash}%", f"/blockfilterheaders/basic/{bb_hash}%", "/mempool/contents.json?%"]:
+ resp = self.test_rest_request(invalid_uri, ret_type=RetType.OBJ, status=400)
+ assert_equal(resp.read().decode('utf-8').rstrip(), "URI parsing failed, it likely contained RFC 3986 invalid characters")
+
# Compare with normal RPC block response
rpc_block_json = self.nodes[0].getblock(bb_hash)
for key in ['hash', 'confirmations', 'height', 'version', 'merkleroot', 'time', 'nonce', 'bits', 'difficulty', 'chainwork', 'previousblockhash']:
diff --git a/test/functional/interface_zmq.py b/test/functional/interface_zmq.py
index 2f41f9aa53..2358dd4387 100755
--- a/test/functional/interface_zmq.py
+++ b/test/functional/interface_zmq.py
@@ -4,6 +4,7 @@
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Test the ZMQ notification interface."""
import struct
+from time import sleep
from test_framework.address import (
ADDRESS_BCRT1_P2WSH_OP_TRUE,
@@ -16,8 +17,8 @@ from test_framework.blocktools import (
)
from test_framework.test_framework import BitcoinTestFramework
from test_framework.messages import (
- CTransaction,
hash256,
+ tx_from_hex,
)
from test_framework.util import (
assert_equal,
@@ -28,8 +29,7 @@ from test_framework.wallet import (
MiniWallet,
)
from test_framework.netutil import test_ipv6_local
-from io import BytesIO
-from time import sleep
+
# Test may be skipped and not have zmq installed
try:
@@ -198,9 +198,7 @@ class ZMQTest (BitcoinTestFramework):
txid = hashtx.receive()
# Should receive the coinbase raw transaction.
- hex = rawtx.receive()
- tx = CTransaction()
- tx.deserialize(BytesIO(hex))
+ tx = tx_from_hex(rawtx.receive().hex())
tx.calc_sha256()
assert_equal(tx.hash, txid.hex())
diff --git a/test/functional/mempool_limit.py b/test/functional/mempool_limit.py
index d38a37f952..f3f4b42ad0 100755
--- a/test/functional/mempool_limit.py
+++ b/test/functional/mempool_limit.py
@@ -7,15 +7,21 @@
from decimal import Decimal
from test_framework.blocktools import COINBASE_MATURITY
+from test_framework.p2p import P2PTxInvStore
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import (
assert_equal,
+ assert_fee_amount,
assert_greater_than,
assert_raises_rpc_error,
create_lots_of_big_transactions,
gen_return_txouts,
)
-from test_framework.wallet import MiniWallet
+from test_framework.wallet import (
+ COIN,
+ DEFAULT_FEE,
+ MiniWallet,
+)
class MempoolLimitTest(BitcoinTestFramework):
@@ -38,13 +44,14 @@ class MempoolLimitTest(BitcoinTestFramework):
assert_equal(node.getmempoolinfo()['minrelaytxfee'], Decimal('0.00001000'))
assert_equal(node.getmempoolinfo()['mempoolminfee'], Decimal('0.00001000'))
- tx_batch_size = 25
- num_of_batches = 3
+ tx_batch_size = 1
+ num_of_batches = 75
# Generate UTXOs to flood the mempool
# 1 to create a tx initially that will be evicted from the mempool later
# 3 batches of multiple transactions with a fee rate much higher than the previous UTXO
# And 1 more to verify that this tx does not get added to the mempool with a fee rate less than the mempoolminfee
- self.generate(miniwallet, 1 + (num_of_batches * tx_batch_size) + 1)
+ # And 2 more for the package cpfp test
+ self.generate(miniwallet, 1 + (num_of_batches * tx_batch_size) + 1 + 2)
# Mine 99 blocks so that the UTXOs are allowed to be spent
self.generate(node, COINBASE_MATURITY - 1)
@@ -76,6 +83,68 @@ class MempoolLimitTest(BitcoinTestFramework):
self.log.info('Create a mempool tx that will not pass mempoolminfee')
assert_raises_rpc_error(-26, "mempool min fee not met", miniwallet.send_self_transfer, from_node=node, fee_rate=relayfee)
+ self.log.info("Check that submitpackage allows cpfp of a parent below mempool min feerate")
+ node = self.nodes[0]
+ peer = node.add_p2p_connection(P2PTxInvStore())
+
+ # Package with 2 parents and 1 child. One parent has a high feerate due to modified fees,
+ # another is below the mempool minimum feerate but bumped by the child.
+ tx_poor = miniwallet.create_self_transfer(fee_rate=relayfee)
+ tx_rich = miniwallet.create_self_transfer(fee=0, fee_rate=0)
+ node.prioritisetransaction(tx_rich["txid"], 0, int(DEFAULT_FEE * COIN))
+ package_txns = [tx_rich, tx_poor]
+ coins = [tx["new_utxo"] for tx in package_txns]
+ tx_child = miniwallet.create_self_transfer_multi(utxos_to_spend=coins, fee_per_output=10000) #DEFAULT_FEE
+ package_txns.append(tx_child)
+
+ submitpackage_result = node.submitpackage([tx["hex"] for tx in package_txns])
+
+ rich_parent_result = submitpackage_result["tx-results"][tx_rich["wtxid"]]
+ poor_parent_result = submitpackage_result["tx-results"][tx_poor["wtxid"]]
+ child_result = submitpackage_result["tx-results"][tx_child["tx"].getwtxid()]
+ assert_fee_amount(poor_parent_result["fees"]["base"], tx_poor["tx"].get_vsize(), relayfee)
+ assert_equal(rich_parent_result["fees"]["base"], 0)
+ assert_equal(child_result["fees"]["base"], DEFAULT_FEE)
+ # The "rich" parent does not require CPFP so its effective feerate is just its individual feerate.
+ assert_fee_amount(DEFAULT_FEE, tx_rich["tx"].get_vsize(), rich_parent_result["fees"]["effective-feerate"])
+ assert_equal(rich_parent_result["fees"]["effective-includes"], [tx_rich["wtxid"]])
+ # The "poor" parent and child's effective feerates are the same, composed of their total
+ # fees divided by their combined vsize.
+ package_fees = poor_parent_result["fees"]["base"] + child_result["fees"]["base"]
+ package_vsize = tx_poor["tx"].get_vsize() + tx_child["tx"].get_vsize()
+ assert_fee_amount(package_fees, package_vsize, poor_parent_result["fees"]["effective-feerate"])
+ assert_fee_amount(package_fees, package_vsize, child_result["fees"]["effective-feerate"])
+ assert_equal([tx_poor["wtxid"], tx_child["tx"].getwtxid()], poor_parent_result["fees"]["effective-includes"])
+ assert_equal([tx_poor["wtxid"], tx_child["tx"].getwtxid()], child_result["fees"]["effective-includes"])
+
+ # The node will broadcast each transaction, still abiding by its peer's fee filter
+ peer.wait_for_broadcast([tx["tx"].getwtxid() for tx in package_txns])
+
+ self.log.info("Check a package that passes mempoolminfee but is evicted immediately after submission")
+ mempoolmin_feerate = node.getmempoolinfo()["mempoolminfee"]
+ current_mempool = node.getrawmempool(verbose=False)
+ worst_feerate_btcvb = Decimal("21000000")
+ for txid in current_mempool:
+ entry = node.getmempoolentry(txid)
+ worst_feerate_btcvb = min(worst_feerate_btcvb, entry["fees"]["descendant"] / entry["descendantsize"])
+ # Needs to be large enough to trigger eviction
+ target_weight_each = 200000
+ assert_greater_than(target_weight_each * 2, node.getmempoolinfo()["maxmempool"] - node.getmempoolinfo()["bytes"])
+ # Should be a true CPFP: parent's feerate is just below mempool min feerate
+ parent_fee = (mempoolmin_feerate / 1000) * (target_weight_each // 4) - Decimal("0.00001")
+ # Parent + child is above mempool minimum feerate
+ child_fee = (worst_feerate_btcvb) * (target_weight_each // 4) - Decimal("0.00001")
+ # However, when eviction is triggered, these transactions should be at the bottom.
+ # This assertion assumes parent and child are the same size.
+ miniwallet.rescan_utxos()
+ tx_parent_just_below = miniwallet.create_self_transfer(fee=parent_fee, target_weight=target_weight_each)
+ tx_child_just_above = miniwallet.create_self_transfer(utxo_to_spend=tx_parent_just_below["new_utxo"], fee=child_fee, target_weight=target_weight_each)
+ # This package ranks below the lowest descendant package in the mempool
+ assert_greater_than(worst_feerate_btcvb, (parent_fee + child_fee) / (tx_parent_just_below["tx"].get_vsize() + tx_child_just_above["tx"].get_vsize()))
+ assert_greater_than(mempoolmin_feerate, (parent_fee) / (tx_parent_just_below["tx"].get_vsize()))
+ assert_greater_than((parent_fee + child_fee) / (tx_parent_just_below["tx"].get_vsize() + tx_child_just_above["tx"].get_vsize()), mempoolmin_feerate / 1000)
+ assert_raises_rpc_error(-26, "mempool full", node.submitpackage, [tx_parent_just_below["hex"], tx_child_just_above["hex"]])
+
self.log.info('Test passing a value below the minimum (5 MB) to -maxmempool throws an error')
self.stop_node(0)
self.nodes[0].assert_start_raises_init_error(["-maxmempool=4"], "Error: -maxmempool must be at least 5 MB")
diff --git a/test/functional/mempool_package_limits.py b/test/functional/mempool_package_limits.py
index 63f5a3e3d3..6143ae83de 100755
--- a/test/functional/mempool_package_limits.py
+++ b/test/functional/mempool_package_limits.py
@@ -3,20 +3,41 @@
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Test logic for limiting mempool and package ancestors/descendants."""
-
-from decimal import Decimal
-
from test_framework.blocktools import COINBASE_MATURITY
-from test_framework.test_framework import BitcoinTestFramework
from test_framework.messages import (
- COIN,
WITNESS_SCALE_FACTOR,
)
+from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import (
assert_equal,
)
from test_framework.wallet import MiniWallet
+# Decorator to
+# 1) check that mempool is empty at the start of a subtest
+# 2) run the subtest, which may submit some transaction(s) to the mempool and
+# create a list of hex transactions
+# 3) testmempoolaccept the package hex and check that it fails with the error
+# "package-mempool-limits" for each tx
+# 4) after mining a block, clearing the pre-submitted transactions from mempool,
+# check that submitting the created package succeeds
+def check_package_limits(func):
+ def func_wrapper(self, *args, **kwargs):
+ node = self.nodes[0]
+ assert_equal(0, node.getmempoolinfo()["size"])
+ package_hex = func(self, *args, **kwargs)
+ testres_error_expected = node.testmempoolaccept(rawtxs=package_hex)
+ assert_equal(len(testres_error_expected), len(package_hex))
+ for txres in testres_error_expected:
+ assert_equal(txres["package-error"], "package-mempool-limits")
+
+ # Clear mempool and check that the package passes now
+ self.generate(node, 1)
+ assert all([res["allowed"] for res in node.testmempoolaccept(rawtxs=package_hex)])
+
+ return func_wrapper
+
+
class MempoolPackageLimitsTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 1
@@ -40,9 +61,9 @@ class MempoolPackageLimitsTest(BitcoinTestFramework):
self.test_anc_size_limits()
self.test_desc_size_limits()
+ @check_package_limits
def test_chain_limits_helper(self, mempool_count, package_count):
node = self.nodes[0]
- assert_equal(0, node.getmempoolinfo()["size"])
chain_hex = []
chaintip_utxo = self.wallet.send_self_transfer_chain(from_node=node, chain_length=mempool_count)[-1]["new_utxo"]
@@ -51,13 +72,7 @@ class MempoolPackageLimitsTest(BitcoinTestFramework):
tx = self.wallet.create_self_transfer(utxo_to_spend=chaintip_utxo)
chaintip_utxo = tx["new_utxo"]
chain_hex.append(tx["hex"])
- testres_too_long = node.testmempoolaccept(rawtxs=chain_hex)
- for txres in testres_too_long:
- assert_equal(txres["package-error"], "package-mempool-limits")
-
- # Clear mempool and check that the package passes now
- self.generate(node, 1)
- assert all([res["allowed"] for res in node.testmempoolaccept(rawtxs=chain_hex)])
+ return chain_hex
def test_chain_limits(self):
"""Create chains from mempool and package transactions that are longer than 25,
@@ -76,6 +91,7 @@ class MempoolPackageLimitsTest(BitcoinTestFramework):
# 13 transactions in the mempool and 13 in the package.
self.test_chain_limits_helper(13, 13)
+ @check_package_limits
def test_desc_count_limits(self):
"""Create an 'A' shaped package with 24 transactions in the mempool and 2 in the package:
M1
@@ -93,7 +109,6 @@ class MempoolPackageLimitsTest(BitcoinTestFramework):
package transactions).
"""
node = self.nodes[0]
- assert_equal(0, node.getmempoolinfo()["size"])
self.log.info("Check that in-mempool and in-package descendants are calculated properly in packages")
# Top parent in mempool, M1
m1_utxos = self.wallet.send_self_transfer_multi(from_node=node, num_outputs=2)['new_utxos']
@@ -113,14 +128,9 @@ class MempoolPackageLimitsTest(BitcoinTestFramework):
assert_equal(24, node.getmempoolinfo()["size"])
assert_equal(2, len(package_hex))
- testres_too_long = node.testmempoolaccept(rawtxs=package_hex)
- for txres in testres_too_long:
- assert_equal(txres["package-error"], "package-mempool-limits")
-
- # Clear mempool and check that the package passes now
- self.generate(node, 1)
- assert all([res["allowed"] for res in node.testmempoolaccept(rawtxs=package_hex)])
+ return package_hex
+ @check_package_limits
def test_desc_count_limits_2(self):
"""Create a Package with 24 transaction in mempool and 2 transaction in package:
M1
@@ -157,15 +167,9 @@ class MempoolPackageLimitsTest(BitcoinTestFramework):
assert_equal(24, node.getmempoolinfo()["size"])
assert_equal(2, len(package_hex))
- testres = node.testmempoolaccept(rawtxs=package_hex)
- assert_equal(len(testres), len(package_hex))
- for txres in testres:
- assert_equal(txres["package-error"], "package-mempool-limits")
-
- # Clear mempool and check that the package passes now
- self.generate(node, 1)
- assert all([res["allowed"] for res in node.testmempoolaccept(rawtxs=package_hex)])
+ return package_hex
+ @check_package_limits
def test_anc_count_limits(self):
"""Create a 'V' shaped chain with 24 transactions in the mempool and 3 in the package:
M1a M1b
@@ -183,7 +187,6 @@ class MempoolPackageLimitsTest(BitcoinTestFramework):
and in-package ancestors are all considered together.
"""
node = self.nodes[0]
- assert_equal(0, node.getmempoolinfo()["size"])
package_hex = []
pc_parent_utxos = []
@@ -203,14 +206,9 @@ class MempoolPackageLimitsTest(BitcoinTestFramework):
assert_equal(24, node.getmempoolinfo()["size"])
assert_equal(3, len(package_hex))
- testres_too_long = node.testmempoolaccept(rawtxs=package_hex)
- for txres in testres_too_long:
- assert_equal(txres["package-error"], "package-mempool-limits")
-
- # Clear mempool and check that the package passes now
- self.generate(node, 1)
- assert all([res["allowed"] for res in node.testmempoolaccept(rawtxs=package_hex)])
+ return package_hex
+ @check_package_limits
def test_anc_count_limits_2(self):
"""Create a 'Y' shaped chain with 24 transactions in the mempool and 2 in the package:
M1a M1b
@@ -228,7 +226,6 @@ class MempoolPackageLimitsTest(BitcoinTestFramework):
and in-package ancestors are all considered together.
"""
node = self.nodes[0]
- assert_equal(0, node.getmempoolinfo()["size"])
pc_parent_utxos = []
self.log.info("Check that in-mempool and in-package ancestors are calculated properly in packages")
@@ -245,14 +242,9 @@ class MempoolPackageLimitsTest(BitcoinTestFramework):
pd_tx = self.wallet.create_self_transfer(utxo_to_spend=pc_tx["new_utxos"][0])
assert_equal(24, node.getmempoolinfo()["size"])
- testres_too_long = node.testmempoolaccept(rawtxs=[pc_tx["hex"], pd_tx["hex"]])
- for txres in testres_too_long:
- assert_equal(txres["package-error"], "package-mempool-limits")
-
- # Clear mempool and check that the package passes now
- self.generate(node, 1)
- assert all([res["allowed"] for res in node.testmempoolaccept(rawtxs=[pc_tx["hex"], pd_tx["hex"]])])
+ return [pc_tx["hex"], pd_tx["hex"]]
+ @check_package_limits
def test_anc_count_limits_bushy(self):
"""Create a tree with 20 transactions in the mempool and 6 in the package:
M1...M4 M5...M8 M9...M12 M13...M16 M17...M20
@@ -265,7 +257,6 @@ class MempoolPackageLimitsTest(BitcoinTestFramework):
combined, PC has 25 in-mempool and in-package parents.
"""
node = self.nodes[0]
- assert_equal(0, node.getmempoolinfo()["size"])
package_hex = []
pc_parent_utxos = []
for _ in range(5): # Make package transactions P0 ... P4
@@ -282,14 +273,9 @@ class MempoolPackageLimitsTest(BitcoinTestFramework):
assert_equal(20, node.getmempoolinfo()["size"])
assert_equal(6, len(package_hex))
- testres = node.testmempoolaccept(rawtxs=package_hex)
- for txres in testres:
- assert_equal(txres["package-error"], "package-mempool-limits")
-
- # Clear mempool and check that the package passes now
- self.generate(node, 1)
- assert all([res["allowed"] for res in node.testmempoolaccept(rawtxs=package_hex)])
+ return package_hex
+ @check_package_limits
def test_anc_size_limits(self):
"""Test Case with 2 independent transactions in the mempool and a parent + child in the
package, where the package parent is the child of both mempool transactions (30KvB each):
@@ -302,10 +288,10 @@ class MempoolPackageLimitsTest(BitcoinTestFramework):
and in-package ancestors are all considered together.
"""
node = self.nodes[0]
- assert_equal(0, node.getmempoolinfo()["size"])
parent_utxos = []
- target_weight = WITNESS_SCALE_FACTOR * 1000 * 30 # 30KvB
- high_fee = Decimal("0.003") # 10 sats/vB
+ target_vsize = 30_000
+ high_fee = 10 * target_vsize # 10 sats/vB
+ target_weight = target_vsize * WITNESS_SCALE_FACTOR
self.log.info("Check that in-mempool and in-package ancestor size limits are calculated properly in packages")
# Mempool transactions A and B
for _ in range(2):
@@ -314,22 +300,17 @@ class MempoolPackageLimitsTest(BitcoinTestFramework):
parent_utxos.append(bulked_tx["new_utxo"])
# Package transaction C
- pc_tx = self.wallet.create_self_transfer_multi(utxos_to_spend=parent_utxos, fee_per_output=int(high_fee * COIN), target_weight=target_weight)
+ pc_tx = self.wallet.create_self_transfer_multi(utxos_to_spend=parent_utxos, fee_per_output=high_fee, target_weight=target_weight)
# Package transaction D
pd_tx = self.wallet.create_self_transfer(utxo_to_spend=pc_tx["new_utxos"][0], target_weight=target_weight)
assert_equal(2, node.getmempoolinfo()["size"])
- testres_too_heavy = node.testmempoolaccept(rawtxs=[pc_tx["hex"], pd_tx["hex"]])
- for txres in testres_too_heavy:
- assert_equal(txres["package-error"], "package-mempool-limits")
-
- # Clear mempool and check that the package passes now
- self.generate(node, 1)
- assert all([res["allowed"] for res in node.testmempoolaccept(rawtxs=[pc_tx["hex"], pd_tx["hex"]])])
+ return [pc_tx["hex"], pd_tx["hex"]]
+ @check_package_limits
def test_desc_size_limits(self):
- """Create 3 mempool transactions and 2 package transactions (25KvB each):
+ """Create 3 mempool transactions and 2 package transactions (21KvB each):
Ma
^ ^
Mb Mc
@@ -339,12 +320,12 @@ class MempoolPackageLimitsTest(BitcoinTestFramework):
and in-package descendants are all considered together.
"""
node = self.nodes[0]
- assert_equal(0, node.getmempoolinfo()["size"])
- target_weight = 21 * 1000 * WITNESS_SCALE_FACTOR
- high_fee = Decimal("0.0021") # 10 sats/vB
+ target_vsize = 21_000
+ high_fee = 10 * target_vsize # 10 sats/vB
+ target_weight = target_vsize * WITNESS_SCALE_FACTOR
self.log.info("Check that in-mempool and in-package descendant sizes are calculated properly in packages")
# Top parent in mempool, Ma
- ma_tx = self.wallet.create_self_transfer_multi(num_outputs=2, fee_per_output=int(high_fee / 2 * COIN), target_weight=target_weight)
+ ma_tx = self.wallet.create_self_transfer_multi(num_outputs=2, fee_per_output=high_fee // 2, target_weight=target_weight)
self.wallet.sendrawtransaction(from_node=node, tx_hex=ma_tx["hex"])
package_hex = []
@@ -359,13 +340,8 @@ class MempoolPackageLimitsTest(BitcoinTestFramework):
assert_equal(3, node.getmempoolinfo()["size"])
assert_equal(2, len(package_hex))
- testres_too_heavy = node.testmempoolaccept(rawtxs=package_hex)
- for txres in testres_too_heavy:
- assert_equal(txres["package-error"], "package-mempool-limits")
+ return package_hex
- # Clear mempool and check that the package passes now
- self.generate(node, 1)
- assert all([res["allowed"] for res in node.testmempoolaccept(rawtxs=package_hex)])
if __name__ == "__main__":
MempoolPackageLimitsTest().main()
diff --git a/test/functional/p2p_disconnect_ban.py b/test/functional/p2p_disconnect_ban.py
index 394009f30f..c389ff732f 100755
--- a/test/functional/p2p_disconnect_ban.py
+++ b/test/functional/p2p_disconnect_ban.py
@@ -4,6 +4,7 @@
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Test node disconnect and ban behavior"""
import time
+from pathlib import Path
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import (
@@ -36,6 +37,17 @@ class DisconnectBanTest(BitcoinTestFramework):
self.log.info("clearbanned: successfully clear ban list")
self.nodes[1].clearbanned()
assert_equal(len(self.nodes[1].listbanned()), 0)
+
+ self.log.info('Test banlist database recreation')
+ self.stop_node(1)
+ target_file = self.nodes[1].chain_path / "banlist.json"
+ Path.unlink(target_file)
+ with self.nodes[1].assert_debug_log(["Recreating the banlist database"]):
+ self.start_node(1)
+
+ assert Path.exists(target_file)
+ assert_equal(self.nodes[1].listbanned(), [])
+
self.nodes[1].setban("127.0.0.0/24", "add")
self.log.info("setban: fail to ban an already banned subnet")
diff --git a/test/functional/p2p_sendheaders.py b/test/functional/p2p_sendheaders.py
index 1ccc447b89..508d6fe403 100755
--- a/test/functional/p2p_sendheaders.py
+++ b/test/functional/p2p_sendheaders.py
@@ -546,15 +546,15 @@ class SendHeadersTest(BitcoinTestFramework):
blocks = []
# Now we test that if we repeatedly don't send connecting headers, we
# don't go into an infinite loop trying to get them to connect.
- MAX_UNCONNECTING_HEADERS = 10
- for _ in range(MAX_UNCONNECTING_HEADERS + 1):
+ MAX_NUM_UNCONNECTING_HEADERS_MSGS = 10
+ for _ in range(MAX_NUM_UNCONNECTING_HEADERS_MSGS + 1):
blocks.append(create_block(tip, create_coinbase(height), block_time))
blocks[-1].solve()
tip = blocks[-1].sha256
block_time += 1
height += 1
- for i in range(1, MAX_UNCONNECTING_HEADERS):
+ for i in range(1, MAX_NUM_UNCONNECTING_HEADERS_MSGS):
# Send a header that doesn't connect, check that we get a getheaders.
with p2p_lock:
test_node.last_message.pop("getheaders", None)
@@ -568,8 +568,8 @@ class SendHeadersTest(BitcoinTestFramework):
blocks = blocks[2:]
# Now try to see how many unconnecting headers we can send
- # before we get disconnected. Should be 5*MAX_UNCONNECTING_HEADERS
- for i in range(5 * MAX_UNCONNECTING_HEADERS - 1):
+ # before we get disconnected. Should be 5*MAX_NUM_UNCONNECTING_HEADERS_MSGS
+ for i in range(5 * MAX_NUM_UNCONNECTING_HEADERS_MSGS - 1):
# Send a header that doesn't connect, check that we get a getheaders.
with p2p_lock:
test_node.last_message.pop("getheaders", None)
diff --git a/test/functional/rpc_createmultisig.py b/test/functional/rpc_createmultisig.py
index 7d03ed2951..bec499107f 100755
--- a/test/functional/rpc_createmultisig.py
+++ b/test/functional/rpc_createmultisig.py
@@ -8,6 +8,7 @@ import itertools
import json
import os
+from test_framework.address import address_to_scriptpubkey
from test_framework.blocktools import COINBASE_MATURITY
from test_framework.authproxy import JSONRPCException
from test_framework.descriptors import descsum_create, drop_origins
@@ -193,7 +194,7 @@ class RpcCreateMultiSigTest(BitcoinTestFramework):
assert mredeemw == mredeem
wmulti.unloadwallet()
- spk = bytes.fromhex(node0.validateaddress(madd)["scriptPubKey"])
+ spk = address_to_scriptpubkey(madd)
txid, _ = self.wallet.send_to(from_node=self.nodes[0], scriptPubKey=spk, amount=1300)
tx = node0.getrawtransaction(txid, True)
vout = [v["n"] for v in tx["vout"] if madd == v["scriptPubKey"]["address"]]
diff --git a/test/functional/rpc_packages.py b/test/functional/rpc_packages.py
index 6cb9760b3d..ae1a498e28 100755
--- a/test/functional/rpc_packages.py
+++ b/test/functional/rpc_packages.py
@@ -20,7 +20,6 @@ from test_framework.util import (
assert_raises_rpc_error,
)
from test_framework.wallet import (
- COIN,
DEFAULT_FEE,
MiniWallet,
)
@@ -325,42 +324,6 @@ class RPCPackagesTest(BitcoinTestFramework):
peer.wait_for_broadcast([tx["tx"].getwtxid() for tx in package_txns])
self.generate(node, 1)
- def test_submit_cpfp(self):
- node = self.nodes[0]
- peer = node.add_p2p_connection(P2PTxInvStore())
-
- # Package with 2 parents and 1 child. One parent pays for itself using modified fees, and
- # another has 0 fees but is bumped by child.
- tx_poor = self.wallet.create_self_transfer(fee=0, fee_rate=0)
- tx_rich = self.wallet.create_self_transfer(fee=0, fee_rate=0)
- node.prioritisetransaction(tx_rich["txid"], 0, int(DEFAULT_FEE * COIN))
- package_txns = [tx_rich, tx_poor]
- coins = [tx["new_utxo"] for tx in package_txns]
- tx_child = self.wallet.create_self_transfer_multi(utxos_to_spend=coins, fee_per_output=10000) #DEFAULT_FEE
- package_txns.append(tx_child)
-
- submitpackage_result = node.submitpackage([tx["hex"] for tx in package_txns])
-
- rich_parent_result = submitpackage_result["tx-results"][tx_rich["wtxid"]]
- poor_parent_result = submitpackage_result["tx-results"][tx_poor["wtxid"]]
- child_result = submitpackage_result["tx-results"][tx_child["tx"].getwtxid()]
- assert_equal(rich_parent_result["fees"]["base"], 0)
- assert_equal(poor_parent_result["fees"]["base"], 0)
- assert_equal(child_result["fees"]["base"], DEFAULT_FEE)
- # The "rich" parent does not require CPFP so its effective feerate.
- assert_fee_amount(DEFAULT_FEE, tx_rich["tx"].get_vsize(), rich_parent_result["fees"]["effective-feerate"])
- assert_equal(rich_parent_result["fees"]["effective-includes"], [tx_rich["wtxid"]])
- # The "poor" parent and child's effective feerates are the same, composed of the child's fee
- # divided by their combined vsize.
- assert_fee_amount(DEFAULT_FEE, tx_poor["tx"].get_vsize() + tx_child["tx"].get_vsize(), poor_parent_result["fees"]["effective-feerate"])
- assert_fee_amount(DEFAULT_FEE, tx_poor["tx"].get_vsize() + tx_child["tx"].get_vsize(), child_result["fees"]["effective-feerate"])
- assert_equal([tx_poor["wtxid"], tx_child["tx"].getwtxid()], poor_parent_result["fees"]["effective-includes"])
- assert_equal([tx_poor["wtxid"], tx_child["tx"].getwtxid()], child_result["fees"]["effective-includes"])
-
- # The node will broadcast each transaction, still abiding by its peer's fee filter
- peer.wait_for_broadcast([tx["tx"].getwtxid() for tx in package_txns])
- self.generate(node, 1)
-
def test_submitpackage(self):
node = self.nodes[0]
@@ -369,9 +332,6 @@ class RPCPackagesTest(BitcoinTestFramework):
self.test_submit_child_with_parents(num_parents, False)
self.test_submit_child_with_parents(num_parents, True)
- self.log.info("Submitpackage valid packages with CPFP")
- self.test_submit_cpfp()
-
self.log.info("Submitpackage only allows packages of 1 child with its parents")
# Chain of 3 transactions has too many generations
chain_hex = [t["hex"] for t in self.wallet.create_self_transfer_chain(chain_length=25)]
diff --git a/test/functional/rpc_psbt.py b/test/functional/rpc_psbt.py
index bf7ff6baa0..49cdfd0e66 100755
--- a/test/functional/rpc_psbt.py
+++ b/test/functional/rpc_psbt.py
@@ -619,17 +619,17 @@ class PSBTTest(BitcoinTestFramework):
# Bech32 inputs should be filled with witness UTXO. Other inputs should not be filled because they are non-witness
updated = self.nodes[1].utxoupdatepsbt(psbt)
decoded = self.nodes[1].decodepsbt(updated)
- test_psbt_input_keys(decoded['inputs'][0], ['witness_utxo'])
- test_psbt_input_keys(decoded['inputs'][1], [])
- test_psbt_input_keys(decoded['inputs'][2], [])
+ test_psbt_input_keys(decoded['inputs'][0], ['witness_utxo', 'non_witness_utxo'])
+ test_psbt_input_keys(decoded['inputs'][1], ['non_witness_utxo'])
+ test_psbt_input_keys(decoded['inputs'][2], ['non_witness_utxo'])
# Try again, now while providing descriptors, making P2SH-segwit work, and causing bip32_derivs and redeem_script to be filled in
descs = [self.nodes[1].getaddressinfo(addr)['desc'] for addr in [addr1,addr2,addr3]]
updated = self.nodes[1].utxoupdatepsbt(psbt=psbt, descriptors=descs)
decoded = self.nodes[1].decodepsbt(updated)
- test_psbt_input_keys(decoded['inputs'][0], ['witness_utxo', 'bip32_derivs'])
- test_psbt_input_keys(decoded['inputs'][1], [])
- test_psbt_input_keys(decoded['inputs'][2], ['witness_utxo', 'bip32_derivs', 'redeem_script'])
+ test_psbt_input_keys(decoded['inputs'][0], ['witness_utxo', 'non_witness_utxo', 'bip32_derivs'])
+ test_psbt_input_keys(decoded['inputs'][1], ['non_witness_utxo', 'bip32_derivs'])
+ test_psbt_input_keys(decoded['inputs'][2], ['non_witness_utxo','witness_utxo', 'bip32_derivs', 'redeem_script'])
# Two PSBTs with a common input should not be joinable
psbt1 = self.nodes[1].createpsbt([{"txid":txid1, "vout":vout1}], {self.nodes[0].getnewaddress():Decimal('10.999')})
diff --git a/test/functional/rpc_scanblocks.py b/test/functional/rpc_scanblocks.py
index 126e95362b..8b4aebc77a 100755
--- a/test/functional/rpc_scanblocks.py
+++ b/test/functional/rpc_scanblocks.py
@@ -3,6 +3,7 @@
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Test the scanblocks RPC call."""
+from test_framework.address import address_to_scriptpubkey
from test_framework.blockfilter import (
bip158_basic_element_hash,
bip158_relevant_scriptpubkeys,
@@ -36,7 +37,7 @@ class ScanblocksTest(BitcoinTestFramework):
# send 1.0, mempool only
# childkey 5 of `parent_key`
wallet.send_to(from_node=node,
- scriptPubKey=bytes.fromhex(node.validateaddress("mkS4HXoTYWRTescLGaUTGbtTTYX5EjJyEE")['scriptPubKey']),
+ scriptPubKey=address_to_scriptpubkey("mkS4HXoTYWRTescLGaUTGbtTTYX5EjJyEE"),
amount=1 * COIN)
# mine a block and assure that the mined blockhash is in the filterresult
@@ -48,6 +49,7 @@ class ScanblocksTest(BitcoinTestFramework):
assert blockhash in out['relevant_blocks']
assert_equal(height, out['to_height'])
assert_equal(0, out['from_height'])
+ assert_equal(True, out['completed'])
# mine another block
blockhash_new = self.generate(node, 1)[0]
diff --git a/test/functional/rpc_scantxoutset.py b/test/functional/rpc_scantxoutset.py
index 507a4f48e5..f97636aae7 100755
--- a/test/functional/rpc_scantxoutset.py
+++ b/test/functional/rpc_scantxoutset.py
@@ -3,12 +3,12 @@
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Test the scantxoutset rpc call."""
+from test_framework.address import address_to_scriptpubkey
from test_framework.messages import COIN
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import assert_equal, assert_raises_rpc_error
from test_framework.wallet import (
MiniWallet,
- address_to_scriptpubkey,
getnewdestination,
)
@@ -123,6 +123,9 @@ class ScantxoutsetTest(BitcoinTestFramework):
# Check that second arg is needed for start
assert_raises_rpc_error(-1, "scanobjects argument is required for the start action", self.nodes[0].scantxoutset, "start")
+ # Check that invalid command give error
+ assert_raises_rpc_error(-8, "Invalid action 'invalid_command'", self.nodes[0].scantxoutset, "invalid_command")
+
if __name__ == "__main__":
ScantxoutsetTest().main()
diff --git a/test/functional/rpc_setban.py b/test/functional/rpc_setban.py
index 97354f480c..b4f3d77e5b 100755
--- a/test/functional/rpc_setban.py
+++ b/test/functional/rpc_setban.py
@@ -6,7 +6,8 @@
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import (
- p2p_port
+ p2p_port,
+ assert_equal,
)
class SetBanTests(BitcoinTestFramework):
@@ -70,6 +71,11 @@ class SetBanTests(BitcoinTestFramework):
assert not self.is_banned(node, tor_addr)
assert not self.is_banned(node, ip_addr)
+ self.log.info("Test -bantime")
+ self.restart_node(1, ["-bantime=1234"])
+ self.nodes[1].setban("127.0.0.1", "add")
+ banned = self.nodes[1].listbanned()[0]
+ assert_equal(banned['ban_duration'], 1234)
if __name__ == '__main__':
SetBanTests().main()
diff --git a/test/functional/rpc_signrawtransactionwithkey.py b/test/functional/rpc_signrawtransactionwithkey.py
index 0da5a99fdb..580f63063d 100755
--- a/test/functional/rpc_signrawtransactionwithkey.py
+++ b/test/functional/rpc_signrawtransactionwithkey.py
@@ -8,6 +8,7 @@ from test_framework.blocktools import (
COINBASE_MATURITY,
)
from test_framework.address import (
+ address_to_scriptpubkey,
script_to_p2sh,
)
from test_framework.key import ECKey
@@ -118,7 +119,7 @@ class SignRawTransactionWithKeyTest(BitcoinTestFramework):
}.get(tx_type, "Invalid tx_type")
redeem_script = script_to_p2wsh_script(witness_script).hex()
addr = script_to_p2sh(redeem_script)
- script_pub_key = self.nodes[1].validateaddress(addr)['scriptPubKey']
+ script_pub_key = address_to_scriptpubkey(addr).hex()
# Fund that address
txid = self.send_to_address(addr, 10)
vout = find_vout_for_address(self.nodes[0], txid, addr)
diff --git a/test/functional/test_framework/address.py b/test/functional/test_framework/address.py
index d1bf186b9d..5b2e3289a9 100644
--- a/test/functional/test_framework/address.py
+++ b/test/functional/test_framework/address.py
@@ -21,11 +21,17 @@ from .script import (
taproot_construct,
)
from .util import assert_equal
+from test_framework.script_util import (
+ keyhash_to_p2pkh_script,
+ program_to_witness_script,
+ scripthash_to_p2sh_script,
+)
from test_framework.segwit_addr import (
decode_segwit_address,
encode_segwit_address,
)
+
ADDRESS_BCRT1_UNSPENDABLE = 'bcrt1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq3xueyj'
ADDRESS_BCRT1_UNSPENDABLE_DESCRIPTOR = 'addr(bcrt1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq3xueyj)#juyq9d97'
# Coins sent to this address can be spent with a witness stack of just OP_TRUE
@@ -172,6 +178,21 @@ def bech32_to_bytes(address):
return version, bytearray(payload)
+def address_to_scriptpubkey(address):
+ """Converts a given address to the corresponding output script (scriptPubKey)."""
+ version, payload = bech32_to_bytes(address)
+ if version is not None:
+ return program_to_witness_script(version, payload) # testnet segwit scriptpubkey
+ payload, version = base58_to_byte(address)
+ if version == 111: # testnet pubkey hash
+ return keyhash_to_p2pkh_script(payload)
+ elif version == 196: # testnet script hash
+ return scripthash_to_p2sh_script(payload)
+ # TODO: also support other address formats
+ else:
+ assert False
+
+
class TestFrameworkScript(unittest.TestCase):
def test_base58encodedecode(self):
def check_base58(data, version):
diff --git a/test/functional/test_framework/authproxy.py b/test/functional/test_framework/authproxy.py
index 61f92aeac3..f7765a9dfa 100644
--- a/test/functional/test_framework/authproxy.py
+++ b/test/functional/test_framework/authproxy.py
@@ -39,7 +39,6 @@ from http import HTTPStatus
import http.client
import json
import logging
-import os
import socket
import time
import urllib.parse
@@ -94,36 +93,14 @@ class AuthServiceProxy():
def _request(self, method, path, postdata):
'''
- Do a HTTP request, with retry if we get disconnected (e.g. due to a timeout).
- This is a workaround for https://bugs.python.org/issue3566 which is fixed in Python 3.5.
+ Do a HTTP request.
'''
headers = {'Host': self.__url.hostname,
'User-Agent': USER_AGENT,
'Authorization': self.__auth_header,
'Content-type': 'application/json'}
- if os.name == 'nt':
- # Windows somehow does not like to re-use connections
- # TODO: Find out why the connection would disconnect occasionally and make it reusable on Windows
- # Avoid "ConnectionAbortedError: [WinError 10053] An established connection was aborted by the software in your host machine"
- self._set_conn()
- try:
- self.__conn.request(method, path, postdata, headers)
- return self._get_response()
- except (BrokenPipeError, ConnectionResetError):
- # Python 3.5+ raises BrokenPipeError when the connection was reset
- # ConnectionResetError happens on FreeBSD
- self.__conn.close()
- self.__conn.request(method, path, postdata, headers)
- return self._get_response()
- except OSError as e:
- # Workaround for a bug on macOS. See https://bugs.python.org/issue33450
- retry = '[Errno 41] Protocol wrong type for socket' in str(e)
- if retry:
- self.__conn.close()
- self.__conn.request(method, path, postdata, headers)
- return self._get_response()
- else:
- raise
+ self.__conn.request(method, path, postdata, headers)
+ return self._get_response()
def get_request(self, *args, **argsn):
AuthServiceProxy.__id_count += 1
diff --git a/test/functional/test_framework/blocktools.py b/test/functional/test_framework/blocktools.py
index b08cc6a3f9..cfd923bab3 100644
--- a/test/functional/test_framework/blocktools.py
+++ b/test/functional/test_framework/blocktools.py
@@ -9,6 +9,7 @@ import time
import unittest
from .address import (
+ address_to_scriptpubkey,
key_to_p2sh_p2wpkh,
key_to_p2wpkh,
script_to_p2sh_p2wsh,
@@ -205,7 +206,7 @@ def create_witness_tx(node, use_p2wsh, utxo, pubkey, encode_p2sh, amount):
else:
addr = key_to_p2sh_p2wpkh(pubkey) if encode_p2sh else key_to_p2wpkh(pubkey)
if not encode_p2sh:
- assert_equal(node.getaddressinfo(addr)['scriptPubKey'], witness_script(use_p2wsh, pubkey))
+ assert_equal(address_to_scriptpubkey(addr).hex(), witness_script(use_p2wsh, pubkey))
return node.createrawtransaction([utxo], {addr: amount})
def send_to_witness(use_p2wsh, node, utxo, pubkey, encode_p2sh, amount, sign=True, insert_redeem_script=""):
diff --git a/test/functional/test_framework/key.py b/test/functional/test_framework/key.py
index ad305ce1ef..efb4934ff0 100644
--- a/test/functional/test_framework/key.py
+++ b/test/functional/test_framework/key.py
@@ -13,8 +13,6 @@ import os
import random
import unittest
-from .util import modinv
-
# Point with no known discrete log.
H_POINT = "50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0"
@@ -78,7 +76,7 @@ class EllipticCurve:
x1, y1, z1 = p1
if z1 == 0:
return None
- inv = modinv(z1, self.p)
+ inv = pow(z1, -1, self.p)
inv_2 = (inv**2) % self.p
inv_3 = (inv_2 * inv) % self.p
return ((inv_2 * x1) % self.p, (inv_3 * y1) % self.p, 1)
@@ -319,7 +317,7 @@ class ECPubKey():
z = int.from_bytes(msg, 'big')
# Run verifier algorithm on r, s
- w = modinv(s, SECP256K1_ORDER)
+ w = pow(s, -1, SECP256K1_ORDER)
u1 = z*w % SECP256K1_ORDER
u2 = r*w % SECP256K1_ORDER
R = SECP256K1.affine(SECP256K1.mul([(SECP256K1_G, u1), (self.p, u2)]))
@@ -397,7 +395,7 @@ class ECKey():
k = random.randrange(1, SECP256K1_ORDER)
R = SECP256K1.affine(SECP256K1.mul([(SECP256K1_G, k)]))
r = R[0] % SECP256K1_ORDER
- s = (modinv(k, SECP256K1_ORDER) * (z + self.secret * r)) % SECP256K1_ORDER
+ s = (pow(k, -1, SECP256K1_ORDER) * (z + self.secret * r)) % SECP256K1_ORDER
if low_s and s > SECP256K1_ORDER_HALF:
s = SECP256K1_ORDER - s
# Represent in DER format. The byte representations of r and s have
diff --git a/test/functional/test_framework/messages.py b/test/functional/test_framework/messages.py
index 8c6f68cacb..a6764365c5 100755
--- a/test/functional/test_framework/messages.py
+++ b/test/functional/test_framework/messages.py
@@ -93,6 +93,7 @@ def ser_compact_size(l):
r = struct.pack("<BQ", 255, l)
return r
+
def deser_compact_size(f):
nit = struct.unpack("<B", f.read(1))[0]
if nit == 253:
@@ -103,35 +104,26 @@ def deser_compact_size(f):
nit = struct.unpack("<Q", f.read(8))[0]
return nit
+
def deser_string(f):
nit = deser_compact_size(f)
return f.read(nit)
+
def ser_string(s):
return ser_compact_size(len(s)) + s
+
def deser_uint256(f):
- r = 0
- for i in range(8):
- t = struct.unpack("<I", f.read(4))[0]
- r += t << (i * 32)
- return r
+ return int.from_bytes(f.read(32), 'little')
def ser_uint256(u):
- rs = b""
- for _ in range(8):
- rs += struct.pack("<I", u & 0xFFFFFFFF)
- u >>= 32
- return rs
+ return u.to_bytes(32, 'little')
def uint256_from_str(s):
- r = 0
- t = struct.unpack("<IIIIIIII", s[:32])
- for i in range(8):
- r += t[i] << (i * 32)
- return r
+ return int.from_bytes(s[:32], 'little')
def uint256_from_compact(c):
diff --git a/test/functional/test_framework/muhash.py b/test/functional/test_framework/muhash.py
index 183548f71f..0d96114e3e 100644
--- a/test/functional/test_framework/muhash.py
+++ b/test/functional/test_framework/muhash.py
@@ -6,8 +6,6 @@
import hashlib
import unittest
-from .util import modinv
-
def rot32(v, bits):
"""Rotate the 32-bit value v left by bits bits."""
bits %= 32 # Make sure the term below does not throw an exception
@@ -88,7 +86,7 @@ class MuHash3072:
def digest(self):
"""Extract the final hash. Does not modify this object."""
- val = (self.numerator * modinv(self.denominator, self.MODULUS)) % self.MODULUS
+ val = (self.numerator * pow(self.denominator, -1, self.MODULUS)) % self.MODULUS
bytes384 = val.to_bytes(384, 'little')
return hashlib.sha256(bytes384).digest()
diff --git a/test/functional/test_framework/util.py b/test/functional/test_framework/util.py
index 9048a915b2..2c227922c5 100644
--- a/test/functional/test_framework/util.py
+++ b/test/functional/test_framework/util.py
@@ -15,7 +15,6 @@ import os
import random
import re
import time
-import unittest
from . import coverage
from .authproxy import AuthServiceProxy, JSONRPCException
@@ -390,6 +389,8 @@ def write_config(config_path, *, n, chain, extra_config="", disable_autoconnect=
f.write("[{}]\n".format(chain_name_conf_section))
f.write("port=" + str(p2p_port(n)) + "\n")
f.write("rpcport=" + str(rpc_port(n)) + "\n")
+ # Disable server-side timeouts to avoid intermittent issues
+ f.write("rpcservertimeout=99000\n")
f.write("rpcdoccheck=1\n")
f.write("fallbackfee=0.0002\n")
f.write("server=1\n")
@@ -535,33 +536,3 @@ def find_vout_for_address(node, txid, addr):
if addr == tx["vout"][i]["scriptPubKey"]["address"]:
return i
raise RuntimeError("Vout not found for address: txid=%s, addr=%s" % (txid, addr))
-
-def modinv(a, n):
- """Compute the modular inverse of a modulo n using the extended Euclidean
- Algorithm. See https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm#Modular_integers.
- """
- # TODO: Change to pow(a, -1, n) available in Python 3.8
- t1, t2 = 0, 1
- r1, r2 = n, a
- while r2 != 0:
- q = r1 // r2
- t1, t2 = t2, t1 - q * t2
- r1, r2 = r2, r1 - q * r2
- if r1 > 1:
- return None
- if t1 < 0:
- t1 += n
- return t1
-
-class TestFrameworkUtil(unittest.TestCase):
- def test_modinv(self):
- test_vectors = [
- [7, 11],
- [11, 29],
- [90, 13],
- [1891, 3797],
- [6003722857, 77695236973],
- ]
-
- for a, n in test_vectors:
- self.assertEqual(modinv(a, n), pow(a, n-2, n))
diff --git a/test/functional/test_framework/wallet.py b/test/functional/test_framework/wallet.py
index eab8fbda47..fcd396c700 100644
--- a/test/functional/test_framework/wallet.py
+++ b/test/functional/test_framework/wallet.py
@@ -13,8 +13,7 @@ from typing import (
Optional,
)
from test_framework.address import (
- base58_to_byte,
- bech32_to_bytes,
+ address_to_scriptpubkey,
create_deterministic_address_bcrt1_p2tr_op_true,
key_to_p2pkh,
key_to_p2sh_p2wpkh,
@@ -49,9 +48,6 @@ from test_framework.script_util import (
key_to_p2pkh_script,
key_to_p2sh_p2wpkh_script,
key_to_p2wpkh_script,
- keyhash_to_p2pkh_script,
- program_to_witness_script,
- scripthash_to_p2sh_script,
)
from test_framework.util import (
assert_equal,
@@ -101,7 +97,7 @@ class MiniWallet:
self._scriptPubKey = key_to_p2pk_script(pub_key.get_bytes())
elif mode == MiniWalletMode.ADDRESS_OP_TRUE:
self._address, self._internal_key = create_deterministic_address_bcrt1_p2tr_op_true()
- self._scriptPubKey = bytes.fromhex(self._test_node.validateaddress(self._address)['scriptPubKey'])
+ self._scriptPubKey = address_to_scriptpubkey(self._address)
# When the pre-mined test framework chain is used, it contains coinbase
# outputs to the MiniWallet's default address in blocks 76-100
@@ -412,18 +408,3 @@ def getnewdestination(address_type='bech32m'):
else:
assert False
return pubkey, scriptpubkey, address
-
-
-def address_to_scriptpubkey(address):
- """Converts a given address to the corresponding output script (scriptPubKey)."""
- version, payload = bech32_to_bytes(address)
- if version is not None:
- return program_to_witness_script(version, payload) # testnet segwit scriptpubkey
- payload, version = base58_to_byte(address)
- if version == 111: # testnet pubkey hash
- return keyhash_to_p2pkh_script(payload)
- elif version == 196: # testnet script hash
- return scripthash_to_p2sh_script(payload)
- # TODO: also support other address formats
- else:
- assert False
diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py
index bcedc0c9af..77e4dab6e4 100755
--- a/test/functional/test_runner.py
+++ b/test/functional/test_runner.py
@@ -69,11 +69,14 @@ if os.name != 'nt' or sys.getwindowsversion() >= (10, 0, 14393): #type:ignore
TEST_EXIT_PASSED = 0
TEST_EXIT_SKIPPED = 77
+# List of framework modules containing unit tests. Should be kept in sync with
+# the output of `git grep unittest.TestCase ./test/functional/test_framework`
TEST_FRAMEWORK_MODULES = [
"address",
"blocktools",
"muhash",
"key",
+ "ripemd160",
"script",
"segwit_addr",
"util",
@@ -320,6 +323,7 @@ BASE_SCRIPTS = [
'feature_includeconf.py',
'feature_addrman.py',
'feature_asmap.py',
+ 'feature_fastprune.py',
'mempool_unbroadcast.py',
'mempool_compatibility.py',
'mempool_accept_wtxid.py',
diff --git a/test/functional/wallet_avoidreuse.py b/test/functional/wallet_avoidreuse.py
index 5601d81227..c257bda452 100755
--- a/test/functional/wallet_avoidreuse.py
+++ b/test/functional/wallet_avoidreuse.py
@@ -4,6 +4,7 @@
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Test the avoid_reuse and setwalletflag features."""
+from test_framework.address import address_to_scriptpubkey
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import (
assert_approx,
@@ -257,7 +258,7 @@ class AvoidReuseTest(BitcoinTestFramework):
if not self.options.descriptors:
# For the second send, we transmute it to a related single-key address
# to make sure it's also detected as re-use
- fund_spk = self.nodes[0].getaddressinfo(fundaddr)["scriptPubKey"]
+ fund_spk = address_to_scriptpubkey(fundaddr).hex()
fund_decoded = self.nodes[0].decodescript(fund_spk)
if second_addr_type == "p2sh-segwit":
new_fundaddr = fund_decoded["segwit"]["p2sh-segwit"]
diff --git a/test/functional/wallet_backwards_compatibility.py b/test/functional/wallet_backwards_compatibility.py
index 76aac3e486..a6401a76c1 100755
--- a/test/functional/wallet_backwards_compatibility.py
+++ b/test/functional/wallet_backwards_compatibility.py
@@ -265,7 +265,12 @@ class BackwardsCompatibilityTest(BitcoinTestFramework):
)
load_res = node_master.loadwallet("u1_v16")
# Make sure this wallet opens without warnings. See https://github.com/bitcoin/bitcoin/pull/19054
- assert_equal(load_res['warning'], '')
+ if int(node_master.getnetworkinfo()["version"]) >= 249900:
+ # loadwallet#warnings (added in v25) -- only present if there is a warning
+ assert "warnings" not in load_res
+ else:
+ # loadwallet#warning (deprecated in v25) -- always present, but empty string if no warning
+ assert_equal(load_res["warning"], '')
wallet = node_master.get_wallet_rpc("u1_v16")
info = wallet.getaddressinfo(v16_addr)
descriptor = f"wpkh([{info['hdmasterfingerprint']}{hdkeypath[1:]}]{v16_pubkey})"
diff --git a/test/functional/wallet_balance.py b/test/functional/wallet_balance.py
index 9ed2caefb7..af9270a321 100755
--- a/test/functional/wallet_balance.py
+++ b/test/functional/wallet_balance.py
@@ -11,6 +11,7 @@ from test_framework.blocktools import COINBASE_MATURITY
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import (
assert_equal,
+ assert_is_hash_string,
assert_raises_rpc_error,
)
@@ -183,8 +184,13 @@ class WalletTest(BitcoinTestFramework):
'untrusted_pending': Decimal('30.0') - fee_node_1}} # Doesn't include output of node 0's send since it was spent
if self.options.descriptors:
del expected_balances_0["watchonly"]
- assert_equal(self.nodes[0].getbalances(), expected_balances_0)
- assert_equal(self.nodes[1].getbalances(), expected_balances_1)
+ balances_0 = self.nodes[0].getbalances()
+ balances_1 = self.nodes[1].getbalances()
+ # remove lastprocessedblock keys (they will be tested later)
+ del balances_0['lastprocessedblock']
+ del balances_1['lastprocessedblock']
+ assert_equal(balances_0, expected_balances_0)
+ assert_equal(balances_1, expected_balances_1)
# getbalance without any arguments includes unconfirmed transactions, but not untrusted transactions
assert_equal(self.nodes[0].getbalance(), Decimal('9.99')) # change from node 0's send
assert_equal(self.nodes[1].getbalance(), Decimal('0')) # node 1's send had an unsafe input
@@ -309,5 +315,30 @@ class WalletTest(BitcoinTestFramework):
assert_equal(self.nodes[0].getbalances()['mine']['untrusted_pending'], Decimal('0.1'))
+ # Tests the lastprocessedblock JSON object in getbalances, getwalletinfo
+ # and gettransaction by checking for valid hex strings and by comparing
+ # the hashes & heights between generated blocks.
+ self.log.info("Test getbalances returns expected lastprocessedblock json object")
+ prev_hash = self.nodes[0].getbestblockhash()
+ prev_height = self.nodes[0].getblock(prev_hash)['height']
+ self.generatetoaddress(self.nodes[0], 5, self.nodes[0].get_deterministic_priv_key().address)
+ lastblock = self.nodes[0].getbalances()['lastprocessedblock']
+ assert_is_hash_string(lastblock['hash'])
+ assert_equal((prev_hash == lastblock['hash']), False)
+ assert_equal(lastblock['height'], prev_height + 5)
+
+ prev_hash = self.nodes[0].getbestblockhash()
+ prev_height = self.nodes[0].getblock(prev_hash)['height']
+ self.log.info("Test getwalletinfo returns expected lastprocessedblock json object")
+ walletinfo = self.nodes[0].getwalletinfo()
+ assert_equal(walletinfo['lastprocessedblock']['height'], prev_height)
+ assert_equal(walletinfo['lastprocessedblock']['hash'], prev_hash)
+
+ self.log.info("Test gettransaction returns expected lastprocessedblock json object")
+ txid = self.nodes[1].sendtoaddress(self.nodes[1].getnewaddress(), 0.01)
+ tx_info = self.nodes[1].gettransaction(txid)
+ assert_equal(tx_info['lastprocessedblock']['height'], prev_height)
+ assert_equal(tx_info['lastprocessedblock']['hash'], prev_hash)
+
if __name__ == '__main__':
WalletTest().main()
diff --git a/test/functional/wallet_basic.py b/test/functional/wallet_basic.py
index 53ac01686a..e23ec7bc01 100755
--- a/test/functional/wallet_basic.py
+++ b/test/functional/wallet_basic.py
@@ -267,6 +267,20 @@ class WalletTest(BitcoinTestFramework):
assert_equal(self.nodes[2].getbalance(), node_2_bal)
node_0_bal = self.check_fee_amount(self.nodes[0].getbalance(), node_0_bal + Decimal('10'), fee_per_byte, self.get_vsize(self.nodes[2].gettransaction(txid)['hex']))
+ # Sendmany 5 BTC to two addresses with subtracting fee from both addresses
+ a0 = self.nodes[0].getnewaddress()
+ a1 = self.nodes[0].getnewaddress()
+ txid = self.nodes[2].sendmany(dummy='', amounts={a0: 5, a1: 5}, subtractfeefrom=[a0, a1])
+ self.generate(self.nodes[2], 1, sync_fun=lambda: self.sync_all(self.nodes[0:3]))
+ node_2_bal -= Decimal('10')
+ assert_equal(self.nodes[2].getbalance(), node_2_bal)
+ tx = self.nodes[2].gettransaction(txid)
+ node_0_bal = self.check_fee_amount(self.nodes[0].getbalance(), node_0_bal + Decimal('10'), fee_per_byte, self.get_vsize(tx['hex']))
+ assert_equal(self.nodes[0].getbalance(), node_0_bal)
+ expected_bal = Decimal('5') + (tx['fee'] / 2)
+ assert_equal(self.nodes[0].getreceivedbyaddress(a0), expected_bal)
+ assert_equal(self.nodes[0].getreceivedbyaddress(a1), expected_bal)
+
self.log.info("Test sendmany with fee_rate param (explicit fee rate in sat/vB)")
fee_rate_sat_vb = 2
fee_rate_btc_kvb = fee_rate_sat_vb * 1e3 / 1e8
@@ -666,7 +680,7 @@ class WalletTest(BitcoinTestFramework):
"category": baz["category"],
"vout": baz["vout"]}
expected_fields = frozenset({'amount', 'bip125-replaceable', 'confirmations', 'details', 'fee',
- 'hex', 'time', 'timereceived', 'trusted', 'txid', 'wtxid', 'walletconflicts'})
+ 'hex', 'lastprocessedblock', 'time', 'timereceived', 'trusted', 'txid', 'wtxid', 'walletconflicts'})
verbose_field = "decoded"
expected_verbose_fields = expected_fields | {verbose_field}
diff --git a/test/functional/wallet_bumpfee.py b/test/functional/wallet_bumpfee.py
index ad79e0288c..19c8022600 100755
--- a/test/functional/wallet_bumpfee.py
+++ b/test/functional/wallet_bumpfee.py
@@ -26,6 +26,7 @@ from test_framework.util import (
assert_equal,
assert_greater_than,
assert_raises_rpc_error,
+ get_fee,
)
from test_framework.wallet import MiniWallet
@@ -40,6 +41,10 @@ NORMAL = 100
HIGH = 500
TOO_HIGH = 100000
+def get_change_address(tx, node):
+ tx_details = node.getrawtransaction(tx, 1)
+ txout_addresses = [txout['scriptPubKey']['address'] for txout in tx_details["vout"]]
+ return [address for address in txout_addresses if node.getaddressinfo(address)["ischange"]]
class BumpFeeTest(BitcoinTestFramework):
def add_options(self, parser):
@@ -103,6 +108,10 @@ class BumpFeeTest(BitcoinTestFramework):
# These tests wipe out a number of utxos that are expected in other tests
test_small_output_with_feerate_succeeds(self, rbf_node, dest_address)
test_no_more_inputs_fails(self, rbf_node, dest_address)
+ self.test_bump_back_to_yourself()
+
+ # Context independent tests
+ test_feerate_checks_replaced_outputs(self, rbf_node, peer_node)
def test_invalid_parameters(self, rbf_node, peer_node, dest_address):
self.log.info('Test invalid parameters')
@@ -167,6 +176,54 @@ class BumpFeeTest(BitcoinTestFramework):
self.clear_mempool()
+ def test_bump_back_to_yourself(self):
+ self.log.info("Test that bumpfee can send coins back to yourself")
+ node = self.nodes[1]
+
+ node.createwallet("back_to_yourself")
+ wallet = node.get_wallet_rpc("back_to_yourself")
+
+ # Make 3 UTXOs
+ addr = wallet.getnewaddress()
+ for _ in range(3):
+ self.nodes[0].sendtoaddress(addr, 5)
+ self.generate(self.nodes[0], 1)
+
+ # Create a tx with two outputs. recipient and change.
+ tx = wallet.send(outputs={wallet.getnewaddress(): 9}, fee_rate=2)
+ tx_info = wallet.gettransaction(txid=tx["txid"], verbose=True)
+ assert_equal(len(tx_info["decoded"]["vout"]), 2)
+ assert_equal(len(tx_info["decoded"]["vin"]), 2)
+
+ # Bump tx, send coins back to change address.
+ change_addr = get_change_address(tx["txid"], wallet)[0]
+ out_amount = 10
+ bumped = wallet.bumpfee(txid=tx["txid"], options={"fee_rate": 20, "outputs": [{change_addr: out_amount}]})
+ bumped_tx = wallet.gettransaction(txid=bumped["txid"], verbose=True)
+ assert_equal(len(bumped_tx["decoded"]["vout"]), 1)
+ assert_equal(len(bumped_tx["decoded"]["vin"]), 2)
+ assert_equal(bumped_tx["decoded"]["vout"][0]["value"] + bumped["fee"], out_amount)
+
+ # Bump tx again, now test send fewer coins back to change address.
+ out_amount = 6
+ bumped = wallet.bumpfee(txid=bumped["txid"], options={"fee_rate": 40, "outputs": [{change_addr: out_amount}]})
+ bumped_tx = wallet.gettransaction(txid=bumped["txid"], verbose=True)
+ assert_equal(len(bumped_tx["decoded"]["vout"]), 2)
+ assert_equal(len(bumped_tx["decoded"]["vin"]), 2)
+ assert any(txout['value'] == out_amount - bumped["fee"] and txout['scriptPubKey']['address'] == change_addr for txout in bumped_tx['decoded']['vout'])
+ # Check that total out amount is still equal to the previously bumped tx
+ assert_equal(bumped_tx["decoded"]["vout"][0]["value"] + bumped_tx["decoded"]["vout"][1]["value"] + bumped["fee"], 10)
+
+ # Bump tx again, send more coins back to change address. The process will add another input to cover the target.
+ out_amount = 12
+ bumped = wallet.bumpfee(txid=bumped["txid"], options={"fee_rate": 80, "outputs": [{change_addr: out_amount}]})
+ bumped_tx = wallet.gettransaction(txid=bumped["txid"], verbose=True)
+ assert_equal(len(bumped_tx["decoded"]["vout"]), 2)
+ assert_equal(len(bumped_tx["decoded"]["vin"]), 3)
+ assert any(txout['value'] == out_amount - bumped["fee"] and txout['scriptPubKey']['address'] == change_addr for txout in bumped_tx['decoded']['vout'])
+ assert_equal(bumped_tx["decoded"]["vout"][0]["value"] + bumped_tx["decoded"]["vout"][1]["value"] + bumped["fee"], 15)
+
+ node.unloadwallet("back_to_yourself")
def test_simple_bumpfee_succeeds(self, mode, rbf_node, peer_node, dest_address):
self.log.info('Test simple bumpfee: {}'.format(mode))
@@ -585,6 +642,11 @@ def test_unconfirmed_not_spendable(self, rbf_node, rbf_node_address):
# Call abandon to make sure the wallet doesn't attempt to resubmit
# the bump tx and hope the wallet does not rebroadcast before we call.
rbf_node.abandontransaction(bumpid)
+
+ tx_bump_abandoned = rbf_node.gettransaction(bumpid)
+ for tx in tx_bump_abandoned['details']:
+ assert_equal(tx['abandoned'], True)
+
assert bumpid not in rbf_node.getrawmempool()
assert rbfid in rbf_node.getrawmempool()
@@ -626,21 +688,16 @@ def test_locked_wallet_fails(self, rbf_node, dest_address):
def test_change_script_match(self, rbf_node, dest_address):
self.log.info('Test that the same change addresses is used for the replacement transaction when possible')
- def get_change_address(tx):
- tx_details = rbf_node.getrawtransaction(tx, 1)
- txout_addresses = [txout['scriptPubKey']['address'] for txout in tx_details["vout"]]
- return [address for address in txout_addresses if rbf_node.getaddressinfo(address)["ischange"]]
-
# Check that there is only one change output
rbfid = spend_one_input(rbf_node, dest_address)
- change_addresses = get_change_address(rbfid)
+ change_addresses = get_change_address(rbfid, rbf_node)
assert_equal(len(change_addresses), 1)
# Now find that address in each subsequent tx, and no other change
bumped_total_tx = rbf_node.bumpfee(rbfid, {"fee_rate": ECONOMICAL})
- assert_equal(change_addresses, get_change_address(bumped_total_tx['txid']))
+ assert_equal(change_addresses, get_change_address(bumped_total_tx['txid'], rbf_node))
bumped_rate_tx = rbf_node.bumpfee(bumped_total_tx["txid"])
- assert_equal(change_addresses, get_change_address(bumped_rate_tx['txid']))
+ assert_equal(change_addresses, get_change_address(bumped_rate_tx['txid'], rbf_node))
self.clear_mempool()
@@ -668,5 +725,35 @@ def test_no_more_inputs_fails(self, rbf_node, dest_address):
self.clear_mempool()
+def test_feerate_checks_replaced_outputs(self, rbf_node, peer_node):
+ # Make sure there is enough balance
+ peer_node.sendtoaddress(rbf_node.getnewaddress(), 60)
+ self.generate(peer_node, 1)
+
+ self.log.info("Test that feerate checks use replaced outputs")
+ outputs = []
+ for i in range(50):
+ outputs.append({rbf_node.getnewaddress(address_type="bech32"): 1})
+ tx_res = rbf_node.send(outputs=outputs, fee_rate=5)
+ tx_details = rbf_node.gettransaction(txid=tx_res["txid"], verbose=True)
+
+ # Calculate the minimum feerate required for the bump to work.
+ # Since the bumped tx will replace all of the outputs with a single output, we can estimate that its size will 31 * (len(outputs) - 1) bytes smaller
+ tx_size = tx_details["decoded"]["vsize"]
+ est_bumped_size = tx_size - (len(tx_details["decoded"]["vout"]) - 1) * 31
+ inc_fee_rate = max(rbf_node.getmempoolinfo()["incrementalrelayfee"], Decimal(0.00005000)) # Wallet has a fixed incremental relay fee of 5 sat/vb
+ # RPC gives us fee as negative
+ min_fee = (-tx_details["fee"] + get_fee(est_bumped_size, inc_fee_rate)) * Decimal(1e8)
+ min_fee_rate = (min_fee / est_bumped_size).quantize(Decimal("1.000"))
+
+ # Attempt to bumpfee and replace all outputs with a single one using a feerate slightly less than the minimum
+ new_outputs = [{rbf_node.getnewaddress(address_type="bech32"): 49}]
+ assert_raises_rpc_error(-8, "Insufficient total fee", rbf_node.bumpfee, tx_res["txid"], {"fee_rate": min_fee_rate - 1, "outputs": new_outputs})
+
+ # Bumpfee and replace all outputs with a single one using the minimum feerate
+ rbf_node.bumpfee(tx_res["txid"], {"fee_rate": min_fee_rate, "outputs": new_outputs})
+ self.clear_mempool()
+
+
if __name__ == "__main__":
BumpFeeTest().main()
diff --git a/test/functional/wallet_create_tx.py b/test/functional/wallet_create_tx.py
index 11c82e15b7..4e31b48ec0 100755
--- a/test/functional/wallet_create_tx.py
+++ b/test/functional/wallet_create_tx.py
@@ -92,6 +92,7 @@ class CreateTxWalletTest(BitcoinTestFramework):
txid = tx_data['txid']
vout = 1
+ self.nodes[0].syncwithvalidationinterfacequeue()
options = {"change_position": 0, "add_inputs": False}
for i in range(1, 25):
options['inputs'] = [{'txid': txid, 'vout': vout}]
diff --git a/test/functional/wallet_createwallet.py b/test/functional/wallet_createwallet.py
index 22c491441b..58cc6befbd 100755
--- a/test/functional/wallet_createwallet.py
+++ b/test/functional/wallet_createwallet.py
@@ -15,12 +15,17 @@ from test_framework.util import (
)
from test_framework.wallet_util import bytes_to_wif, generate_wif_key
+EMPTY_PASSPHRASE_MSG = "Empty string given as passphrase, wallet will not be encrypted."
+LEGACY_WALLET_MSG = "Wallet created successfully. The legacy wallet type is being deprecated and support for creating and opening legacy wallets will be removed in the future."
+
+
class CreateWalletTest(BitcoinTestFramework):
def add_options(self, parser):
self.add_wallet_options(parser)
def set_test_params(self):
self.num_nodes = 1
+ self.extra_args = [["-deprecatedrpc=walletwarningfield"]]
def skip_test_if_missing_module(self):
self.skip_if_no_wallet()
@@ -55,7 +60,7 @@ class CreateWalletTest(BitcoinTestFramework):
else:
result = w1.importmulti([{'scriptPubKey': {'address': key_to_p2wpkh(eckey.get_pubkey().get_bytes())}, 'timestamp': 'now', 'keys': [privkey]}])
assert not result[0]['success']
- assert 'warning' not in result[0]
+ assert 'warnings' not in result[0]
assert_equal(result[0]['error']['code'], -4)
assert_equal(result[0]['error']['message'], 'Cannot import private keys to a wallet with private keys disabled')
@@ -159,7 +164,9 @@ class CreateWalletTest(BitcoinTestFramework):
assert_equal(walletinfo['keypoolsize_hd_internal'], keys)
# Allow empty passphrase, but there should be a warning
resp = self.nodes[0].createwallet(wallet_name='w7', disable_private_keys=False, blank=False, passphrase='')
- assert 'Empty string given as passphrase, wallet will not be encrypted.' in resp['warning']
+ assert_equal(resp["warning"], EMPTY_PASSPHRASE_MSG if self.options.descriptors else f"{EMPTY_PASSPHRASE_MSG}\n{LEGACY_WALLET_MSG}")
+ assert_equal(resp["warnings"], [EMPTY_PASSPHRASE_MSG] if self.options.descriptors else [EMPTY_PASSPHRASE_MSG, LEGACY_WALLET_MSG])
+
w7 = node.get_wallet_rpc('w7')
assert_raises_rpc_error(-15, 'Error: running with an unencrypted wallet, but walletpassphrase was called.', w7.walletpassphrase, '', 60)
@@ -174,8 +181,24 @@ class CreateWalletTest(BitcoinTestFramework):
if self.is_bdb_compiled():
self.log.info("Test legacy wallet deprecation")
- res = self.nodes[0].createwallet(wallet_name="legacy_w0", descriptors=False, passphrase=None)
- assert_equal(res["warning"], "Wallet created successfully. The legacy wallet type is being deprecated and support for creating and opening legacy wallets will be removed in the future.")
+ result = self.nodes[0].createwallet(wallet_name="legacy_w0", descriptors=False, passphrase=None)
+ assert_equal(result, {
+ "name": "legacy_w0",
+ "warning": LEGACY_WALLET_MSG,
+ "warnings": [LEGACY_WALLET_MSG],
+ })
+ result = self.nodes[0].createwallet(wallet_name="legacy_w1", descriptors=False, passphrase="")
+ assert_equal(result, {
+ "name": "legacy_w1",
+ "warning": f"{EMPTY_PASSPHRASE_MSG}\n{LEGACY_WALLET_MSG}",
+ "warnings": [EMPTY_PASSPHRASE_MSG, LEGACY_WALLET_MSG],
+ })
+
+ self.log.info('Test "warning" field deprecation, i.e. not returned without -deprecatedrpc=walletwarningfield')
+ self.restart_node(0, extra_args=[])
+ result = self.nodes[0].createwallet(wallet_name="w7_again", disable_private_keys=False, blank=False, passphrase="")
+ assert "warning" not in result
+
if __name__ == '__main__':
CreateWalletTest().main()
diff --git a/test/functional/wallet_fast_rescan.py b/test/functional/wallet_fast_rescan.py
index 1ab24f1a96..112aa25e86 100755
--- a/test/functional/wallet_fast_rescan.py
+++ b/test/functional/wallet_fast_rescan.py
@@ -7,6 +7,7 @@
import os
from typing import List
+from test_framework.address import address_to_scriptpubkey
from test_framework.descriptors import descsum_create
from test_framework.test_framework import BitcoinTestFramework
from test_framework.test_node import TestNode
@@ -58,7 +59,7 @@ class WalletFastRescanTest(BitcoinTestFramework):
if 'range' in desc_info:
start_range, end_range = desc_info['range']
addr = w.deriveaddresses(desc_info['desc'], [end_range, end_range])[0]
- spk = bytes.fromhex(w.getaddressinfo(addr)['scriptPubKey'])
+ spk = address_to_scriptpubkey(addr)
self.log.info(f"-> range [{start_range},{end_range}], last address {addr}")
else:
spk = bytes.fromhex(fixed_key.p2wpkh_script)
diff --git a/test/functional/wallet_labels.py b/test/functional/wallet_labels.py
index a39700f73a..f074339a2b 100755
--- a/test/functional/wallet_labels.py
+++ b/test/functional/wallet_labels.py
@@ -71,6 +71,10 @@ class WalletLabelsTest(BitcoinTestFramework):
node = self.nodes[0]
assert_equal(len(node.listunspent()), 0)
+ self.log.info("Checking listlabels' invalid parameters")
+ assert_raises_rpc_error(-8, "Invalid 'purpose' argument, must be a known purpose string, typically 'send', or 'receive'.", node.listlabels, "notavalidpurpose")
+ assert_raises_rpc_error(-8, "Invalid 'purpose' argument, must be a known purpose string, typically 'send', or 'receive'.", node.listlabels, "unknown")
+
# Note each time we call generate, all generated coins go into
# the same address, so we call twice to get two addresses w/50 each
self.generatetoaddress(node, nblocks=1, address=node.getnewaddress(label='coinbase'))
diff --git a/test/functional/wallet_orphanedreward.py b/test/functional/wallet_orphanedreward.py
index d8931fa620..451f8abb0a 100755
--- a/test/functional/wallet_orphanedreward.py
+++ b/test/functional/wallet_orphanedreward.py
@@ -65,7 +65,10 @@ class OrphanedBlockRewardTest(BitcoinTestFramework):
assert_equal(self.nodes[0].getbestblockhash(), orig_chain_tip)
self.generate(self.nodes[0], 3)
- assert_equal(self.nodes[1].getbalances(), pre_reorg_conf_bals)
+ balances = self.nodes[1].getbalances()
+ del balances["lastprocessedblock"]
+ del pre_reorg_conf_bals["lastprocessedblock"]
+ assert_equal(balances, pre_reorg_conf_bals)
assert_equal(self.nodes[1].gettransaction(txid)["details"][0]["abandoned"], True)
diff --git a/test/lint/lint-circular-dependencies.py b/test/lint/lint-circular-dependencies.py
index cf6a5f81f1..307b4dca5a 100755
--- a/test/lint/lint-circular-dependencies.py
+++ b/test/lint/lint-circular-dependencies.py
@@ -12,7 +12,7 @@ import subprocess
import sys
EXPECTED_CIRCULAR_DEPENDENCIES = (
- "chainparamsbase -> util/system -> chainparamsbase",
+ "chainparamsbase -> common/args -> chainparamsbase",
"node/blockstorage -> validation -> node/blockstorage",
"node/utxo_snapshot -> validation -> node/utxo_snapshot",
"qt/addresstablemodel -> qt/walletmodel -> qt/addresstablemodel",
diff --git a/test/lint/lint-locale-dependence.py b/test/lint/lint-locale-dependence.py
index faea643882..d84e458bb1 100755
--- a/test/lint/lint-locale-dependence.py
+++ b/test/lint/lint-locale-dependence.py
@@ -44,8 +44,6 @@ from subprocess import check_output, CalledProcessError
KNOWN_VIOLATIONS = [
"src/dbwrapper.cpp:.*vsnprintf",
"src/test/fuzz/locale.cpp:.*setlocale",
- "src/test/fuzz/string.cpp:.*strtol",
- "src/test/fuzz/string.cpp:.*strtoul",
"src/test/util_tests.cpp:.*strtoll",
"src/wallet/bdb.cpp:.*DbEnv::strerror", # False positive
"src/util/syserror.cpp:.*strerror", # Outside this function use `SysErrorString`
diff --git a/test/lint/lint-python-utf8-encoding.py b/test/lint/lint-python-utf8-encoding.py
index 364da63468..64d04bff57 100755
--- a/test/lint/lint-python-utf8-encoding.py
+++ b/test/lint/lint-python-utf8-encoding.py
@@ -12,7 +12,7 @@ import re
from subprocess import check_output, CalledProcessError
-EXCLUDED_DIRS = ["src/crc32c/"]
+EXCLUDED_DIRS = ["src/crc32c/", "src/secp256k1/"]
def get_exclude_args():
diff --git a/test/lint/lint-python.py b/test/lint/lint-python.py
index 4ec7608708..9de13e44e2 100755
--- a/test/lint/lint-python.py
+++ b/test/lint/lint-python.py
@@ -15,7 +15,13 @@ import sys
DEPS = ['flake8', 'mypy', 'pyzmq']
MYPY_CACHE_DIR = f"{os.getenv('BASE_ROOT_DIR', '')}/test/.mypy_cache"
-FILES_ARGS = ['git', 'ls-files', 'test/functional/*.py', 'contrib/devtools/*.py']
+
+# All .py files, except those in src/ (to exclude subtrees there)
+FLAKE_FILES_ARGS = ['git', 'ls-files', '*.py', ':!:src/*.py']
+
+# Only .py files in test/functional and contrib/devtools have type annotations
+# enforced.
+MYPY_FILES_ARGS = ['git', 'ls-files', 'test/functional/*.py', 'contrib/devtools/*.py']
ENABLED = (
'E101,' # indentation contains mixed spaces and tabs
@@ -107,8 +113,7 @@ def main():
if len(sys.argv) > 1:
flake8_files = sys.argv[1:]
else:
- files_args = ['git', 'ls-files', '*.py']
- flake8_files = subprocess.check_output(files_args).decode("utf-8").splitlines()
+ flake8_files = subprocess.check_output(FLAKE_FILES_ARGS).decode("utf-8").splitlines()
flake8_args = ['flake8', '--ignore=B,C,E,F,I,N,W', f'--select={ENABLED}'] + flake8_files
flake8_env = os.environ.copy()
@@ -119,7 +124,7 @@ def main():
except subprocess.CalledProcessError:
exit(1)
- mypy_files = subprocess.check_output(FILES_ARGS).decode("utf-8").splitlines()
+ mypy_files = subprocess.check_output(MYPY_FILES_ARGS).decode("utf-8").splitlines()
mypy_args = ['mypy', '--show-error-codes'] + mypy_files
try:
diff --git a/test/sanitizer_suppressions/lsan b/test/sanitizer_suppressions/lsan
index 828b1676f6..7ccb22515f 100644
--- a/test/sanitizer_suppressions/lsan
+++ b/test/sanitizer_suppressions/lsan
@@ -1,5 +1,2 @@
# Suppress warnings triggered in dependencies
leak:libQt5Widgets
-
-# false-positive due to use of secure_allocator<>
-leak:GetRNGState
diff --git a/test/sanitizer_suppressions/tsan b/test/sanitizer_suppressions/tsan
index d331991273..5a790b72f2 100644
--- a/test/sanitizer_suppressions/tsan
+++ b/test/sanitizer_suppressions/tsan
@@ -13,6 +13,8 @@ race:zmq::*
race:bitcoin-qt
# deadlock (TODO fix)
+# To reproduce, see:
+# https://github.com/bitcoin/bitcoin/issues/19303#issuecomment-1514926359
deadlock:Chainstate::ConnectTip
# Intentional deadlock in tests
@@ -35,7 +37,7 @@ race:libzmq
# https://github.com/bitcoin/bitcoin/issues/20618
race:CZMQAbstractPublishNotifier::SendZmqMessage
-# https://github.com/bitcoin/bitcoin/pull/20218, https://github.com/bitcoin/bitcoin/pull/20745
+# https://github.com/bitcoin/bitcoin/pull/27498#issuecomment-1517410478
race:epoll_ctl
# https://github.com/bitcoin/bitcoin/issues/23366
diff --git a/test/sanitizer_suppressions/ubsan b/test/sanitizer_suppressions/ubsan
index 2fa4e383e2..6b891c462e 100644
--- a/test/sanitizer_suppressions/ubsan
+++ b/test/sanitizer_suppressions/ubsan
@@ -5,16 +5,12 @@
# names can be used.
# See https://github.com/google/sanitizers/issues/1364
-# https://github.com/bitcoin/bitcoin/pull/21798#issuecomment-829180719
-signed-integer-overflow:policy/feerate.cpp
-
# -fsanitize=integer suppressions
# ===============================
# Dependencies
# ------------
# Suppressions in dependencies that are developed outside this repository.
unsigned-integer-overflow:*/include/c++/
-unsigned-integer-overflow:bench/bench.h
# unsigned-integer-overflow in FuzzedDataProvider's ConsumeIntegralInRange
unsigned-integer-overflow:FuzzedDataProvider.h
unsigned-integer-overflow:leveldb/
@@ -31,8 +27,6 @@ implicit-signed-integer-truncation:leveldb/
implicit-unsigned-integer-truncation:*/include/c++/
implicit-unsigned-integer-truncation:leveldb/
implicit-unsigned-integer-truncation:test/fuzz/crypto_diff_fuzz_chacha20.cpp
-# std::variant warning fixed in https://github.com/gcc-mirror/gcc/commit/074436cf8cdd2a9ce75cadd36deb8301f00e55b9
-implicit-unsigned-integer-truncation:std::__detail::__variant::_Variant_storage
shift-base:*/include/c++/
shift-base:leveldb/
shift-base:minisketch/