aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml2
-rw-r--r--COPYING2
-rw-r--r--Makefile.am13
-rw-r--r--README.md39
-rw-r--r--build-aux/m4/bitcoin_find_bdb48.m42
-rw-r--r--configure.ac83
-rw-r--r--contrib/debian/manpages/bitcoind.124
-rwxr-xr-xcontrib/devtools/github-merge.sh6
-rwxr-xr-xcontrib/devtools/optimize-pngs.py73
-rw-r--r--contrib/gitian-descriptors/gitian-osx-signer.yml6
-rw-r--r--contrib/gitian-descriptors/gitian-osx.yml6
-rw-r--r--contrib/gitian-downloader/jonasschnelli-key.pgpbin0 -> 2230 bytes
-rw-r--r--contrib/macdeploy/DS_Storebin15364 -> 10244 bytes
-rw-r--r--contrib/macdeploy/background.pngbin12073 -> 48690 bytes
-rw-r--r--contrib/macdeploy/background.psdbin163518 -> 982442 bytes
-rw-r--r--contrib/macdeploy/background.tiffbin0 -> 202136 bytes
-rw-r--r--contrib/macdeploy/background@2x.pngbin0 -> 138890 bytes
-rw-r--r--contrib/macdeploy/fancy.plist2
-rwxr-xr-xcontrib/macdeploy/macdeployqtplus9
-rw-r--r--contrib/seeds/README.md11
-rwxr-xr-xcontrib/seeds/makeseeds.py122
-rw-r--r--depends/README2
-rwxr-xr-xdepends/config.guess15
-rwxr-xr-xdepends/config.sub25
-rw-r--r--depends/funcs.mk6
-rw-r--r--depends/hosts/darwin.mk9
-rw-r--r--depends/packages/native_cctools.mk88
-rw-r--r--depends/packages/native_libuuid.mk24
-rw-r--r--depends/packages/native_openssl.mk21
-rw-r--r--depends/packages/openssl.mk6
-rw-r--r--depends/packages/packages.mk2
-rw-r--r--depends/packages/qt.mk5
-rw-r--r--depends/patches/qt/mac-qmake.conf2
-rw-r--r--depends/patches/qt/qt5-yosemite.patch52
-rw-r--r--doc/README.md9
-rw-r--r--doc/README_osx.txt9
-rw-r--r--doc/README_windows.txt12
-rw-r--r--doc/assets-attribution.md30
-rw-r--r--doc/bootstrap.md56
-rw-r--r--doc/build-osx.md16
-rw-r--r--doc/build-unix.md4
-rw-r--r--doc/developer-notes.md (renamed from doc/coding.md)48
-rw-r--r--doc/gitian-building.md36
-rw-r--r--doc/release-process.md10
-rw-r--r--pkg.m4214
-rwxr-xr-xqa/pull-tester/rpc-tests.sh3
-rwxr-xr-xqa/pull-tester/run-bitcoind-for-test.sh.in2
-rw-r--r--qa/rpc-tests/README.md2
-rwxr-xr-xqa/rpc-tests/bipdersig.py90
-rwxr-xr-xqa/rpc-tests/getblocktemplate_proposals.py1
-rwxr-xr-xqa/rpc-tests/httpbasics.py36
-rwxr-xr-xqa/rpc-tests/smartfees.py6
-rwxr-xr-xqa/rpc-tests/test_framework.py5
-rwxr-xr-xqa/rpc-tests/wallet.py9
-rwxr-xr-xqa/rpc-tests/zapwallettxes.py82
-rwxr-xr-xqa/rpc-tests/zapwallettxes.sh165
-rw-r--r--share/seeds/nodes_main.txt1115
-rw-r--r--src/Makefile.am88
-rw-r--r--src/Makefile.qt.include15
-rw-r--r--src/Makefile.test.include11
-rw-r--r--src/addrman.cpp8
-rw-r--r--src/alert.cpp2
-rw-r--r--src/arith_uint256.cpp259
-rw-r--r--src/arith_uint256.h290
-rw-r--r--src/bitcoin-cli.cpp14
-rw-r--r--src/bitcoin-tx.cpp17
-rw-r--r--src/bitcoind.cpp16
-rw-r--r--src/chain.h11
-rw-r--r--src/chainparams.cpp70
-rw-r--r--src/chainparams.h7
-rw-r--r--src/chainparamsbase.cpp8
-rw-r--r--src/chainparamsbase.h1
-rw-r--r--src/chainparamsseeds.h1092
-rw-r--r--src/checkqueue.h14
-rw-r--r--src/clientversion.h2
-rw-r--r--src/coins.cpp34
-rw-r--r--src/coins.h13
-rw-r--r--src/core_io.h1
-rw-r--r--src/core_read.cpp19
-rw-r--r--src/core_write.cpp2
-rw-r--r--src/crypter.cpp39
-rw-r--r--src/crypter.h3
-rw-r--r--src/crypto/rfc6979_hmac_sha256.cpp47
-rw-r--r--src/crypto/rfc6979_hmac_sha256.h36
-rw-r--r--src/db.cpp51
-rw-r--r--src/db.h5
-rw-r--r--src/ecwrapper.cpp30
-rw-r--r--src/init.cpp87
-rw-r--r--src/key.cpp47
-rw-r--r--src/keystore.cpp4
-rw-r--r--src/keystore.h5
-rw-r--r--src/main.cpp542
-rw-r--r--src/main.h39
-rw-r--r--src/merkleblock.cpp28
-rw-r--r--src/miner.cpp58
-rw-r--r--src/miner.h16
-rw-r--r--src/net.cpp75
-rw-r--r--src/net.h3
-rw-r--r--src/pow.cpp19
-rw-r--r--src/pow.h3
-rw-r--r--src/primitives/block.cpp4
-rw-r--r--src/primitives/block.h8
-rw-r--r--src/primitives/transaction.cpp4
-rw-r--r--src/primitives/transaction.h4
-rw-r--r--src/protocol.cpp8
-rw-r--r--src/pubkey.h2
-rw-r--r--src/qt/addresstablemodel.cpp6
-rw-r--r--src/qt/bitcoin.cpp27
-rw-r--r--src/qt/bitcoin.qrc6
-rw-r--r--src/qt/bitcoinamountfield.cpp40
-rw-r--r--src/qt/bitcoingui.cpp35
-rw-r--r--src/qt/bitcoingui.h2
-rw-r--r--src/qt/bitcoinunits.cpp11
-rw-r--r--src/qt/bitcoinunits.h2
-rw-r--r--src/qt/clientmodel.cpp4
-rw-r--r--src/qt/coincontroldialog.cpp28
-rw-r--r--src/qt/coincontroldialog.h2
-rw-r--r--src/qt/coincontroltreewidget.cpp5
-rw-r--r--src/qt/forms/addressbookpage.ui2
-rw-r--r--src/qt/forms/helpmessagedialog.ui114
-rw-r--r--src/qt/forms/optionsdialog.ui2
-rw-r--r--src/qt/forms/rpcconsole.ui25
-rw-r--r--src/qt/forms/signverifymessagedialog.ui4
-rw-r--r--src/qt/guiutil.cpp43
-rw-r--r--src/qt/guiutil.h7
-rw-r--r--src/qt/paymentrequestplus.cpp32
-rw-r--r--src/qt/paymentserver.cpp114
-rw-r--r--src/qt/paymentserver.h7
-rw-r--r--src/qt/res/icons/about.pngbin5925 -> 4726 bytes
-rw-r--r--src/qt/res/icons/about_qt.pngbin3107 -> 2338 bytes
-rw-r--r--src/qt/res/icons/add.pngbin15199 -> 784 bytes
-rw-r--r--src/qt/res/icons/address-book.pngbin16150 -> 1275 bytes
-rw-r--r--src/qt/res/icons/bitcoin.pngbin350390 -> 312944 bytes
-rw-r--r--src/qt/res/icons/clock1.pngbin2448 -> 1921 bytes
-rw-r--r--src/qt/res/icons/clock2.pngbin2269 -> 1731 bytes
-rw-r--r--src/qt/res/icons/clock3.pngbin2184 -> 1557 bytes
-rw-r--r--src/qt/res/icons/clock4.pngbin1995 -> 1395 bytes
-rw-r--r--src/qt/res/icons/clock5.pngbin2682 -> 1889 bytes
-rw-r--r--src/qt/res/icons/configure.pngbin3891 -> 2865 bytes
-rw-r--r--src/qt/res/icons/connect0.pngbin16890 -> 2290 bytes
-rw-r--r--src/qt/res/icons/connect1.pngbin16870 -> 2242 bytes
-rw-r--r--src/qt/res/icons/connect2.pngbin16566 -> 1966 bytes
-rw-r--r--src/qt/res/icons/connect3.pngbin16566 -> 1966 bytes
-rw-r--r--src/qt/res/icons/connect4.pngbin16117 -> 1490 bytes
-rw-r--r--src/qt/res/icons/debugwindow.pngbin15930 -> 1327 bytes
-rw-r--r--src/qt/res/icons/edit.pngbin2544 -> 1847 bytes
-rw-r--r--src/qt/res/icons/editcopy.pngbin1295 -> 883 bytes
-rw-r--r--src/qt/res/icons/editpaste.pngbin15778 -> 1024 bytes
-rw-r--r--src/qt/res/icons/export.pngbin17005 -> 1750 bytes
-rw-r--r--src/qt/res/icons/eye.pngbin2806 -> 2241 bytes
-rw-r--r--src/qt/res/icons/eye_minus.pngbin3087 -> 2438 bytes
-rw-r--r--src/qt/res/icons/eye_plus.pngbin3368 -> 2599 bytes
-rw-r--r--src/qt/res/icons/filesave.pngbin2874 -> 2359 bytes
-rw-r--r--src/qt/res/icons/history.pngbin16271 -> 762 bytes
-rw-r--r--src/qt/res/icons/info.pngbin2895 -> 2028 bytes
-rw-r--r--src/qt/res/icons/key.pngbin2434 -> 1759 bytes
-rw-r--r--src/qt/res/icons/lock_closed.pngbin1686 -> 1197 bytes
-rw-r--r--src/qt/res/icons/lock_open.pngbin1751 -> 1257 bytes
-rw-r--r--src/qt/res/icons/open.pngbin2239 -> 1694 bytes
-rw-r--r--src/qt/res/icons/overview.pngbin2215 -> 1662 bytes
-rw-r--r--src/qt/res/icons/quit.pngbin15766 -> 1091 bytes
-rw-r--r--src/qt/res/icons/receive.pngbin2874 -> 2067 bytes
-rw-r--r--src/qt/res/icons/remove.pngbin16663 -> 1723 bytes
-rw-r--r--src/qt/res/icons/send.pngbin17005 -> 1750 bytes
-rw-r--r--src/qt/res/icons/synced.pngbin16891 -> 1619 bytes
-rw-r--r--src/qt/res/icons/transaction0.pngbin1759 -> 1220 bytes
-rw-r--r--src/qt/res/icons/transaction2.pngbin16891 -> 1619 bytes
-rw-r--r--src/qt/res/icons/transaction_conflicted.pngbin15766 -> 1091 bytes
-rw-r--r--src/qt/res/icons/tx_inout.pngbin2568 -> 1655 bytes
-rw-r--r--src/qt/res/icons/tx_input.pngbin2590 -> 1783 bytes
-rw-r--r--src/qt/res/icons/tx_mined.pngbin2166 -> 1578 bytes
-rw-r--r--src/qt/res/icons/tx_output.pngbin2699 -> 1771 bytes
-rw-r--r--src/qt/res/icons/unit_btc.pngbin1318 -> 0 bytes
-rw-r--r--src/qt/res/icons/unit_mbtc.pngbin1407 -> 0 bytes
-rw-r--r--src/qt/res/icons/unit_ubtc.pngbin1369 -> 0 bytes
-rw-r--r--src/qt/res/icons/verify.pngbin2984 -> 2034 bytes
-rw-r--r--src/qt/res/images/about.pngbin1136 -> 0 bytes
-rw-r--r--src/qt/res/movies/spinner-000.pngbin16636 -> 1835 bytes
-rw-r--r--src/qt/res/movies/spinner-001.pngbin2785 -> 2376 bytes
-rw-r--r--src/qt/res/movies/spinner-002.pngbin2814 -> 2376 bytes
-rw-r--r--src/qt/res/movies/spinner-003.pngbin2775 -> 2355 bytes
-rw-r--r--src/qt/res/movies/spinner-004.pngbin2850 -> 2349 bytes
-rw-r--r--src/qt/res/movies/spinner-005.pngbin2728 -> 2305 bytes
-rw-r--r--src/qt/res/movies/spinner-006.pngbin2734 -> 2304 bytes
-rw-r--r--src/qt/res/movies/spinner-007.pngbin2633 -> 2283 bytes
-rw-r--r--src/qt/res/movies/spinner-008.pngbin2611 -> 2312 bytes
-rw-r--r--src/qt/res/movies/spinner-009.pngbin2074 -> 1810 bytes
-rw-r--r--src/qt/res/movies/spinner-010.pngbin2666 -> 2305 bytes
-rw-r--r--src/qt/res/movies/spinner-011.pngbin2751 -> 2338 bytes
-rw-r--r--src/qt/res/movies/spinner-012.pngbin2828 -> 2352 bytes
-rw-r--r--src/qt/res/movies/spinner-013.pngbin2896 -> 2377 bytes
-rw-r--r--src/qt/res/movies/spinner-014.pngbin2867 -> 2358 bytes
-rw-r--r--src/qt/res/movies/spinner-015.pngbin2860 -> 2405 bytes
-rw-r--r--src/qt/res/movies/spinner-016.pngbin2825 -> 2429 bytes
-rw-r--r--src/qt/res/movies/spinner-017.pngbin2833 -> 2408 bytes
-rw-r--r--src/qt/res/movies/spinner-018.pngbin2147 -> 1831 bytes
-rw-r--r--src/qt/res/movies/spinner-019.pngbin2808 -> 2380 bytes
-rw-r--r--src/qt/res/movies/spinner-020.pngbin2800 -> 2366 bytes
-rw-r--r--src/qt/res/movies/spinner-021.pngbin2833 -> 2368 bytes
-rw-r--r--src/qt/res/movies/spinner-022.pngbin2823 -> 2356 bytes
-rw-r--r--src/qt/res/movies/spinner-023.pngbin2710 -> 2311 bytes
-rw-r--r--src/qt/res/movies/spinner-024.pngbin2732 -> 2315 bytes
-rw-r--r--src/qt/res/movies/spinner-025.pngbin2635 -> 2298 bytes
-rw-r--r--src/qt/res/movies/spinner-026.pngbin2643 -> 2291 bytes
-rw-r--r--src/qt/res/movies/spinner-027.pngbin2099 -> 1816 bytes
-rw-r--r--src/qt/res/movies/spinner-028.pngbin2665 -> 2308 bytes
-rw-r--r--src/qt/res/movies/spinner-029.pngbin2761 -> 2356 bytes
-rw-r--r--src/qt/res/movies/spinner-030.pngbin2832 -> 2346 bytes
-rw-r--r--src/qt/res/movies/spinner-031.pngbin2871 -> 2380 bytes
-rw-r--r--src/qt/res/movies/spinner-032.pngbin2839 -> 2345 bytes
-rw-r--r--src/qt/res/movies/spinner-033.pngbin2829 -> 2401 bytes
-rw-r--r--src/qt/res/movies/spinner-034.pngbin2851 -> 2422 bytes
-rw-r--r--src/qt/res/movies/spinner-035.pngbin2837 -> 2406 bytes
-rw-r--r--src/qt/rpcconsole.cpp1
-rw-r--r--src/qt/sendcoinsdialog.cpp16
-rw-r--r--src/qt/splashscreen.cpp2
-rw-r--r--src/qt/test/paymentrequestdata.h173
-rw-r--r--src/qt/test/paymentservertests.cpp107
-rw-r--r--src/qt/transactiontablemodel.cpp10
-rw-r--r--src/qt/transactionview.h4
-rw-r--r--src/qt/utilitydialog.cpp96
-rw-r--r--src/qt/walletmodel.cpp14
-rw-r--r--src/qt/walletmodel.h5
-rw-r--r--src/rest.cpp2
-rw-r--r--src/rpcblockchain.cpp29
-rw-r--r--src/rpcdump.cpp10
-rw-r--r--src/rpcmining.cpp46
-rw-r--r--src/rpcmisc.cpp25
-rw-r--r--src/rpcnet.cpp12
-rw-r--r--src/rpcprotocol.cpp2
-rw-r--r--src/rpcrawtransaction.cpp42
-rw-r--r--src/rpcserver.cpp312
-rw-r--r--src/rpcserver.h12
-rw-r--r--src/rpcwallet.cpp170
-rw-r--r--src/script/bitcoinconsensus.cpp2
-rw-r--r--src/script/bitcoinconsensus.h1
-rw-r--r--src/script/interpreter.cpp176
-rw-r--r--src/script/interpreter.h26
-rw-r--r--src/script/script.h2
-rw-r--r--src/script/script_error.h1
-rw-r--r--src/script/sigcache.cpp4
-rw-r--r--src/script/sigcache.h4
-rw-r--r--src/script/sign.cpp4
-rw-r--r--src/script/standard.h8
-rw-r--r--src/secp256k1/.gitignore1
-rw-r--r--src/secp256k1/.travis.yml14
-rw-r--r--src/secp256k1/Makefile.am4
-rw-r--r--src/secp256k1/build-aux/m4/bitcoin_secp.m420
-rw-r--r--src/secp256k1/configure.ac113
-rw-r--r--src/secp256k1/include/secp256k1.h51
-rw-r--r--src/secp256k1/src/bench_sign.c5
-rw-r--r--src/secp256k1/src/bench_verify.c4
-rw-r--r--src/secp256k1/src/ecdsa_impl.h59
-rw-r--r--src/secp256k1/src/ecmult_gen_impl.h2
-rw-r--r--src/secp256k1/src/ecmult_impl.h4
-rw-r--r--src/secp256k1/src/field.h19
-rw-r--r--src/secp256k1/src/field_10x26_impl.h111
-rw-r--r--src/secp256k1/src/field_5x52_impl.h96
-rw-r--r--src/secp256k1/src/field_gmp.h18
-rw-r--r--src/secp256k1/src/field_gmp_impl.h184
-rw-r--r--src/secp256k1/src/field_impl.h16
-rw-r--r--src/secp256k1/src/group.h7
-rw-r--r--src/secp256k1/src/group_impl.h66
-rw-r--r--src/secp256k1/src/hash.h41
-rw-r--r--src/secp256k1/src/hash_impl.h291
-rw-r--r--src/secp256k1/src/secp256k1.c73
-rw-r--r--src/secp256k1/src/tests.c502
-rw-r--r--src/serialize.h2
-rw-r--r--src/streams.h18
-rw-r--r--src/sync.h11
-rw-r--r--src/test/Checkpoints_tests.cpp4
-rw-r--r--src/test/accounting_tests.cpp6
-rw-r--r--src/test/arith_uint256_tests.cpp566
-rw-r--r--src/test/bignum.h8
-rw-r--r--src/test/bloom_tests.cpp59
-rw-r--r--src/test/crypto_tests.cpp35
-rw-r--r--src/test/data/README.md8
-rw-r--r--src/test/data/bitcoin-util-test.json10
-rw-r--r--src/test/data/script_invalid.json120
-rw-r--r--src/test/data/script_valid.json81
-rw-r--r--src/test/data/sig_canonical.json7
-rw-r--r--src/test/data/sig_noncanonical.json22
-rw-r--r--src/test/data/txcreatesign.hex1
-rw-r--r--src/test/multisig_tests.cpp40
-rw-r--r--src/test/pmt_tests.cpp35
-rw-r--r--src/test/rpc_wallet_tests.cpp37
-rw-r--r--src/test/sanity_tests.cpp18
-rw-r--r--src/test/script_P2SH_tests.cpp4
-rw-r--r--src/test/script_tests.cpp132
-rw-r--r--src/test/sighash_tests.cpp9
-rw-r--r--src/test/sigopcount_tests.cpp2
-rw-r--r--src/test/skiplist_tests.cpp12
-rw-r--r--src/test/transaction_tests.cpp22
-rw-r--r--src/test/uint256_tests.cpp745
-rw-r--r--src/test/util_tests.cpp18
-rw-r--r--src/timedata.cpp4
-rw-r--r--src/txdb.cpp63
-rw-r--r--src/txmempool.cpp15
-rw-r--r--src/uint256.cpp281
-rw-r--r--src/uint256.h321
-rw-r--r--src/undo.h14
-rw-r--r--src/wallet.cpp250
-rw-r--r--src/wallet.h837
-rw-r--r--src/walletdb.cpp23
-rw-r--r--src/walletdb.h2
305 files changed, 7328 insertions, 5829 deletions
diff --git a/.travis.yml b/.travis.yml
index 1630c1d02a..3c995be9a5 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -33,7 +33,7 @@ matrix:
- compiler: ": 32-bit + dash"
env: HOST=i686-pc-linux-gnu PACKAGES="g++-multilib bc" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat" USE_SHELL="/bin/dash"
- compiler: ": Cross-Mac"
- env: HOST=x86_64-apple-darwin11 PACKAGES="gcc-multilib g++-multilib cmake libcap-dev libz-dev libbz2-dev" OSX_SDK=10.7 GOAL="deploy"
+ env: HOST=x86_64-apple-darwin11 PACKAGES="cmake libcap-dev libz-dev libbz2-dev" OSX_SDK=10.9 GOAL="deploy"
- compiler: ": Win64"
env: HOST=x86_64-w64-mingw32 PACKAGES="nsis gcc-mingw-w64-x86-64 g++-mingw-w64-x86-64 binutils-mingw-w64-x86-64 mingw-w64-dev wine bc" RUN_TESTS=true GOAL="deploy" BITCOIN_CONFIG="--enable-gui" MAKEJOBS="-j2"
- compiler: ": Win32"
diff --git a/COPYING b/COPYING
index 6219bd75a6..9fd3266622 100644
--- a/COPYING
+++ b/COPYING
@@ -1,4 +1,4 @@
-Copyright (c) 2009-2014 Bitcoin Developers
+Copyright (c) 2009-2015 Bitcoin Developers
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/Makefile.am b/Makefile.am
index 5649770602..c59648fd02 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -16,6 +16,7 @@ BITCOIN_WIN_INSTALLER=$(PACKAGE)-$(PACKAGE_VERSION)-win$(WINDOWS_BITS)-setup$(EX
OSX_APP=Bitcoin-Qt.app
OSX_DMG=Bitcoin-Qt.dmg
+OSX_BACKGROUND_IMAGE=background.tiff
OSX_DEPLOY_SCRIPT=$(top_srcdir)/contrib/macdeploy/macdeployqtplus
OSX_FANCY_PLIST=$(top_srcdir)/contrib/macdeploy/fancy.plist
OSX_INSTALLER_ICONS=$(top_srcdir)/src/qt/res/icons/bitcoin.icns
@@ -30,7 +31,7 @@ WINDOWS_PACKAGING = $(top_srcdir)/share/pixmaps/bitcoin.ico \
$(top_srcdir)/doc/README_windows.txt
OSX_PACKAGING = $(OSX_DEPLOY_SCRIPT) $(OSX_FANCY_PLIST) $(OSX_INSTALLER_ICONS) \
- $(top_srcdir)/contrib/macdeploy/background.png \
+ $(top_srcdir)/contrib/macdeploy/$(OSX_BACKGROUND_IMAGE) \
$(top_srcdir)/contrib/macdeploy/DS_Store \
$(top_srcdir)/contrib/macdeploy/detached-sig-apply.sh \
$(top_srcdir)/contrib/macdeploy/detached-sig-create.sh
@@ -95,7 +96,7 @@ $(OSX_DMG): $(OSX_APP_BUILT) $(OSX_PACKAGING)
deploydir: $(OSX_DMG)
else
APP_DIST_DIR=$(top_builddir)/dist
-APP_DIST_EXTRAS=$(APP_DIST_DIR)/.background/background.png $(APP_DIST_DIR)/.DS_Store $(APP_DIST_DIR)/Applications
+APP_DIST_EXTRAS=$(APP_DIST_DIR)/.background/$(OSX_BACKGROUND_IMAGE) $(APP_DIST_DIR)/.DS_Store $(APP_DIST_DIR)/Applications
$(APP_DIST_DIR)/Applications:
@rm -f $@
@@ -106,11 +107,11 @@ $(APP_DIST_EXTRAS): $(APP_DIST_DIR)/$(OSX_APP)/Contents/MacOS/Bitcoin-Qt
$(OSX_DMG): $(APP_DIST_EXTRAS)
$(GENISOIMAGE) -no-cache-inodes -D -l -probe -V "Bitcoin-Qt" -no-pad -r -apple -o $@ dist
-$(APP_DIST_DIR)/.background/background.png:
+$(APP_DIST_DIR)/.background/$(OSX_BACKGROUND_IMAGE): contrib/macdeploy/$(OSX_BACKGROUND_IMAGE)
$(MKDIR_P) $(@D)
- $(INSTALL) $(top_srcdir)/contrib/macdeploy/background.png $@
-$(APP_DIST_DIR)/.DS_Store:
- $(INSTALL) $(top_srcdir)/contrib/macdeploy/DS_Store $@
+ $(INSTALL) $< $@
+$(APP_DIST_DIR)/.DS_Store: contrib/macdeploy/DS_Store
+ $(INSTALL) $< $@
$(APP_DIST_DIR)/$(OSX_APP)/Contents/MacOS/Bitcoin-Qt: $(OSX_APP_BUILT) $(OSX_PACKAGING)
INSTALLNAMETOOL=$(INSTALLNAMETOOL) OTOOL=$(OTOOL) STRIP=$(STRIP) $(OSX_DEPLOY_SCRIPT) $(OSX_APP) -translations-dir=$(QT_TRANSLATION_DIR) -add-qt-tr $(OSX_QT_TRANSLATIONS) -verbose 2
diff --git a/README.md b/README.md
index cf650fe543..67c5ed5b41 100644
--- a/README.md
+++ b/README.md
@@ -5,8 +5,6 @@ Bitcoin Core integration/staging tree
https://www.bitcoin.org
-Copyright (c) 2009-2014 Bitcoin Core Developers
-
What is Bitcoin?
----------------
@@ -40,7 +38,7 @@ submitter will be asked to start a discussion (if they haven't already) on the
The patch will be accepted if there is broad consensus that it is a good thing.
Developers should expect to rework and resubmit patches if the code doesn't
-match the project's coding conventions (see [doc/coding.md](doc/coding.md)) or are
+match the project's coding conventions (see [doc/developer-notes.md](doc/developer-notes.md)) or are
controversial.
The `master` branch is regularly built and tested, but is not guaranteed to be
@@ -85,38 +83,3 @@ Translations are periodically pulled from Transifex and merged into the git repo
pull from Transifex would automatically overwrite them again.
Translators should also subscribe to the [mailing list](https://groups.google.com/forum/#!forum/bitcoin-translators).
-
-Development tips and tricks
----------------------------
-
-**compiling for debugging**
-
-Run configure with the --enable-debug option, then make. Or run configure with
-CXXFLAGS="-g -ggdb -O0" or whatever debug flags you need.
-
-**debug.log**
-
-If the code is behaving strangely, take a look in the debug.log file in the data directory;
-error and debugging messages are written there.
-
-The -debug=... command-line option controls debugging; running with just -debug will turn
-on all categories (and give you a very large debug.log file).
-
-The Qt code routes qDebug() output to debug.log under category "qt": run with -debug=qt
-to see it.
-
-**testnet and regtest modes**
-
-Run with the -testnet option to run with "play bitcoins" on the test network, if you
-are testing multi-machine code that needs to operate across the internet.
-
-If you are testing something that can run on one machine, run with the -regtest option.
-In regression test mode, blocks can be created on-demand; see qa/rpc-tests/ for tests
-that run in -regtest mode.
-
-**DEBUG_LOCKORDER**
-
-Bitcoin Core is a multithreaded application, and deadlocks or other multithreading bugs
-can be very difficult to track down. Compiling with -DDEBUG_LOCKORDER (configure
-CXXFLAGS="-DDEBUG_LOCKORDER -g") inserts run-time checks to keep track of which locks
-are held, and adds warnings to the debug.log file if inconsistencies are detected.
diff --git a/build-aux/m4/bitcoin_find_bdb48.m4 b/build-aux/m4/bitcoin_find_bdb48.m4
index f3b14461eb..0bf558d25b 100644
--- a/build-aux/m4/bitcoin_find_bdb48.m4
+++ b/build-aux/m4/bitcoin_find_bdb48.m4
@@ -38,7 +38,7 @@ AC_DEFUN([BITCOIN_FIND_BDB48],[
done
if test "x$bdbpath" = "xX"; then
AC_MSG_RESULT([no])
- AC_MSG_ERROR(libdb_cxx headers missing)
+ AC_MSG_ERROR([libdb_cxx headers missing, Bitcoin Core requires this library for wallet functionality (--disable-wallet to disable wallet functionality)])
elif test "x$bdb48path" = "xX"; then
BITCOIN_SUBDIR_TO_INCLUDE(BDB_CPPFLAGS,[${bdbpath}],db_cxx)
AC_ARG_WITH([incompatible-bdb],[AS_HELP_STRING([--with-incompatible-bdb], [allow using a bdb version other than 4.8])],[
diff --git a/configure.ac b/configure.ac
index b28898a4fa..85e3d1d669 100644
--- a/configure.ac
+++ b/configure.ac
@@ -5,7 +5,7 @@ define(_CLIENT_VERSION_MINOR, 10)
define(_CLIENT_VERSION_REVISION, 99)
define(_CLIENT_VERSION_BUILD, 0)
define(_CLIENT_VERSION_IS_RELEASE, false)
-define(_COPYRIGHT_YEAR, 2014)
+define(_COPYRIGHT_YEAR, 2015)
AC_INIT([Bitcoin Core],[_CLIENT_VERSION_MAJOR._CLIENT_VERSION_MINOR._CLIENT_VERSION_REVISION],[info@bitcoin.org],[bitcoin])
AC_CONFIG_SRCDIR([src/main.cpp])
AC_CONFIG_HEADERS([src/config/bitcoin-config.h])
@@ -64,13 +64,6 @@ AC_PATH_PROG(CCACHE,ccache)
AC_PATH_PROG(XGETTEXT,xgettext)
AC_PATH_PROG(HEXDUMP,hexdump)
-# This m4 will only be used if a system copy cannot be found. This is helpful
-# on systems where autotools are installed but the pkg-config macros are not in
-# a default location. It is currently used for building on OSX where autotools
-# are preinstalled but pkg-config comes from macports or homebrew. It should
-# probably be removed when building on <= 10.6 is no longer supported.
-m4_include([pkg.m4])
-
dnl pkg-config check.
PKG_PROG_PKG_CONFIG
@@ -171,6 +164,24 @@ if test "x$CXXFLAGS_overridden" = "xno"; then
fi
CPPFLAGS="$CPPFLAGS -DBOOST_SPIRIT_THREADSAFE -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS"
+AC_ARG_WITH([utils],
+ [AS_HELP_STRING([--with-utils],
+ [build bitcoin-cli bitcoin-tx (default=yes)])],
+ [build_bitcoin_utils=$withval],
+ [build_bitcoin_utils=yes])
+
+AC_ARG_WITH([libs],
+ [AS_HELP_STRING([--with-libs],
+ [build libraries (default=yes)])],
+ [build_bitcoin_libs=$withval],
+ [build_bitcoin_libs=yes])
+
+AC_ARG_WITH([daemon],
+ [AS_HELP_STRING([--with-daemon],
+ [build bitcoind daemon (default=yes)])],
+ [build_bitcoind=$withval],
+ [build_bitcoind=yes])
+
AC_LANG_PUSH([C++])
use_pkgconfig=yes
@@ -500,6 +511,19 @@ if test x$use_upnp != xno; then
)
fi
+BITCOIN_QT_INIT
+
+dnl sets $bitcoin_enable_qt, $bitcoin_enable_qt_test, $bitcoin_enable_qt_dbus
+BITCOIN_QT_CONFIGURE([$use_pkgconfig], [qt4])
+
+if test x$build_bitcoin_utils$build_bitcoind$bitcoin_enable_qt$use_tests = xnononono; then
+ use_boost=no
+else
+ use_boost=yes
+fi
+
+if test x$use_boost = xyes; then
+
dnl Check for boost libs
AX_BOOST_BASE
AX_BOOST_SYSTEM
@@ -537,6 +561,10 @@ if test x$use_reduce_exports != xno; then
CPPFLAGS="$TEMP_CPPFLAGS"
fi
+elif test x$use_reduce_exports = xauto; then
+ use_reduce_exports=yes
+fi
+
if test x$use_reduce_exports != xno; then
CXXFLAGS="$CXXFLAGS $RE_CXXFLAGS"
AX_CHECK_LINK_FLAG([[-Wl,--exclude-libs,ALL]], [RELDFLAGS="-Wl,--exclude-libs,ALL"])
@@ -549,6 +577,8 @@ if test x$use_tests = xyes; then
fi
+ if test x$use_boost = xyes; then
+
AX_BOOST_UNIT_TEST_FRAMEWORK
dnl Determine if -DBOOST_TEST_DYN_LINK is needed
@@ -568,8 +598,12 @@ if test x$use_tests = xyes; then
[AC_MSG_RESULT(no)])
LIBS="$TEMP_LIBS"
CPPFLAGS="$TEMP_CPPFLAGS"
+
+ fi
fi
+if test x$use_boost = xyes; then
+
BOOST_LIBS="$BOOST_LDFLAGS $BOOST_SYSTEM_LIB $BOOST_FILESYSTEM_LIB $BOOST_PROGRAM_OPTIONS_LIB $BOOST_THREAD_LIB"
dnl Boost >= 1.50 uses sleep_for rather than the now-deprecated sleep, however
@@ -626,25 +660,7 @@ if test x$boost_sleep != xyes; then
AC_MSG_ERROR(No working boost sleep implementation found.)
fi
-AC_ARG_WITH([utils],
- [AS_HELP_STRING([--with-utils],
- [build bitcoin-cli bitcoin-tx (default=yes)])],
- [build_bitcoin_utils=$withval],
- [build_bitcoin_utils=yes])
-
-AC_ARG_WITH([libs],
- [AS_HELP_STRING([--with-libs],
- [build libraries (default=yes)])],
- [build_bitcoin_libs=$withval],
- [build_bitcoin_libs=yes])
-
-AC_ARG_WITH([daemon],
- [AS_HELP_STRING([--with-daemon],
- [build bitcoind daemon (default=yes)])],
- [build_bitcoind=$withval],
- [build_bitcoind=yes])
-
-BITCOIN_QT_INIT
+fi
if test x$use_pkgconfig = xyes; then
@@ -678,6 +694,14 @@ else
fi
fi
+CFLAGS_TEMP="$CFLAGS"
+LIBS_TEMP="$LIBS"
+CFLAGS="$CFLAGS $SSL_CFLAGS $CRYPTO_CFLAGS"
+LIBS="$LIBS $SSL_LIBS $CRYPTO_LIBS"
+AC_CHECK_HEADER([openssl/ec.h],, AC_MSG_ERROR(OpenSSL ec header missing),)
+CFLAGS="$CFLAGS_TEMP"
+LIBS="$LIBS_TEMP"
+
BITCOIN_QT_PATH_PROGS([PROTOC], [protoc],$protoc_bin_path)
AC_MSG_CHECKING([whether to build bitcoind])
@@ -696,9 +720,6 @@ if test x$build_bitcoin_libs = xyes; then
fi
AC_MSG_RESULT($build_bitcoin_libs)
-dnl sets $bitcoin_enable_qt, $bitcoin_enable_qt_test, $bitcoin_enable_qt_dbus
-BITCOIN_QT_CONFIGURE([$use_pkgconfig], [qt4])
-
AC_LANG_POP
if test "x$use_ccache" != "xno"; then
@@ -812,7 +833,7 @@ else
AC_MSG_RESULT([no])
fi
-if test x$build_bitcoin_utils$build_bitcoin_libs$build_bitcoind$bitcoin_enable_qt$use_tests = xnononono; then
+if test x$build_bitcoin_utils$build_bitcoin_libs$build_bitcoind$bitcoin_enable_qt$use_tests = xnonononono; then
AC_MSG_ERROR([No targets! Please specify at least one of: --with-utils --with-libs --with-daemon --with-gui or --enable-tests])
fi
diff --git a/contrib/debian/manpages/bitcoind.1 b/contrib/debian/manpages/bitcoind.1
index a1b17d6077..c225b9f3e9 100644
--- a/contrib/debian/manpages/bitcoind.1
+++ b/contrib/debian/manpages/bitcoind.1
@@ -85,19 +85,19 @@ This help message
Safely copies *wallet.dat* to 'destination', which can be a directory or a path with filename.
.TP
\fBgetaccount 'bitcoinaddress'\fR
-Returns the account associated with the given address.
+DEPRECATED. Returns the account associated with the given address.
.TP
\fBsetaccount 'bitcoinaddress' ['account']\fR
-Sets the ['account'] associated with the given address. ['account'] may be omitted to remove an address from ['account'].
+DEPRECATED. Sets the ['account'] associated with the given address. ['account'] may be omitted to remove an address from ['account'].
.TP
\fBgetaccountaddress 'account'\fR
-Returns a new bitcoin address for 'account'.
+DEPRECATED. Returns a new bitcoin address for 'account'.
.TP
\fBgetaddressesbyaccount 'account'\fR
-Returns the list of addresses associated with the given 'account'.
+DEPRECATED. Returns the list of addresses associated with the given 'account'.
.TP
\fBgetbalance 'account'\fR
-Returns the server's available balance, or the balance for 'account'.
+Returns the server's available balance, or the balance for 'account' (accounts are deprecated).
.TP
\fBgetblockcount\fR
Returns the number of blocks in the longest block chain.
@@ -124,10 +124,10 @@ Returns a recent hashes per second performance measurement while generating.
Returns an object containing server information.
.TP
\fBgetnewaddress 'account'\fR
-Returns a new bitcoin address for receiving payments. If 'account' is specified (recommended), it is added to the address book so payments received with the address will be credited to 'account'.
+Returns a new bitcoin address for receiving payments. If 'account' is specified (deprecated), it is added to the address book so payments received with the address will be credited to 'account'.
.TP
\fBgetreceivedbyaccount 'account' ['minconf=1']\fR
-Returns the total amount received by addresses associated with 'account' in transactions with at least ['minconf'] confirmations.
+DEPRECATED. Returns the total amount received by addresses associated with 'account' in transactions with at least ['minconf'] confirmations.
.TP
\fBgetreceivedbyaddress 'bitcoinaddress' ['minconf=1']\fR
Returns the total amount received by 'bitcoinaddress' in transactions with at least ['minconf'] confirmations.
@@ -147,13 +147,13 @@ If 'data' is specified, tries to solve the block and returns true if it was succ
List commands, or get help for a command.
.TP
\fBlistaccounts ['minconf=1']\fR
-List accounts and their current balances.
+DEPRECATED. List accounts and their current balances.
*note: requires bitcoin 0.3.20 or later.
.TP
\fBlistreceivedbyaccount ['minconf=1'] ['includeempty=false']\fR
['minconf'] is the minimum number of confirmations before payments are included. ['includeempty'] whether to include addresses that haven't received any payments. Returns an array of objects containing:
- "account" : the account of the receiving address.
+ "account" : DEPRECATED. the account of the receiving address.
"amount" : total amount received by the address.
"confirmations" : number of confirmations of the most recent transaction included.
.TP
@@ -161,7 +161,7 @@ List accounts and their current balances.
['minconf'] is the minimum number of confirmations before payments are included. ['includeempty'] whether to include addresses that haven't received any payments. Returns an array of objects containing:
"address" : receiving address.
- "account" : the account of the receiving address.
+ "account" : DEPRECATED. the account of the receiving address.
"amount" : total amount received by the address.
"confirmations" : number of confirmations of the most recent transaction included.
.TP
@@ -180,10 +180,10 @@ Returns a list of the last ['count'] transactions for 'account' \- for all accou
*note: requires bitcoin 0.3.20 or later.
.TP
\fBmove <'fromaccount'> <'toaccount'> <'amount'> ['minconf=1'] ['comment']\fR
-Moves funds between accounts.
+DEPRECATED. Moves funds between accounts.
.TP
\fBsendfrom* <'account'> <'bitcoinaddress'> <'amount'> ['minconf=1'] ['comment'] ['comment-to']\fR
-Sends amount from account's balance to 'bitcoinaddress'. This method will fail if there is less than amount bitcoins with ['minconf'] confirmations in the account's balance (unless account is the empty-string-named default account; it behaves like the *sendtoaddress* method). Returns transaction ID on success.
+DEPRECATED. Sends amount from account's balance to 'bitcoinaddress'. This method will fail if there is less than amount bitcoins with ['minconf'] confirmations in the account's balance (unless account is the empty-string-named default account; it behaves like the *sendtoaddress* method). Returns transaction ID on success.
.TP
\fBsendtoaddress 'bitcoinaddress' 'amount' ['comment'] ['comment-to']\fR
Sends amount from the server's available balance to 'bitcoinaddress'. amount is a real and is rounded to the nearest 0.01. Returns transaction id on success.
diff --git a/contrib/devtools/github-merge.sh b/contrib/devtools/github-merge.sh
index ec7a1f4c4b..7e3dad49d2 100755
--- a/contrib/devtools/github-merge.sh
+++ b/contrib/devtools/github-merge.sh
@@ -82,13 +82,15 @@ function cleanup() {
}
# Create unsigned merge commit.
+PRTITLE=`curl -s https://api.github.com/repos/$REPO/pulls/$PULL | grep -e ' "title": ".*",'| awk -F'"' '{print $4}'`
+MERGEMESSAGE="Merge #$PULL: $PRTITLE"
(
- echo "Merge pull request #$PULL"
+ echo $MERGEMESSAGE
echo ""
git log --no-merges --topo-order --pretty='format:%h %s (%an)' pull/"$PULL"/base..pull/"$PULL"/head
)>"$TMPDIR/message"
if git merge -q --commit --no-edit --no-ff -m "$(<"$TMPDIR/message")" pull/"$PULL"/head; then
- if [ "d$(git log --pretty='format:%s' -n 1)" != "dMerge pull request #$PULL" ]; then
+ if [ "d$(git log --pretty='format:%s' -n 1)" != "d$MERGEMESSAGE" ]; then
echo "ERROR: Creating merge failed (already merged?)." >&2
cleanup
exit 4
diff --git a/contrib/devtools/optimize-pngs.py b/contrib/devtools/optimize-pngs.py
new file mode 100755
index 0000000000..38aaa00f31
--- /dev/null
+++ b/contrib/devtools/optimize-pngs.py
@@ -0,0 +1,73 @@
+#!/usr/bin/env python
+
+import os
+import sys
+import subprocess
+import hashlib
+from PIL import Image
+
+def file_hash(filename):
+ '''Return hash of raw file contents'''
+ with open(filename, 'rb') as f:
+ return hashlib.sha256(f.read()).hexdigest()
+
+def content_hash(filename):
+ '''Return hash of RGBA contents of image'''
+ i = Image.open(filename)
+ i = i.convert('RGBA')
+ data = i.tostring()
+ return hashlib.sha256(data).hexdigest()
+
+#optimize png, remove various color profiles, remove ancillary chunks (alla) and text chunks (text)
+#pngcrush -brute -ow -rem gAMA -rem cHRM -rem iCCP -rem sRGB -rem alla -rem text
+
+pngcrush = 'pngcrush'
+git = 'git'
+folders = ["src/qt/res/movies", "src/qt/res/icons", "src/qt/res/images"]
+basePath = subprocess.check_output([git, 'rev-parse', '--show-toplevel']).rstrip('\n')
+totalSaveBytes = 0
+
+outputArray = []
+for folder in folders:
+ absFolder=os.path.join(basePath, folder)
+ for file in os.listdir(absFolder):
+ extension = os.path.splitext(file)[1]
+ if extension.lower() == '.png':
+ print("optimizing "+file+"..."),
+ file_path = os.path.join(absFolder, file)
+ fileMetaMap = {'file' : file, 'osize': os.path.getsize(file_path), 'sha256Old' : file_hash(file_path)};
+ fileMetaMap['contentHashPre'] = content_hash(file_path)
+
+ pngCrushOutput = ""
+ try:
+ pngCrushOutput = subprocess.check_output(
+ [pngcrush, "-brute", "-ow", "-rem", "gAMA", "-rem", "cHRM", "-rem", "iCCP", "-rem", "sRGB", "-rem", "alla", "-rem", "text", file_path],
+ stderr=subprocess.STDOUT).rstrip('\n')
+ except:
+ print "pngcrush is not installed, aborting..."
+ sys.exit(0)
+
+ #verify
+ if "Not a PNG file" in subprocess.check_output([pngcrush, "-n", "-v", file_path], stderr=subprocess.STDOUT):
+ print "PNG file "+file+" is corrupted after crushing, check out pngcursh version"
+ sys.exit(1)
+
+ fileMetaMap['sha256New'] = file_hash(file_path)
+ fileMetaMap['contentHashPost'] = content_hash(file_path)
+
+ if fileMetaMap['contentHashPre'] != fileMetaMap['contentHashPost']:
+ print "Image contents of PNG file "+file+" before and after crushing don't match"
+ sys.exit(1)
+
+ fileMetaMap['psize'] = os.path.getsize(file_path)
+ outputArray.append(fileMetaMap)
+ print("done\n"),
+
+print "summary:\n+++++++++++++++++"
+for fileDict in outputArray:
+ oldHash = fileDict['sha256Old']
+ newHash = fileDict['sha256New']
+ totalSaveBytes += fileDict['osize'] - fileDict['psize']
+ print fileDict['file']+"\n size diff from: "+str(fileDict['osize'])+" to: "+str(fileDict['psize'])+"\n old sha256: "+oldHash+"\n new sha256: "+newHash+"\n"
+
+print "completed. Total reduction: "+str(totalSaveBytes)+" bytes"
diff --git a/contrib/gitian-descriptors/gitian-osx-signer.yml b/contrib/gitian-descriptors/gitian-osx-signer.yml
index db9b4af93d..1792f9de3f 100644
--- a/contrib/gitian-descriptors/gitian-osx-signer.yml
+++ b/contrib/gitian-descriptors/gitian-osx-signer.yml
@@ -10,7 +10,7 @@ packages:
reference_datetime: "2013-06-01 00:00:00"
remotes: []
files:
-- "bitcoin-0.9.99-osx-unsigned.tar.gz"
+- "bitcoin-osx-unsigned.tar.gz"
- "signature.tar.gz"
script: |
WRAP_DIR=$HOME/wrapped
@@ -28,8 +28,8 @@ script: |
chmod +x ${WRAP_DIR}/${prog}
done
- UNSIGNED=`echo bitcoin-*.tar.gz`
- SIGNED=`echo ${UNSIGNED} | sed 's/.tar.*//' | sed 's/-unsigned//'`.dmg
+ UNSIGNED=bitcoin-osx-unsigned.tar.gz
+ SIGNED=bitcoin-osx-signed.dmg
tar -xf ${UNSIGNED}
./detached-sig-apply.sh ${UNSIGNED} signature.tar.gz
diff --git a/contrib/gitian-descriptors/gitian-osx.yml b/contrib/gitian-descriptors/gitian-osx.yml
index 4f05aad233..3ca42248d4 100644
--- a/contrib/gitian-descriptors/gitian-osx.yml
+++ b/contrib/gitian-descriptors/gitian-osx.yml
@@ -6,7 +6,7 @@ suites:
architectures:
- "amd64"
packages:
-- "g++-multilib"
+- "g++"
- "git-core"
- "pkg-config"
- "autoconf2.13"
@@ -23,7 +23,7 @@ remotes:
- "url": "https://github.com/bitcoin/bitcoin.git"
"dir": "bitcoin"
files:
-- "MacOSX10.7.sdk.tar.gz"
+- "MacOSX10.9.sdk.tar.gz"
script: |
WRAP_DIR=$HOME/wrapped
HOSTS="x86_64-apple-darwin11"
@@ -72,7 +72,7 @@ script: |
BASEPREFIX=`pwd`/depends
mkdir -p ${BASEPREFIX}/SDKs
- tar -C ${BASEPREFIX}/SDKs -xf ${BUILD_DIR}/MacOSX10.7.sdk.tar.gz
+ tar -C ${BASEPREFIX}/SDKs -xf ${BUILD_DIR}/MacOSX10.9.sdk.tar.gz
# Build dependencies for each host
for i in $HOSTS; do
diff --git a/contrib/gitian-downloader/jonasschnelli-key.pgp b/contrib/gitian-downloader/jonasschnelli-key.pgp
new file mode 100644
index 0000000000..fe44c0fbd4
--- /dev/null
+++ b/contrib/gitian-downloader/jonasschnelli-key.pgp
Binary files differ
diff --git a/contrib/macdeploy/DS_Store b/contrib/macdeploy/DS_Store
index 7527dc671f..099960712a 100644
--- a/contrib/macdeploy/DS_Store
+++ b/contrib/macdeploy/DS_Store
Binary files differ
diff --git a/contrib/macdeploy/background.png b/contrib/macdeploy/background.png
index fce12e3807..f88a2ae74b 100644
--- a/contrib/macdeploy/background.png
+++ b/contrib/macdeploy/background.png
Binary files differ
diff --git a/contrib/macdeploy/background.psd b/contrib/macdeploy/background.psd
index 5889676f8e..fdc4f4ca4a 100644
--- a/contrib/macdeploy/background.psd
+++ b/contrib/macdeploy/background.psd
Binary files differ
diff --git a/contrib/macdeploy/background.tiff b/contrib/macdeploy/background.tiff
new file mode 100644
index 0000000000..4b44ac672e
--- /dev/null
+++ b/contrib/macdeploy/background.tiff
Binary files differ
diff --git a/contrib/macdeploy/background@2x.png b/contrib/macdeploy/background@2x.png
new file mode 100644
index 0000000000..4858183f75
--- /dev/null
+++ b/contrib/macdeploy/background@2x.png
Binary files differ
diff --git a/contrib/macdeploy/fancy.plist b/contrib/macdeploy/fancy.plist
index e73b9b697e..ef277a7f14 100644
--- a/contrib/macdeploy/fancy.plist
+++ b/contrib/macdeploy/fancy.plist
@@ -10,7 +10,7 @@
<integer>620</integer>
</array>
<key>background_picture</key>
- <string>background.png</string>
+ <string>background.tiff</string>
<key>icon_size</key>
<integer>96</integer>
<key>applications_symlink</key>
diff --git a/contrib/macdeploy/macdeployqtplus b/contrib/macdeploy/macdeployqtplus
index 541136001f..0eb6b2c84d 100755
--- a/contrib/macdeploy/macdeployqtplus
+++ b/contrib/macdeploy/macdeployqtplus
@@ -767,7 +767,7 @@ if config.dmg is not None:
for path, dirs, files in os.walk("dist"):
for file in files:
size += os.path.getsize(os.path.join(path, file))
- size += int(size * 0.1)
+ size += int(size * 0.15)
if verbose >= 3:
print "Creating temp image for modification..."
@@ -791,7 +791,8 @@ if config.dmg is not None:
print "+ Applying fancy settings +"
if fancy.has_key("background_picture"):
- bg_path = os.path.join(disk_root, os.path.basename(fancy["background_picture"]))
+ bg_path = os.path.join(disk_root, ".background", os.path.basename(fancy["background_picture"]))
+ os.mkdir(os.path.dirname(bg_path))
if verbose >= 3:
print fancy["background_picture"], "->", bg_path
shutil.copy2(fancy["background_picture"], bg_path)
@@ -849,8 +850,8 @@ if config.dmg is not None:
if bg_path is not None:
# Set background file, then call SetFile to make it invisible.
# (note: making it invisible first makes set background picture fail)
- bgscript = Template("""set background picture of theViewOptions to file "$bgpic"
- do shell script "SetFile -a V /Volumes/$disk/$bgpic" """)
+ bgscript = Template("""set background picture of theViewOptions to file ".background:$bgpic"
+ do shell script "SetFile -a V /Volumes/$disk/.background/$bgpic" """)
params["background_commands"] = bgscript.substitute({"bgpic" : os.path.basename(bg_path), "disk" : params["disk"]})
s = appscript.substitute(params)
diff --git a/contrib/seeds/README.md b/contrib/seeds/README.md
index f9a0c277e2..bc88201f0f 100644
--- a/contrib/seeds/README.md
+++ b/contrib/seeds/README.md
@@ -1,11 +1,8 @@
### Seeds ###
-Utility to generate the pnSeed[] array that is compiled into the client
-(see [src/net.cpp](/src/net.cpp)).
+Utility to generate the seeds.txt list that is compiled into the client
+(see [src/chainparamsseeds.h](/src/chainparamsseeds.h) and [share/seeds](/share/seeds)).
-The 600 seeds compiled into the 0.8 release were created from sipa's DNS seed data, like this:
+The 512 seeds compiled into the 0.10 release were created from sipa's DNS seed data, like this:
- curl -s http://bitcoin.sipa.be/seeds.txt | head -1000 | makeseeds.py
-
-The input to makeseeds.py is assumed to be approximately sorted from most-reliable to least-reliable,
-with IP:port first on each line (lines that don't match IPv4:port are ignored).
+ curl -s http://bitcoin.sipa.be/seeds.txt | makeseeds.py
diff --git a/contrib/seeds/makeseeds.py b/contrib/seeds/makeseeds.py
index 1d01fd7d20..b831395f2c 100755
--- a/contrib/seeds/makeseeds.py
+++ b/contrib/seeds/makeseeds.py
@@ -1,32 +1,118 @@
#!/usr/bin/env python
#
-# Generate pnSeed[] from Pieter's DNS seeder
+# Generate seeds.txt from Pieter's DNS seeder
#
-NSEEDS=600
+NSEEDS=512
+
+MAX_SEEDS_PER_ASN=2
+
+MIN_BLOCKS = 337600
+
+# These are hosts that have been observed to be behaving strangely (e.g.
+# aggressively connecting to every node).
+SUSPICIOUS_HOSTS = set([
+ "130.211.129.106", "178.63.107.226",
+ "83.81.130.26", "88.198.17.7", "148.251.238.178", "176.9.46.6",
+ "54.173.72.127", "54.174.10.182", "54.183.64.54", "54.194.231.211",
+ "54.66.214.167", "54.66.220.137", "54.67.33.14", "54.77.251.214",
+ "54.94.195.96", "54.94.200.247"
+])
import re
import sys
-from subprocess import check_output
+import dns.resolver
+
+PATTERN_IPV4 = re.compile(r"^((\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})):8333$")
+PATTERN_AGENT = re.compile(r"^(\/Satoshi:0.8.6\/|\/Satoshi:0.9.(2|3)\/|\/Satoshi:0.10.\d{1,2}\/)$")
+
+def parseline(line):
+ sline = line.split()
+ if len(sline) < 11:
+ return None
+ # Match only IPv4
+ m = PATTERN_IPV4.match(sline[0])
+ if m is None:
+ return None
+ # Do IPv4 sanity check
+ ip = 0
+ for i in range(0,4):
+ if int(m.group(i+2)) < 0 or int(m.group(i+2)) > 255:
+ return None
+ ip = ip + (int(m.group(i+2)) << (8*(3-i)))
+ if ip == 0:
+ return None
+ # Skip bad results.
+ if sline[1] == 0:
+ return None
+ # Extract uptime %.
+ uptime30 = float(sline[7][:-1])
+ # Extract Unix timestamp of last success.
+ lastsuccess = int(sline[2])
+ # Extract protocol version.
+ version = int(sline[10])
+ # Extract user agent.
+ agent = sline[11][1:-1]
+ # Extract service flags.
+ service = int(sline[9], 16)
+ # Extract blocks.
+ blocks = int(sline[8])
+ # Construct result.
+ return {
+ 'ip': m.group(1),
+ 'ipnum': ip,
+ 'uptime': uptime30,
+ 'lastsuccess': lastsuccess,
+ 'version': version,
+ 'agent': agent,
+ 'service': service,
+ 'blocks': blocks,
+ }
+
+# Based on Greg Maxwell's seed_filter.py
+def filterbyasn(ips, max_per_asn, max_total):
+ result = []
+ asn_count = {}
+ for ip in ips:
+ if len(result) == max_total:
+ break
+ try:
+ asn = int([x.to_text() for x in dns.resolver.query('.'.join(reversed(ip['ip'].split('.'))) + '.origin.asn.cymru.com', 'TXT').response.answer][0].split('\"')[1].split(' ')[0])
+ if asn not in asn_count:
+ asn_count[asn] = 0
+ if asn_count[asn] == max_per_asn:
+ continue
+ asn_count[asn] += 1
+ result.append(ip)
+ except:
+ sys.stderr.write('ERR: Could not resolve ASN for "' + ip['ip'] + '"\n')
+ return result
def main():
lines = sys.stdin.readlines()
+ ips = [parseline(line) for line in lines]
+
+ # Skip entries with valid IPv4 address.
+ ips = [ip for ip in ips if ip is not None]
+ # Skip entries from suspicious hosts.
+ ips = [ip for ip in ips if ip['ip'] not in SUSPICIOUS_HOSTS]
+ # Enforce minimal number of blocks.
+ ips = [ip for ip in ips if ip['blocks'] >= MIN_BLOCKS]
+ # Require service bit 1.
+ ips = [ip for ip in ips if (ip['service'] & 1) == 1]
+ # Require at least 50% 30-day uptime.
+ ips = [ip for ip in ips if ip['uptime'] > 50]
+ # Require a known and recent user agent.
+ ips = [ip for ip in ips if PATTERN_AGENT.match(ip['agent'])]
+ # Sort by availability (and use last success as tie breaker)
+ ips.sort(key=lambda x: (x['uptime'], x['lastsuccess'], x['ip']), reverse=True)
+ # Look up ASNs and limit results, both per ASN and globally.
+ ips = filterbyasn(ips, MAX_SEEDS_PER_ASN, NSEEDS)
+ # Sort the results by IP address (for deterministic output).
+ ips.sort(key=lambda x: (x['ipnum']))
- ips = []
- pattern = re.compile(r"^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3}):8333")
- for line in lines:
- m = pattern.match(line)
- if m is None:
- continue
- ip = 0
- for i in range(0,4):
- ip = ip + (int(m.group(i+1)) << (8*(i)))
- if ip == 0:
- continue
- ips.append(ip)
-
- for row in range(0, min(NSEEDS,len(ips)), 8):
- print " " + ", ".join([ "0x%08x"%i for i in ips[row:row+8] ]) + ","
+ for ip in ips:
+ print ip['ip']
if __name__ == '__main__':
main()
diff --git a/depends/README b/depends/README
index fed2f9b5ab..55e7222697 100644
--- a/depends/README
+++ b/depends/README
@@ -7,7 +7,7 @@ There are several features that make it different from most similar systems:
In theory, binaries for any target OS/architecture can be created, from a
builder running any OS/architecture. In practice, build-side tools must be
-specified when the defaults don't fit, and packages must be ammended to work
+specified when the defaults don't fit, and packages must be amended to work
on new hosts. For now, a build architecture of x86_64 is assumed, either on
Linux or OSX.
diff --git a/depends/config.guess b/depends/config.guess
index 1f5c50c0d1..dbfb9786cb 100755
--- a/depends/config.guess
+++ b/depends/config.guess
@@ -1,8 +1,8 @@
#! /bin/sh
# Attempt to guess a canonical system name.
-# Copyright 1992-2014 Free Software Foundation, Inc.
+# Copyright 1992-2015 Free Software Foundation, Inc.
-timestamp='2014-03-23'
+timestamp='2015-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
@@ -24,12 +24,12 @@ timestamp='2014-03-23'
# program. This Exception is an additional permission under section 7
# of the GNU General Public License, version 3 ("GPLv3").
#
-# Originally written by Per Bothner.
+# Originally written by Per Bothner; maintained since 2000 by Ben Elliston.
#
# You can get the latest version of this script from:
# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
#
-# Please send patches with a ChangeLog entry to config-patches@gnu.org.
+# Please send patches to <config-patches@gnu.org>.
me=`echo "$0" | sed -e 's,.*/,,'`
@@ -50,7 +50,7 @@ version="\
GNU config.guess ($timestamp)
Originally written by Per Bothner.
-Copyright 1992-2014 Free Software Foundation, Inc.
+Copyright 1992-2015 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."
@@ -579,8 +579,9 @@ EOF
else
IBM_ARCH=powerpc
fi
- if [ -x /usr/bin/oslevel ] ; then
- IBM_REV=`/usr/bin/oslevel`
+ if [ -x /usr/bin/lslpp ] ; then
+ 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}
fi
diff --git a/depends/config.sub b/depends/config.sub
index d654d03cdc..6d2e94c8bf 100755
--- a/depends/config.sub
+++ b/depends/config.sub
@@ -1,8 +1,8 @@
#! /bin/sh
# Configuration validation subroutine script.
-# Copyright 1992-2014 Free Software Foundation, Inc.
+# Copyright 1992-2015 Free Software Foundation, Inc.
-timestamp='2014-05-01'
+timestamp='2015-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
@@ -25,7 +25,7 @@ timestamp='2014-05-01'
# of the GNU General Public License, version 3 ("GPLv3").
-# Please send patches with a ChangeLog entry to config-patches@gnu.org.
+# Please send patches to <config-patches@gnu.org>.
#
# Configuration subroutine to validate and canonicalize a configuration type.
# Supply the specified configuration type as an argument.
@@ -68,7 +68,7 @@ Report bugs and patches to <config-patches@gnu.org>."
version="\
GNU config.sub ($timestamp)
-Copyright 1992-2014 Free Software Foundation, Inc.
+Copyright 1992-2015 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."
@@ -260,7 +260,7 @@ case $basic_machine in
| c4x | c8051 | clipper \
| d10v | d30v | dlx | dsp16xx \
| epiphany \
- | fido | fr30 | frv \
+ | fido | fr30 | frv | ft32 \
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
| hexagon \
| i370 | i860 | i960 | ia64 \
@@ -302,6 +302,7 @@ case $basic_machine in
| pdp10 | pdp11 | pj | pjl \
| powerpc | powerpc64 | powerpc64le | powerpcle \
| pyramid \
+ | riscv32 | riscv64 \
| rl78 | rx \
| score \
| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
@@ -312,6 +313,7 @@ case $basic_machine in
| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
| ubicom32 \
| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
+ | visium \
| we32k \
| x86 | xc16x | xstormy16 | xtensa \
| z8k | z80)
@@ -326,6 +328,9 @@ case $basic_machine in
c6x)
basic_machine=tic6x-unknown
;;
+ leon|leon[3-9])
+ basic_machine=sparc-$basic_machine
+ ;;
m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
basic_machine=$basic_machine-unknown
os=-none
@@ -436,6 +441,7 @@ case $basic_machine in
| ubicom32-* \
| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
| vax-* \
+ | visium-* \
| we32k-* \
| x86-* | x86_64-* | xc16x-* | xps100-* \
| xstormy16-* | xtensa*-* \
@@ -773,6 +779,9 @@ case $basic_machine in
basic_machine=m68k-isi
os=-sysv
;;
+ leon-*|leon[3-9]-*)
+ basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'`
+ ;;
m68knommu)
basic_machine=m68k-unknown
os=-linux
@@ -828,6 +837,10 @@ case $basic_machine in
basic_machine=powerpc-unknown
os=-morphos
;;
+ moxiebox)
+ basic_machine=moxie-unknown
+ os=-moxiebox
+ ;;
msdos)
basic_machine=i386-pc
os=-msdos
@@ -1373,7 +1386,7 @@ case $os in
| -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
| -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
| -linux-newlib* | -linux-musl* | -linux-uclibc* \
- | -uxpv* | -beos* | -mpeix* | -udk* \
+ | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
diff --git a/depends/funcs.mk b/depends/funcs.mk
index 79015c047c..b407737f7f 100644
--- a/depends/funcs.mk
+++ b/depends/funcs.mk
@@ -31,8 +31,8 @@ define fetch_file
endef
define int_get_build_recipe_hash
-$(eval $(1)_all_file_checksums:=$(shell $(build_SHA256SUM) $(meta_depends) packages/$(1).mk $(addprefix $(PATCHES_PATH)/$(1)/,$($(1)_patches))))
-$(eval $(1)_recipe_hash:=$(shell echo -n "$($(1)_all_file_checksums)" | cut -d" " -f1 | $(build_SHA256SUM)))
+$(eval $(1)_all_file_checksums:=$(shell $(build_SHA256SUM) $(meta_depends) packages/$(1).mk $(addprefix $(PATCHES_PATH)/$(1)/,$($(1)_patches)) | cut -d" " -f1))
+$(eval $(1)_recipe_hash:=$(shell echo -n "$($(1)_all_file_checksums)" | $(build_SHA256SUM) | cut -d" " -f1))
endef
define int_get_build_id
@@ -205,7 +205,7 @@ endef
# These functions create the build targets for each package. They must be
# broken down into small steps so that each part is done for all packages
# before moving on to the next step. Otherwise, a package's info
-# (build-id for example) would only be avilable to another package if it
+# (build-id for example) would only be available to another package if it
# happened to be computed already.
#set the type for host/build packages.
diff --git a/depends/hosts/darwin.mk b/depends/hosts/darwin.mk
index 8d718eba17..2958dc50cc 100644
--- a/depends/hosts/darwin.mk
+++ b/depends/hosts/darwin.mk
@@ -1,8 +1,9 @@
-OSX_MIN_VERSION=10.6
-OSX_SDK_VERSION=10.7
+OSX_MIN_VERSION=10.7
+OSX_SDK_VERSION=10.9
OSX_SDK=$(SDK_PATH)/MacOSX$(OSX_SDK_VERSION).sdk
-darwin_CC=clang -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK)
-darwin_CXX=clang++ -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK)
+LD64_VERSION=241.9
+darwin_CC=clang -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK) -mlinker-version=$(LD64_VERSION)
+darwin_CXX=clang++ -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK) -mlinker-version=$(LD64_VERSION)
darwin_CFLAGS=-pipe
darwin_CXXFLAGS=$(darwin_CFLAGS)
diff --git a/depends/packages/native_cctools.mk b/depends/packages/native_cctools.mk
index 1675afe781..951ad4fb29 100644
--- a/depends/packages/native_cctools.mk
+++ b/depends/packages/native_cctools.mk
@@ -1,61 +1,37 @@
package=native_cctools
-$(package)_version=809
-$(package)_download_path=http://www.opensource.apple.com/tarballs/cctools
-$(package)_file_name=cctools-$($(package)_version).tar.gz
-$(package)_sha256_hash=03ba62749b843b131c7304a044a98c6ffacd65b1399b921d69add0375f79d8ad
-$(package)_build_subdir=cctools2odcctools/odcctools-$($(package)_version)
-$(package)_dependencies=native_libuuid native_openssl
-$(package)_ld64_download_file=ld64-127.2.tar.gz
-$(package)_ld64_download_path=http://www.opensource.apple.com/tarballs/ld64
-$(package)_ld64_file_name=$($(package)_ld64_download_file)
-$(package)_ld64_sha256_hash=97b75547b2bd761306ab3e15ae297f01e7ab9760b922bc657f4ef72e4e052142
-$(package)_dyld_download_file=dyld-195.5.tar.gz
-$(package)_dyld_download_path=http://www.opensource.apple.com/tarballs/dyld
-$(package)_dyld_file_name=$($(package)_dyld_download_file)
-$(package)_dyld_sha256_hash=2cf0484c87cf79b606b351a7055a247dae84093ae92c747a74e0cde2c8c8f83c
-$(package)_toolchain4_download_file=10cc648683617cca8bcbeae507888099b41b530c.tar.gz
-$(package)_toolchain4_download_path=https://github.com/mingwandroid/toolchain4/archive
-$(package)_toolchain4_file_name=toolchain4-1.tar.gz
-$(package)_toolchain4_sha256_hash=18406961fd4a1ec5c7ea35c91d6a80a2f8bb797a2bd243a610bd75e13eff9aca
-$(package)_clang_download_file=clang+llvm-3.2-x86-linux-ubuntu-12.04.tar.gz
-$(package)_clang_download_path=http://llvm.org/releases/3.2
-$(package)_clang_file_name=clang-llvm-3.2-x86-linux-ubuntu-12.04.tar.gz
-$(package)_clang_sha256_hash=b9d57a88f9514fa1f327a1a703756d0c1c960f4c58494a5bd80313245d13ffff
-
+$(package)_version=ee31ae567931c426136c94aad457c7b51d844beb
+$(package)_download_path=https://github.com/theuni/cctools-port/archive
+$(package)_file_name=$($(package)_version).tar.gz
+$(package)_sha256_hash=ef107e6ab1b3994cb22e14f4f5c59ea0c0b5a988e6b21d42ed9616b018bbcbf9
+$(package)_build_subdir=cctools
+$(package)_clang_version=3.3
+$(package)_clang_download_path=http://llvm.org/releases/$($(package)_clang_version)
+$(package)_clang_download_file=clang+llvm-$($(package)_clang_version)-amd64-Ubuntu-12.04.2.tar.gz
+$(package)_clang_file_name=clang-llvm-$($(package)_clang_version)-amd64-Ubuntu-12.04.2.tar.gz
+$(package)_clang_sha256_hash=60d8f69f032d62ef61bf527857ebb933741ec3352d4d328c5516aa520662dab7
define $(package)_fetch_cmds
$(call fetch_file,$(package),$($(package)_download_path),$($(package)_download_file),$($(package)_file_name),$($(package)_sha256_hash)) && \
-$(call fetch_file,$(package),$($(package)_ld64_download_path),$($(package)_ld64_download_file),$($(package)_ld64_file_name),$($(package)_ld64_sha256_hash)) && \
-$(call fetch_file,$(package),$($(package)_dyld_download_path),$($(package)_dyld_download_file),$($(package)_dyld_file_name),$($(package)_dyld_sha256_hash)) && \
-$(call fetch_file,$(package),$($(package)_clang_download_path),$($(package)_clang_download_file),$($(package)_clang_file_name),$($(package)_clang_sha256_hash)) && \
-$(call fetch_file,$(package),$($(package)_toolchain4_download_path),$($(package)_toolchain4_download_file),$($(package)_toolchain4_file_name),$($(package)_toolchain4_sha256_hash))
+$(call fetch_file,$(package),$($(package)_clang_download_path),$($(package)_clang_download_file),$($(package)_clang_file_name),$($(package)_clang_sha256_hash))
endef
-define $(package)_set_vars
-$(package)_config_opts=--target=$(host) --with-sysroot=$(OSX_SDK)
-$(package)_cflags+=-m32
-$(package)_cxxflags+=-m32
-$(package)_cppflags+=-D__DARWIN_UNIX03 -D__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS
-$(package)_ldflags+=-m32 -Wl,-rpath=\\$$$$$$$$\$$$$$$$$ORIGIN/../lib
-$(package)_ldflags+=-L$$(native_cctools_extract_dir)/clang+llvm-3.2-x86-linux-ubuntu-12.04/lib
-endef
define $(package)_extract_cmds
- tar --strip-components=1 -xf $($(package)_source_dir)/$($(package)_toolchain4_file_name) && \
- ln -sf $($(package)_source) cctools2odcctools/$($(package)_file_name) && \
- ln -sf $($(package)_source_dir)/$($(package)_ld64_file_name) cctools2odcctools/$($(package)_ld64_file_name) && \
- ln -sf $($(package)_source_dir)/$($(package)_dyld_file_name) cctools2odcctools/$($(package)_dyld_file_name) && \
- tar xf $($(package)_source_dir)/$($(package)_clang_file_name) && \
- mkdir -p $(SDK_PATH) sdks &&\
- cd sdks; ln -sf $(OSX_SDK) MacOSX$(OSX_SDK_VERSION).sdk
+ mkdir -p toolchain/bin toolchain/lib/clang/3.5/include && \
+ tar --strip-components=1 -C toolchain -xf $($(package)_source_dir)/$($(package)_clang_file_name) && \
+ echo "#!/bin/sh" > toolchain/bin/$(host)-dsymutil && \
+ echo "exit 0" >> toolchain/bin/$(host)-dsymutil && \
+ chmod +x toolchain/bin/$(host)-dsymutil && \
+ tar --strip-components=1 -xf $($(package)_source)
+endef
+
+define $(package)_set_vars
+$(package)_config_opts=--target=$(host) --disable-libuuid
+$(package)_ldflags+=-Wl,-rpath=\\$$$$$$$$\$$$$$$$$ORIGIN/../lib
+$(package)_cc=$($(package)_extract_dir)/toolchain/bin/clang
+$(package)_cxx=$($(package)_extract_dir)/toolchain/bin/clang++
endef
define $(package)_preprocess_cmds
- sed -i "s|GCC_DIR|LLVM_CLANG_DIR|g" cctools2odcctools/extract.sh && \
- sed -i "s|llvmgcc42-2336.1|clang+llvm-3.2-x86-linux-ubuntu-12.04|g" cctools2odcctools/extract.sh && \
- sed -i "s|/llvmCore/include/llvm-c|/include/llvm-c \$$$${LLVM_CLANG_DIR}/include/llvm |" cctools2odcctools/extract.sh && \
- sed -i "s|fAC_INIT|AC_INIT|" cctools2odcctools/files/configure.ac && \
- sed -i 's/\# Dynamically linked LTO/\t ;\&\n\t linux*)\n# Dynamically linked LTO/' cctools2odcctools/files/configure.ac && \
- cd cctools2odcctools; ./extract.sh --osxver $(OSX_SDK_VERSION) && \
- sed -i "s|define\tPC|define\tPC_|" odcctools-809/include/architecture/sparc/reg.h
+ cd $($(package)_build_subdir); ./autogen.sh
endef
define $(package)_config_cmds
@@ -68,13 +44,13 @@ endef
define $(package)_stage_cmds
$(MAKE) DESTDIR=$($(package)_staging_dir) install && \
- cd ../../clang+llvm-3.2-x86-linux-ubuntu-12.04 && \
- mkdir -p $($(package)_staging_prefix_dir)/lib/clang/3.2/include && \
- mkdir -p $($(package)_staging_prefix_dir)/bin && \
+ cd $($(package)_extract_dir)/toolchain && \
+ mkdir -p $($(package)_staging_prefix_dir)/lib/clang/$($(package)_clang_version)/include && \
+ mkdir -p $($(package)_staging_prefix_dir)/bin $($(package)_staging_prefix_dir)/include && \
cp -P bin/clang bin/clang++ $($(package)_staging_prefix_dir)/bin/ &&\
cp lib/libLTO.so $($(package)_staging_prefix_dir)/lib/ && \
- cp lib/clang/3.2/include/* $($(package)_staging_prefix_dir)/lib/clang/3.2/include/ && \
- echo "#!/bin/sh" > $($(package)_staging_prefix_dir)/bin/$(host)-dsymutil && \
- echo "exit 0" >> $($(package)_staging_prefix_dir)/bin/$(host)-dsymutil && \
- chmod +x $($(package)_staging_prefix_dir)/bin/$(host)-dsymutil
+ cp -rf lib/clang/$($(package)_clang_version)/include/* $($(package)_staging_prefix_dir)/lib/clang/$($(package)_clang_version)/include/ && \
+ cp bin/$(host)-dsymutil $($(package)_staging_prefix_dir)/bin && \
+ if `test -d include/c++/`; then cp -rf include/c++/ $($(package)_staging_prefix_dir)/include/; fi && \
+ if `test -d lib/c++/`; then cp -rf lib/c++/ $($(package)_staging_prefix_dir)/lib/; fi
endef
diff --git a/depends/packages/native_libuuid.mk b/depends/packages/native_libuuid.mk
deleted file mode 100644
index b25540f80d..0000000000
--- a/depends/packages/native_libuuid.mk
+++ /dev/null
@@ -1,24 +0,0 @@
-package:=native_libuuid
-$(package)_version=1.41.14
-$(package)_download_path=http://downloads.sourceforge.net/e2fsprogs
-$(package)_file_name=e2fsprogs-libs-$($(package)_version).tar.gz
-$(package)_sha256_hash=dbc7a138a3218d9b80a0626b5b692d76934d6746d8cbb762751be33785d8d9f5
-
-define $(package)_set_vars
-$(package)_config_opts=--disable-elf-shlibs --disable-uuidd
-$(package)_cflags+=-m32
-$(package)_ldflags+=-m32
-$(package)_cxxflags+=-m32
-endef
-
-define $(package)_config_cmds
- $($(package)_autoconf)
-endef
-
-define $(package)_build_cmds
- $(MAKE) -C lib/uuid
-endef
-
-define $(package)_stage_cmds
- $(MAKE) DESTDIR=$($(package)_staging_dir) -C lib/uuid install
-endef
diff --git a/depends/packages/native_openssl.mk b/depends/packages/native_openssl.mk
deleted file mode 100644
index 1f25d6afcc..0000000000
--- a/depends/packages/native_openssl.mk
+++ /dev/null
@@ -1,21 +0,0 @@
-package=native_openssl
-$(package)_version=1.0.1h
-$(package)_download_path=https://www.openssl.org/source
-$(package)_file_name=openssl-$($(package)_version).tar.gz
-$(package)_sha256_hash=9d1c8a9836aa63e2c6adb684186cbd4371c9e9dcc01d6e3bb447abf2d4d3d093
-define $(package)_set_vars
-$(package)_build_config_opts= --prefix=$(build_prefix) no-zlib no-shared no-krb5C linux-generic32 -m32
-endef
-
-define $(package)_config_cmds
- ./Configure $($(package)_build_config_opts) &&\
- sed -i "s|engines apps test|engines|" Makefile
-endef
-
-define $(package)_build_cmds
- $(MAKE) -j1
-endef
-
-define $(package)_stage_cmds
- $(MAKE) INSTALL_PREFIX=$($(package)_staging_dir) -j1 install_sw
-endef
diff --git a/depends/packages/openssl.mk b/depends/packages/openssl.mk
index ad64494c1f..22b1017ffc 100644
--- a/depends/packages/openssl.mk
+++ b/depends/packages/openssl.mk
@@ -1,8 +1,8 @@
package=openssl
-$(package)_version=1.0.1j
+$(package)_version=1.0.1k
$(package)_download_path=https://www.openssl.org/source
$(package)_file_name=$(package)-$($(package)_version).tar.gz
-$(package)_sha256_hash=1b60ca8789ba6f03e8ef20da2293b8dc131c39d83814e775069f02d26354edf3
+$(package)_sha256_hash=8f9faeaebad088e772f4ef5e38252d472be4d878c6b3a2718c10a4fcebe7a41c
define $(package)_set_vars
$(package)_config_env=AR="$($(package)_ar)" RANLIB="$($(package)_ranlib)" CC="$($(package)_cc)"
@@ -23,7 +23,7 @@ $(package)_config_opts_i686_mingw32=mingw
endef
define $(package)_preprocess_cmds
- sed -i.old "/define DATE/d" crypto/Makefile && \
+ sed -i.old "/define DATE/d" util/mkbuildinf.pl && \
sed -i.old "s|engines apps test|engines|" Makefile.org
endef
diff --git a/depends/packages/packages.mk b/depends/packages/packages.mk
index bbf53cc2dc..08fd8a5247 100644
--- a/depends/packages/packages.mk
+++ b/depends/packages/packages.mk
@@ -19,5 +19,5 @@ wallet_packages=bdb
upnp_packages=miniupnpc
ifneq ($(build_os),darwin)
-darwin_native_packages=native_libuuid native_openssl native_cctools native_cdrkit native_libdmg-hfsplus
+darwin_native_packages=native_cctools native_cdrkit native_libdmg-hfsplus
endif
diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk
index 6a8e714a48..59c12d22f1 100644
--- a/depends/packages/qt.mk
+++ b/depends/packages/qt.mk
@@ -7,7 +7,7 @@ $(package)_dependencies=openssl
$(package)_linux_dependencies=freetype fontconfig dbus libxcb libX11 xproto libXext
$(package)_build_subdir=qtbase
$(package)_qt_libs=corelib network widgets gui plugins testlib
-$(package)_patches=mac-qmake.conf fix-xcb-include-order.patch qt5-tablet-osx.patch
+$(package)_patches=mac-qmake.conf fix-xcb-include-order.patch qt5-tablet-osx.patch qt5-yosemite.patch
define $(package)_set_vars
$(package)_config_opts_release = -release
@@ -34,7 +34,7 @@ $(package)_config_opts += -qt-libpng -qt-libjpeg -qt-zlib -qt-pcre
ifneq ($(build_os),darwin)
$(package)_config_opts_darwin = -xplatform macx-clang-linux -device-option MAC_SDK_PATH=$(OSX_SDK) -device-option CROSS_COMPILE="$(host)-"
-$(package)_config_opts_darwin += -device-option MAC_MIN_VERSION=$(OSX_MIN_VERSION) -device-option MAC_TARGET=$(host)
+$(package)_config_opts_darwin += -device-option MAC_MIN_VERSION=$(OSX_MIN_VERSION) -device-option MAC_TARGET=$(host) -device-option MAC_LD64_VERSION=$(LD64_VERSION)
endif
$(package)_config_opts_linux = -qt-xkbcommon -qt-xcb -no-eglfs -no-linuxfb -system-freetype -no-sm -fontconfig -no-xinput2 -no-libudev -no-egl -no-opengl
@@ -56,6 +56,7 @@ define $(package)_preprocess_cmds
cp -f $($(package)_patch_dir)/mac-qmake.conf qtbase/mkspecs/macx-clang-linux/qmake.conf && \
patch -p1 < $($(package)_patch_dir)/fix-xcb-include-order.patch && \
patch -p1 < $($(package)_patch_dir)/qt5-tablet-osx.patch && \
+ patch -d qtbase -p1 < $($(package)_patch_dir)/qt5-yosemite.patch && \
echo "QMAKE_CFLAGS += $($(package)_cflags) $($(package)_cppflags)" >> qtbase/mkspecs/common/gcc-base.conf && \
echo "QMAKE_CXXFLAGS += $($(package)_cxxflags) $($(package)_cppflags)" >> qtbase/mkspecs/common/gcc-base.conf && \
echo "QMAKE_LFLAGS += $($(package)_ldflags)" >> qtbase/mkspecs/common/gcc-base.conf && \
diff --git a/depends/patches/qt/mac-qmake.conf b/depends/patches/qt/mac-qmake.conf
index f7302265bc..a97945bc8c 100644
--- a/depends/patches/qt/mac-qmake.conf
+++ b/depends/patches/qt/mac-qmake.conf
@@ -15,7 +15,7 @@ QMAKE_MAC_SDK.macosx.platform_name = macosx
QMAKE_CFLAGS += -target $${MAC_TARGET}
QMAKE_OBJECTIVE_CFLAGS += $$QMAKE_CFLAGS
QMAKE_CXXFLAGS += $$QMAKE_CFLAGS
-QMAKE_LFLAGS += -target $${MAC_TARGET}
+QMAKE_LFLAGS += -target $${MAC_TARGET} -mlinker-version=$${MAC_LD64_VERSION}
QMAKE_AR = $${CROSS_COMPILE}ar cq
QMAKE_RANLIB=$${CROSS_COMPILE}ranlib
QMAKE_LIBTOOL=$${CROSS_COMPILE}libtool
diff --git a/depends/patches/qt/qt5-yosemite.patch b/depends/patches/qt/qt5-yosemite.patch
new file mode 100644
index 0000000000..d569d34d47
--- /dev/null
+++ b/depends/patches/qt/qt5-yosemite.patch
@@ -0,0 +1,52 @@
+The following patch was taken from upstream:
+https://qt.gitorious.org/qt/qtbase/commit/70e4428b6f1c6a4bad112203f67ee7d22107616c.patch
+
+The first hunk was removed because it conflicts with 5.2.1, and is not currently needed.
+
+From 70e4428b6f1c6a4bad112203f67ee7d22107616c Mon Sep 17 00:00:00 2001
+From: Gabriel de Dietrich <gabriel.dedietrich@digia.com>
+Date: Tue, 3 Jun 2014 14:20:20 +0200
+Subject: [PATCH] Cocoa: Adapt to Xcode 6 clang version sudden pickiness
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Yes, that means OS X Yosemite fix.
+
+Change-Id: I236f7af7b803de24ff0895e04c9a9253b5cfdb3b
+Reviewed-by: Morten Johan Sørvig <morten.sorvig@digia.com>
+---
+ .../platforms/cocoa/qcocoaaccessibilityelement.mm | 2 +-
+ .../platforms/cocoa/qcocoaapplicationdelegate.mm | 2 +-
+ src/plugins/platforms/cocoa/qcocoamenuloader.mm | 2 +-
+ 3 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
+index f841184..548c6a2 100644
+--- a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
++++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
+@@ -124,7 +124,7 @@ static void cleanupCocoaApplicationDelegate()
+ [dockMenu release];
+ [qtMenuLoader release];
+ if (reflectionDelegate) {
+- [NSApp setDelegate:reflectionDelegate];
++ [[NSApplication sharedApplication] setDelegate:reflectionDelegate];
+ [reflectionDelegate release];
+ }
+ [[NSNotificationCenter defaultCenter] removeObserver:self];
+diff --git a/src/plugins/platforms/cocoa/qcocoamenuloader.mm b/src/plugins/platforms/cocoa/qcocoamenuloader.mm
+index 60bc3b5..9340e94 100644
+--- a/src/plugins/platforms/cocoa/qcocoamenuloader.mm
++++ b/src/plugins/platforms/cocoa/qcocoamenuloader.mm
+@@ -174,7 +174,7 @@ QT_END_NAMESPACE
+ - (void)removeActionsFromAppMenu
+ {
+ for (NSMenuItem *item in [appMenu itemArray])
+- [item setTag:nil];
++ [item setTag:0];
+ }
+
+ - (void)dealloc
+--
+1.7.1
+
diff --git a/doc/README.md b/doc/README.md
index ecb8dc80fd..0ade8f9923 100644
--- a/doc/README.md
+++ b/doc/README.md
@@ -1,12 +1,9 @@
-Bitcoin 0.10.99
+Bitcoin Core 0.10.99
=====================
-Copyright (c) 2009-2014 Bitcoin Developers
-
-
Setup
---------------------
-[Bitcoin Core](http://bitcoin.org/en/download) is the original Bitcoin client and it builds the backbone of the network. However, it downloads and stores the entire history of Bitcoin transactions (which is currently several GBs); depending on the speed of your computer and network connection, the synchronization process can take anywhere from a few hours to a day or more. Thankfully you only have to do this once. If you would like the process to go faster you can [download the blockchain directly](bootstrap.md).
+[Bitcoin Core](http://bitcoin.org/en/download) is the original Bitcoin client and it builds the backbone of the network. However, it downloads and stores the entire history of Bitcoin transactions (which is currently several GBs); depending on the speed of your computer and network connection, the synchronization process can take anywhere from a few hours to a day or more.
Running
---------------------
@@ -51,7 +48,7 @@ Development
---------------------
The Bitcoin repo's [root README](https://github.com/bitcoin/bitcoin/blob/master/README.md) contains relevant information on the development process and automated testing.
-- [Coding Guidelines](coding.md)
+- [Developer Notes](developer-notes.md)
- [Multiwallet Qt Development](multiwallet-qt.md)
- [Release Notes](release-notes.md)
- [Release Process](release-process.md)
diff --git a/doc/README_osx.txt b/doc/README_osx.txt
index d56234f7d9..6c0c21c190 100644
--- a/doc/README_osx.txt
+++ b/doc/README_osx.txt
@@ -29,14 +29,15 @@ originally done in toolchain4.
To complicate things further, all builds must target an Apple SDK. These SDKs
are free to download, but not redistributable.
-To obtain it, register for a developer account, then download xcode4630916281a.dmg:
-https://developer.apple.com/downloads/download.action?path=Developer_Tools/xcode_4.6.3/xcode4630916281a.dmg
+To obtain it, register for a developer account, then download the XCode 6.1.1 dmg:
+https://developer.apple.com/downloads/download.action?path=Developer_Tools/xcode_6.1.1/xcode_6.1.1.dmg
+
This file is several gigabytes in size, but only a single directory inside is
-needed: Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk
+needed: Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk
Unfortunately, the usual linux tools (7zip, hpmount, loopback mount) are incapable of opening this file.
To create a tarball suitable for gitian input, mount the dmg in OSX, then create it with:
- $ tar -C /Volumes/Xcode/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/ -czf MacOSX10.7.sdk.tar.gz MacOSX10.7.sdk
+ $ tar -C /Volumes/Xcode/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/ -czf MacOSX10.9.sdk.tar.gz MacOSX10.9.sdk
The gitian descriptors build 2 sets of files: Linux tools, then Apple binaries
diff --git a/doc/README_windows.txt b/doc/README_windows.txt
index 5ac1152055..c582941696 100644
--- a/doc/README_windows.txt
+++ b/doc/README_windows.txt
@@ -1,13 +1,5 @@
-Bitcoin 0.10.99
-
-Copyright (c) 2009-2014 Bitcoin Core Developers
-
-Distributed under the MIT software license, see the accompanying
-file COPYING or http://www.opensource.org/licenses/mit-license.php.
-This product includes software developed by the OpenSSL Project for use in
-the OpenSSL Toolkit (https://www.openssl.org/). This product includes
-cryptographic software written by Eric Young (eay@cryptsoft.com).
-
+Bitcoin Core 0.10.99
+=====================
Intro
-----
diff --git a/doc/assets-attribution.md b/doc/assets-attribution.md
index 6c5f91a834..c860cdc534 100644
--- a/doc/assets-attribution.md
+++ b/doc/assets-attribution.md
@@ -1,14 +1,5 @@
The following is a list of assets used in the bitcoin source and their proper attribution.
-[Wladimir van der Laan](https://github.com/laanwj)
------------------------
-#### Info
-* License: MIT
-
-### Assets Used
- src/qt/res/icons/watch*.png, src/qt/res/icons/tx_in.png,
- src/qt/res/icons/tx_inout.png,
-
[Typicons/Stephen Hutchings](http://typicons.com)
-----------------------
@@ -30,7 +21,7 @@ The following is a list of assets used in the bitcoin source and their proper at
src/qt/res/icons/overview.png, src/qt/res/icons/quit.png,
src/qt/res/icons/receive.png, src/qt/res/icons/remove.png,
src/qt/res/icons/send.png, src/qt/res/icons/synced.png,
- src/qt/res/icons/transaction*.png, src/qt/res/icons/tx_input.png,
+ src/qt/res/icons/transaction*.png, src/qt/res/icons/tx_output.png,
Jonas Schnelli
-----------------------
@@ -38,18 +29,17 @@ Jonas Schnelli
### Info
* Designer: Jonas Schnelli
* Bitcoin Icon: (based on the original bitcoin logo from Bitboy)
-* Some icons are based on Stephan Hutchings Typicons
+* Some icons are based on Stephan Hutchings Typicons (these are under CC BY-SA license)
* License: MIT
### Assets Used
src/qt/res/icons/about.png, src/qt/res/icons/about_qt.png,
- src/qt/res/icons/clock*.png, src/qt/res/icons/connect[0-3].png,
- src/qt/res/icons/eye_minus.png, src/qt/res/icons/verify.png,
- src/qt/res/icons/eye_plus.png, src/qt/res/icons/tx_inout.png,
- src/qt/res/icons/tx_output.png, src/qt/res/icons/bitcoin.icns,
- src/qt/res/src/bitcoin.svg, src/qt/res/src/bitcoin.ico,
- src/qt/res/src/bitcoin.png, src/qt/res/src/bitcoin_testnet.png,
- docs/bitcoin_logo_doxygen.png, src/qt/res/src/tx*.svg,
- src/qt/res/src/connect*.svg, src/qt/res/src/clock*.svg,
- src/qt/res/src/mine.svg, src/qt/res/src/qt.svg,
+ src/qt/res/icons/bitcoin.icns, src/qt/res/icons/bitcoin.ico,
+ src/qt/res/icons/bitcoin.png, src/qt/res/icons/clock*.png,
+ src/qt/res/icons/connect[0-3].png, src/qt/res/icons/eye_minus.png,
+ src/qt/res/icons/eye_plus.png, src/qt/res/icons/verify.png,
+ src/qt/res/icons/tx_inout.png, src/qt/res/icons/tx_input.png,
+ src/qt/res/src/verify.svg, src/qt/res/src/bitcoin.svg,
+ src/qt/res/src/clock*.svg, src/qt/res/src/connect*.svg,
+ src/qt/res/src/mine.svg, src/qt/res/src/qt.svg, src/qt/res/src/tx*.svg,
src/qt/res/src/verify.svg,
diff --git a/doc/bootstrap.md b/doc/bootstrap.md
deleted file mode 100644
index b84fd24b11..0000000000
--- a/doc/bootstrap.md
+++ /dev/null
@@ -1,56 +0,0 @@
-### Bootstrap the Blockchain Synchronization
-
-Normally the Bitcoin client will download the transaction and network information, called the blockchain, from the network by syncing with the other clients. This process can take quite some time as the [Bitcoin blockchain](https://blockchain.info/charts/blocks-size) is growing bigger and bigger for each day. Luckily there is a safe and fast way to speed up this process. We'll show you how to bootstrap your blockchain to bring your client up to speed in just a few simple steps.
-
-### Requirements
-
-- A fresh install of the Bitcoin client software.
-
-### Download the blockchain via BitTorrent
-
-Jeff Garzik, Bitcoin Core developer, offers an [torrent file](https://bitcointalk.org/index.php?topic=145386.0) for bootstrapping purposes that is updated often. BitTorrent is a protocol that speeds up the downloading of large files by using the other clients in the network. Examples of free and safe open source clients are [Deluge](http://deluge-torrent.org/) or [qBittorrent](http://www.qbittorrent.org/). A guide to installing and configuring the torrent clients can be found [here](http://dev.deluge-torrent.org/wiki/UserGuide) for Deluge and [here](http://qbforums.shiki.hu/) for qBittorrent. A further in-depth tutorial on BitTorrent can be found [here](http://www.howtogeek.com/howto/31846/bittorrent-for-beginners-how-get-started-downloading-torrents/).
-
-With the client installed we'll proceed to download the blockchain torrent file. Use the following magnet link:
-
- magnet:?xt=urn:btih:2d4e6c1f96c5d5fb260dff92aea4e600227f1aea&dn=bootstrap.dat&tr=udp://tracker.openbittorrent.com:80&tr=udp://tracker.publicbt.com:80&tr=udp://tracker.ccc.de:80&tr=udp://tracker.istole.it:80
-
- or go to [Jeff Garzik's topic](https://bitcointalk.org/index.php?topic=145386.0) for a signed magnet link. Alternatively you can use the [.torrent file](http://sourceforge.net/projects/bitcoin/files/Bitcoin/blockchain/bootstrap.dat.torrent/download) found on SourceForge.
-
-![Fig1](img/bootstrap1.png)
-
-The download page should look like this, with a countdown to the download. If it does not work click the direct download link.
-
-The torrent client installed will recognize the download of the torrent file. Save the bootstrap.dat file to the folder you use for downloads. The image below shows the torrent download in qBittorrent, with current speed and ETA highlighted.
-
-![Fig2](img/bootstrap2.png)
-
-### Importing the blockchain
-Exit the Bitcoin client software if you have it running. Be sure not to have an actively used wallet in use. We are going to copy the download of the blockchain to the Bitcoin client data directory. You should run the client software at least once so it can generate the data directory. Copy the downloaded bootstrap.dat file into the Bitcoin data folder.
-
-**For Windows users:**
-Open explorer, and type into the address bar:
-
- %APPDATA%\Bitcoin
-
-This will open up the data folder. It should look like the image below. Copy over the bootstrap.dat from your download folder to this directory.
-![Fig4](img/bootstrap4.png)
-
-**For OSX users:**
-Open Finder by pressing Press [shift] + [cmd] + [g] and enter:
-
- ~/Library/Application Support/Bitcoin/
-
-**For Linux users:**
-The directory is hidden in your User folder. Go to:
-
- ~/.bitcoin/
-
-### Importing the blockchain
-Now start the Bitcoin client software. It should show "Importing blocks from disk" like the image below.
-![Fig5](img/bootstrap5.png)
-
-Wait until the import finishes. The client will download the last days not covered by the import. Congratulations you have successfully imported the blockchain!
-
-### Is this safe?
-
-Yes, the above method is safe. The download contains only raw blockchain data and the client verifies this on import. Do not download the blockchain from unofficial sources, especially if they provide `*.rev` and `*.sst` files. These files are not verified and can contain malicious edits.
diff --git a/doc/build-osx.md b/doc/build-osx.md
index c41820f2b1..d6e93cb23d 100644
--- a/doc/build-osx.md
+++ b/doc/build-osx.md
@@ -21,12 +21,6 @@ Xcode 4.3 or later, you'll need to install its command line tools. This can
be done in `Xcode > Preferences > Downloads > Components` and generally must
be re-done or updated every time Xcode is updated.
-There's also an assumption that you already have `git` installed. If
-not, it's the path of least resistance to install [Github for Mac](https://mac.github.com/)
-(OS X 10.7+) or
-[Git for OS X](https://code.google.com/p/git-osx-installer/). It is also
-available via Homebrew.
-
You will also need to install [Homebrew](http://brew.sh) in order to install library
dependencies.
@@ -38,7 +32,9 @@ Instructions: Homebrew
#### Install dependencies using Homebrew
- brew install autoconf automake libtool boost miniupnpc openssl pkg-config protobuf qt
+ brew install autoconf automake libtool boost miniupnpc openssl pkg-config protobuf qt5
+
+NOTE: Building with Qt4 is still supported, however, could result in a broken UI. As such, building with Qt5 is recommended.
#### Installing berkeley-db4 using Homebrew
@@ -46,7 +42,7 @@ The homebrew package for berkeley-db4 has been broken for some time. It will in
Running this command takes you into brew's interactive mode, which allows you to configure, make, and install by hand:
```
-$ brew install https://raw.github.com/mxcl/homebrew/master/Library/Formula/berkeley-db4.rb -–without-java
+$ brew install https://raw.github.com/homebrew/homebrew/master/Library/Formula/berkeley-db4.rb -–without-java
```
The rest of these commands are run inside brew interactive mode:
@@ -73,7 +69,7 @@ After exiting, you'll get a warning that the install is keg-only, which means it
2. Build bitcoind:
./autogen.sh
- ./configure
+ ./configure --with-gui=qt5
make
3. It is also a good idea to build and run the unit tests:
@@ -115,7 +111,7 @@ All dependencies should be compiled with these flags:
-arch x86_64
-isysroot $(xcode-select --print-path)/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk
-Once dependencies are compiled, see release-process.md for how the Bitcoin-Qt.app
+Once dependencies are compiled, see [doc/release-process.md](release-process.md) for how the Bitcoin-Qt.app
bundle is packaged and signed to create the .dmg disk image that is distributed.
Running
diff --git a/doc/build-unix.md b/doc/build-unix.md
index 8ddee3b757..0984f689a8 100644
--- a/doc/build-unix.md
+++ b/doc/build-unix.md
@@ -159,7 +159,7 @@ tar -xzvf db-4.8.30.NC.tar.gz
# Build the library and install to our prefix
cd db-4.8.30.NC/build_unix/
-# Note: Do a static build so that it can be embedded into the exectuable, instead of having to find a .so at runtime
+# Note: Do a static build so that it can be embedded into the executable, instead of having to find a .so at runtime
../dist/configure --enable-cxx --disable-shared --with-pic --prefix=$BDB_PREFIX
make install
@@ -196,7 +196,7 @@ Hardening enables the following features:
* Position Independent Executable
Build position independent code to take advantage of Address Space Layout Randomization
offered by some kernels. An attacker who is able to cause execution of code at an arbitrary
- memory location is thwarted if he doesn't know where anything useful is located.
+ memory location is thwarted if he or she doesn't know where anything useful is located.
The stack and heap are randomly located by default but this allows the code section to be
randomly located as well.
diff --git a/doc/coding.md b/doc/developer-notes.md
index 43294dbe4c..eaeb90da1d 100644
--- a/doc/coding.md
+++ b/doc/developer-notes.md
@@ -89,6 +89,41 @@ Not OK (used plenty in the current source, but not picked up):
A full list of comment syntaxes picked up by doxygen can be found at http://www.stack.nl/~dimitri/doxygen/manual/docblocks.html,
but if possible use one of the above styles.
+Development tips and tricks
+---------------------------
+
+**compiling for debugging**
+
+Run configure with the --enable-debug option, then make. Or run configure with
+CXXFLAGS="-g -ggdb -O0" or whatever debug flags you need.
+
+**debug.log**
+
+If the code is behaving strangely, take a look in the debug.log file in the data directory;
+error and debugging messages are written there.
+
+The -debug=... command-line option controls debugging; running with just -debug will turn
+on all categories (and give you a very large debug.log file).
+
+The Qt code routes qDebug() output to debug.log under category "qt": run with -debug=qt
+to see it.
+
+**testnet and regtest modes**
+
+Run with the -testnet option to run with "play bitcoins" on the test network, if you
+are testing multi-machine code that needs to operate across the internet.
+
+If you are testing something that can run on one machine, run with the -regtest option.
+In regression test mode, blocks can be created on-demand; see qa/rpc-tests/ for tests
+that run in -regtest mode.
+
+**DEBUG_LOCKORDER**
+
+Bitcoin Core is a multithreaded application, and deadlocks or other multithreading bugs
+can be very difficult to track down. Compiling with -DDEBUG_LOCKORDER (configure
+CXXFLAGS="-DDEBUG_LOCKORDER -g") inserts run-time checks to keep track of which locks
+are held, and adds warnings to the debug.log file if inconsistencies are detected.
+
Locking/mutex usage notes
-------------------------
@@ -136,3 +171,16 @@ Threads
- BitcoinMiner : Generates bitcoins (if wallet is enabled).
- Shutdown : Does an orderly shutdown of everything.
+
+Pull Request Terminology
+------------------------
+
+Concept ACK - Agree with the idea and overall direction, but haven't reviewed the code changes or tested them.
+
+utACK (untested ACK) - Reviewed and agree with the code changes but haven't actually tested them.
+
+Tested ACK - Reviewed the code changes and have verified the functionality or bug fix.
+
+ACK - A loose ACK can be confusing. It's best to avoid them unless it's a documentation/comment only change in which case there is nothing to test/verify; therefore the tested/untested distinction is not there.
+
+NACK - Disagree with the code changes/concept. Should be accompanied by an explanation.
diff --git a/doc/gitian-building.md b/doc/gitian-building.md
index defddedc6e..25d3b8390c 100644
--- a/doc/gitian-building.md
+++ b/doc/gitian-building.md
@@ -24,7 +24,7 @@ Table of Contents
- [Connecting to the VM](#connecting-to-the-vm)
- [Setting up Debian for gitian building](#setting-up-debian-for-gitian-building)
- [Installing gitian](#installing-gitian)
-- [Setting up gitian images](#setting-up-gitian-images)
+- [Setting up the gitian image](#setting-up-the-gitian-image)
- [Getting and building the inputs](#getting-and-building-the-inputs)
- [Building Bitcoin](#building-bitcoin)
- [Building an alternative repository](#building-an-alternative-repository)
@@ -74,16 +74,16 @@ In the VirtualBox GUI click "Create" and choose the following parameters in the
- Disk size: at least 40GB; as low as 20GB *may* be possible, but better to err on the safe side
- Push the `Create` button
-Get the [Debian 7.4 net installer](http://ftp.at.debian.org/debian-jigdo/current/amd64/iso-cd/debian-7.4.0-amd64-netinst.iso) (a more recent minor version should also work, see also [Debian Network installation](https://www.debian.org/CD/netinst/)).
+Get the [Debian 7.7 net installer](http://cdimage.debian.org/debian-cd/7.7.0/amd64/iso-cd/debian-7.7.0-amd64-netinst.iso) (a more recent minor version should also work, see also [Debian Network installation](https://www.debian.org/CD/netinst/)).
This DVD image can be validated using a SHA256 hashing tool, for example on
Unixy OSes by entering the following in a terminal:
- echo "b712a141bc60269db217d3b3e456179bd6b181645f90e4aac9c42ed63de492e9 debian-7.4.0-amd64-netinst.iso" | sha256sum -c
+ echo "d440e85b4121f94608748139f25dbce1ad36771348b002fe07d4d44b9d9e623f debian-7.7.0-amd64-netinst.iso" | sha256sum -c
# (must return OK)
After creating the VM, we need to configure it.
-- Click the `Settings` button, then go to the `Network` tab. Adapter 1 should be attacked to `NAT`.
+- Click the `Settings` button, then go to the `Network` tab. Adapter 1 should be attached to `NAT`.
![](gitian-building/network_settings.png)
@@ -109,7 +109,7 @@ Then start the VM. On the first launch you will be asked for a CD or DVD image.
Installing Debian
------------------
-In this section it will be explained how to install Debian on the newly created VM.
+This section will explain how to install Debian on the newly created VM.
- Choose the non-graphical installer. We do not need the graphical environment, it will only increase installation time and disk usage.
@@ -277,24 +277,21 @@ cd ..
**Note**: When sudo asks for a password, enter the password for the user *debian* not for *root*.
-Clone the git repositories for bitcoin and gitian and then checkout the bitcoin version that you want to build.
+Clone the git repositories for bitcoin and gitian.
```bash
git clone https://github.com/devrandom/gitian-builder.git
git clone https://github.com/bitcoin/bitcoin
-cd bitcoin
-git checkout v${VERSION}
-cd ..
```
-Setting up gitian images
+Setting up the gitian image
-------------------------
-Gitian needs virtual images of the operating system to build in.
-Currently this is Ubuntu Precise for x86_64.
-These images will be copied and used every time that a build is started to
+Gitian needs a virtual image of the operating system to build in.
+Currently this is Ubuntu Precise x86_64.
+This image will be copied and used every time that a build is started to
make sure that the build is deterministic.
-Creating the images will take a while, but only has to be done once.
+Creating the image will take a while, but only has to be done once.
Execute the following as user `debian`:
@@ -303,7 +300,7 @@ cd gitian-builder
bin/make-base-vm --lxc --arch amd64 --suite precise
```
-There will be a lot of warnings printed during build of the images. These can be ignored.
+There will be a lot of warnings printed during build of the image. These can be ignored.
**Note**: When sudo asks for a password, enter the password for the user *debian* not for *root*.
@@ -322,13 +319,14 @@ To build Bitcoin (for Linux, OSX and Windows) just follow the steps under 'perfo
gitian builds' in [doc/release-process.md](release-process.md) in the bitcoin repository.
This may take a long time as it also builds the dependencies needed for each descriptor.
-These dependencies will be cached after a successful build to avoid rebuilding them when possible.
+These dependencies will be cached after a successful build to avoid rebuilding them where possible.
At any time you can check the package installation and build progress with
```bash
tail -f var/install.log
tail -f var/build.log
+```
Output from `gbuild` will look something like
@@ -382,9 +380,9 @@ When you execute `gsign` you will get an error from GPG, which can be ignored. C
in `gitian.sigs` to your signing machine and do
```bash
- gpg --detach-sign ${VERSION}-linux/${SIGNER}/bitcoin-build.assert
- gpg --detach-sign ${VERSION}-win/${SIGNER}/bitcoin-build.assert
- gpg --detach-sign ${VERSION}-osx/${SIGNER}/bitcoin-build.assert
+ gpg --detach-sign ${VERSION}-linux/${SIGNER}/bitcoin-linux-build.assert
+ gpg --detach-sign ${VERSION}-win/${SIGNER}/bitcoin-win-build.assert
+ gpg --detach-sign ${VERSION}-osx-unsigned/${SIGNER}/bitcoin-osx-build.assert
```
This will create the `.sig` files that can be committed together with the `.assert` files to assert your
diff --git a/doc/release-process.md b/doc/release-process.md
index 30f9797752..363465d827 100644
--- a/doc/release-process.md
+++ b/doc/release-process.md
@@ -44,11 +44,11 @@ Release Process
Register and download the Apple SDK: (see OSX Readme for details)
- https://developer.apple.com/downloads/download.action?path=Developer_Tools/xcode_4.6.3/xcode4630916281a.dmg
+ https://developer.apple.com/downloads/download.action?path=Developer_Tools/xcode_6.1.1/xcode_6.1.1.dmg
- Using a Mac, create a tarball for the 10.7 SDK and copy it to the inputs directory:
+ Using a Mac, create a tarball for the 10.9 SDK and copy it to the inputs directory:
- tar -C /Volumes/Xcode/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/ -czf MacOSX10.7.sdk.tar.gz MacOSX10.7.sdk
+ tar -C /Volumes/Xcode/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/ -czf MacOSX10.9.sdk.tar.gz MacOSX10.9.sdk
###Optional: Seed the Gitian sources cache
@@ -68,7 +68,7 @@ Release Process
mv build/out/bitcoin-*.zip build/out/bitcoin-*.exe ../
./bin/gbuild --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-osx.yml
./bin/gsign --signer $SIGNER --release ${VERSION}-osx-unsigned --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-osx.yml
- mv build/out/bitcoin-*-unsigned.tar.gz inputs
+ mv build/out/bitcoin-*-unsigned.tar.gz inputs/bitcoin-osx-unsigned.tar.gz
mv build/out/bitcoin-*.tar.gz build/out/bitcoin-*.dmg ../
popd
Build output expected:
@@ -102,7 +102,7 @@ Commit your signature to gitian.sigs:
cp signature.tar.gz inputs/
./bin/gbuild -i ../bitcoin/contrib/gitian-descriptors/gitian-osx-signer.yml
./bin/gsign --signer $SIGNER --release ${VERSION}-osx-signed --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-osx-signer.yml
- mv build/out/bitcoin-${VERSION}-osx.dmg ../
+ mv build/out/bitcoin-osx-signed.dmg ../bitcoin-${VERSION}-osx.dmg
popd
Commit your signature for the signed OSX binary:
diff --git a/pkg.m4 b/pkg.m4
deleted file mode 100644
index c5b26b52e6..0000000000
--- a/pkg.m4
+++ /dev/null
@@ -1,214 +0,0 @@
-# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
-# serial 1 (pkg-config-0.24)
-#
-# Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
-#
-# This program 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 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
-
-# PKG_PROG_PKG_CONFIG([MIN-VERSION])
-# ----------------------------------
-AC_DEFUN([PKG_PROG_PKG_CONFIG],
-[m4_pattern_forbid([^_?PKG_[A-Z_]+$])
-m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$])
-m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$])
-AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])
-AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path])
-AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path])
-
-if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
- AC_PATH_TOOL([PKG_CONFIG], [pkg-config])
-fi
-if test -n "$PKG_CONFIG"; then
- _pkg_min_version=m4_default([$1], [0.9.0])
- AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version])
- if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
- AC_MSG_RESULT([yes])
- else
- AC_MSG_RESULT([no])
- PKG_CONFIG=""
- fi
-fi[]dnl
-])# PKG_PROG_PKG_CONFIG
-
-# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
-#
-# Check to see whether a particular set of modules exists. Similar
-# to PKG_CHECK_MODULES(), but does not set variables or print errors.
-#
-# Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG])
-# only at the first occurence in configure.ac, so if the first place
-# it's called might be skipped (such as if it is within an "if", you
-# have to call PKG_CHECK_EXISTS manually
-# --------------------------------------------------------------
-AC_DEFUN([PKG_CHECK_EXISTS],
-[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
-if test -n "$PKG_CONFIG" && \
- AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then
- m4_default([$2], [:])
-m4_ifvaln([$3], [else
- $3])dnl
-fi])
-
-# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
-# ---------------------------------------------
-m4_define([_PKG_CONFIG],
-[if test -n "$$1"; then
- pkg_cv_[]$1="$$1"
- elif test -n "$PKG_CONFIG"; then
- PKG_CHECK_EXISTS([$3],
- [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`
- test "x$?" != "x0" && pkg_failed=yes ],
- [pkg_failed=yes])
- else
- pkg_failed=untried
-fi[]dnl
-])# _PKG_CONFIG
-
-# _PKG_SHORT_ERRORS_SUPPORTED
-# -----------------------------
-AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED],
-[AC_REQUIRE([PKG_PROG_PKG_CONFIG])
-if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
- _pkg_short_errors_supported=yes
-else
- _pkg_short_errors_supported=no
-fi[]dnl
-])# _PKG_SHORT_ERRORS_SUPPORTED
-
-
-# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
-# [ACTION-IF-NOT-FOUND])
-#
-#
-# Note that if there is a possibility the first call to
-# PKG_CHECK_MODULES might not happen, you should be sure to include an
-# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac
-#
-#
-# --------------------------------------------------------------
-AC_DEFUN([PKG_CHECK_MODULES],
-[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
-AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
-AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
-
-pkg_failed=no
-AC_MSG_CHECKING([for $1])
-
-_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
-_PKG_CONFIG([$1][_LIBS], [libs], [$2])
-
-m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS
-and $1[]_LIBS to avoid the need to call pkg-config.
-See the pkg-config man page for more details.])
-
-if test $pkg_failed = yes; then
- AC_MSG_RESULT([no])
- _PKG_SHORT_ERRORS_SUPPORTED
- if test $_pkg_short_errors_supported = yes; then
- $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1`
- else
- $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1`
- fi
- # Put the nasty error message in config.log where it belongs
- echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
-
- m4_default([$4], [AC_MSG_ERROR(
-[Package requirements ($2) were not met:
-
-$$1_PKG_ERRORS
-
-Consider adjusting the PKG_CONFIG_PATH environment variable if you
-installed software in a non-standard prefix.
-
-_PKG_TEXT])[]dnl
- ])
-elif test $pkg_failed = untried; then
- AC_MSG_RESULT([no])
- m4_default([$4], [AC_MSG_FAILURE(
-[The pkg-config script could not be found or is too old. Make sure it
-is in your PATH or set the PKG_CONFIG environment variable to the full
-path to pkg-config.
-
-_PKG_TEXT
-
-To get pkg-config, see <http://pkg-config.freedesktop.org/>.])[]dnl
- ])
-else
- $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
- $1[]_LIBS=$pkg_cv_[]$1[]_LIBS
- AC_MSG_RESULT([yes])
- $3
-fi[]dnl
-])# PKG_CHECK_MODULES
-
-
-# PKG_INSTALLDIR(DIRECTORY)
-# -------------------------
-# Substitutes the variable pkgconfigdir as the location where a module
-# should install pkg-config .pc files. By default the directory is
-# $libdir/pkgconfig, but the default can be changed by passing
-# DIRECTORY. The user can override through the --with-pkgconfigdir
-# parameter.
-AC_DEFUN([PKG_INSTALLDIR],
-[m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])])
-m4_pushdef([pkg_description],
- [pkg-config installation directory @<:@]pkg_default[@:>@])
-AC_ARG_WITH([pkgconfigdir],
- [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],,
- [with_pkgconfigdir=]pkg_default)
-AC_SUBST([pkgconfigdir], [$with_pkgconfigdir])
-m4_popdef([pkg_default])
-m4_popdef([pkg_description])
-]) dnl PKG_INSTALLDIR
-
-
-# PKG_NOARCH_INSTALLDIR(DIRECTORY)
-# -------------------------
-# Substitutes the variable noarch_pkgconfigdir as the location where a
-# module should install arch-independent pkg-config .pc files. By
-# default the directory is $datadir/pkgconfig, but the default can be
-# changed by passing DIRECTORY. The user can override through the
-# --with-noarch-pkgconfigdir parameter.
-AC_DEFUN([PKG_NOARCH_INSTALLDIR],
-[m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])])
-m4_pushdef([pkg_description],
- [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@])
-AC_ARG_WITH([noarch-pkgconfigdir],
- [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],,
- [with_noarch_pkgconfigdir=]pkg_default)
-AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir])
-m4_popdef([pkg_default])
-m4_popdef([pkg_description])
-]) dnl PKG_NOARCH_INSTALLDIR
-
-
-# PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE,
-# [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
-# -------------------------------------------
-# Retrieves the value of the pkg-config variable for the given module.
-AC_DEFUN([PKG_CHECK_VAR],
-[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
-AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl
-
-_PKG_CONFIG([$1], [variable="][$3]["], [$2])
-AS_VAR_COPY([$1], [pkg_cv_][$1])
-
-AS_VAR_IF([$1], [""], [$5], [$4])dnl
-])# PKG_CHECK_VAR
diff --git a/qa/pull-tester/rpc-tests.sh b/qa/pull-tester/rpc-tests.sh
index 15cac14595..efeee45530 100755
--- a/qa/pull-tester/rpc-tests.sh
+++ b/qa/pull-tester/rpc-tests.sh
@@ -26,6 +26,7 @@ testScripts=(
'mempool_spendcoinbase.py'
'mempool_coinbase_spends.py'
'httpbasics.py'
+ 'zapwallettxes.py'
# 'forknotify.py'
);
if [ "x${ENABLE_BITCOIND}${ENABLE_UTILS}${ENABLE_WALLET}" = "x111" ]; then
@@ -33,7 +34,7 @@ if [ "x${ENABLE_BITCOIND}${ENABLE_UTILS}${ENABLE_WALLET}" = "x111" ]; then
do
if [ -z "$1" ] || [ "$1" == "${testScripts[$i]}" ] || [ "$1.py" == "${testScripts[$i]}" ]
then
- echo -e "running testscript \033[1m${testScripts[$i]}...\033[0m"
+ echo -e "Running testscript \033[1m${testScripts[$i]}...\033[0m"
${BUILDDIR}/qa/rpc-tests/${testScripts[$i]} --srcdir "${BUILDDIR}/src"
fi
done
diff --git a/qa/pull-tester/run-bitcoind-for-test.sh.in b/qa/pull-tester/run-bitcoind-for-test.sh.in
index 42d8ad52e8..14ae08e4e5 100755
--- a/qa/pull-tester/run-bitcoind-for-test.sh.in
+++ b/qa/pull-tester/run-bitcoind-for-test.sh.in
@@ -10,7 +10,7 @@ touch "$DATADIR/regtest/debug.log"
tail -q -n 1 -F "$DATADIR/regtest/debug.log" | grep -m 1 -q "Done loading" &
WAITER=$!
PORT=`expr 10000 + $$ % 55536`
-"@abs_top_builddir@/src/bitcoind@EXEEXT@" -connect=0.0.0.0 -datadir="$DATADIR" -rpcuser=user -rpcpassword=pass -listen -keypool=3 -debug -debug=net -logtimestamps -checkmempool=0 -port=$PORT -whitelist=127.0.0.1 -regtest -rpcport=`expr $PORT + 1` &
+"@abs_top_builddir@/src/bitcoind@EXEEXT@" -connect=0.0.0.0 -datadir="$DATADIR" -rpcuser=user -rpcpassword=pass -listen -keypool=3 -debug -debug=net -logtimestamps -checkmempool=0 -relaypriority=0 -port=$PORT -whitelist=127.0.0.1 -regtest -rpcport=`expr $PORT + 1` &
BITCOIND=$!
#Install a watchdog.
diff --git a/qa/rpc-tests/README.md b/qa/rpc-tests/README.md
index 3e916a7688..02170d13ec 100644
--- a/qa/rpc-tests/README.md
+++ b/qa/rpc-tests/README.md
@@ -12,7 +12,7 @@ Base class for new regression tests.
### [listtransactions.py](listtransactions.py)
Tests for the listtransactions RPC call.
-### [util.py](util.sh)
+### [util.py](util.py)
Generally useful functions.
Bash-based tests, to be ported to Python:
diff --git a/qa/rpc-tests/bipdersig.py b/qa/rpc-tests/bipdersig.py
new file mode 100755
index 0000000000..9f2cc84601
--- /dev/null
+++ b/qa/rpc-tests/bipdersig.py
@@ -0,0 +1,90 @@
+#!/usr/bin/env python2
+# Copyright (c) 2014 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#
+# Test the BIP66 changeover logic
+#
+
+from test_framework import BitcoinTestFramework
+from bitcoinrpc.authproxy import AuthServiceProxy, JSONRPCException
+from util import *
+import os
+import shutil
+
+class BIP66Test(BitcoinTestFramework):
+
+ def setup_network(self):
+ self.nodes = []
+ self.nodes.append(start_node(0, self.options.tmpdir, []))
+ self.nodes.append(start_node(1, self.options.tmpdir, ["-blockversion=2"]))
+ self.nodes.append(start_node(2, self.options.tmpdir, ["-blockversion=3"]))
+ connect_nodes(self.nodes[1], 0)
+ connect_nodes(self.nodes[2], 0)
+ self.is_network_split = False
+ self.sync_all()
+
+ def run_test(self):
+ cnt = self.nodes[0].getblockcount()
+
+ # Mine some old-version blocks
+ self.nodes[1].setgenerate(True, 100)
+ self.sync_all()
+ if (self.nodes[0].getblockcount() != cnt + 100):
+ raise AssertionError("Failed to mine 100 version=2 blocks")
+
+ # Mine 750 new-version blocks
+ for i in xrange(15):
+ self.nodes[2].setgenerate(True, 50)
+ self.sync_all()
+ if (self.nodes[0].getblockcount() != cnt + 850):
+ raise AssertionError("Failed to mine 750 version=3 blocks")
+
+ # TODO: check that new DERSIG rules are not enforced
+
+ # Mine 1 new-version block
+ self.nodes[2].setgenerate(True, 1)
+ self.sync_all()
+ if (self.nodes[0].getblockcount() != cnt + 851):
+ raise AssertionFailure("Failed to mine a version=3 blocks")
+
+ # TODO: check that new DERSIG rules are enforced
+
+ # Mine 198 new-version blocks
+ for i in xrange(2):
+ self.nodes[2].setgenerate(True, 99)
+ self.sync_all()
+ if (self.nodes[0].getblockcount() != cnt + 1049):
+ raise AssertionError("Failed to mine 198 version=3 blocks")
+
+ # Mine 1 old-version block
+ self.nodes[1].setgenerate(True, 1)
+ self.sync_all()
+ if (self.nodes[0].getblockcount() != cnt + 1050):
+ raise AssertionError("Failed to mine a version=2 block after 949 version=3 blocks")
+
+ # Mine 1 new-version blocks
+ self.nodes[2].setgenerate(True, 1)
+ self.sync_all()
+ if (self.nodes[0].getblockcount() != cnt + 1051):
+ raise AssertionError("Failed to mine a version=3 block")
+
+ # Mine 1 old-version blocks
+ try:
+ self.nodes[1].setgenerate(True, 1)
+ raise AssertionError("Succeeded to mine a version=2 block after 950 version=3 blocks")
+ except JSONRPCException:
+ pass
+ self.sync_all()
+ if (self.nodes[0].getblockcount() != cnt + 1051):
+ raise AssertionError("Accepted a version=2 block after 950 version=3 blocks")
+
+ # Mine 1 new-version blocks
+ self.nodes[2].setgenerate(True, 1)
+ self.sync_all()
+ if (self.nodes[0].getblockcount() != cnt + 1052):
+ raise AssertionError("Failed to mine a version=3 block")
+
+if __name__ == '__main__':
+ BIP66Test().main()
diff --git a/qa/rpc-tests/getblocktemplate_proposals.py b/qa/rpc-tests/getblocktemplate_proposals.py
index 22fe2ce044..f65162002d 100755
--- a/qa/rpc-tests/getblocktemplate_proposals.py
+++ b/qa/rpc-tests/getblocktemplate_proposals.py
@@ -95,6 +95,7 @@ class GetBlockTemplateProposalTest(BitcoinTestFramework):
def run_test(self):
node = self.nodes[0]
+ node.setgenerate(True, 1) # Mine a block to leave initial block download
tmpl = node.getblocktemplate()
if 'coinbasetxn' not in tmpl:
rawcoinbase = encodeUNum(tmpl['height'])
diff --git a/qa/rpc-tests/httpbasics.py b/qa/rpc-tests/httpbasics.py
index 85e85e7f0f..24533741e5 100755
--- a/qa/rpc-tests/httpbasics.py
+++ b/qa/rpc-tests/httpbasics.py
@@ -21,6 +21,9 @@ except ImportError:
import urlparse
class HTTPBasicsTest (BitcoinTestFramework):
+ def setup_nodes(self):
+ return start_nodes(4, self.options.tmpdir, extra_args=[['-rpckeepalive=1'], ['-rpckeepalive=0'], [], []])
+
def run_test(self):
#################################################
@@ -32,13 +35,13 @@ class HTTPBasicsTest (BitcoinTestFramework):
conn = httplib.HTTPConnection(url.hostname, url.port)
conn.connect()
- conn.request('GET', '/', '{"method": "getbestblockhash"}', headers)
+ conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
out1 = conn.getresponse().read();
assert_equal('"error":null' in out1, True)
assert_equal(conn.sock!=None, True) #according to http/1.1 connection must still be open!
#send 2nd request without closing connection
- conn.request('GET', '/', '{"method": "getchaintips"}', headers)
+ conn.request('POST', '/', '{"method": "getchaintips"}', headers)
out2 = conn.getresponse().read();
assert_equal('"error":null' in out1, True) #must also response with a correct json-rpc message
assert_equal(conn.sock!=None, True) #according to http/1.1 connection must still be open!
@@ -49,13 +52,13 @@ class HTTPBasicsTest (BitcoinTestFramework):
conn = httplib.HTTPConnection(url.hostname, url.port)
conn.connect()
- conn.request('GET', '/', '{"method": "getbestblockhash"}', headers)
+ conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
out1 = conn.getresponse().read();
assert_equal('"error":null' in out1, True)
assert_equal(conn.sock!=None, True) #according to http/1.1 connection must still be open!
#send 2nd request without closing connection
- conn.request('GET', '/', '{"method": "getchaintips"}', headers)
+ conn.request('POST', '/', '{"method": "getchaintips"}', headers)
out2 = conn.getresponse().read();
assert_equal('"error":null' in out1, True) #must also response with a correct json-rpc message
assert_equal(conn.sock!=None, True) #according to http/1.1 connection must still be open!
@@ -66,11 +69,34 @@ class HTTPBasicsTest (BitcoinTestFramework):
conn = httplib.HTTPConnection(url.hostname, url.port)
conn.connect()
- conn.request('GET', '/', '{"method": "getbestblockhash"}', headers)
+ conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
out1 = conn.getresponse().read();
assert_equal('"error":null' in out1, True)
assert_equal(conn.sock!=None, False) #now the connection must be closed after the response
+ #node1 (2nd node) is running with disabled keep-alive option
+ urlNode1 = urlparse.urlparse(self.nodes[1].url)
+ authpair = urlNode1.username + ':' + urlNode1.password
+ headers = {"Authorization": "Basic " + base64.b64encode(authpair)}
+
+ conn = httplib.HTTPConnection(urlNode1.hostname, urlNode1.port)
+ conn.connect()
+ conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
+ out1 = conn.getresponse().read();
+ assert_equal('"error":null' in out1, True)
+ assert_equal(conn.sock!=None, False) #connection must be closed because keep-alive was set to false
+
+ #node2 (third node) is running with standard keep-alive parameters which means keep-alive is off
+ urlNode2 = urlparse.urlparse(self.nodes[2].url)
+ authpair = urlNode2.username + ':' + urlNode2.password
+ headers = {"Authorization": "Basic " + base64.b64encode(authpair)}
+
+ conn = httplib.HTTPConnection(urlNode2.hostname, urlNode2.port)
+ conn.connect()
+ conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
+ out1 = conn.getresponse().read();
+ assert_equal('"error":null' in out1, True)
+ assert_equal(conn.sock!=None, True) #connection must be closed because bitcoind should use keep-alive by default
if __name__ == '__main__':
HTTPBasicsTest ().main ()
diff --git a/qa/rpc-tests/smartfees.py b/qa/rpc-tests/smartfees.py
index 924d160102..0c07ef8a53 100755
--- a/qa/rpc-tests/smartfees.py
+++ b/qa/rpc-tests/smartfees.py
@@ -16,20 +16,20 @@ class EstimateFeeTest(BitcoinTestFramework):
def setup_network(self):
self.nodes = []
self.nodes.append(start_node(0, self.options.tmpdir,
- ["-debug=mempool", "-debug=estimatefee"]))
+ ["-debug=mempool", "-debug=estimatefee", "-relaypriority=0"]))
# Node1 mines small-but-not-tiny blocks, and allows free transactions.
# NOTE: the CreateNewBlock code starts counting block size at 1,000 bytes,
# so blockmaxsize of 2,000 is really just 1,000 bytes (room enough for
# 6 or 7 transactions)
self.nodes.append(start_node(1, self.options.tmpdir,
["-blockprioritysize=1500", "-blockmaxsize=2000",
- "-debug=mempool", "-debug=estimatefee"]))
+ "-debug=mempool", "-debug=estimatefee", "-relaypriority=0"]))
connect_nodes(self.nodes[1], 0)
# Node2 is a stingy miner, that
# produces very small blocks (room for only 3 or so transactions)
node2args = [ "-blockprioritysize=0", "-blockmaxsize=1500",
- "-debug=mempool", "-debug=estimatefee"]
+ "-debug=mempool", "-debug=estimatefee", "-relaypriority=0"]
self.nodes.append(start_node(2, self.options.tmpdir, node2args))
connect_nodes(self.nodes[2], 0)
diff --git a/qa/rpc-tests/test_framework.py b/qa/rpc-tests/test_framework.py
index 6c4ec073c2..4c8a11b821 100755
--- a/qa/rpc-tests/test_framework.py
+++ b/qa/rpc-tests/test_framework.py
@@ -33,8 +33,11 @@ class BitcoinTestFramework(object):
print("Initializing test directory "+self.options.tmpdir)
initialize_chain(self.options.tmpdir)
+ def setup_nodes(self):
+ return start_nodes(4, self.options.tmpdir)
+
def setup_network(self, split = False):
- self.nodes = start_nodes(4, self.options.tmpdir)
+ self.nodes = self.setup_nodes()
# Connect the nodes as a "chain". This allows us
# to split the network between nodes 1 and 2 to get
diff --git a/qa/rpc-tests/wallet.py b/qa/rpc-tests/wallet.py
index d99540b58a..3e63493dc6 100755
--- a/qa/rpc-tests/wallet.py
+++ b/qa/rpc-tests/wallet.py
@@ -41,6 +41,10 @@ class WalletTest (BitcoinTestFramework):
self.nodes[0].setgenerate(True, 1)
+ walletinfo = self.nodes[0].getwalletinfo()
+ assert_equal(walletinfo['immature_balance'], 50)
+ assert_equal(walletinfo['balance'], 0)
+
self.sync_all()
self.nodes[1].setgenerate(True, 101)
self.sync_all()
@@ -54,7 +58,10 @@ class WalletTest (BitcoinTestFramework):
self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 11)
self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 10)
- # Have node0 mine a block, thus he will collect his own fee.
+ walletinfo = self.nodes[0].getwalletinfo()
+ assert_equal(walletinfo['immature_balance'], 0)
+
+ # Have node0 mine a block, thus they will collect their own fee.
self.nodes[0].setgenerate(True, 1)
self.sync_all()
diff --git a/qa/rpc-tests/zapwallettxes.py b/qa/rpc-tests/zapwallettxes.py
new file mode 100755
index 0000000000..a773575906
--- /dev/null
+++ b/qa/rpc-tests/zapwallettxes.py
@@ -0,0 +1,82 @@
+#!/usr/bin/env python2
+# Copyright (c) 2014 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+from test_framework import BitcoinTestFramework
+from util import *
+
+
+class ZapWalletTXesTest (BitcoinTestFramework):
+
+ def setup_chain(self):
+ print("Initializing test directory "+self.options.tmpdir)
+ initialize_chain_clean(self.options.tmpdir, 3)
+
+ def setup_network(self, split=False):
+ self.nodes = start_nodes(3, self.options.tmpdir)
+ connect_nodes_bi(self.nodes,0,1)
+ connect_nodes_bi(self.nodes,1,2)
+ connect_nodes_bi(self.nodes,0,2)
+ self.is_network_split=False
+ self.sync_all()
+
+ def run_test (self):
+ print "Mining blocks..."
+ self.nodes[0].setgenerate(True, 1)
+ self.sync_all()
+ self.nodes[1].setgenerate(True, 101)
+ self.sync_all()
+
+ assert_equal(self.nodes[0].getbalance(), 50)
+
+ txid0 = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 11)
+ txid1 = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 10)
+ self.sync_all()
+ self.nodes[0].setgenerate(True, 1)
+ self.sync_all()
+
+ txid2 = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 11)
+ txid3 = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 10)
+
+ tx0 = self.nodes[0].gettransaction(txid0)
+ assert_equal(tx0['txid'], txid0) #tx0 must be available (confirmed)
+
+ tx1 = self.nodes[0].gettransaction(txid1)
+ assert_equal(tx1['txid'], txid1) #tx1 must be available (confirmed)
+
+ tx2 = self.nodes[0].gettransaction(txid2)
+ assert_equal(tx2['txid'], txid2) #tx2 must be available (unconfirmed)
+
+ tx3 = self.nodes[0].gettransaction(txid3)
+ assert_equal(tx3['txid'], txid3) #tx3 must be available (unconfirmed)
+
+ #restart bitcoind
+ self.nodes[0].stop()
+ bitcoind_processes[0].wait()
+ self.nodes[0] = start_node(0,self.options.tmpdir)
+
+ tx3 = self.nodes[0].gettransaction(txid3)
+ assert_equal(tx3['txid'], txid3) #tx must be available (unconfirmed)
+
+ self.nodes[0].stop()
+ bitcoind_processes[0].wait()
+
+ #restart bitcoind with zapwallettxes
+ self.nodes[0] = start_node(0,self.options.tmpdir, ["-zapwallettxes=1"])
+
+ aException = False
+ try:
+ tx3 = self.nodes[0].gettransaction(txid3)
+ except JSONRPCException,e:
+ print e
+ aException = True
+
+ assert_equal(aException, True) #there must be a expection because the unconfirmed wallettx0 must be gone by now
+
+ tx0 = self.nodes[0].gettransaction(txid0)
+ assert_equal(tx0['txid'], txid0) #tx0 (confirmed) must still be available because it was confirmed
+
+
+if __name__ == '__main__':
+ ZapWalletTXesTest ().main ()
diff --git a/qa/rpc-tests/zapwallettxes.sh b/qa/rpc-tests/zapwallettxes.sh
deleted file mode 100755
index 4312d84e94..0000000000
--- a/qa/rpc-tests/zapwallettxes.sh
+++ /dev/null
@@ -1,165 +0,0 @@
-#!/usr/bin/env bash
-# Copyright (c) 2014 The Bitcoin Core developers
-# Distributed under the MIT software license, see the accompanying
-# file COPYING or http://www.opensource.org/licenses/mit-license.php.
-
-# Test -zapwallettxes=<mode>
-
-if [ $# -lt 1 ]; then
- echo "Usage: $0 path_to_binaries"
- echo "e.g. $0 ../../src"
- echo "Env vars BITCOIND and BITCOINCLI may be used to specify the exact binaries used"
- exit 1
-fi
-
-set -f
-
-BITCOIND=${BITCOIND:-${1}/bitcoind}
-CLI=${BITCOINCLI:-${1}/bitcoin-cli}
-
-DIR="${BASH_SOURCE%/*}"
-SENDANDWAIT="${DIR}/send.sh"
-if [[ ! -d "$DIR" ]]; then DIR="$PWD"; fi
-. "$DIR/util.sh"
-
-D=$(mktemp -d test.XXXXX)
-
-D1=${D}/node1
-CreateDataDir "$D1" port=11000 rpcport=11001
-B1ARGS="-datadir=$D1"
-$BITCOIND $B1ARGS &
-B1PID=$!
-
-D2=${D}/node2
-CreateDataDir "$D2" port=11010 rpcport=11011
-B2ARGS="-datadir=$D2"
-$BITCOIND $B2ARGS &
-B2PID=$!
-
-function CleanUp {
-$CLI $B2ARGS stop > /dev/null 2>&1
-wait $B2PID
-$CLI $B1ARGS stop > /dev/null 2>&1
-wait $B1PID
-
-rm -rf $D
-}
-
-# 110 blocks, 10 mature == 500 XBT
-$CLI $B1ARGS setgenerate true 110
-$CLI $B2ARGS setgenerate true 110
-
-CheckBalance "$B1ARGS" 500
-CheckBalance "$B2ARGS" 500
-
-# Send 10 XBT
-TXID1_DEFAULT=$($CLI $B1ARGS sendtoaddress "mrhz5ZgSF3C1BSdyCKt3gEdhKoRL5BNfJV" 10)
-TXID2_DEFAULT=$($CLI $B2ARGS sendtoaddress "mrhz5ZgSF3C1BSdyCKt3gEdhKoRL5BNfJV" 10)
-
-CheckBalance $B1ARGS 490
-CheckBalance $B2ARGS 490
-
-# Move 10 XBT to testaccount
-TMP=$($CLI $B1ARGS move "" "testaccount" 10)
-TMP=$($CLI $B2ARGS move "" "testaccount" 10)
-
-CheckBalance $B1ARGS 10 "testaccount"
-CheckBalance $B2ARGS 10 "testaccount"
-
-# Send 1 XBT from testaccount
-TXID1_TESTACCOUNT=$($CLI $B1ARGS sendfrom "testaccount" "mrhz5ZgSF3C1BSdyCKt3gEdhKoRL5BNfJV" 1)
-TXID2_TESTACCOUNT=$($CLI $B2ARGS sendfrom "testaccount" "mrhz5ZgSF3C1BSdyCKt3gEdhKoRL5BNfJV" 1)
-
-CheckBalance $B1ARGS 9 "testaccount"
-CheckBalance $B2ARGS 9 "testaccount"
-
-CheckBalance $B1ARGS 489
-CheckBalance $B2ARGS 489
-
-# Confirm transactions
-$CLI $B1ARGS setgenerate true 1
-$CLI $B2ARGS setgenerate true 1
-
-# Create unconfirmed transaction
-TXID1_UNCONFIRMED=$($CLI $B1ARGS sendtoaddress "mrhz5ZgSF3C1BSdyCKt3gEdhKoRL5BNfJV" 1)
-TXID2_UNCONFIRMED=$($CLI $B2ARGS sendtoaddress "mrhz5ZgSF3C1BSdyCKt3gEdhKoRL5BNfJV" 1)
-
-# check balance (we created another 50 and spent 1 in the meantime)
-CheckBalance $B1ARGS 538
-CheckBalance $B2ARGS 538
-
-# Safety check, if unconfirmed transactions are there
-$CLI $B1ARGS gettransaction $TXID1_UNCONFIRMED > /dev/null 2>&1
-if [[ $? -ne 0 ]] ; then
- echoerr "gettransaction1_1: $TXID1_UNCONFIRMED failed"
- CleanUp
- exit 1
-fi
-$CLI $B2ARGS gettransaction $TXID2_UNCONFIRMED > /dev/null 2>&1
-if [[ $? -ne 0 ]] ; then
- echoerr "gettransaction2_1: $TXID2_UNCONFIRMED failed"
- CleanUp
- exit 1
-fi
-
-# stop nodes
-$CLI $B2ARGS stop > /dev/null 2>&1
-wait $B2PID
-$CLI $B1ARGS stop > /dev/null 2>&1
-wait $B1PID
-
-# restart nodes with -zapwallettxes
-$BITCOIND -zapwallettxes=1 $B1ARGS &
-B1PID=$!
-$BITCOIND -zapwallettxes=2 $B2ARGS &
-B2PID=$!
-
-# check if confirmed transactions are there
-$CLI $B1ARGS gettransaction $TXID1_DEFAULT > /dev/null 2>&1
-if [[ $? -ne 0 ]] ; then
- echoerr "check confirmed transaction 1: $TXID1_DEFAULT failed"
- CleanUp
- exit 1
-fi
-$CLI $B2ARGS gettransaction $TXID2_DEFAULT > /dev/null 2>&1
-if [[ $? -ne 0 ]] ; then
- echoerr "check confirmed transaction 2: $TXID2_DEFAULT failed"
- CleanUp
- exit 1
-fi
-$CLI $B1ARGS gettransaction $TXID1_TESTACCOUNT > /dev/null 2>&1
-if [[ $? -ne 0 ]] ; then
- echoerr "check confirmed transaction 3: $TXID1_TESTACCOUNT failed"
- CleanUp
- exit 1
-fi
-$CLI $B2ARGS gettransaction $TXID2_TESTACCOUNT > /dev/null 2>&1
-if [[ $? -ne 0 ]] ; then
- echoerr "check confirmed transaction 4: $TXID2_TESTACCOUNT failed"
- CleanUp
- exit 1
-fi
-
-# check if unconfirmed transaction is gone
-$CLI $B1ARGS gettransaction $TXID1_UNCONFIRMED > /dev/null 2>&1
-if [[ $? -eq 0 ]] ; then
- echoerr "check unconfirmed transaction 1: $TXID1_UNCONFIRMED failed"
- CleanUp
- exit 1
-fi
-$CLI $B2ARGS gettransaction $TXID2_UNCONFIRMED > /dev/null 2>&1
-if [[ $? -eq 0 ]] ; then
- echoerr "check unconfirmed transaction 2: $TXID2_UNCONFIRMED failed"
- CleanUp
- exit 1
-fi
-
-# check zapwallet mode 1, testaccount balance must be 9 (keeping transaction metadata)
-CheckBalance $B1ARGS 9 "testaccount"
-
-# check zapwallet mode 2, testaccount balance must be 10 (dropping transaction metadata)
-CheckBalance $B2ARGS 10 "testaccount"
-
-echo "Tests successful, cleaning up"
-CleanUp
-exit 0
diff --git a/share/seeds/nodes_main.txt b/share/seeds/nodes_main.txt
index f2558cf3c4..3dba6d8a64 100644
--- a/share/seeds/nodes_main.txt
+++ b/share/seeds/nodes_main.txt
@@ -1,607 +1,518 @@
# List of fixed seed nodes for main network
-# IPv4 nodes (in old chainparams.cpp 0xDDCCBBAA format)
-# n.b. when importing a new list, there is no need to use this format, just use IPv4 dotted addresses directly
-0x7e6a692e # 46.105.106.126
-0x7d04d1a2 # 162.209.4.125
-0x6c0c17d9 # 217.23.12.108
-0xdb330ab9 # 185.10.51.219
-0xc649c7c6 # 198.199.73.198
-0x7895484d # 77.72.149.120
-0x047109b0 # 176.9.113.4
-0xb90ca5bc # 188.165.12.185
-0xd130805f # 95.128.48.209
-0xbd074ea6 # 166.78.7.189
-0x578ff1c0 # 192.241.143.87
-0x286e09b0 # 176.9.110.40
-0xd4dcaf42 # 66.175.220.212
-0x529b6bb8 # 184.107.155.82
-0x635cc6c0 # 192.198.92.99
-0xedde892e # 46.137.222.237
-0xa976d9c7 # 199.217.118.169
-0xea91a4b8 # 184.164.145.234
-0x03fa4eb2 # 178.78.250.3
-0x6ca9008d # 141.0.169.108
-0xaf62c825 # 37.200.98.175
-0x93f3ba51 # 81.186.243.147
-0xc2c9efd5 # 213.239.201.194
-0x0ed5175e # 94.23.213.14
-0x487028bc # 188.40.112.72
-0x7297c225 # 37.194.151.114
-0x8af0c658 # 88.198.240.138
-0x2e57ba1f # 31.186.87.46
-0xd0098abc # 188.138.9.208
-0x46a8853e # 62.133.168.70
-0xcc92dc3e # 62.220.146.204
-0xeb6f1955 # 85.25.111.235
-0x8cce175e # 94.23.206.140
-0x237281ae # 174.129.114.35
-0x9d42795b # 91.121.66.157
-0x4f4f0905 # 5.9.79.79
-0xc50151d0 # 208.81.1.197
-0xb1ba90c6 # 198.144.186.177
-0xaed7175e # 94.23.215.174
-0x204de55b # 91.229.77.32
-0x4bb03245 # 69.50.176.75
-0x932b28bc # 188.40.43.147
-0x2dcce65b # 91.230.204.45
-0xe2708abc # 188.138.112.226
-0x1b08b8d5 # 213.184.8.27
-0x12a3dc5b # 91.220.163.18
-0x8a884c90 # 144.76.136.138
-0xa386a8b8 # 184.168.134.163
-0x18e417c6 # 198.23.228.24
-0x2e709ac3 # 195.154.112.46
-0xeb62e925 # 37.233.98.235
-0x6f6503ae # 174.3.101.111
-0x05d0814e # 78.129.208.5
-0x8a9ac545 # 69.197.154.138
-0x946fd65e # 94.214.111.148
-0x3f57495d # 93.73.87.63
-0x4a29c658 # 88.198.41.74
-0xad454c90 # 144.76.69.173
-0x15340905 # 5.9.52.21
-0x4c3f3b25 # 37.59.63.76
-0x01fe19b9 # 185.25.254.1
-0x5620595b # 91.89.32.86
-0x443c795b # 91.121.60.68
-0x44f24ac8 # 200.74.242.68
-0x0442464e # 78.70.66.4
-0xc8665882 # 130.88.102.200
-0xed3f3ec3 # 195.62.63.237
-0xf585bf5d # 93.191.133.245
-0x5dd141da # 218.65.209.93
-0xf93a084e # 78.8.58.249
-0x1264dd52 # 82.221.100.18
-0x0711c658 # 88.198.17.7
-0xf12e7bbe # 190.123.46.241
-0x5b02b740 # 64.183.2.91
-0x7d526dd5 # 213.109.82.125
-0x0cb04c90 # 144.76.176.12
-0x2abe1132 # 50.17.190.42
-0x61a39f58 # 88.159.163.97
-0x044a0618 # 24.6.74.4
-0xf3af7dce # 206.125.175.243
-0xb994c96d # 109.201.148.185
-0x361c5058 # 88.80.28.54
-0xca735d53 # 83.93.115.202
-0xeca743b0 # 176.67.167.236
-0xec790905 # 5.9.121.236
-0xc4d37845 # 69.120.211.196
-0xa1c4a2b2 # 178.162.196.161
-0x726fd453 # 83.212.111.114
-0x625cc6c0 # 192.198.92.98
-0x6c20132e # 46.19.32.108
-0xb7aa0c79 # 121.12.170.183
-0xc6ed983d # 61.152.237.198
-0x47e4cbc0 # 192.203.228.71
-0xa4ac75d4 # 212.117.172.164
-0xe2e59345 # 69.147.229.226
-0x4d784ad0 # 208.74.120.77
-0x18a5ec5e # 94.236.165.24
-0x481cc85b # 91.200.28.72
-0x7c6c2fd5 # 213.47.108.124
-0x5e4d6018 # 24.96.77.94
-0x5b4b6c18 # 24.108.75.91
-0xd99b4c90 # 144.76.155.217
-0xe63987dc # 220.135.57.230
-0xb817bb25 # 37.187.23.184
-0x141cfeb2 # 178.254.28.20
-0x5f005058 # 88.80.0.95
-0x0d987f47 # 71.127.152.13
-0x242a496d # 109.73.42.36
-0x3e519bc0 # 192.155.81.62
-0x02b2454b # 75.69.178.2
-0xdfaf3dc6 # 198.61.175.223
-0x888128bc # 188.40.129.136
-0x1165bb25 # 37.187.101.17
-0xabfeca5b # 91.202.254.171
-0x2ef63540 # 64.53.246.46
-0x5773c7c6 # 198.199.115.87
-0x1280dd52 # 82.221.128.18
-0x8ebcacd9 # 217.172.188.142
-0x81c439c6 # 198.57.196.129
-0x39fcfa45 # 69.250.252.57
-0x62177d41 # 65.125.23.98
-0xc975ed62 # 98.237.117.201
-0x05cff476 # 118.244.207.5
-0xdabda743 # 67.167.189.218
-0xaa1ac24e # 78.194.26.170
-0xe255a22e # 46.162.85.226
-0x88aac705 # 5.199.170.136
-0xe707c658 # 88.198.7.231
-0xa9e94b5e # 94.75.233.169
-0x2893484b # 75.72.147.40
-0x99512705 # 5.39.81.153
-0xd63970ca # 202.112.57.214
-0x45994f32 # 50.79.153.69
-0xe519a8ad # 173.168.25.229
-0x92e25f5d # 93.95.226.146
-0x8b84a9c1 # 193.169.132.139
-0x5eaa0a05 # 5.10.170.94
-0xa74de55b # 91.229.77.167
-0xb090ff62 # 98.255.144.176
-0x5eee326c # 108.50.238.94
-0xc331a679 # 121.166.49.195
-0xc1d9b72e # 46.183.217.193
-0x0c6ab982 # 130.185.106.12
-0x7362bb25 # 37.187.98.115
-0x4cfedd42 # 66.221.254.76
-0x1e09a032 # 50.160.9.30
-0xa4c34c5e # 94.76.195.164
-0x3777d9c7 # 199.217.119.55
-0x5edcf260 # 96.242.220.94
-0x3ce2b548 # 72.181.226.60
-0xd2ac0360 # 96.3.172.210
-0x2f80b992 # 146.185.128.47
-0x3e4cbb25 # 37.187.76.62
-0x3995e236 # 54.226.149.57
-0xd03977ae # 174.119.57.208
-0x953cf054 # 84.240.60.149
-0x3c654ed0 # 208.78.101.60
-0x74024c90 # 144.76.2.116
-0xa14f1155 # 85.17.79.161
-0x14ce0125 # 37.1.206.20
-0xc15ebb6a # 106.187.94.193
-0x2c08c452 # 82.196.8.44
-0xc7fd0652 # 82.6.253.199
-0x7604f8ce # 206.248.4.118
-0xffb38332 # 50.131.179.255
-0xa4c2efd5 # 213.239.194.164
-0xe9614018 # 24.64.97.233
-0xab49e557 # 87.229.73.171
-0x1648c052 # 82.192.72.22
-0x36024047 # 71.64.2.54
-0x0e8cffad # 173.255.140.14
-0x21918953 # 83.137.145.33
-0xb61f50ad # 173.80.31.182
-0x9b406b59 # 89.107.64.155
-0xaf282218 # 24.34.40.175
-0x7f1d164e # 78.22.29.127
-0x1f560da2 # 162.13.86.31
-0xe237be58 # 88.190.55.226
-0xbdeb1955 # 85.25.235.189
-0x6c0717d9 # 217.23.7.108
-0xdaf8ce62 # 98.206.248.218
-0x0f74246c # 108.36.116.15
-0xdee95243 # 67.82.233.222
-0xf23f1a56 # 86.26.63.242
-0x61bdf867 # 103.248.189.97
-0xd254c854 # 84.200.84.210
-0xc4422e4e # 78.46.66.196
-0xae0563c0 # 192.99.5.174
-0xbdb9a95f # 95.169.185.189
-0xa9eb32c6 # 198.50.235.169
-0xd9943950 # 80.57.148.217
-0x116add52 # 82.221.106.17
-0x73a54c90 # 144.76.165.115
-0xb36b525e # 94.82.107.179
-0xd734175e # 94.23.52.215
-0x333d7f76 # 118.127.61.51
-0x51431bc6 # 198.27.67.81
-0x084ae5cf # 207.229.74.8
-0xa60a236c # 108.35.10.166
-0x5c67692e # 46.105.103.92
-0x0177cf45 # 69.207.119.1
-0xa6683ac6 # 198.58.104.166
-0x7ff4ea47 # 71.234.244.127
-0x2192fab2 # 178.250.146.33
-0xa03a0f46 # 70.15.58.160
-0xfe3e39ae # 174.57.62.254
-0x2cce5fc1 # 193.95.206.44
-0xc8a6c148 # 72.193.166.200
-0x96fb7e4c # 76.126.251.150
-0x0a66c752 # 82.199.102.10
-0x6b4d2705 # 5.39.77.107
-0xeba0c118 # 24.193.160.235
-0x3ba0795b # 91.121.160.59
-0x1dccd23e # 62.210.204.29
-0x6912f3a2 # 162.243.18.105
-0x22f23c41 # 65.60.242.34
-0x65646b4a # 74.107.100.101
-0x8b9f8705 # 5.135.159.139
-0xeb9b9a95 # 149.154.155.235
-0x79fe6b4e # 78.107.254.121
-0x0536f447 # 71.244.54.5
-0x23224d61 # 97.77.34.35
-0x5d952ec6 # 198.46.149.93
-0x0cb4f736 # 54.247.180.12
-0xdc14be6d # 109.190.20.220
-0xb24609b0 # 176.9.70.178
-0xd3f79b62 # 98.155.247.211
-0x6518c836 # 54.200.24.101
-0x83a3cf42 # 66.207.163.131
-0x9b641fb0 # 176.31.100.155
-0x17fef1c0 # 192.241.254.23
-0xd508cc82 # 130.204.8.213
-0x91a4369b # 155.54.164.145
-0x39cb4a4c # 76.74.203.57
-0xbbc9536c # 108.83.201.187
-0xaf64c44a # 74.196.100.175
-0x605eca50 # 80.202.94.96
-0x0c6a6805 # 5.104.106.12
-0xd07e9d4e # 78.157.126.208
-0x78e6d3a2 # 162.211.230.120
-0x1b31eb6d # 109.235.49.27
-0xaa01feb2 # 178.254.1.170
-0x4603c236 # 54.194.3.70
-0x1ecba3b6 # 182.163.203.30
-0x0effe336 # 54.227.255.14
-0xc3fdcb36 # 54.203.253.195
-0xc290036f # 111.3.144.194
-0x4464692e # 46.105.100.68
-0x1aca7589 # 137.117.202.26
-0x59a9e52e # 46.229.169.89
-0x19aa7489 # 137.116.170.25
-0x2622c85e # 94.200.34.38
-0xa598d318 # 24.211.152.165
-0x438ec345 # 69.195.142.67
-0xc79619b9 # 185.25.150.199
-0xaf570360 # 96.3.87.175
-0x5098e289 # 137.226.152.80
-0x36add862 # 98.216.173.54
-0x83c1a2b2 # 178.162.193.131
-0x969d0905 # 5.9.157.150
-0xcf3d156c # 108.21.61.207
-0x49c1a445 # 69.164.193.73
-0xbd0b7562 # 98.117.11.189
-0x8fff1955 # 85.25.255.143
-0x1e51fe53 # 83.254.81.30
-0x28d6efd5 # 213.239.214.40
-0x2837cc62 # 98.204.55.40
-0x02f42d42 # 66.45.244.2
-0x070e3fb2 # 178.63.14.7
-0xbcb18705 # 5.135.177.188
-0x14a4e15b # 91.225.164.20
-0x82096844 # 68.104.9.130
-0xcfcb1c2e # 46.28.203.207
-0x37e27fc7 # 199.127.226.55
-0x07923748 # 72.55.146.7
-0x0c14bc2e # 46.188.20.12
-0x26100905 # 5.9.16.38
-0xcb7cd93e # 62.217.124.203
-0x3bc0d2c0 # 192.210.192.59
-0x97131b4c # 76.27.19.151
-0x6f1e5c17 # 23.92.30.111
-0xa7939f43 # 67.159.147.167
-0xb7a0bf58 # 88.191.160.183
-0xafa83a47 # 71.58.168.175
-0xcbb83f32 # 50.63.184.203
-0x5f321cb0 # 176.28.50.95
-0x52d6c3c7 # 199.195.214.82
-0xdeac5bc7 # 199.91.172.222
-0x2cf310cc # 204.16.243.44
-0x108a2bc3 # 195.43.138.16
-0x726fa14f # 79.161.111.114
-0x85bad2cc # 204.210.186.133
-0x459e4c90 # 144.76.158.69
-0x1a08b8d8 # 216.184.8.26
-0xcd7048c6 # 198.72.112.205
-0x6d5b4c90 # 144.76.91.109
-0xa66cfe7b # 123.254.108.166
-0xad730905 # 5.9.115.173
-0xdaac5bc7 # 199.91.172.218
-0x8417fd9f # 159.253.23.132
-0x41377432 # 50.116.55.65
-0x1f138632 # 50.134.19.31
-0x295a12b2 # 178.18.90.41
-0x7ac031b2 # 178.49.192.122
-0x3a87d295 # 149.210.135.58
-0xe219bc2e # 46.188.25.226
-0xf485d295 # 149.210.133.244
-0x137b6405 # 5.100.123.19
-0xcfffd9ad # 173.217.255.207
-0xafe20844 # 68.8.226.175
-0x32679a5f # 95.154.103.50
-0xa431c644 # 68.198.49.164
-0x0e5fce8c # 140.206.95.14
-0x305ef853 # 83.248.94.48
-0xad26ca32 # 50.202.38.173
-0xd9d21a54 # 84.26.210.217
-0xddd0d736 # 54.215.208.221
-0xc24ec0c7 # 199.192.78.194
-0x4aadcd5b # 91.205.173.74
-0x49109852 # 82.152.16.73
-0x9d6b3ac6 # 198.58.107.157
-0xf0aa1e8b # 139.30.170.240
-0xf1bfa343 # 67.163.191.241
-0x8a30c0ad # 173.192.48.138
-0x260f93d4 # 212.147.15.38
-0x2339e760 # 96.231.57.35
-0x8869959f # 159.149.105.136
-0xc207216c # 108.33.7.194
-0x29453448 # 72.52.69.41
-0xb651ec36 # 54.236.81.182
-0x45496259 # 89.98.73.69
-0xa23d1bcc # 204.27.61.162
-0xb39bcf43 # 67.207.155.179
-0xa1d29432 # 50.148.210.161
-0x3507c658 # 88.198.7.53
-0x4a88dd62 # 98.221.136.74
-0x27aff363 # 99.243.175.39
-0x7498ea6d # 109.234.152.116
-0x4a6785d5 # 213.133.103.74
-0x5e6d47c2 # 194.71.109.94
-0x3baba542 # 66.165.171.59
-0x045a37ae # 174.55.90.4
-0xa24dc0c7 # 199.192.77.162
-0xe981ea4d # 77.234.129.233
-0xed6ce217 # 23.226.108.237
-0x857214c6 # 198.20.114.133
-0x6b6c0464 # 100.4.108.107
-0x5a4945b8 # 184.69.73.90
-0x12f24742 # 66.71.242.18
-0xf35f42ad # 173.66.95.243
-0xfd0f5a4e # 78.90.15.253
-0xfb081556 # 86.21.8.251
-0xb24b5861 # 97.88.75.178
-0x2e114146 # 70.65.17.46
-0xb7780905 # 5.9.120.183
-0x33bb0e48 # 72.14.187.51
-0x39e26556 # 86.101.226.57
-0xa794484d # 77.72.148.167
-0x4225424d # 77.66.37.66
-0x3003795b # 91.121.3.48
-0x31c8cf44 # 68.207.200.49
-0xd65bad59 # 89.173.91.214
-0x127bc648 # 72.198.123.18
-0xf2bc4d4c # 76.77.188.242
-0x0273dc50 # 80.220.115.2
-0x4572d736 # 54.215.114.69
-0x064bf653 # 83.246.75.6
-0xcdcd126c # 108.18.205.205
-0x608281ae # 174.129.130.96
-0x4d130087 # 135.0.19.77
-0x1016f725 # 37.247.22.16
-0xba185fc0 # 192.95.24.186
-0x16c1a84f # 79.168.193.22
-0xfb697252 # 82.114.105.251
-0xa2942360 # 96.35.148.162
-0x53083b6c # 108.59.8.83
-0x0583f1c0 # 192.241.131.5
-0x2d5a2441 # 65.36.90.45
-0xc172aa43 # 67.170.114.193
-0xcd11cf36 # 54.207.17.205
-0x7b14ed62 # 98.237.20.123
-0x5c94f1c0 # 192.241.148.92
-0x7c23132e # 46.19.35.124
-0x39965a6f # 111.90.150.57
-0x7890e24e # 78.226.144.120
-0xa38ec447 # 71.196.142.163
-0xc187f1c0 # 192.241.135.193
-0xef80b647 # 71.182.128.239
-0xf20a7432 # 50.116.10.242
-0x7ad1d8d2 # 210.216.209.122
-0x869e2ec6 # 198.46.158.134
-0xccdb5c5d # 93.92.219.204
-0x9d11f636 # 54.246.17.157
-0x2161bb25 # 37.187.97.33
-0x7599f889 # 137.248.153.117
-0x2265ecad # 173.236.101.34
-0x0f4f0e55 # 85.14.79.15
-0x7d25854a # 74.133.37.125
-0xf857e360 # 96.227.87.248
-0xf83f3d6c # 108.61.63.248
-0x9cc93bb8 # 184.59.201.156
-0x02716857 # 87.104.113.2
-0x5dd8a177 # 119.161.216.93
-0x8adc6cd4 # 212.108.220.138
-0xe5613d46 # 70.61.97.229
-0x6a734f50 # 80.79.115.106
-0x2a5c3bae # 174.59.92.42
-0x4a04c3d1 # 209.195.4.74
-0xe4613d46 # 70.61.97.228
-0x8426f4bc # 188.244.38.132
-0x3e1b5fc0 # 192.95.27.62
-0x0d5a3c18 # 24.60.90.13
-0xd0f6d154 # 84.209.246.208
-0x21c7ff5e # 94.255.199.33
-0xeb3f3d6c # 108.61.63.235
-0x9da5edc0 # 192.237.165.157
-0x5d753b81 # 129.59.117.93
-0x0d8d53d4 # 212.83.141.13
-0x2613f018 # 24.240.19.38
-0x4443698d # 141.105.67.68
-0x8ca1edcd # 205.237.161.140
-0x10ed3f4e # 78.63.237.16
-0x789b403a # 58.64.155.120
-0x7b984a4b # 75.74.152.123
-0x964ebc25 # 37.188.78.150
-0x7520ee60 # 96.238.32.117
-0x4f4828bc # 188.40.72.79
-0x115c407d # 125.64.92.17
-0x32dd0667 # 103.6.221.50
-0xa741715e # 94.113.65.167
-0x1d3f3532 # 50.53.63.29
-0x817d1f56 # 86.31.125.129
-0x2f99a552 # 82.165.153.47
-0x6b2a5956 # 86.89.42.107
-0x8d4f4f05 # 5.79.79.141
-0xd23c1e17 # 23.30.60.210
-0x98993748 # 72.55.153.152
-0x2c92e536 # 54.229.146.44
-0x237ebdc3 # 195.189.126.35
-0xa762fb43 # 67.251.98.167
-0x32016b71 # 113.107.1.50
-0xd0e7cf79 # 121.207.231.208
-0x7d35bdd5 # 213.189.53.125
-0x53dac3d2 # 210.195.218.83
-0x31016b71 # 113.107.1.49
-0x7fb8f8ce # 206.248.184.127
-0x9a38c232 # 50.194.56.154
-0xefaa42ad # 173.66.170.239
-0x876b823d # 61.130.107.135
-0x18175347 # 71.83.23.24
-0xdb46597d # 125.89.70.219
-0xd2c168da # 218.104.193.210
-0xcd6fe9dc # 220.233.111.205
-0x45272e4e # 78.46.39.69
-0x8d4bca5b # 91.202.75.141
-0xa4043d47 # 71.61.4.164
-0xaab7aa47 # 71.170.183.170
-0x202881ae # 174.129.40.32
-0xa4aef160 # 96.241.174.164
-0xecd7e6bc # 188.230.215.236
-0x391359ad # 173.89.19.57
-0xd8cc9318 # 24.147.204.216
-0xbbeee52e # 46.229.238.187
-0x077067b0 # 176.103.112.7
-0xebd39d62 # 98.157.211.235
-0x0cedc547 # 71.197.237.12
-0x23d3e15e # 94.225.211.35
-0xa5a81318 # 24.19.168.165
-0x179a32c6 # 198.50.154.23
-0xe4d3483d # 61.72.211.228
-0x03680905 # 5.9.104.3
-0xe8018abc # 188.138.1.232
-0xdde9ef5b # 91.239.233.221
-0x438b8705 # 5.135.139.67
-0xb48224a0 # 160.36.130.180
-0xcbd69218 # 24.146.214.203
-0x9075795b # 91.121.117.144
-0xc6411c3e # 62.28.65.198
-0x03833f5c # 92.63.131.3
-0xf33f8b5e # 94.139.63.243
-0x495e464b # 75.70.94.73
-0x83c8e65b # 91.230.200.131
-0xac09cd25 # 37.205.9.172
-0xdaabc547 # 71.197.171.218
-0x7665a553 # 83.165.101.118
-0xc5263718 # 24.55.38.197
-0x2fd0c5cd # 205.197.208.47
-0x22224d61 # 97.77.34.34
-0x3e954048 # 72.64.149.62
-0xfaa37557 # 87.117.163.250
-0x36dbc658 # 88.198.219.54
-0xa81453d0 # 208.83.20.168
-0x5a941f5d # 93.31.148.90
-0xa598ea60 # 96.234.152.165
-0x65384ac6 # 198.74.56.101
-0x10aaa545 # 69.165.170.16
-0xaaab795b # 91.121.171.170
-0xdda7024c # 76.2.167.221
-0x0966f4c6 # 198.244.102.9
-0x68571c08 # 8.28.87.104
-0x8b40ee59 # 89.238.64.139
-0x33ac096c # 108.9.172.51
-0x844b4c4b # 75.76.75.132
-0xd392254d # 77.37.146.211
-0xba4d5a46 # 70.90.77.186
-0x63029653 # 83.150.2.99
-0xf655f636 # 54.246.85.246
-0xbe4c4bb1 # 177.75.76.190
-0x45dad036 # 54.208.218.69
-0x204bc052 # 82.192.75.32
-0x06c3a2b2 # 178.162.195.6
-0xf31fba6a # 106.186.31.243
-0xb21f09b0 # 176.9.31.178
-0x540d0751 # 81.7.13.84
-0xc7b46a57 # 87.106.180.199
-0x6a11795b # 91.121.17.106
-0x3d514045 # 69.64.81.61
-0x0318aa6d # 109.170.24.3
-0x30306ec3 # 195.110.48.48
-0x5c077432 # 50.116.7.92
-0x259ae46d # 109.228.154.37
-0x82bbd35f # 95.211.187.130
-0xae4222c0 # 192.34.66.174
-0x254415d4 # 212.21.68.37
-0xbd5f574b # 75.87.95.189
-0xd8fd175e # 94.23.253.216
-0x0a3f38c3 # 195.56.63.10
-0x2dce6bb8 # 184.107.206.45
-0xc201d058 # 88.208.1.194
-0x17fca5bc # 188.165.252.23
-0xe8453cca # 202.60.69.232
-0xd361f636 # 54.246.97.211
-0xa0d9edc0 # 192.237.217.160
-0x2f232e4e # 78.46.35.47
-0x134e116c # 108.17.78.19
-0x61ddc058 # 88.192.221.97
-0x05ba7283 # 131.114.186.5
-0xe1f7ed5b # 91.237.247.225
-0x040ec452 # 82.196.14.4
-0x4b672e4e # 78.46.103.75
-0xe4efa36d # 109.163.239.228
-0x47dca52e # 46.165.220.71
-0xe9332e4e # 78.46.51.233
-0xa3acb992 # 146.185.172.163
-0x24714c90 # 144.76.113.36
-0xa8cc8632 # 50.134.204.168
-0x26b1ce6d # 109.206.177.38
-0x264e53d4 # 212.83.78.38
-0xd3d2718c # 140.113.210.211
-0x225534ad # 173.52.85.34
-0xe289f3a2 # 162.243.137.226
-0x87341717 # 23.23.52.135
-0x9255ad4f # 79.173.85.146
-0x184bbb25 # 37.187.75.24
-0x885c7abc # 188.122.92.136
-0x3a6e9ac6 # 198.154.110.58
-0x1924185e # 94.24.36.25
-0xb73d4c90 # 144.76.61.183
-0x946d807a # 122.128.109.148
-0xa0d78e3f # 63.142.215.160
-0x5a16bb25 # 37.187.22.90
-0xcb09795b # 91.121.9.203
-0x8d0de657 # 87.230.13.141
-0x630b8b25 # 37.139.11.99
-0xe572c6cf # 207.198.114.229
-0x2b3f1118 # 24.17.63.43
-0x4242a91f # 31.169.66.66
-0x32990905 # 5.9.153.50
-0x058b0905 # 5.9.139.5
-0xe266fc60 # 96.252.102.226
-0xbe66c5b0 # 176.197.102.190
-0xcc98e46d # 109.228.152.204
-0x698c943e # 62.148.140.105
-0x44bd0cc3 # 195.12.189.68
-0x865c7abc # 188.122.92.134
-0x771764d3 # 211.100.23.119
-0x4675d655 # 85.214.117.70
-0x354e4826 # 38.72.78.53
-0xb67ac152 # 82.193.122.182
-0xaeccf285 # 133.242.204.174
-0xea625b4e # 78.91.98.234
-0xbcd6031f # 31.3.214.188
-0x5e81eb18 # 24.235.129.94
-0x74b347ce # 206.71.179.116
-0x3ca56ac1 # 193.106.165.60
-0x54ee4546 # 70.69.238.84
-0x38a8175e # 94.23.168.56
-0xa3c21155 # 85.17.194.163
-0x2f01576d # 109.87.1.47
-0x5d7ade50 # 80.222.122.93
-0xa003ae48 # 72.174.3.160
-0x2bc1d31f # 31.211.193.43
-0x13f5094c # 76.9.245.19
-0x7ab32648 # 72.38.179.122
-0x542e9fd5 # 213.159.46.84
-0x53136bc1 # 193.107.19.83
-0x7fdf51c0 # 192.81.223.127
-0x802197b2 # 178.151.33.128
-0xa2d2cc5b # 91.204.210.162
-0x6b5f4bc0 # 192.75.95.107
+# IPv4 nodes (generated using contrib/seeds/makeseeds.py)
+1.33.197.110
+1.34.180.245
+1.202.128.218
+2.35.195.25
+5.100.123.19
+5.175.145.169
+5.199.133.193
+5.199.151.10
+5.228.1.230
+14.200.200.145
+18.228.0.188
+18.228.0.200
+23.30.243.153
+23.88.232.49
+23.99.105.9
+23.226.137.208
+23.227.177.161
+23.227.191.50
+23.229.45.32
+23.236.144.69
+23.253.148.113
+23.253.241.22
+23.255.227.231
+24.20.205.222
+24.23.120.252
+24.94.98.96
+24.98.95.201
+24.111.90.55
+24.119.119.105
+24.138.25.149
+31.3.214.45
+31.186.87.46
+31.186.101.98
+31.186.250.186
+31.204.153.107
+37.44.16.231
+37.44.44.11
+37.120.168.204
+37.143.86.26
+37.187.75.24
+37.188.68.169
+37.192.95.150
+37.201.246.116
+37.205.10.140
+46.10.210.17
+46.19.138.154
+46.28.204.123
+46.28.205.67
+46.38.235.229
+46.163.76.230
+46.166.162.91
+46.173.190.50
+46.227.66.132
+46.229.238.187
+46.236.116.209
+47.55.14.65
+50.7.252.229
+50.46.159.91
+50.78.49.181
+50.78.231.57
+50.79.153.65
+50.116.34.44
+50.126.86.253
+50.142.41.23
+50.199.113.193
+50.200.78.107
+50.206.138.177
+50.252.52.49
+54.165.25.75
+54.169.107.40
+54.179.190.56
+54.187.82.121
+54.246.85.246
+58.74.7.205
+58.96.183.121
+61.62.58.38
+61.63.91.72
+61.63.91.112
+61.72.211.228
+62.43.40.154
+62.43.130.178
+62.80.185.213
+62.109.49.26
+62.173.139.58
+62.181.238.186
+62.210.114.127
+63.141.228.138
+63.153.213.78
+63.223.84.145
+63.251.88.112
+64.31.110.50
+64.34.121.45
+64.114.6.42
+64.140.125.98
+64.156.193.100
+65.30.47.116
+65.35.132.177
+65.96.193.165
+65.111.189.26
+66.68.10.30
+66.114.33.250
+66.130.46.63
+66.175.215.135
+66.190.253.165
+66.194.38.254
+66.244.98.111
+67.162.238.30
+67.169.255.17
+67.183.173.25
+67.219.233.140
+67.227.240.115
+67.247.222.71
+68.43.114.66
+68.52.33.36
+68.198.245.241
+69.12.226.165
+69.13.198.188
+69.15.179.62
+69.39.239.47
+69.47.45.87
+69.62.217.206
+69.64.42.31
+69.64.81.61
+69.67.219.200
+69.90.132.157
+69.94.30.177
+69.136.175.241
+70.61.97.228
+70.123.118.132
+71.59.152.182
+71.198.248.151
+71.200.242.89
+71.225.179.157
+72.14.187.51
+72.38.34.180
+72.52.72.187
+72.91.144.182
+72.167.49.217
+72.201.243.55
+72.223.60.249
+72.228.153.102
+73.26.101.228
+73.50.158.200
+73.181.204.170
+74.57.199.180
+74.63.222.226
+74.81.231.21
+74.193.126.82
+74.207.235.164
+75.83.197.114
+75.144.114.9
+76.112.5.247
+76.174.20.247
+77.37.240.142
+77.57.202.107
+77.172.123.53
+77.221.91.253
+77.235.48.48
+77.245.78.2
+78.8.58.249
+78.27.191.182
+78.129.236.141
+78.131.88.47
+78.157.205.6
+79.132.230.144
+79.143.188.155
+79.160.221.140
+79.161.111.114
+80.100.189.3
+80.147.140.121
+80.203.75.133
+80.220.99.227
+80.222.20.169
+80.241.1.7
+81.23.191.243
+81.38.11.202
+81.80.9.71
+81.110.213.165
+81.133.155.237
+81.171.34.37
+81.181.155.180
+82.39.156.137
+82.73.161.95
+82.130.45.40
+82.165.153.47
+82.168.128.133
+82.179.225.118
+82.194.245.158
+82.199.102.10
+82.211.30.243
+82.217.133.145
+82.221.128.35
+82.221.131.177
+82.233.225.205
+83.0.249.146
+83.89.31.249
+83.128.29.231
+83.128.253.142
+83.143.130.56
+83.150.2.99
+83.150.9.196
+83.161.64.45
+83.212.103.212
+83.212.111.114
+83.246.75.8
+83.254.81.31
+83.254.150.54
+84.2.34.104
+84.15.61.60
+84.17.25.135
+84.42.144.19
+84.212.210.135
+84.215.165.231
+84.238.140.176
+84.240.31.184
+85.25.214.137
+85.139.163.132
+85.199.4.228
+85.214.61.209
+85.214.108.77
+86.123.16.17
+87.48.42.199
+87.104.168.104
+87.229.73.171
+87.236.196.77
+88.97.56.98
+88.134.178.89
+88.150.233.19
+88.168.133.3
+88.208.18.246
+88.208.33.202
+89.18.28.21
+89.85.220.84
+89.163.227.28
+89.184.83.60
+89.231.96.83
+89.236.49.117
+91.90.66.209
+91.106.194.97
+91.134.75.115
+91.152.193.36
+91.152.219.35
+91.197.10.234
+91.209.77.101
+91.210.106.147
+91.214.200.205
+91.223.115.38
+91.234.48.232
+91.250.86.18
+92.27.7.209
+92.255.207.73
+93.74.163.234
+93.84.114.106
+93.152.166.29
+93.171.216.221
+93.185.177.71
+94.19.12.244
+94.42.115.50
+94.79.177.206
+94.136.147.119
+94.143.245.5
+94.188.50.39
+94.190.227.112
+94.198.135.29
+94.226.107.86
+94.242.219.90
+94.242.229.168
+94.244.160.84
+95.31.10.209
+95.85.25.41
+95.105.161.136
+95.154.165.45
+95.154.200.216
+95.167.109.125
+95.211.125.231
+95.211.216.235
+96.33.25.17
+96.43.130.178
+97.118.8.236
+98.102.6.125
+98.202.20.45
+98.217.125.225
+98.234.210.111
+98.237.20.123
+98.255.144.176
+99.113.64.43
+99.229.22.8
+103.1.212.19
+103.30.42.189
+103.224.165.48
+103.243.94.140
+104.131.107.107
+104.131.116.184
+104.143.0.156
+104.219.184.9
+106.185.38.174
+107.6.4.145
+107.150.8.27
+107.150.33.20
+107.170.228.129
+107.170.240.173
+108.51.20.86
+108.61.149.222
+108.61.151.172
+108.161.129.247
+108.170.140.21
+109.60.211.216
+109.73.42.36
+109.73.172.138
+109.163.235.239
+109.190.196.220
+109.201.135.216
+109.228.152.2
+109.228.154.81
+109.230.220.125
+109.234.156.218
+109.235.49.27
+109.235.69.84
+112.124.71.0
+113.146.68.251
+115.29.17.82
+115.70.176.17
+117.41.162.184
+118.27.8.170
+119.230.7.211
+119.246.71.52
+121.172.8.100
+122.128.109.148
+123.231.224.63
+128.175.195.31
+128.199.164.96
+128.199.254.244
+129.97.69.76
+129.123.7.7
+129.123.7.39
+129.186.17.17
+131.247.169.190
+133.242.209.63
+134.102.94.38
+134.119.17.145
+137.116.160.176
+137.226.34.42
+138.210.217.170
+141.255.166.194
+143.215.129.126
+144.76.244.19
+146.148.52.162
+146.148.80.57
+146.185.19.30
+146.185.142.86
+146.185.253.51
+148.251.6.214
+149.154.155.235
+149.210.133.244
+151.224.248.252
+153.121.75.229
+153.127.251.67
+154.20.2.139
+157.13.61.5
+158.58.173.48
+159.253.23.132
+162.209.110.218
+162.213.254.205
+162.239.254.100
+162.242.150.39
+162.243.81.138
+162.243.235.56
+162.244.79.16
+162.245.217.119
+162.248.102.117
+162.251.108.53
+162.254.149.139
+162.255.116.78
+166.70.94.106
+167.88.45.124
+167.88.120.210
+173.26.49.43
+173.30.14.6
+173.80.114.197
+173.167.214.243
+173.208.219.108
+173.220.67.156
+173.236.101.34
+173.246.107.34
+173.255.237.241
+174.2.213.209
+174.51.23.224
+174.51.123.159
+174.57.212.121
+174.109.33.28
+175.126.124.91
+175.126.124.92
+176.10.116.242
+176.36.35.126
+176.36.99.222
+176.124.110.47
+176.194.33.44
+176.223.201.198
+178.62.26.83
+178.62.36.48
+178.62.212.141
+178.62.254.59
+178.78.250.3
+178.155.86.226
+178.175.134.35
+178.248.111.4
+178.254.1.170
+178.254.34.161
+179.43.114.14
+182.213.208.28
+184.68.2.46
+184.72.238.42
+184.94.226.34
+184.94.227.58
+184.107.139.58
+184.107.206.45
+185.10.48.117
+185.21.216.156
+185.38.47.224
+185.45.192.129
+185.53.129.230
+185.53.131.114
+185.55.53.61
+185.55.53.63
+185.61.119.2
+185.61.148.203
+186.2.167.23
+188.92.75.178
+188.122.92.134
+188.138.9.208
+188.165.209.148
+188.226.206.239
+190.10.8.124
+190.10.10.147
+192.0.130.142
+192.3.89.159
+192.73.234.138
+192.75.95.107
+192.95.100.102
+192.155.84.181
+192.169.233.206
+192.198.93.86
+192.227.135.216
+193.0.109.3
+193.77.50.208
+193.109.68.62
+193.150.121.37
+193.224.69.98
+194.79.8.37
+194.141.86.10
+195.12.180.94
+195.56.63.10
+195.116.93.93
+195.154.174.226
+195.159.111.98
+195.169.138.2
+195.189.126.35
+195.197.175.190
+197.242.93.82
+198.11.214.147
+198.49.41.21
+199.33.124.186
+199.204.186.146
+199.233.238.115
+199.241.189.66
+202.60.68.242
+202.60.69.232
+203.183.151.39
+203.219.14.204
+204.44.123.109
+204.44.123.162
+204.45.120.178
+206.190.134.44
+206.248.184.127
+207.244.73.8
+208.66.30.27
+209.81.9.223
+209.105.243.229
+209.126.70.159
+209.140.30.169
+209.165.128.235
+209.190.2.242
+210.66.254.236
+210.73.27.33
+211.72.66.229
+212.25.37.124
+212.71.235.114
+212.71.252.109
+212.114.48.31
+212.174.151.118
+213.66.205.194
+213.129.248.139
+213.136.87.34
+213.165.82.133
+213.167.17.6
+213.179.158.253
+213.189.53.125
+213.222.208.93
+216.49.158.161
+216.55.143.154
+216.131.91.100
+216.245.206.181
+216.250.138.230
+217.11.225.189
+217.23.6.133
+217.75.88.178
+217.172.143.140
+217.195.169.209
+217.196.248.106
+219.138.161.162
+222.167.248.90
+223.18.254.55
# Onion nodes
bitcoinostk4e4re.onion:8333
diff --git a/src/Makefile.am b/src/Makefile.am
index d6ac6e1277..009c3c5196 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -37,7 +37,7 @@ $(LIBSECP256K1): $(wildcard secp256k1/src/*) $(wildcard secp256k1/include/*)
# Make is not made aware of per-object dependencies to avoid limiting building parallelization
# But to build the less dependent modules first, we manually select their order here:
-noinst_LIBRARIES = \
+EXTRA_LIBRARIES = \
crypto/libbitcoin_crypto.a \
libbitcoin_util.a \
libbitcoin_common.a \
@@ -46,7 +46,7 @@ noinst_LIBRARIES = \
libbitcoin_cli.a
if ENABLE_WALLET
BITCOIN_INCLUDES += $(BDB_CPPFLAGS)
-noinst_LIBRARIES += libbitcoin_wallet.a
+EXTRA_LIBRARIES += libbitcoin_wallet.a
endif
if BUILD_BITCOIN_LIBS
@@ -74,11 +74,12 @@ BITCOIN_CORE_H = \
alert.h \
allocators.h \
amount.h \
+ arith_uint256.h \
base58.h \
bloom.h \
chain.h \
- chainparams.h \
chainparamsbase.h \
+ chainparams.h \
chainparamsseeds.h \
checkpoints.h \
checkqueue.h \
@@ -87,8 +88,6 @@ BITCOIN_CORE_H = \
coins.h \
compat.h \
compressor.h \
- primitives/block.h \
- primitives/transaction.h \
core_io.h \
crypter.h \
db.h \
@@ -108,6 +107,8 @@ BITCOIN_CORE_H = \
net.h \
noui.h \
pow.h \
+ primitives/block.h \
+ primitives/transaction.h \
protocol.h \
pubkey.h \
random.h \
@@ -115,11 +116,11 @@ BITCOIN_CORE_H = \
rpcprotocol.h \
rpcserver.h \
script/interpreter.h \
+ script/script_error.h \
script/script.h \
script/sigcache.h \
script/sign.h \
script/standard.h \
- script/script_error.h \
serialize.h \
streams.h \
sync.h \
@@ -132,13 +133,13 @@ BITCOIN_CORE_H = \
uint256.h \
undo.h \
util.h \
- utilstrencodings.h \
utilmoneystr.h \
+ utilstrencodings.h \
utiltime.h \
version.h \
+ walletdb.h \
wallet.h \
wallet_ismine.h \
- walletdb.h \
compat/sanity.h
JSON_H = \
@@ -208,14 +209,12 @@ crypto_libbitcoin_crypto_a_SOURCES = \
crypto/sha256.cpp \
crypto/sha512.cpp \
crypto/hmac_sha256.cpp \
- crypto/rfc6979_hmac_sha256.cpp \
crypto/hmac_sha512.cpp \
crypto/ripemd160.cpp \
crypto/common.h \
crypto/sha256.h \
crypto/sha512.h \
crypto/hmac_sha256.h \
- crypto/rfc6979_hmac_sha256.h \
crypto/hmac_sha512.h \
crypto/sha1.h \
crypto/ripemd160.h
@@ -232,6 +231,7 @@ univalue_libbitcoin_univalue_a_SOURCES = \
libbitcoin_common_a_CPPFLAGS = $(BITCOIN_INCLUDES)
libbitcoin_common_a_SOURCES = \
allocators.cpp \
+ arith_uint256.cpp \
amount.cpp \
base58.cpp \
chainparams.cpp \
@@ -261,18 +261,18 @@ libbitcoin_common_a_SOURCES = \
# backward-compatibility objects and their sanity checks are linked.
libbitcoin_util_a_CPPFLAGS = $(BITCOIN_INCLUDES)
libbitcoin_util_a_SOURCES = \
- compat/strnlen.cpp \
- compat/glibc_sanity.cpp \
- compat/glibcxx_sanity.cpp \
chainparamsbase.cpp \
clientversion.cpp \
+ compat/glibc_sanity.cpp \
+ compat/glibcxx_sanity.cpp \
+ compat/strnlen.cpp \
random.cpp \
rpcprotocol.cpp \
sync.cpp \
uint256.cpp \
util.cpp \
- utilstrencodings.cpp \
utilmoneystr.cpp \
+ utilstrencodings.cpp \
utiltime.cpp \
$(BITCOIN_CORE_H)
@@ -291,6 +291,14 @@ nodist_libbitcoin_util_a_SOURCES = $(srcdir)/obj/build.h
#
# bitcoind binary #
+bitcoind_SOURCES = bitcoind.cpp
+bitcoind_CPPFLAGS = $(BITCOIN_INCLUDES)
+bitcoind_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
+
+if TARGET_WINDOWS
+bitcoind_SOURCES += bitcoind-res.rc
+endif
+
bitcoind_LDADD = \
$(LIBBITCOIN_SERVER) \
$(LIBBITCOIN_COMMON) \
@@ -304,67 +312,59 @@ bitcoind_LDADD = \
if ENABLE_WALLET
bitcoind_LDADD += libbitcoin_wallet.a
endif
-bitcoind_SOURCES = bitcoind.cpp
+
+bitcoind_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS)
#
+# bitcoin-cli binary #
+bitcoin_cli_SOURCES = bitcoin-cli.cpp
+bitcoin_cli_CPPFLAGS = $(BITCOIN_INCLUDES)
+bitcoin_cli_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
+
if TARGET_WINDOWS
-bitcoind_SOURCES += bitcoind-res.rc
+bitcoin_cli_SOURCES += bitcoin-cli-res.rc
endif
-bitcoind_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS)
-bitcoind_CPPFLAGS = $(BITCOIN_INCLUDES)
-bitcoind_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
-
-# bitcoin-cli binary #
bitcoin_cli_LDADD = \
$(LIBBITCOIN_CLI) \
$(LIBBITCOIN_UTIL) \
- $(BOOST_LIBS) \
- $(SSL_LIBS) \
- $(CRYPTO_LIBS)
-
-bitcoin_cli_SOURCES = \
- bitcoin-cli.cpp
+ $(LIBSECP256K1)
-bitcoin_cli_CPPFLAGS = $(BITCOIN_INCLUDES)
+bitcoin_cli_LDADD += $(BOOST_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS)
#
# bitcoin-tx binary #
+bitcoin_tx_SOURCES = bitcoin-tx.cpp
+bitcoin_tx_CPPFLAGS = $(BITCOIN_INCLUDES)
+bitcoin_tx_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
+
bitcoin_tx_LDADD = \
$(LIBBITCOIN_UNIVALUE) \
$(LIBBITCOIN_COMMON) \
$(LIBBITCOIN_UTIL) \
$(LIBBITCOIN_CRYPTO) \
- $(LIBSECP256K1) \
- $(BOOST_LIBS) \
- $(CRYPTO_LIBS)
+ $(LIBSECP256K1)
-bitcoin_tx_SOURCES = bitcoin-tx.cpp
-bitcoin_tx_CPPFLAGS = $(BITCOIN_INCLUDES)
+bitcoin_tx_LDADD += $(BOOST_LIBS) $(CRYPTO_LIBS)
#
-bitcoin_tx_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
-
-if TARGET_WINDOWS
-bitcoin_cli_SOURCES += bitcoin-cli-res.rc
-endif
-bitcoin_cli_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
+# bitcoinconsensus library #
if BUILD_BITCOIN_LIBS
include_HEADERS = script/bitcoinconsensus.h
libbitcoinconsensus_la_SOURCES = \
- primitives/transaction.cpp \
crypto/hmac_sha512.cpp \
+ crypto/ripemd160.cpp \
crypto/sha1.cpp \
crypto/sha256.cpp \
crypto/sha512.cpp \
- crypto/ripemd160.cpp \
eccryptoverify.cpp \
ecwrapper.cpp \
hash.cpp \
+ primitives/transaction.cpp \
pubkey.cpp \
- script/script.cpp \
- script/interpreter.cpp \
script/bitcoinconsensus.cpp \
+ script/interpreter.cpp \
+ script/script.cpp \
uint256.cpp \
utilstrencodings.cpp
@@ -376,10 +376,12 @@ endif
libbitcoinconsensus_la_LDFLAGS = -no-undefined $(RELDFLAGS)
libbitcoinconsensus_la_LIBADD = $(CRYPTO_LIBS)
libbitcoinconsensus_la_CPPFLAGS = $(CRYPTO_CFLAGS) -I$(builddir)/obj -DBUILD_BITCOIN_INTERNAL
+
if USE_LIBSECP256K1
libbitcoinconsensus_la_LIBADD += secp256k1/libsecp256k1.la
endif
endif
+#
CLEANFILES = leveldb/libleveldb.a leveldb/libmemenv.a *.gcda *.gcno
diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include
index 8b782b2ad5..31fe3a9f69 100644
--- a/src/Makefile.qt.include
+++ b/src/Makefile.qt.include
@@ -1,5 +1,5 @@
bin_PROGRAMS += qt/bitcoin-qt
-noinst_LIBRARIES += qt/libbitcoinqt.a
+EXTRA_LIBRARIES += qt/libbitcoinqt.a
# bitcoin qt core #
QT_TS = \
@@ -256,9 +256,6 @@ RES_ICONS = \
qt/res/icons/tx_input.png \
qt/res/icons/tx_output.png \
qt/res/icons/tx_mined.png \
- qt/res/icons/unit_btc.png \
- qt/res/icons/unit_mbtc.png \
- qt/res/icons/unit_ubtc.png \
qt/res/icons/verify.png
BITCOIN_QT_CPP = \
@@ -281,8 +278,11 @@ BITCOIN_QT_CPP = \
qt/scicon.cpp \
qt/splashscreen.cpp \
qt/trafficgraphwidget.cpp \
- qt/utilitydialog.cpp \
- qt/winshutdownmonitor.cpp
+ qt/utilitydialog.cpp
+
+if TARGET_WINDOWS
+BITCOIN_QT_CPP += qt/winshutdownmonitor.cpp
+endif
if ENABLE_WALLET
BITCOIN_QT_CPP += \
@@ -314,8 +314,7 @@ BITCOIN_QT_CPP += \
qt/walletview.cpp
endif
-RES_IMAGES = \
- qt/res/images/about.png
+RES_IMAGES =
RES_MOVIES = $(wildcard qt/res/movies/spinner-*.png)
diff --git a/src/Makefile.test.include b/src/Makefile.test.include
index 9e9f478d8f..90494439fa 100644
--- a/src/Makefile.test.include
+++ b/src/Makefile.test.include
@@ -1,4 +1,4 @@
-TESTS += test/test_bitcoin test/bitcoin-util-test.py
+TESTS += test/test_bitcoin
bin_PROGRAMS += test/test_bitcoin
TEST_SRCDIR = test
TEST_BINARY=test/test_bitcoin$(EXEEXT)
@@ -14,13 +14,12 @@ EXTRA_DIST += \
test/data/tt-locktime317000-out.hex \
test/data/tx394b54bb.hex \
test/data/txcreate1.hex \
- test/data/txcreate2.hex
+ test/data/txcreate2.hex \
+ test/data/txcreatesign.hex
JSON_TEST_FILES = \
test/data/script_valid.json \
test/data/base58_keys_valid.json \
- test/data/sig_canonical.json \
- test/data/sig_noncanonical.json \
test/data/base58_encode_decode.json \
test/data/base58_keys_invalid.json \
test/data/script_invalid.json \
@@ -33,6 +32,7 @@ RAW_TEST_FILES = test/data/alertTests.raw
GENERATED_TEST_FILES = $(JSON_TEST_FILES:.json=.json.h) $(RAW_TEST_FILES:.raw=.raw.h)
BITCOIN_TESTS =\
+ test/arith_uint256_tests.cpp \
test/bignum.h \
test/alert_tests.cpp \
test/allocator_tests.cpp \
@@ -56,6 +56,7 @@ BITCOIN_TESTS =\
test/netbase_tests.cpp \
test/pmt_tests.cpp \
test/rpc_tests.cpp \
+ test/sanity_tests.cpp \
test/script_P2SH_tests.cpp \
test/script_tests.cpp \
test/scriptnum_tests.cpp \
@@ -105,6 +106,8 @@ bitcoin_test_clean : FORCE
rm -f $(CLEAN_BITCOIN_TEST) $(test_test_bitcoin_OBJECTS) $(TEST_BINARY)
check-local:
+ @echo "Running test/bitcoin-util-test.py..."
+ $(AM_V_at)srcdir=$(srcdir) PYTHONPATH=$(builddir)/test $(srcdir)/test/bitcoin-util-test.py
$(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C secp256k1 check
%.json.h: %.json
diff --git a/src/addrman.cpp b/src/addrman.cpp
index 1982db52ae..1e08ae772e 100644
--- a/src/addrman.cpp
+++ b/src/addrman.cpp
@@ -15,12 +15,12 @@ int CAddrInfo::GetTriedBucket(const std::vector<unsigned char>& nKey) const
CDataStream ss1(SER_GETHASH, 0);
std::vector<unsigned char> vchKey = GetKey();
ss1 << nKey << vchKey;
- uint64_t hash1 = Hash(ss1.begin(), ss1.end()).GetLow64();
+ uint64_t hash1 = Hash(ss1.begin(), ss1.end()).GetCheapHash();
CDataStream ss2(SER_GETHASH, 0);
std::vector<unsigned char> vchGroupKey = GetGroup();
ss2 << nKey << vchGroupKey << (hash1 % ADDRMAN_TRIED_BUCKETS_PER_GROUP);
- uint64_t hash2 = Hash(ss2.begin(), ss2.end()).GetLow64();
+ uint64_t hash2 = Hash(ss2.begin(), ss2.end()).GetCheapHash();
return hash2 % ADDRMAN_TRIED_BUCKET_COUNT;
}
@@ -30,11 +30,11 @@ int CAddrInfo::GetNewBucket(const std::vector<unsigned char>& nKey, const CNetAd
std::vector<unsigned char> vchGroupKey = GetGroup();
std::vector<unsigned char> vchSourceGroupKey = src.GetGroup();
ss1 << nKey << vchGroupKey << vchSourceGroupKey;
- uint64_t hash1 = Hash(ss1.begin(), ss1.end()).GetLow64();
+ uint64_t hash1 = Hash(ss1.begin(), ss1.end()).GetCheapHash();
CDataStream ss2(SER_GETHASH, 0);
ss2 << nKey << vchSourceGroupKey << (hash1 % ADDRMAN_NEW_BUCKETS_PER_SOURCE_GROUP);
- uint64_t hash2 = Hash(ss2.begin(), ss2.end()).GetLow64();
+ uint64_t hash2 = Hash(ss2.begin(), ss2.end()).GetCheapHash();
return hash2 % ADDRMAN_NEW_BUCKET_COUNT;
}
diff --git a/src/alert.cpp b/src/alert.cpp
index 370d0cecc6..323939913b 100644
--- a/src/alert.cpp
+++ b/src/alert.cpp
@@ -149,7 +149,7 @@ bool CAlert::CheckSignature() const
{
CPubKey key(Params().AlertKey());
if (!key.Verify(Hash(vchMsg.begin(), vchMsg.end()), vchSig))
- return error("CAlert::CheckSignature() : verify signature failed");
+ return error("CAlert::CheckSignature(): verify signature failed");
// Now unserialize the data
CDataStream sMsg(vchMsg, SER_NETWORK, PROTOCOL_VERSION);
diff --git a/src/arith_uint256.cpp b/src/arith_uint256.cpp
new file mode 100644
index 0000000000..1243823da5
--- /dev/null
+++ b/src/arith_uint256.cpp
@@ -0,0 +1,259 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "arith_uint256.h"
+
+#include "uint256.h"
+#include "utilstrencodings.h"
+
+#include <stdio.h>
+#include <string.h>
+
+template <unsigned int BITS>
+base_uint<BITS>::base_uint(const std::string& str)
+{
+ SetHex(str);
+}
+
+template <unsigned int BITS>
+base_uint<BITS>& base_uint<BITS>::operator<<=(unsigned int shift)
+{
+ base_uint<BITS> a(*this);
+ for (int i = 0; i < WIDTH; i++)
+ pn[i] = 0;
+ int k = shift / 32;
+ shift = shift % 32;
+ for (int i = 0; i < WIDTH; i++) {
+ if (i + k + 1 < WIDTH && shift != 0)
+ pn[i + k + 1] |= (a.pn[i] >> (32 - shift));
+ if (i + k < WIDTH)
+ pn[i + k] |= (a.pn[i] << shift);
+ }
+ return *this;
+}
+
+template <unsigned int BITS>
+base_uint<BITS>& base_uint<BITS>::operator>>=(unsigned int shift)
+{
+ base_uint<BITS> a(*this);
+ for (int i = 0; i < WIDTH; i++)
+ pn[i] = 0;
+ int k = shift / 32;
+ shift = shift % 32;
+ for (int i = 0; i < WIDTH; i++) {
+ if (i - k - 1 >= 0 && shift != 0)
+ pn[i - k - 1] |= (a.pn[i] << (32 - shift));
+ if (i - k >= 0)
+ pn[i - k] |= (a.pn[i] >> shift);
+ }
+ return *this;
+}
+
+template <unsigned int BITS>
+base_uint<BITS>& base_uint<BITS>::operator*=(uint32_t b32)
+{
+ uint64_t carry = 0;
+ for (int i = 0; i < WIDTH; i++) {
+ uint64_t n = carry + (uint64_t)b32 * pn[i];
+ pn[i] = n & 0xffffffff;
+ carry = n >> 32;
+ }
+ return *this;
+}
+
+template <unsigned int BITS>
+base_uint<BITS>& base_uint<BITS>::operator*=(const base_uint& b)
+{
+ base_uint<BITS> a = *this;
+ *this = 0;
+ for (int j = 0; j < WIDTH; j++) {
+ uint64_t carry = 0;
+ for (int i = 0; i + j < WIDTH; i++) {
+ uint64_t n = carry + pn[i + j] + (uint64_t)a.pn[j] * b.pn[i];
+ pn[i + j] = n & 0xffffffff;
+ carry = n >> 32;
+ }
+ }
+ return *this;
+}
+
+template <unsigned int BITS>
+base_uint<BITS>& base_uint<BITS>::operator/=(const base_uint& b)
+{
+ base_uint<BITS> div = b; // make a copy, so we can shift.
+ base_uint<BITS> num = *this; // make a copy, so we can subtract.
+ *this = 0; // the quotient.
+ int num_bits = num.bits();
+ int div_bits = div.bits();
+ if (div_bits == 0)
+ throw uint_error("Division by zero");
+ if (div_bits > num_bits) // the result is certainly 0.
+ return *this;
+ int shift = num_bits - div_bits;
+ div <<= shift; // shift so that div and num align.
+ while (shift >= 0) {
+ if (num >= div) {
+ num -= div;
+ pn[shift / 32] |= (1 << (shift & 31)); // set a bit of the result.
+ }
+ div >>= 1; // shift back.
+ shift--;
+ }
+ // num now contains the remainder of the division.
+ return *this;
+}
+
+template <unsigned int BITS>
+int base_uint<BITS>::CompareTo(const base_uint<BITS>& b) const
+{
+ for (int i = WIDTH - 1; i >= 0; i--) {
+ if (pn[i] < b.pn[i])
+ return -1;
+ if (pn[i] > b.pn[i])
+ return 1;
+ }
+ return 0;
+}
+
+template <unsigned int BITS>
+bool base_uint<BITS>::EqualTo(uint64_t b) const
+{
+ for (int i = WIDTH - 1; i >= 2; i--) {
+ if (pn[i])
+ return false;
+ }
+ if (pn[1] != (b >> 32))
+ return false;
+ if (pn[0] != (b & 0xfffffffful))
+ return false;
+ return true;
+}
+
+template <unsigned int BITS>
+double base_uint<BITS>::getdouble() const
+{
+ double ret = 0.0;
+ double fact = 1.0;
+ for (int i = 0; i < WIDTH; i++) {
+ ret += fact * pn[i];
+ fact *= 4294967296.0;
+ }
+ return ret;
+}
+
+template <unsigned int BITS>
+std::string base_uint<BITS>::GetHex() const
+{
+ return ArithToUint256(*this).GetHex();
+}
+
+template <unsigned int BITS>
+void base_uint<BITS>::SetHex(const char* psz)
+{
+ *this = UintToArith256(uint256S(psz));
+}
+
+template <unsigned int BITS>
+void base_uint<BITS>::SetHex(const std::string& str)
+{
+ SetHex(str.c_str());
+}
+
+template <unsigned int BITS>
+std::string base_uint<BITS>::ToString() const
+{
+ return (GetHex());
+}
+
+template <unsigned int BITS>
+unsigned int base_uint<BITS>::bits() const
+{
+ for (int pos = WIDTH - 1; pos >= 0; pos--) {
+ if (pn[pos]) {
+ for (int bits = 31; bits > 0; bits--) {
+ if (pn[pos] & 1 << bits)
+ return 32 * pos + bits + 1;
+ }
+ return 32 * pos + 1;
+ }
+ }
+ return 0;
+}
+
+// Explicit instantiations for base_uint<256>
+template base_uint<256>::base_uint(const std::string&);
+template base_uint<256>& base_uint<256>::operator<<=(unsigned int);
+template base_uint<256>& base_uint<256>::operator>>=(unsigned int);
+template base_uint<256>& base_uint<256>::operator*=(uint32_t b32);
+template base_uint<256>& base_uint<256>::operator*=(const base_uint<256>& b);
+template base_uint<256>& base_uint<256>::operator/=(const base_uint<256>& b);
+template int base_uint<256>::CompareTo(const base_uint<256>&) const;
+template bool base_uint<256>::EqualTo(uint64_t) const;
+template double base_uint<256>::getdouble() const;
+template std::string base_uint<256>::GetHex() const;
+template std::string base_uint<256>::ToString() const;
+template void base_uint<256>::SetHex(const char*);
+template void base_uint<256>::SetHex(const std::string&);
+template unsigned int base_uint<256>::bits() const;
+
+// This implementation directly uses shifts instead of going
+// through an intermediate MPI representation.
+arith_uint256& arith_uint256::SetCompact(uint32_t nCompact, bool* pfNegative, bool* pfOverflow)
+{
+ int nSize = nCompact >> 24;
+ uint32_t nWord = nCompact & 0x007fffff;
+ if (nSize <= 3) {
+ nWord >>= 8 * (3 - nSize);
+ *this = nWord;
+ } else {
+ *this = nWord;
+ *this <<= 8 * (nSize - 3);
+ }
+ if (pfNegative)
+ *pfNegative = nWord != 0 && (nCompact & 0x00800000) != 0;
+ if (pfOverflow)
+ *pfOverflow = nWord != 0 && ((nSize > 34) ||
+ (nWord > 0xff && nSize > 33) ||
+ (nWord > 0xffff && nSize > 32));
+ return *this;
+}
+
+uint32_t arith_uint256::GetCompact(bool fNegative) const
+{
+ int nSize = (bits() + 7) / 8;
+ uint32_t nCompact = 0;
+ if (nSize <= 3) {
+ nCompact = GetLow64() << 8 * (3 - nSize);
+ } else {
+ arith_uint256 bn = *this >> 8 * (nSize - 3);
+ nCompact = bn.GetLow64();
+ }
+ // The 0x00800000 bit denotes the sign.
+ // Thus, if it is already set, divide the mantissa by 256 and increase the exponent.
+ if (nCompact & 0x00800000) {
+ nCompact >>= 8;
+ nSize++;
+ }
+ assert((nCompact & ~0x007fffff) == 0);
+ assert(nSize < 256);
+ nCompact |= nSize << 24;
+ nCompact |= (fNegative && (nCompact & 0x007fffff) ? 0x00800000 : 0);
+ return nCompact;
+}
+
+uint256 ArithToUint256(const arith_uint256 &a)
+{
+ uint256 b;
+ // TODO: needs bswap32 on big-endian
+ memcpy(b.begin(), a.pn, a.size());
+ return b;
+}
+arith_uint256 UintToArith256(const uint256 &a)
+{
+ arith_uint256 b;
+ // TODO: needs bswap32 on big-endian
+ memcpy(b.pn, a.begin(), a.size());
+ return b;
+}
diff --git a/src/arith_uint256.h b/src/arith_uint256.h
new file mode 100644
index 0000000000..b6ba3a1087
--- /dev/null
+++ b/src/arith_uint256.h
@@ -0,0 +1,290 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_ARITH_UINT256_H
+#define BITCOIN_ARITH_UINT256_H
+
+#include <assert.h>
+#include <cstring>
+#include <stdexcept>
+#include <stdint.h>
+#include <string>
+#include <vector>
+
+class uint256;
+
+class uint_error : public std::runtime_error {
+public:
+ explicit uint_error(const std::string& str) : std::runtime_error(str) {}
+};
+
+/** Template base class for unsigned big integers. */
+template<unsigned int BITS>
+class base_uint
+{
+protected:
+ enum { WIDTH=BITS/32 };
+ uint32_t pn[WIDTH];
+public:
+
+ base_uint()
+ {
+ for (int i = 0; i < WIDTH; i++)
+ pn[i] = 0;
+ }
+
+ base_uint(const base_uint& b)
+ {
+ for (int i = 0; i < WIDTH; i++)
+ pn[i] = b.pn[i];
+ }
+
+ base_uint& operator=(const base_uint& b)
+ {
+ for (int i = 0; i < WIDTH; i++)
+ pn[i] = b.pn[i];
+ return *this;
+ }
+
+ base_uint(uint64_t b)
+ {
+ pn[0] = (unsigned int)b;
+ pn[1] = (unsigned int)(b >> 32);
+ for (int i = 2; i < WIDTH; i++)
+ pn[i] = 0;
+ }
+
+ explicit base_uint(const std::string& str);
+
+ bool operator!() const
+ {
+ for (int i = 0; i < WIDTH; i++)
+ if (pn[i] != 0)
+ return false;
+ return true;
+ }
+
+ const base_uint operator~() const
+ {
+ base_uint ret;
+ for (int i = 0; i < WIDTH; i++)
+ ret.pn[i] = ~pn[i];
+ return ret;
+ }
+
+ const base_uint operator-() const
+ {
+ base_uint ret;
+ for (int i = 0; i < WIDTH; i++)
+ ret.pn[i] = ~pn[i];
+ ret++;
+ return ret;
+ }
+
+ double getdouble() const;
+
+ base_uint& operator=(uint64_t b)
+ {
+ pn[0] = (unsigned int)b;
+ pn[1] = (unsigned int)(b >> 32);
+ for (int i = 2; i < WIDTH; i++)
+ pn[i] = 0;
+ return *this;
+ }
+
+ base_uint& operator^=(const base_uint& b)
+ {
+ for (int i = 0; i < WIDTH; i++)
+ pn[i] ^= b.pn[i];
+ return *this;
+ }
+
+ base_uint& operator&=(const base_uint& b)
+ {
+ for (int i = 0; i < WIDTH; i++)
+ pn[i] &= b.pn[i];
+ return *this;
+ }
+
+ base_uint& operator|=(const base_uint& b)
+ {
+ for (int i = 0; i < WIDTH; i++)
+ pn[i] |= b.pn[i];
+ return *this;
+ }
+
+ base_uint& operator^=(uint64_t b)
+ {
+ pn[0] ^= (unsigned int)b;
+ pn[1] ^= (unsigned int)(b >> 32);
+ return *this;
+ }
+
+ base_uint& operator|=(uint64_t b)
+ {
+ pn[0] |= (unsigned int)b;
+ pn[1] |= (unsigned int)(b >> 32);
+ return *this;
+ }
+
+ base_uint& operator<<=(unsigned int shift);
+ base_uint& operator>>=(unsigned int shift);
+
+ base_uint& operator+=(const base_uint& b)
+ {
+ uint64_t carry = 0;
+ for (int i = 0; i < WIDTH; i++)
+ {
+ uint64_t n = carry + pn[i] + b.pn[i];
+ pn[i] = n & 0xffffffff;
+ carry = n >> 32;
+ }
+ return *this;
+ }
+
+ base_uint& operator-=(const base_uint& b)
+ {
+ *this += -b;
+ return *this;
+ }
+
+ base_uint& operator+=(uint64_t b64)
+ {
+ base_uint b;
+ b = b64;
+ *this += b;
+ return *this;
+ }
+
+ base_uint& operator-=(uint64_t b64)
+ {
+ base_uint b;
+ b = b64;
+ *this += -b;
+ return *this;
+ }
+
+ base_uint& operator*=(uint32_t b32);
+ base_uint& operator*=(const base_uint& b);
+ base_uint& operator/=(const base_uint& b);
+
+ base_uint& operator++()
+ {
+ // prefix operator
+ int i = 0;
+ while (++pn[i] == 0 && i < WIDTH-1)
+ i++;
+ return *this;
+ }
+
+ const base_uint operator++(int)
+ {
+ // postfix operator
+ const base_uint ret = *this;
+ ++(*this);
+ return ret;
+ }
+
+ base_uint& operator--()
+ {
+ // prefix operator
+ int i = 0;
+ while (--pn[i] == (uint32_t)-1 && i < WIDTH-1)
+ i++;
+ return *this;
+ }
+
+ const base_uint operator--(int)
+ {
+ // postfix operator
+ const base_uint ret = *this;
+ --(*this);
+ return ret;
+ }
+
+ int CompareTo(const base_uint& b) const;
+ bool EqualTo(uint64_t b) const;
+
+ friend inline const base_uint operator+(const base_uint& a, const base_uint& b) { return base_uint(a) += b; }
+ friend inline const base_uint operator-(const base_uint& a, const base_uint& b) { return base_uint(a) -= b; }
+ friend inline const base_uint operator*(const base_uint& a, const base_uint& b) { return base_uint(a) *= b; }
+ friend inline const base_uint operator/(const base_uint& a, const base_uint& b) { return base_uint(a) /= b; }
+ friend inline const base_uint operator|(const base_uint& a, const base_uint& b) { return base_uint(a) |= b; }
+ friend inline const base_uint operator&(const base_uint& a, const base_uint& b) { return base_uint(a) &= b; }
+ friend inline const base_uint operator^(const base_uint& a, const base_uint& b) { return base_uint(a) ^= b; }
+ friend inline const base_uint operator>>(const base_uint& a, int shift) { return base_uint(a) >>= shift; }
+ friend inline const base_uint operator<<(const base_uint& a, int shift) { return base_uint(a) <<= shift; }
+ friend inline const base_uint operator*(const base_uint& a, uint32_t b) { return base_uint(a) *= b; }
+ friend inline bool operator==(const base_uint& a, const base_uint& b) { return memcmp(a.pn, b.pn, sizeof(a.pn)) == 0; }
+ friend inline bool operator!=(const base_uint& a, const base_uint& b) { return memcmp(a.pn, b.pn, sizeof(a.pn)) != 0; }
+ friend inline bool operator>(const base_uint& a, const base_uint& b) { return a.CompareTo(b) > 0; }
+ friend inline bool operator<(const base_uint& a, const base_uint& b) { return a.CompareTo(b) < 0; }
+ friend inline bool operator>=(const base_uint& a, const base_uint& b) { return a.CompareTo(b) >= 0; }
+ friend inline bool operator<=(const base_uint& a, const base_uint& b) { return a.CompareTo(b) <= 0; }
+ friend inline bool operator==(const base_uint& a, uint64_t b) { return a.EqualTo(b); }
+ friend inline bool operator!=(const base_uint& a, uint64_t b) { return !a.EqualTo(b); }
+
+ std::string GetHex() const;
+ void SetHex(const char* psz);
+ void SetHex(const std::string& str);
+ std::string ToString() const;
+
+ unsigned int size() const
+ {
+ return sizeof(pn);
+ }
+
+ /**
+ * Returns the position of the highest bit set plus one, or zero if the
+ * value is zero.
+ */
+ unsigned int bits() const;
+
+ uint64_t GetLow64() const
+ {
+ assert(WIDTH >= 2);
+ return pn[0] | (uint64_t)pn[1] << 32;
+ }
+};
+
+/** 256-bit unsigned big integer. */
+class arith_uint256 : public base_uint<256> {
+public:
+ arith_uint256() {}
+ arith_uint256(const base_uint<256>& b) : base_uint<256>(b) {}
+ arith_uint256(uint64_t b) : base_uint<256>(b) {}
+ explicit arith_uint256(const std::string& str) : base_uint<256>(str) {}
+
+ /**
+ * The "compact" format is a representation of a whole
+ * number N using an unsigned 32bit number similar to a
+ * floating point format.
+ * The most significant 8 bits are the unsigned exponent of base 256.
+ * This exponent can be thought of as "number of bytes of N".
+ * The lower 23 bits are the mantissa.
+ * Bit number 24 (0x800000) represents the sign of N.
+ * N = (-1^sign) * mantissa * 256^(exponent-3)
+ *
+ * Satoshi's original implementation used BN_bn2mpi() and BN_mpi2bn().
+ * MPI uses the most significant bit of the first byte as sign.
+ * Thus 0x1234560000 is compact (0x05123456)
+ * and 0xc0de000000 is compact (0x0600c0de)
+ *
+ * Bitcoin only uses this "compact" format for encoding difficulty
+ * targets, which are unsigned 256bit quantities. Thus, all the
+ * complexities of the sign bit and using base 256 are probably an
+ * implementation accident.
+ */
+ arith_uint256& SetCompact(uint32_t nCompact, bool *pfNegative = NULL, bool *pfOverflow = NULL);
+ uint32_t GetCompact(bool fNegative = false) const;
+
+ friend uint256 ArithToUint256(const arith_uint256 &);
+ friend arith_uint256 UintToArith256(const uint256 &);
+};
+
+uint256 ArithToUint256(const arith_uint256 &);
+arith_uint256 UintToArith256(const uint256 &);
+
+#endif // BITCOIN_UINT256_H
diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp
index 668d492d6b..f273a15713 100644
--- a/src/bitcoin-cli.cpp
+++ b/src/bitcoin-cli.cpp
@@ -15,8 +15,6 @@
#define _(x) std::string(x) /* Keep the _() around in case gettext or such will be used later to translate non-UI */
using namespace std;
-using namespace boost;
-using namespace boost::asio;
using namespace json_spirit;
std::string HelpMessageCli()
@@ -108,12 +106,12 @@ Object CallRPC(const string& strMethod, const Array& params)
// Connect to localhost
bool fUseSSL = GetBoolArg("-rpcssl", false);
- asio::io_service io_service;
- ssl::context context(io_service, ssl::context::sslv23);
- context.set_options(ssl::context::no_sslv2 | ssl::context::no_sslv3);
- asio::ssl::stream<asio::ip::tcp::socket> sslStream(io_service, context);
- SSLIOStreamDevice<asio::ip::tcp> d(sslStream, fUseSSL);
- iostreams::stream< SSLIOStreamDevice<asio::ip::tcp> > stream(d);
+ boost::asio::io_service io_service;
+ boost::asio::ssl::context context(io_service, boost::asio::ssl::context::sslv23);
+ context.set_options(boost::asio::ssl::context::no_sslv2 | boost::asio::ssl::context::no_sslv3);
+ boost::asio::ssl::stream<boost::asio::ip::tcp::socket> sslStream(io_service, context);
+ SSLIOStreamDevice<boost::asio::ip::tcp> d(sslStream, fUseSSL);
+ boost::iostreams::stream< SSLIOStreamDevice<boost::asio::ip::tcp> > stream(d);
const bool fConnected = d.connect(GetArg("-rpcconnect", "127.0.0.1"), GetArg("-rpcport", itostr(BaseParams().RPCPort())));
if (!fConnected)
diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp
index 337cd44cd9..c1622cf5d3 100644
--- a/src/bitcoin-tx.cpp
+++ b/src/bitcoin-tx.cpp
@@ -22,7 +22,6 @@
#include <boost/algorithm/string.hpp>
#include <boost/assign/list_of.hpp>
-using namespace boost::assign;
using namespace std;
static bool fCreateBlank;
@@ -191,7 +190,7 @@ static void MutateTxAddInput(CMutableTransaction& tx, const string& strInput)
string strTxid = strInput.substr(0, pos);
if ((strTxid.size() != 64) || !IsHex(strTxid))
throw runtime_error("invalid TX input txid");
- uint256 txid(strTxid);
+ uint256 txid(uint256S(strTxid));
static const unsigned int minTxOutSz = 9;
static const unsigned int maxVout = MAX_BLOCK_SIZE / minTxOutSz;
@@ -315,7 +314,7 @@ static bool findSighashFlags(int& flags, const string& flagStr)
uint256 ParseHashUO(map<string,UniValue>& o, string strKey)
{
if (!o.count(strKey))
- return 0;
+ return uint256();
return ParseHashUV(o[strKey], strKey);
}
@@ -368,24 +367,24 @@ static void MutateTxSign(CMutableTransaction& tx, const string& flagStr)
// Add previous txouts given in the RPC call:
if (!registers.count("prevtxs"))
throw runtime_error("prevtxs register variable must be set.");
- UniValue prevtxsObj = registers["privatekeys"];
+ UniValue prevtxsObj = registers["prevtxs"];
{
for (unsigned int previdx = 0; previdx < prevtxsObj.count(); previdx++) {
UniValue prevOut = prevtxsObj[previdx];
if (!prevOut.isObject())
throw runtime_error("expected prevtxs internal object");
- map<string,UniValue::VType> types = map_list_of("txid", UniValue::VSTR)("vout",UniValue::VNUM)("scriptPubKey",UniValue::VSTR);
+ map<string,UniValue::VType> types = boost::assign::map_list_of("txid", UniValue::VSTR)("vout",UniValue::VNUM)("scriptPubKey",UniValue::VSTR);
if (!prevOut.checkObject(types))
throw runtime_error("prevtxs internal object typecheck fail");
- uint256 txid = ParseHashUV(prevOut, "txid");
+ uint256 txid = ParseHashUV(prevOut["txid"], "txid");
int nOut = atoi(prevOut["vout"].getValStr());
if (nOut < 0)
throw runtime_error("vout must be positive");
- vector<unsigned char> pkData(ParseHexUV(prevOut, "scriptPubKey"));
+ vector<unsigned char> pkData(ParseHexUV(prevOut["scriptPubKey"], "scriptPubKey"));
CScript scriptPubKey(pkData.begin(), pkData.end());
{
@@ -437,7 +436,7 @@ static void MutateTxSign(CMutableTransaction& tx, const string& flagStr)
BOOST_FOREACH(const CTransaction& txv, txVariants) {
txin.scriptSig = CombineSignatures(prevPubKey, mergedTx, i, txin.scriptSig, txv.vin[i].scriptSig);
}
- if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, SignatureChecker(mergedTx, i)))
+ if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, MutableTransactionSignatureChecker(&mergedTx, i)))
fComplete = false;
}
@@ -485,7 +484,7 @@ static void MutateTx(CMutableTransaction& tx, const string& command,
static void OutputTxJSON(const CTransaction& tx)
{
UniValue entry(UniValue::VOBJ);
- TxToUniv(tx, 0, entry);
+ TxToUniv(tx, uint256(), entry);
string jsonOutput = entry.write(4);
fprintf(stdout, "%s\n", jsonOutput.c_str());
diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp
index 8a1745b50d..a0a96c2dfa 100644
--- a/src/bitcoind.cpp
+++ b/src/bitcoind.cpp
@@ -33,7 +33,7 @@
static bool fDaemon;
-void DetectShutdownThread(boost::thread_group* threadGroup)
+void WaitForShutdown(boost::thread_group* threadGroup)
{
bool fShutdown = ShutdownRequested();
// Tell the main threads to shutdown.
@@ -56,7 +56,6 @@ void DetectShutdownThread(boost::thread_group* threadGroup)
bool AppInit(int argc, char* argv[])
{
boost::thread_group threadGroup;
- boost::thread* detectShutdownThread = NULL;
bool fRet = false;
@@ -144,7 +143,6 @@ bool AppInit(int argc, char* argv[])
#endif
SoftSetBoolArg("-server", true);
- detectShutdownThread = new boost::thread(boost::bind(&DetectShutdownThread, &threadGroup));
fRet = AppInit2(threadGroup);
}
catch (const std::exception& e) {
@@ -155,20 +153,12 @@ bool AppInit(int argc, char* argv[])
if (!fRet)
{
- if (detectShutdownThread)
- detectShutdownThread->interrupt();
-
threadGroup.interrupt_all();
// threadGroup.join_all(); was left out intentionally here, because we didn't re-test all of
// the startup-failure cases to make sure they don't result in a hang due to some
// thread-blocking-waiting-for-another-thread-during-startup case
- }
-
- if (detectShutdownThread)
- {
- detectShutdownThread->join();
- delete detectShutdownThread;
- detectShutdownThread = NULL;
+ } else {
+ WaitForShutdown(&threadGroup);
}
Shutdown();
diff --git a/src/chain.h b/src/chain.h
index b459c975f8..004e87ab52 100644
--- a/src/chain.h
+++ b/src/chain.h
@@ -6,6 +6,7 @@
#ifndef BITCOIN_CHAIN_H
#define BITCOIN_CHAIN_H
+#include "arith_uint256.h"
#include "primitives/block.h"
#include "pow.h"
#include "tinyformat.h"
@@ -117,7 +118,7 @@ public:
unsigned int nUndoPos;
//! (memory only) Total amount of work (expected number of hashes) in the chain up to and including this block
- uint256 nChainWork;
+ arith_uint256 nChainWork;
//! Number of transactions in this block.
//! Note: in a potential headers-first mode, this number cannot be relied upon
@@ -150,14 +151,14 @@ public:
nFile = 0;
nDataPos = 0;
nUndoPos = 0;
- nChainWork = 0;
+ nChainWork = arith_uint256();
nTx = 0;
nChainTx = 0;
nStatus = 0;
nSequenceId = 0;
nVersion = 0;
- hashMerkleRoot = 0;
+ hashMerkleRoot = uint256();
nTime = 0;
nBits = 0;
nNonce = 0;
@@ -282,11 +283,11 @@ public:
uint256 hashPrev;
CDiskBlockIndex() {
- hashPrev = 0;
+ hashPrev = uint256();
}
explicit CDiskBlockIndex(const CBlockIndex* pindex) : CBlockIndex(*pindex) {
- hashPrev = (pprev ? pprev->GetBlockHash() : 0);
+ hashPrev = (pprev ? pprev->GetBlockHash() : uint256());
}
ADD_SERIALIZE_METHODS;
diff --git a/src/chainparams.cpp b/src/chainparams.cpp
index 7562509bd5..1fd3b01681 100644
--- a/src/chainparams.cpp
+++ b/src/chainparams.cpp
@@ -14,7 +14,6 @@
#include <boost/assign/list_of.hpp>
using namespace std;
-using namespace boost::assign;
struct SeedSpec6 {
uint8_t addr[16];
@@ -54,19 +53,19 @@ static void convertSeed6(std::vector<CAddress> &vSeedsOut, const SeedSpec6 *data
*/
static Checkpoints::MapCheckpoints mapCheckpoints =
boost::assign::map_list_of
- ( 11111, uint256("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d"))
- ( 33333, uint256("0x000000002dd5588a74784eaa7ab0507a18ad16a236e7b1ce69f00d7ddfb5d0a6"))
- ( 74000, uint256("0x0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20"))
- (105000, uint256("0x00000000000291ce28027faea320c8d2b054b2e0fe44a773f3eefb151d6bdc97"))
- (134444, uint256("0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe"))
- (168000, uint256("0x000000000000099e61ea72015e79632f216fe6cb33d7899acb35b75c8303b763"))
- (193000, uint256("0x000000000000059f452a5f7340de6682a977387c17010ff6e6c3bd83ca8b1317"))
- (210000, uint256("0x000000000000048b95347e83192f69cf0366076336c639f9b7228e9ba171342e"))
- (216116, uint256("0x00000000000001b4f4b433e81ee46494af945cf96014816a4e2370f11b23df4e"))
- (225430, uint256("0x00000000000001c108384350f74090433e7fcf79a606b8e797f065b130575932"))
- (250000, uint256("0x000000000000003887df1f29024b06fc2200b55f8af8f35453d7be294df2d214"))
- (279000, uint256("0x0000000000000001ae8c72a0b0c301f67e3afca10e819efa9041e458e9bd7e40"))
- (295000, uint256("0x00000000000000004d9b4ef50f0f9d686fd69db2e03af35a100370c64632a983"))
+ ( 11111, uint256S("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d"))
+ ( 33333, uint256S("0x000000002dd5588a74784eaa7ab0507a18ad16a236e7b1ce69f00d7ddfb5d0a6"))
+ ( 74000, uint256S("0x0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20"))
+ (105000, uint256S("0x00000000000291ce28027faea320c8d2b054b2e0fe44a773f3eefb151d6bdc97"))
+ (134444, uint256S("0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe"))
+ (168000, uint256S("0x000000000000099e61ea72015e79632f216fe6cb33d7899acb35b75c8303b763"))
+ (193000, uint256S("0x000000000000059f452a5f7340de6682a977387c17010ff6e6c3bd83ca8b1317"))
+ (210000, uint256S("0x000000000000048b95347e83192f69cf0366076336c639f9b7228e9ba171342e"))
+ (216116, uint256S("0x00000000000001b4f4b433e81ee46494af945cf96014816a4e2370f11b23df4e"))
+ (225430, uint256S("0x00000000000001c108384350f74090433e7fcf79a606b8e797f065b130575932"))
+ (250000, uint256S("0x000000000000003887df1f29024b06fc2200b55f8af8f35453d7be294df2d214"))
+ (279000, uint256S("0x0000000000000001ae8c72a0b0c301f67e3afca10e819efa9041e458e9bd7e40"))
+ (295000, uint256S("0x00000000000000004d9b4ef50f0f9d686fd69db2e03af35a100370c64632a983"))
;
static const Checkpoints::CCheckpointData data = {
&mapCheckpoints,
@@ -78,7 +77,7 @@ static const Checkpoints::CCheckpointData data = {
static Checkpoints::MapCheckpoints mapCheckpointsTestnet =
boost::assign::map_list_of
- ( 546, uint256("000000002a936ca763904c3c35fce2f3556c559c0214345d31b1bcebf76acb70"))
+ ( 546, uint256S("000000002a936ca763904c3c35fce2f3556c559c0214345d31b1bcebf76acb70"))
;
static const Checkpoints::CCheckpointData dataTestnet = {
&mapCheckpointsTestnet,
@@ -89,7 +88,7 @@ static const Checkpoints::CCheckpointData dataTestnet = {
static Checkpoints::MapCheckpoints mapCheckpointsRegtest =
boost::assign::map_list_of
- ( 0, uint256("0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206"))
+ ( 0, uint256S("0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206"))
;
static const Checkpoints::CCheckpointData dataRegtest = {
&mapCheckpointsRegtest,
@@ -101,7 +100,6 @@ static const Checkpoints::CCheckpointData dataRegtest = {
class CMainParams : public CChainParams {
public:
CMainParams() {
- networkID = CBaseChainParams::MAIN;
strNetworkID = "main";
/**
* The message start string is designed to be unlikely to occur in normal data.
@@ -114,7 +112,7 @@ public:
pchMessageStart[3] = 0xd9;
vAlertPubKey = ParseHex("04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284");
nDefaultPort = 8333;
- bnProofOfWorkLimit = ~uint256(0) >> 32;
+ bnProofOfWorkLimit = ~arith_uint256(0) >> 32;
nSubsidyHalvingInterval = 210000;
nEnforceBlockUpgradeMajority = 750;
nRejectBlockOutdatedMajority = 950;
@@ -141,7 +139,7 @@ public:
txNew.vout[0].nValue = 50 * COIN;
txNew.vout[0].scriptPubKey = CScript() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") << OP_CHECKSIG;
genesis.vtx.push_back(txNew);
- genesis.hashPrevBlock = 0;
+ genesis.hashPrevBlock.SetNull();
genesis.hashMerkleRoot = genesis.BuildMerkleTree();
genesis.nVersion = 1;
genesis.nTime = 1231006505;
@@ -149,21 +147,20 @@ public:
genesis.nNonce = 2083236893;
hashGenesisBlock = genesis.GetHash();
- assert(hashGenesisBlock == uint256("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"));
- assert(genesis.hashMerkleRoot == uint256("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"));
+ assert(hashGenesisBlock == uint256S("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"));
+ assert(genesis.hashMerkleRoot == uint256S("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"));
vSeeds.push_back(CDNSSeedData("bitcoin.sipa.be", "seed.bitcoin.sipa.be"));
vSeeds.push_back(CDNSSeedData("bluematt.me", "dnsseed.bluematt.me"));
vSeeds.push_back(CDNSSeedData("dashjr.org", "dnsseed.bitcoin.dashjr.org"));
vSeeds.push_back(CDNSSeedData("bitcoinstats.com", "seed.bitcoinstats.com"));
- vSeeds.push_back(CDNSSeedData("bitnodes.io", "seed.bitnodes.io"));
vSeeds.push_back(CDNSSeedData("xf2.org", "bitseed.xf2.org"));
- base58Prefixes[PUBKEY_ADDRESS] = list_of(0);
- base58Prefixes[SCRIPT_ADDRESS] = list_of(5);
- base58Prefixes[SECRET_KEY] = list_of(128);
- base58Prefixes[EXT_PUBLIC_KEY] = list_of(0x04)(0x88)(0xB2)(0x1E);
- base58Prefixes[EXT_SECRET_KEY] = list_of(0x04)(0x88)(0xAD)(0xE4);
+ base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1,0);
+ base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,5);
+ base58Prefixes[SECRET_KEY] = std::vector<unsigned char>(1,128);
+ base58Prefixes[EXT_PUBLIC_KEY] = boost::assign::list_of(0x04)(0x88)(0xB2)(0x1E).convert_to_container<std::vector<unsigned char> >();
+ base58Prefixes[EXT_SECRET_KEY] = boost::assign::list_of(0x04)(0x88)(0xAD)(0xE4).convert_to_container<std::vector<unsigned char> >();
convertSeed6(vFixedSeeds, pnSeed6_main, ARRAYLEN(pnSeed6_main));
@@ -190,7 +187,6 @@ static CMainParams mainParams;
class CTestNetParams : public CMainParams {
public:
CTestNetParams() {
- networkID = CBaseChainParams::TESTNET;
strNetworkID = "test";
pchMessageStart[0] = 0x0b;
pchMessageStart[1] = 0x11;
@@ -209,7 +205,7 @@ public:
genesis.nTime = 1296688602;
genesis.nNonce = 414098458;
hashGenesisBlock = genesis.GetHash();
- assert(hashGenesisBlock == uint256("0x000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943"));
+ assert(hashGenesisBlock == uint256S("0x000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943"));
vFixedSeeds.clear();
vSeeds.clear();
@@ -218,11 +214,11 @@ public:
vSeeds.push_back(CDNSSeedData("bluematt.me", "testnet-seed.bluematt.me"));
vSeeds.push_back(CDNSSeedData("bitcoin.schildbach.de", "testnet-seed.bitcoin.schildbach.de"));
- base58Prefixes[PUBKEY_ADDRESS] = list_of(111);
- base58Prefixes[SCRIPT_ADDRESS] = list_of(196);
- base58Prefixes[SECRET_KEY] = list_of(239);
- base58Prefixes[EXT_PUBLIC_KEY] = list_of(0x04)(0x35)(0x87)(0xCF);
- base58Prefixes[EXT_SECRET_KEY] = list_of(0x04)(0x35)(0x83)(0x94);
+ base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1,111);
+ base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,196);
+ base58Prefixes[SECRET_KEY] = std::vector<unsigned char>(1,239);
+ base58Prefixes[EXT_PUBLIC_KEY] = boost::assign::list_of(0x04)(0x35)(0x87)(0xCF).convert_to_container<std::vector<unsigned char> >();
+ base58Prefixes[EXT_SECRET_KEY] = boost::assign::list_of(0x04)(0x35)(0x83)(0x94).convert_to_container<std::vector<unsigned char> >();
convertSeed6(vFixedSeeds, pnSeed6_test, ARRAYLEN(pnSeed6_test));
@@ -247,7 +243,6 @@ static CTestNetParams testNetParams;
class CRegTestParams : public CTestNetParams {
public:
CRegTestParams() {
- networkID = CBaseChainParams::REGTEST;
strNetworkID = "regtest";
pchMessageStart[0] = 0xfa;
pchMessageStart[1] = 0xbf;
@@ -260,13 +255,13 @@ public:
nMinerThreads = 1;
nTargetTimespan = 14 * 24 * 60 * 60; //! two weeks
nTargetSpacing = 10 * 60;
- bnProofOfWorkLimit = ~uint256(0) >> 1;
+ bnProofOfWorkLimit = ~arith_uint256(0) >> 1;
genesis.nTime = 1296688602;
genesis.nBits = 0x207fffff;
genesis.nNonce = 2;
hashGenesisBlock = genesis.GetHash();
nDefaultPort = 18444;
- assert(hashGenesisBlock == uint256("0x0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206"));
+ assert(hashGenesisBlock == uint256S("0x0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206"));
vFixedSeeds.clear(); //! Regtest mode doesn't have any fixed seeds.
vSeeds.clear(); //! Regtest mode doesn't have any DNS seeds.
@@ -292,7 +287,6 @@ static CRegTestParams regTestParams;
class CUnitTestParams : public CMainParams, public CModifiableParams {
public:
CUnitTestParams() {
- networkID = CBaseChainParams::UNITTEST;
strNetworkID = "unittest";
nDefaultPort = 18445;
vFixedSeeds.clear(); //! Unit test mode doesn't have any fixed seeds.
diff --git a/src/chainparams.h b/src/chainparams.h
index 60c7b47585..f52bf4e55f 100644
--- a/src/chainparams.h
+++ b/src/chainparams.h
@@ -10,7 +10,7 @@
#include "checkpoints.h"
#include "primitives/block.h"
#include "protocol.h"
-#include "uint256.h"
+#include "arith_uint256.h"
#include <vector>
@@ -45,7 +45,7 @@ public:
const MessageStartChars& MessageStart() const { return pchMessageStart; }
const std::vector<unsigned char>& AlertKey() const { return vAlertPubKey; }
int GetDefaultPort() const { return nDefaultPort; }
- const uint256& ProofOfWorkLimit() const { return bnProofOfWorkLimit; }
+ const arith_uint256& ProofOfWorkLimit() const { return bnProofOfWorkLimit; }
int SubsidyHalvingInterval() const { return nSubsidyHalvingInterval; }
/** Used to check majorities for block version upgrade */
int EnforceBlockUpgradeMajority() const { return nEnforceBlockUpgradeMajority; }
@@ -87,7 +87,7 @@ protected:
//! Raw pub key bytes for the broadcast alert signing key.
std::vector<unsigned char> vAlertPubKey;
int nDefaultPort;
- uint256 bnProofOfWorkLimit;
+ arith_uint256 bnProofOfWorkLimit;
int nSubsidyHalvingInterval;
int nEnforceBlockUpgradeMajority;
int nRejectBlockOutdatedMajority;
@@ -97,7 +97,6 @@ protected:
int nMinerThreads;
std::vector<CDNSSeedData> vSeeds;
std::vector<unsigned char> base58Prefixes[MAX_BASE58_TYPES];
- CBaseChainParams::Network networkID;
std::string strNetworkID;
CBlock genesis;
std::vector<CAddress> vFixedSeeds;
diff --git a/src/chainparamsbase.cpp b/src/chainparamsbase.cpp
index e45536ce71..c42fd106be 100644
--- a/src/chainparamsbase.cpp
+++ b/src/chainparamsbase.cpp
@@ -9,10 +9,6 @@
#include <assert.h>
-#include <boost/assign/list_of.hpp>
-
-using namespace boost::assign;
-
/**
* Main network
*/
@@ -21,7 +17,6 @@ class CBaseMainParams : public CBaseChainParams
public:
CBaseMainParams()
{
- networkID = CBaseChainParams::MAIN;
nRPCPort = 8332;
}
};
@@ -35,7 +30,6 @@ class CBaseTestNetParams : public CBaseMainParams
public:
CBaseTestNetParams()
{
- networkID = CBaseChainParams::TESTNET;
nRPCPort = 18332;
strDataDir = "testnet3";
}
@@ -50,7 +44,6 @@ class CBaseRegTestParams : public CBaseTestNetParams
public:
CBaseRegTestParams()
{
- networkID = CBaseChainParams::REGTEST;
strDataDir = "regtest";
}
};
@@ -64,7 +57,6 @@ class CBaseUnitTestParams : public CBaseMainParams
public:
CBaseUnitTestParams()
{
- networkID = CBaseChainParams::UNITTEST;
strDataDir = "unittest";
}
};
diff --git a/src/chainparamsbase.h b/src/chainparamsbase.h
index 24db9b2840..cebe7aa01a 100644
--- a/src/chainparamsbase.h
+++ b/src/chainparamsbase.h
@@ -32,7 +32,6 @@ protected:
int nRPCPort;
std::string strDataDir;
- Network networkID;
};
/**
diff --git a/src/chainparamsseeds.h b/src/chainparamsseeds.h
index 575e129334..6b6e5103f5 100644
--- a/src/chainparamsseeds.h
+++ b/src/chainparamsseeds.h
@@ -8,606 +8,518 @@
* IPv4 as well as onion addresses are wrapped inside a IPv6 address accordingly.
*/
static SeedSpec6 pnSeed6_main[] = {
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x69,0x6a,0x7e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xd1,0x04,0x7d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x17,0x0c,0x6c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x0a,0x33,0xdb}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0xc7,0x49,0xc6}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0x48,0x95,0x78}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x09,0x71,0x04}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0xa5,0x0c,0xb9}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0x80,0x30,0xd1}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa6,0x4e,0x07,0xbd}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0xf1,0x8f,0x57}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x09,0x6e,0x28}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0xaf,0xdc,0xd4}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb8,0x6b,0x9b,0x52}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0xc6,0x5c,0x63}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x89,0xde,0xed}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc7,0xd9,0x76,0xa9}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb8,0xa4,0x91,0xea}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x4e,0xfa,0x03}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8d,0x00,0xa9,0x6c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xc8,0x62,0xaf}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0xba,0xf3,0x93}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0xef,0xc9,0xc2}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x17,0xd5,0x0e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x28,0x70,0x48}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xc2,0x97,0x72}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xc6,0xf0,0x8a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x01,0x21,0xc5,0x6e}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x01,0x22,0xb4,0xf5}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x01,0xca,0x80,0xda}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x02,0x23,0xc3,0x19}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x64,0x7b,0x13}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0xaf,0x91,0xa9}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0xc7,0x85,0xc1}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0xc7,0x97,0x0a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0xe4,0x01,0xe6}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x0e,0xc8,0xc8,0x91}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x12,0xe4,0x00,0xbc}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x12,0xe4,0x00,0xc8}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0x1e,0xf3,0x99}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0x58,0xe8,0x31}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0x63,0x69,0x09}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0xe2,0x89,0xd0}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0xe3,0xb1,0xa1}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0xe3,0xbf,0x32}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0xe5,0x2d,0x20}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0xec,0x90,0x45}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0xfd,0x94,0x71}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0xfd,0xf1,0x16}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0xff,0xe3,0xe7}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x14,0xcd,0xde}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x17,0x78,0xfc}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x5e,0x62,0x60}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x62,0x5f,0xc9}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x6f,0x5a,0x37}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x77,0x77,0x69}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x8a,0x19,0x95}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0x03,0xd6,0x2d}, 8333},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0xba,0x57,0x2e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x8a,0x09,0xd0}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0x85,0xa8,0x46}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0xdc,0x92,0xcc}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0x19,0x6f,0xeb}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x17,0xce,0x8c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x81,0x72,0x23}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x79,0x42,0x9d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x09,0x4f,0x4f}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd0,0x51,0x01,0xc5}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x90,0xba,0xb1}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x17,0xd7,0xae}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xe5,0x4d,0x20}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x32,0xb0,0x4b}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x28,0x2b,0x93}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xe6,0xcc,0x2d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x8a,0x70,0xe2}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0xb8,0x08,0x1b}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xdc,0xa3,0x12}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x90,0x4c,0x88,0x8a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb8,0xa8,0x86,0xa3}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x17,0xe4,0x18}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0x9a,0x70,0x2e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xe9,0x62,0xeb}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x03,0x65,0x6f}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x81,0xd0,0x05}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0xc5,0x9a,0x8a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xd6,0x6f,0x94}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5d,0x49,0x57,0x3f}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xc6,0x29,0x4a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x90,0x4c,0x45,0xad}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x09,0x34,0x15}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0x3b,0x3f,0x4c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x19,0xfe,0x01}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x59,0x20,0x56}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x79,0x3c,0x44}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc8,0x4a,0xf2,0x44}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x46,0x42,0x04}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x82,0x58,0x66,0xc8}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0x3e,0x3f,0xed}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5d,0xbf,0x85,0xf5}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xda,0x41,0xd1,0x5d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0xba,0x65,0x62}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0xba,0xfa,0xba}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0xcc,0x99,0x6b}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0x2c,0x10,0xe7}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0x2c,0x2c,0x0b}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0x78,0xa8,0xcc}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0x8f,0x56,0x1a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xbb,0x4b,0x18}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xbc,0x44,0xa9}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xc0,0x5f,0x96}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xc9,0xf6,0x74}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xcd,0x0a,0x8c}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x0a,0xd2,0x11}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x13,0x8a,0x9a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x1c,0xcc,0x7b}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x1c,0xcd,0x43}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x26,0xeb,0xe5}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xa3,0x4c,0xe6}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xa6,0xa2,0x5b}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xad,0xbe,0x32}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xe3,0x42,0x84}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xe5,0xee,0xbb}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xec,0x74,0xd1}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2f,0x37,0x0e,0x41}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x07,0xfc,0xe5}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x2e,0x9f,0x5b}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x4e,0x31,0xb5}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x4e,0xe7,0x39}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x4f,0x99,0x41}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x74,0x22,0x2c}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x7e,0x56,0xfd}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x8e,0x29,0x17}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0xc7,0x71,0xc1}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0xc8,0x4e,0x6b}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0xce,0x8a,0xb1}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0xfc,0x34,0x31}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xa5,0x19,0x4b}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xa9,0x6b,0x28}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xb3,0xbe,0x38}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xbb,0x52,0x79}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xf6,0x55,0xf6}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3a,0x4a,0x07,0xcd}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3a,0x60,0xb7,0x79}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3d,0x3e,0x3a,0x26}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3d,0x3f,0x5b,0x48}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3d,0x3f,0x5b,0x70}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3d,0x48,0xd3,0xe4}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0x2b,0x28,0x9a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0x2b,0x82,0xb2}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0x50,0xb9,0xd5}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0x6d,0x31,0x1a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0xad,0x8b,0x3a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0xb5,0xee,0xba}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0xd2,0x72,0x7f}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3f,0x8d,0xe4,0x8a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3f,0x99,0xd5,0x4e}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3f,0xdf,0x54,0x91}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3f,0xfb,0x58,0x70}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x40,0x1f,0x6e,0x32}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x40,0x22,0x79,0x2d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x40,0x72,0x06,0x2a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x40,0x8c,0x7d,0x62}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x40,0x9c,0xc1,0x64}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x41,0x1e,0x2f,0x74}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x41,0x23,0x84,0xb1}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x41,0x60,0xc1,0xa5}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x41,0x6f,0xbd,0x1a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0x44,0x0a,0x1e}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0x72,0x21,0xfa}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0x82,0x2e,0x3f}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0xaf,0xd7,0x87}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0xbe,0xfd,0xa5}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0xc2,0x26,0xfe}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0xf4,0x62,0x6f}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0xa2,0xee,0x1e}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0xa9,0xff,0x11}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0xb7,0xad,0x19}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0xdb,0xe9,0x8c}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0xe3,0xf0,0x73}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0xf7,0xde,0x47}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x44,0x2b,0x72,0x42}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x44,0x34,0x21,0x24}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x44,0xc6,0xf5,0xf1}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x0c,0xe2,0xa5}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x0d,0xc6,0xbc}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x0f,0xb3,0x3e}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x27,0xef,0x2f}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x2f,0x2d,0x57}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x3e,0xd9,0xce}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x40,0x2a,0x1f}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x40,0x51,0x3d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x43,0xdb,0xc8}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x5a,0x84,0x9d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x5e,0x1e,0xb1}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x88,0xaf,0xf1}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x46,0x3d,0x61,0xe4}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x46,0x7b,0x76,0x84}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0x3b,0x98,0xb6}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0xc6,0xf8,0x97}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0xc8,0xf2,0x59}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0xe1,0xb3,0x9d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0x0e,0xbb,0x33}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0x26,0x22,0xb4}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0x34,0x48,0xbb}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0x5b,0x90,0xb6}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0xa7,0x31,0xd9}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0xc9,0xf3,0x37}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0xdf,0x3c,0xf9}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0xe4,0x99,0x66}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x49,0x1a,0x65,0xe4}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x49,0x32,0x9e,0xc8}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x49,0xb5,0xcc,0xaa}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0x39,0xc7,0xb4}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0x3f,0xde,0xe2}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0x51,0xe7,0x15}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0xc1,0x7e,0x52}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0xcf,0xeb,0xa4}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4b,0x53,0xc5,0x72}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4b,0x90,0x72,0x09}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4c,0x70,0x05,0xf7}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4c,0xae,0x14,0xf7}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0x25,0xf0,0x8e}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0x39,0xca,0x6b}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0xac,0x7b,0x35}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0xdd,0x5b,0xfd}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0xeb,0x30,0x30}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0xf5,0x4e,0x02}, 8333},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x08,0x3a,0xf9}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xdd,0x64,0x12}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xc6,0x11,0x07}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbe,0x7b,0x2e,0xf1}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x40,0xb7,0x02,0x5b}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0x6d,0x52,0x7d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x90,0x4c,0xb0,0x0c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x11,0xbe,0x2a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0x9f,0xa3,0x61}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x06,0x4a,0x04}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xce,0x7d,0xaf,0xf3}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xc9,0x94,0xb9}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0x50,0x1c,0x36}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0x5d,0x73,0xca}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x43,0xa7,0xec}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x09,0x79,0xec}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x78,0xd3,0xc4}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xa2,0xc4,0xa1}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x1b,0xbf,0xb6}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x81,0xec,0x8d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x83,0x58,0x2f}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x9d,0xcd,0x06}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4f,0x84,0xe6,0x90}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4f,0x8f,0xbc,0x9b}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4f,0xa0,0xdd,0x8c}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4f,0xa1,0x6f,0x72}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0x64,0xbd,0x03}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0x93,0x8c,0x79}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0xcb,0x4b,0x85}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0xdc,0x63,0xe3}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0xde,0x14,0xa9}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0xf1,0x01,0x07}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0x17,0xbf,0xf3}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0x26,0x0b,0xca}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0x50,0x09,0x47}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0x6e,0xd5,0xa5}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0x85,0x9b,0xed}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0xab,0x22,0x25}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0xb5,0x9b,0xb4}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0x27,0x9c,0x89}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0x49,0xa1,0x5f}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0x82,0x2d,0x28}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xa5,0x99,0x2f}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xa8,0x80,0x85}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xb3,0xe1,0x76}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xc2,0xf5,0x9e}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xc7,0x66,0x0a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xd3,0x1e,0xf3}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xd9,0x85,0x91}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xdd,0x80,0x23}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xdd,0x83,0xb1}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xe9,0xe1,0xcd}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0x00,0xf9,0x92}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0x59,0x1f,0xf9}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0x80,0x1d,0xe7}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0x80,0xfd,0x8e}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0x8f,0x82,0x38}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0x96,0x02,0x63}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0x96,0x09,0xc4}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xa1,0x40,0x2d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xd4,0x67,0xd4}, 8333},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xd4,0x6f,0x72}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0xc6,0x5c,0x62}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x13,0x20,0x6c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x79,0x0c,0xaa,0xb7}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3d,0x98,0xed,0xc6}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0xcb,0xe4,0x47}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0x75,0xac,0xa4}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x93,0xe5,0xe2}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd0,0x4a,0x78,0x4d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xec,0xa5,0x18}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xc8,0x1c,0x48}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0x2f,0x6c,0x7c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x60,0x4d,0x5e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x6c,0x4b,0x5b}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x90,0x4c,0x9b,0xd9}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xdc,0x87,0x39,0xe6}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xbb,0x17,0xb8}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xfe,0x1c,0x14}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0x50,0x00,0x5f}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0x7f,0x98,0x0d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0x49,0x2a,0x24}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x9b,0x51,0x3e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4b,0x45,0xb2,0x02}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x3d,0xaf,0xdf}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x28,0x81,0x88}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xbb,0x65,0x11}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xca,0xfe,0xab}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x40,0x35,0xf6,0x2e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0xc7,0x73,0x57}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xdd,0x80,0x12}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0xac,0xbc,0x8e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x39,0xc4,0x81}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0xfa,0xfc,0x39}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x41,0x7d,0x17,0x62}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0xed,0x75,0xc9}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x76,0xf4,0xcf,0x05}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0xa7,0xbd,0xda}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0xc2,0x1a,0xaa}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xa2,0x55,0xe2}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0xc7,0xaa,0x88}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xc6,0x07,0xe7}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x4b,0xe9,0xa9}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4b,0x48,0x93,0x28}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x27,0x51,0x99}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xca,0x70,0x39,0xd6}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x4f,0x99,0x45}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xa8,0x19,0xe5}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5d,0x5f,0xe2,0x92}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0xa9,0x84,0x8b}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x0a,0xaa,0x5e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xe5,0x4d,0xa7}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0xff,0x90,0xb0}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0x32,0xee,0x5e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x79,0xa6,0x31,0xc3}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xb7,0xd9,0xc1}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x82,0xb9,0x6a,0x0c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xbb,0x62,0x73}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0xdd,0xfe,0x4c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0xa0,0x09,0x1e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x4c,0xc3,0xa4}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc7,0xd9,0x77,0x37}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x60,0xf2,0xdc,0x5e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0xb5,0xe2,0x3c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x60,0x03,0xac,0xd2}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x92,0xb9,0x80,0x2f}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xbb,0x4c,0x3e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xe2,0x95,0x39}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x77,0x39,0xd0}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0xf0,0x3c,0x95}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd0,0x4e,0x65,0x3c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x90,0x4c,0x02,0x74}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0x11,0x4f,0xa1}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0x01,0xce,0x14}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6a,0xbb,0x5e,0xc1}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xc4,0x08,0x2c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0x06,0xfd,0xc7}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xce,0xf8,0x04,0x76}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x83,0xb3,0xff}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0xef,0xc2,0xa4}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x40,0x61,0xe9}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xf6,0x4b,0x08}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xfe,0x51,0x1f}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xfe,0x96,0x36}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0x02,0x22,0x68}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0x0f,0x3d,0x3c}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0x11,0x19,0x87}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0x2a,0x90,0x13}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0xd4,0xd2,0x87}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0xd7,0xa5,0xe7}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0xee,0x8c,0xb0}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0xf0,0x1f,0xb8}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0x19,0xd6,0x89}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0x8b,0xa3,0x84}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0xc7,0x04,0xe4}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0xd6,0x3d,0xd1}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0xd6,0x6c,0x4d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x56,0x7b,0x10,0x11}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0x30,0x2a,0xc7}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0x68,0xa8,0x68}, 8333},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0xe5,0x49,0xab}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xc0,0x48,0x16}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0x40,0x02,0x36}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xff,0x8c,0x0e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0x89,0x91,0x21}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0x50,0x1f,0xb6}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0x6b,0x40,0x9b}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x22,0x28,0xaf}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x16,0x1d,0x7f}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0x0d,0x56,0x1f}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xbe,0x37,0xe2}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0x19,0xeb,0xbd}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x17,0x07,0x6c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0xce,0xf8,0xda}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0x24,0x74,0x0f}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0x52,0xe9,0xde}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x56,0x1a,0x3f,0xf2}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x67,0xf8,0xbd,0x61}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0xc8,0x54,0xd2}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x2e,0x42,0xc4}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x63,0x05,0xae}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0xa9,0xb9,0xbd}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x32,0xeb,0xa9}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0x39,0x94,0xd9}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xdd,0x6a,0x11}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x90,0x4c,0xa5,0x73}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x52,0x6b,0xb3}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x17,0x34,0xd7}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x76,0x7f,0x3d,0x33}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x1b,0x43,0x51}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcf,0xe5,0x4a,0x08}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0x23,0x0a,0xa6}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x69,0x67,0x5c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0xcf,0x77,0x01}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x3a,0x68,0xa6}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0xea,0xf4,0x7f}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xfa,0x92,0x21}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x46,0x0f,0x3a,0xa0}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x39,0x3e,0xfe}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0x5f,0xce,0x2c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0xc1,0xa6,0xc8}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4c,0x7e,0xfb,0x96}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xc7,0x66,0x0a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x27,0x4d,0x6b}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0xc1,0xa0,0xeb}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x79,0xa0,0x3b}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0xd2,0xcc,0x1d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xf3,0x12,0x69}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x41,0x3c,0xf2,0x22}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0x6b,0x64,0x65}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x87,0x9f,0x8b}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x95,0x9a,0x9b,0xeb}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x6b,0xfe,0x79}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0xf4,0x36,0x05}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x61,0x4d,0x22,0x23}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x2e,0x95,0x5d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xf7,0xb4,0x0c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xbe,0x14,0xdc}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x09,0x46,0xb2}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0x9b,0xf7,0xd3}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xc8,0x18,0x65}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0xcf,0xa3,0x83}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x1f,0x64,0x9b}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0xf1,0xfe,0x17}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x82,0xcc,0x08,0xd5}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x9b,0x36,0xa4,0x91}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4c,0x4a,0xcb,0x39}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0x53,0xc9,0xbb}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0xc4,0x64,0xaf}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0xca,0x5e,0x60}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x68,0x6a,0x0c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x9d,0x7e,0xd0}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xd3,0xe6,0x78}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0xec,0xc4,0x4d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0x61,0x38,0x62}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0x86,0xb2,0x59}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0x96,0xe9,0x13}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xa8,0x85,0x03}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xd0,0x12,0xf6}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xd0,0x21,0xca}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0x12,0x1c,0x15}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0x55,0xdc,0x54}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0xa3,0xe3,0x1c}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0xb8,0x53,0x3c}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0xe7,0x60,0x53}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0xec,0x31,0x75}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x5a,0x42,0xd1}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x6a,0xc2,0x61}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x86,0x4b,0x73}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x98,0xc1,0x24}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x98,0xdb,0x23}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xc5,0x0a,0xea}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xd1,0x4d,0x65}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xd2,0x6a,0x93}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xd6,0xc8,0xcd}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xdf,0x73,0x26}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xea,0x30,0xe8}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xfa,0x56,0x12}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5c,0x1b,0x07,0xd1}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5c,0xff,0xcf,0x49}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5d,0x4a,0xa3,0xea}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5d,0x54,0x72,0x6a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5d,0x98,0xa6,0x1d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5d,0xab,0xd8,0xdd}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5d,0xb9,0xb1,0x47}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x13,0x0c,0xf4}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x2a,0x73,0x32}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x4f,0xb1,0xce}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x88,0x93,0x77}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x8f,0xf5,0x05}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xbc,0x32,0x27}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xbe,0xe3,0x70}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xc6,0x87,0x1d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xe2,0x6b,0x56}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xf2,0xdb,0x5a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xf2,0xe5,0xa8}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xf4,0xa0,0x54}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0x1f,0x0a,0xd1}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0x55,0x19,0x29}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0x69,0xa1,0x88}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0x9a,0xa5,0x2d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0x9a,0xc8,0xd8}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0xa7,0x6d,0x7d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0xd3,0x7d,0xe7}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0xd3,0xd8,0xeb}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x60,0x21,0x19,0x11}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x60,0x2b,0x82,0xb2}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x61,0x76,0x08,0xec}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0x66,0x06,0x7d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0xca,0x14,0x2d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0xd9,0x7d,0xe1}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0xea,0xd2,0x6f}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0xed,0x14,0x7b}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0xff,0x90,0xb0}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x63,0x71,0x40,0x2b}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x63,0xe5,0x16,0x08}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x67,0x01,0xd4,0x13}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x67,0x1e,0x2a,0xbd}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x67,0xe0,0xa5,0x30}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x67,0xf3,0x5e,0x8c}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0x83,0x6b,0x6b}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0x83,0x74,0xb8}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0x8f,0x00,0x9c}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0xdb,0xb8,0x09}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6a,0xb9,0x26,0xae}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6b,0x06,0x04,0x91}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6b,0x96,0x08,0x1b}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6b,0x96,0x21,0x14}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6b,0xaa,0xe4,0x81}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6b,0xaa,0xf0,0xad}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0x33,0x14,0x56}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0x3d,0x95,0xde}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0x3d,0x97,0xac}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0xa1,0x81,0xf7}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0xaa,0x8c,0x15}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0x3c,0xd3,0xd8}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0x49,0x2a,0x24}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0x49,0xac,0x8a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xa3,0xeb,0xef}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xbe,0xc4,0xdc}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xc9,0x87,0xd8}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xe4,0x98,0x02}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xe4,0x9a,0x51}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xe6,0xdc,0x7d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xea,0x9c,0xda}, 8333},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xeb,0x31,0x1b}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xfe,0x01,0xaa}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xc2,0x03,0x46}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb6,0xa3,0xcb,0x1e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xe3,0xff,0x0e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xcb,0xfd,0xc3}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6f,0x03,0x90,0xc2}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x69,0x64,0x44}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x89,0x75,0xca,0x1a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xe5,0xa9,0x59}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x89,0x74,0xaa,0x19}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xc8,0x22,0x26}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0xd3,0x98,0xa5}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0xc3,0x8e,0x43}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x19,0x96,0xc7}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x60,0x03,0x57,0xaf}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x89,0xe2,0x98,0x50}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0xd8,0xad,0x36}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xa2,0xc1,0x83}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x09,0x9d,0x96}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0x15,0x3d,0xcf}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0xa4,0xc1,0x49}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0x75,0x0b,0xbd}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0x19,0xff,0x8f}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xfe,0x51,0x1e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0xef,0xd6,0x28}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0xcc,0x37,0x28}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0x2d,0xf4,0x02}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x3f,0x0e,0x07}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x87,0xb1,0xbc}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xe1,0xa4,0x14}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x44,0x68,0x09,0x82}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x1c,0xcb,0xcf}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc7,0x7f,0xe2,0x37}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0x37,0x92,0x07}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xbc,0x14,0x0c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x09,0x10,0x26}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0xd9,0x7c,0xcb}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0xd2,0xc0,0x3b}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4c,0x1b,0x13,0x97}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0x5c,0x1e,0x6f}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0x9f,0x93,0xa7}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xbf,0xa0,0xb7}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0x3a,0xa8,0xaf}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x3f,0xb8,0xcb}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x1c,0x32,0x5f}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc7,0xc3,0xd6,0x52}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc7,0x5b,0xac,0xde}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcc,0x10,0xf3,0x2c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0x2b,0x8a,0x10}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4f,0xa1,0x6f,0x72}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcc,0xd2,0xba,0x85}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x90,0x4c,0x9e,0x45}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0xb8,0x08,0x1a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x48,0x70,0xcd}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x90,0x4c,0x5b,0x6d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x7b,0xfe,0x6c,0xa6}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x09,0x73,0xad}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc7,0x5b,0xac,0xda}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x9f,0xfd,0x17,0x84}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x74,0x37,0x41}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x86,0x13,0x1f}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x12,0x5a,0x29}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x31,0xc0,0x7a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x95,0xd2,0x87,0x3a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xbc,0x19,0xe2}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xeb,0x45,0x54}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x70,0x7c,0x47,0x00}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x71,0x92,0x44,0xfb}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x73,0x1d,0x11,0x52}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x73,0x46,0xb0,0x11}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x75,0x29,0xa2,0xb8}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x76,0x1b,0x08,0xaa}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x77,0xe6,0x07,0xd3}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x77,0xf6,0x47,0x34}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x79,0xac,0x08,0x64}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x7a,0x80,0x6d,0x94}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x7b,0xe7,0xe0,0x3f}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x80,0xaf,0xc3,0x1f}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x80,0xc7,0xa4,0x60}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x80,0xc7,0xfe,0xf4}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x81,0x61,0x45,0x4c}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x81,0x7b,0x07,0x07}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x81,0x7b,0x07,0x27}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x81,0xba,0x11,0x11}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x83,0xf7,0xa9,0xbe}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x85,0xf2,0xd1,0x3f}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x86,0x66,0x5e,0x26}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x86,0x77,0x11,0x91}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x89,0x74,0xa0,0xb0}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x89,0xe2,0x22,0x2a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8a,0xd2,0xd9,0xaa}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8d,0xff,0xa6,0xc2}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8f,0xd7,0x81,0x7e}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x90,0x4c,0xf4,0x13}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x92,0x94,0x34,0xa2}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x92,0x94,0x50,0x39}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x92,0xb9,0x13,0x1e}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x92,0xb9,0x8e,0x56}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x92,0xb9,0xfd,0x33}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x94,0xfb,0x06,0xd6}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x95,0x9a,0x9b,0xeb}, 8333},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x95,0xd2,0x85,0xf4}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x64,0x7b,0x13}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xd9,0xff,0xcf}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x44,0x08,0xe2,0xaf}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0x9a,0x67,0x32}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x44,0xc6,0x31,0xa4}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8c,0xce,0x5f,0x0e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xf8,0x5e,0x30}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0xca,0x26,0xad}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0x1a,0xd2,0xd9}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xd7,0xd0,0xdd}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc7,0xc0,0x4e,0xc2}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xcd,0xad,0x4a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0x98,0x10,0x49}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x3a,0x6b,0x9d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8b,0x1e,0xaa,0xf0}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0xa3,0xbf,0xf1}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xc0,0x30,0x8a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0x93,0x0f,0x26}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x60,0xe7,0x39,0x23}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x9f,0x95,0x69,0x88}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0x21,0x07,0xc2}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0x34,0x45,0x29}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xec,0x51,0xb6}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0x62,0x49,0x45}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcc,0x1b,0x3d,0xa2}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0xcf,0x9b,0xb3}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x94,0xd2,0xa1}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xc6,0x07,0x35}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0xdd,0x88,0x4a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x63,0xf3,0xaf,0x27}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xea,0x98,0x74}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0x85,0x67,0x4a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc2,0x47,0x6d,0x5e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0xa5,0xab,0x3b}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x37,0x5a,0x04}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc7,0xc0,0x4d,0xa2}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0xea,0x81,0xe9}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0xe2,0x6c,0xed}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x14,0x72,0x85}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x64,0x04,0x6c,0x6b}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb8,0x45,0x49,0x5a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0x47,0xf2,0x12}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0x42,0x5f,0xf3}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x5a,0x0f,0xfd}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x56,0x15,0x08,0xfb}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x61,0x58,0x4b,0xb2}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x46,0x41,0x11,0x2e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x09,0x78,0xb7}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0x0e,0xbb,0x33}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x56,0x65,0xe2,0x39}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0x48,0x94,0xa7}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0x42,0x25,0x42}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x79,0x03,0x30}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x44,0xcf,0xc8,0x31}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0xad,0x5b,0xd6}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0xc6,0x7b,0x12}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4c,0x4d,0xbc,0xf2}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0xdc,0x73,0x02}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xd7,0x72,0x45}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xf6,0x4b,0x06}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0x12,0xcd,0xcd}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x81,0x82,0x60}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x87,0x00,0x13,0x4d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xf7,0x16,0x10}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x5f,0x18,0xba}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4f,0xa8,0xc1,0x16}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0x72,0x69,0xfb}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x60,0x23,0x94,0xa2}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0x3b,0x08,0x53}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0xf1,0x83,0x05}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x41,0x24,0x5a,0x2d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0xaa,0x72,0xc1}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xcf,0x11,0xcd}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0xed,0x14,0x7b}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0xf1,0x94,0x5c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x13,0x23,0x7c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6f,0x5a,0x96,0x39}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0xe2,0x90,0x78}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0xc4,0x8e,0xa3}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0xf1,0x87,0xc1}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0xb6,0x80,0xef}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x74,0x0a,0xf2}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd2,0xd8,0xd1,0x7a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x2e,0x9e,0x86}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5d,0x5c,0xdb,0xcc}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xf6,0x11,0x9d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xbb,0x61,0x21}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x89,0xf8,0x99,0x75}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x97,0xe0,0xf8,0xfc}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x99,0x79,0x4b,0xe5}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x99,0x7f,0xfb,0x43}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x9a,0x14,0x02,0x8b}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x9d,0x0d,0x3d,0x05}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x9e,0x3a,0xad,0x30}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x9f,0xfd,0x17,0x84}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xd1,0x6e,0xda}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xd5,0xfe,0xcd}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xef,0xfe,0x64}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xf2,0x96,0x27}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xf3,0x51,0x8a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xf3,0xeb,0x38}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xf4,0x4f,0x10}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xf5,0xd9,0x77}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xf8,0x66,0x75}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xfb,0x6c,0x35}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xfe,0x95,0x8b}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xff,0x74,0x4e}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa6,0x46,0x5e,0x6a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa7,0x58,0x2d,0x7c}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa7,0x58,0x78,0xd2}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0x1a,0x31,0x2b}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0x1e,0x0e,0x06}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0x50,0x72,0xc5}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xa7,0xd6,0xf3}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xd0,0xdb,0x6c}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xdc,0x43,0x9c}, 8333},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xec,0x65,0x22}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0x0e,0x4f,0x0f}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0x85,0x25,0x7d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x60,0xe3,0x57,0xf8}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0x3d,0x3f,0xf8}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb8,0x3b,0xc9,0x9c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0x68,0x71,0x02}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x77,0xa1,0xd8,0x5d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0x6c,0xdc,0x8a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x46,0x3d,0x61,0xe5}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0x4f,0x73,0x6a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x3b,0x5c,0x2a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0xc3,0x04,0x4a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x46,0x3d,0x61,0xe4}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0xf4,0x26,0x84}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x5f,0x1b,0x3e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x3c,0x5a,0x0d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0xd1,0xf6,0xd0}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xff,0xc7,0x21}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0x3d,0x3f,0xeb}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0xed,0xa5,0x9d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x81,0x3b,0x75,0x5d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0x53,0x8d,0x0d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0xf0,0x13,0x26}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8d,0x69,0x43,0x44}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcd,0xed,0xa1,0x8c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x3f,0xed,0x10}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3a,0x40,0x9b,0x78}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4b,0x4a,0x98,0x7b}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xbc,0x4e,0x96}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x60,0xee,0x20,0x75}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x28,0x48,0x4f}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x7d,0x40,0x5c,0x11}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x67,0x06,0xdd,0x32}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x71,0x41,0xa7}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x35,0x3f,0x1d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x56,0x1f,0x7d,0x81}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xa5,0x99,0x2f}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x56,0x59,0x2a,0x6b}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x4f,0x4f,0x8d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0x1e,0x3c,0xd2}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0x37,0x99,0x98}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xe5,0x92,0x2c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0xbd,0x7e,0x23}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0xfb,0x62,0xa7}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x71,0x6b,0x01,0x32}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x79,0xcf,0xe7,0xd0}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0xbd,0x35,0x7d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd2,0xc3,0xda,0x53}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x71,0x6b,0x01,0x31}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xce,0xf8,0xb8,0x7f}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0xc2,0x38,0x9a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0x42,0xaa,0xef}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3d,0x82,0x6b,0x87}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0x53,0x17,0x18}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x7d,0x59,0x46,0xdb}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xda,0x68,0xc1,0xd2}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xdc,0xe9,0x6f,0xcd}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x2e,0x27,0x45}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xca,0x4b,0x8d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0x3d,0x04,0xa4}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0xaa,0xb7,0xaa}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x81,0x28,0x20}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x60,0xf1,0xae,0xa4}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0xe6,0xd7,0xec}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0x59,0x13,0x39}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x93,0xcc,0xd8}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xe5,0xee,0xbb}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x67,0x70,0x07}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0x9d,0xd3,0xeb}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0xc5,0xed,0x0c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xe1,0xd3,0x23}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x13,0xa8,0xa5}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x32,0x9a,0x17}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3d,0x48,0xd3,0xe4}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x09,0x68,0x03}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x8a,0x01,0xe8}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xef,0xe9,0xdd}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x87,0x8b,0x43}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa0,0x24,0x82,0xb4}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x92,0xd6,0xcb}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x79,0x75,0x90}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0x1c,0x41,0xc6}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5c,0x3f,0x83,0x03}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x8b,0x3f,0xf3}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4b,0x46,0x5e,0x49}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xe6,0xc8,0x83}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xcd,0x09,0xac}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0xc5,0xab,0xda}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xa5,0x65,0x76}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x37,0x26,0xc5}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcd,0xc5,0xd0,0x2f}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x61,0x4d,0x22,0x22}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0x40,0x95,0x3e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0x75,0xa3,0xfa}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xc6,0xdb,0x36}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd0,0x53,0x14,0xa8}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5d,0x1f,0x94,0x5a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x60,0xea,0x98,0xa5}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x4a,0x38,0x65}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0xa5,0xaa,0x10}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x79,0xab,0xaa}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4c,0x02,0xa7,0xdd}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0xf4,0x66,0x09}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x08,0x1c,0x57,0x68}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0xee,0x40,0x8b}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0x09,0xac,0x33}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4b,0x4c,0x4b,0x84}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0x25,0x92,0xd3}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x46,0x5a,0x4d,0xba}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0x96,0x02,0x63}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xf6,0x55,0xf6}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb1,0x4b,0x4c,0xbe}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xd0,0xda,0x45}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xc0,0x4b,0x20}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xa2,0xc3,0x06}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6a,0xba,0x1f,0xf3}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x09,0x1f,0xb2}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0x07,0x0d,0x54}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0x6a,0xb4,0xc7}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x79,0x11,0x6a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x40,0x51,0x3d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xaa,0x18,0x03}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0x6e,0x30,0x30}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x74,0x07,0x5c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xe4,0x9a,0x25}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0xd3,0xbb,0x82}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x22,0x42,0xae}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0x15,0x44,0x25}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4b,0x57,0x5f,0xbd}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x17,0xfd,0xd8}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0x38,0x3f,0x0a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xf6,0x6b,0x22}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xff,0xed,0xf1}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x02,0xd5,0xd1}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x33,0x17,0xe0}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x33,0x7b,0x9f}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x39,0xd4,0x79}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x6d,0x21,0x1c}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xaf,0x7e,0x7c,0x5b}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xaf,0x7e,0x7c,0x5c}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x0a,0x74,0xf2}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x24,0x23,0x7e}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x24,0x63,0xde}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x7c,0x6e,0x2f}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0xc2,0x21,0x2c}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0xdf,0xc9,0xc6}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x3e,0x1a,0x53}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x3e,0x24,0x30}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x3e,0xd4,0x8d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x3e,0xfe,0x3b}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x4e,0xfa,0x03}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x9b,0x56,0xe2}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xaf,0x86,0x23}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xf8,0x6f,0x04}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xfe,0x01,0xaa}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xfe,0x22,0xa1}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb3,0x2b,0x72,0x0e}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb6,0xd5,0xd0,0x1c}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb8,0x44,0x02,0x2e}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb8,0x48,0xee,0x2a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb8,0x5e,0xe2,0x22}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb8,0x5e,0xe3,0x3a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb8,0x6b,0x8b,0x3a}, 8333},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb8,0x6b,0xce,0x2d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xd0,0x01,0xc2}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0xa5,0xfc,0x17}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xca,0x3c,0x45,0xe8}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xf6,0x61,0xd3}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0xed,0xd9,0xa0}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x2e,0x23,0x2f}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0x11,0x4e,0x13}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xc0,0xdd,0x61}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x83,0x72,0xba,0x05}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xed,0xf7,0xe1}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xc4,0x0e,0x04}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x2e,0x67,0x4b}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xa3,0xef,0xe4}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xa5,0xdc,0x47}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x2e,0x33,0xe9}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x92,0xb9,0xac,0xa3}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x90,0x4c,0x71,0x24}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x86,0xcc,0xa8}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xce,0xb1,0x26}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0x53,0x4e,0x26}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8c,0x71,0xd2,0xd3}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0x34,0x55,0x22}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xf3,0x89,0xe2}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0x17,0x34,0x87}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4f,0xad,0x55,0x92}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xbb,0x4b,0x18}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x7a,0x5c,0x88}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x9a,0x6e,0x3a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x18,0x24,0x19}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x90,0x4c,0x3d,0xb7}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x7a,0x80,0x6d,0x94}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3f,0x8e,0xd7,0xa0}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xbb,0x16,0x5a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x79,0x09,0xcb}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0xe6,0x0d,0x8d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0x8b,0x0b,0x63}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcf,0xc6,0x72,0xe5}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x11,0x3f,0x2b}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0xa9,0x42,0x42}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x09,0x99,0x32}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x09,0x8b,0x05}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x60,0xfc,0x66,0xe2}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0xc5,0x66,0xbe}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xe4,0x98,0xcc}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0x94,0x8c,0x69}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0x0c,0xbd,0x44}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x0a,0x30,0x75}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x15,0xd8,0x9c}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x26,0x2f,0xe0}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x2d,0xc0,0x81}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x35,0x81,0xe6}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x35,0x83,0x72}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x37,0x35,0x3d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x37,0x35,0x3f}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x3d,0x77,0x02}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x3d,0x94,0xcb}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xba,0x02,0xa7,0x17}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x5c,0x4b,0xb2}, 8333},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x7a,0x5c,0x86}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd3,0x64,0x17,0x77}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0xd6,0x75,0x46}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x26,0x48,0x4e,0x35}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xc1,0x7a,0xb6}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x85,0xf2,0xcc,0xae}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x5b,0x62,0xea}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0x03,0xd6,0xbc}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0xeb,0x81,0x5e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xce,0x47,0xb3,0x74}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0x6a,0xa5,0x3c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x46,0x45,0xee,0x54}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x17,0xa8,0x38}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0x11,0xc2,0xa3}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0x57,0x01,0x2f}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0xde,0x7a,0x5d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0xae,0x03,0xa0}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0xd3,0xc1,0x2b}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4c,0x09,0xf5,0x13}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0x26,0xb3,0x7a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0x9f,0x2e,0x54}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0x6b,0x13,0x53}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x51,0xdf,0x7f}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x97,0x21,0x80}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xcc,0xd2,0xa2}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x8a,0x09,0xd0}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0xa5,0xd1,0x94}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0xe2,0xce,0xef}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbe,0x0a,0x08,0x7c}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbe,0x0a,0x0a,0x93}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x00,0x82,0x8e}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x03,0x59,0x9f}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x49,0xea,0x8a}, 8333},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x4b,0x5f,0x6b}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x5f,0x64,0x66}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x9b,0x54,0xb5}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0xa9,0xe9,0xce}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0xc6,0x5d,0x56}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0xe3,0x87,0xd8}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0x00,0x6d,0x03}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0x4d,0x32,0xd0}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0x6d,0x44,0x3e}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0x96,0x79,0x25}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0xe0,0x45,0x62}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc2,0x4f,0x08,0x25}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc2,0x8d,0x56,0x0a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0x0c,0xb4,0x5e}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0x38,0x3f,0x0a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0x74,0x5d,0x5d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0x9a,0xae,0xe2}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0x9f,0x6f,0x62}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0xa9,0x8a,0x02}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0xbd,0x7e,0x23}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0xc5,0xaf,0xbe}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc5,0xf2,0x5d,0x52}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x0b,0xd6,0x93}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x31,0x29,0x15}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc7,0x21,0x7c,0xba}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc7,0xcc,0xba,0x92}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc7,0xe9,0xee,0x73}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc7,0xf1,0xbd,0x42}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xca,0x3c,0x44,0xf2}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xca,0x3c,0x45,0xe8}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcb,0xb7,0x97,0x27}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcb,0xdb,0x0e,0xcc}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcc,0x2c,0x7b,0x6d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcc,0x2c,0x7b,0xa2}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcc,0x2d,0x78,0xb2}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xce,0xbe,0x86,0x2c}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xce,0xf8,0xb8,0x7f}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcf,0xf4,0x49,0x08}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd0,0x42,0x1e,0x1b}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0x51,0x09,0xdf}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0x69,0xf3,0xe5}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0x7e,0x46,0x9f}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0x8c,0x1e,0xa9}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0xa5,0x80,0xeb}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0xbe,0x02,0xf2}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd2,0x42,0xfe,0xec}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd2,0x49,0x1b,0x21}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd3,0x48,0x42,0xe5}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0x19,0x25,0x7c}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0x47,0xeb,0x72}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0x47,0xfc,0x6d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0x72,0x30,0x1f}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0xae,0x97,0x76}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0x42,0xcd,0xc2}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0x81,0xf8,0x8b}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0x88,0x57,0x22}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0xa5,0x52,0x85}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0xa7,0x11,0x06}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0xb3,0x9e,0xfd}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0xbd,0x35,0x7d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0xde,0xd0,0x5d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0x31,0x9e,0xa1}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0x37,0x8f,0x9a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0x83,0x5b,0x64}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0xf5,0xce,0xb5}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0xfa,0x8a,0xe6}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x0b,0xe1,0xbd}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x17,0x06,0x85}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x4b,0x58,0xb2}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0xac,0x8f,0x8c}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0xc3,0xa9,0xd1}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0xc4,0xf8,0x6a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xdb,0x8a,0xa1,0xa2}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xde,0xa7,0xf8,0x5a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xdf,0x12,0xfe,0x37}, 8333},
{{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x0a,0x26,0x27,0x21,0xae,0x94,0xd5,0xc2,0x72,0x24}, 8333},
{{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xea,0xb9,0x5b,0x63,0x1d,0x94,0xe2,0xed,0xec,0xa1}, 8333},
{{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xce,0x36,0xa1,0xc1,0xd6,0x64,0x43,0xfb,0xb3,0xe7}, 8333},
diff --git a/src/checkqueue.h b/src/checkqueue.h
index b8e2a17c76..6f6b97e3a7 100644
--- a/src/checkqueue.h
+++ b/src/checkqueue.h
@@ -81,7 +81,7 @@ private:
fAllOk &= fOk;
nTodo -= nNow;
if (nTodo == 0 && !fMaster)
- // We processed the last element; inform the master he can exit and return the result
+ // We processed the last element; inform the master he or she can exit and return the result
condMaster.notify_one();
} else {
// first iteration
@@ -161,7 +161,12 @@ public:
{
}
- friend class CCheckQueueControl<T>;
+ bool IsIdle()
+ {
+ boost::unique_lock<boost::mutex> lock(mutex);
+ return (nTotal == nIdle && nTodo == 0 && fAllOk == true);
+ }
+
};
/**
@@ -180,9 +185,8 @@ public:
{
// passed queue is supposed to be unused, or NULL
if (pqueue != NULL) {
- assert(pqueue->nTotal == pqueue->nIdle);
- assert(pqueue->nTodo == 0);
- assert(pqueue->fAllOk == true);
+ bool isIdle = pqueue->IsIdle();
+ assert(isIdle);
}
}
diff --git a/src/clientversion.h b/src/clientversion.h
index 40de7837aa..3c8c969f9d 100644
--- a/src/clientversion.h
+++ b/src/clientversion.h
@@ -26,7 +26,7 @@
* Copyright year (2009-this)
* Todo: update this when changing our copyright comments in the source
*/
-#define COPYRIGHT_YEAR 2014
+#define COPYRIGHT_YEAR 2015
#endif //HAVE_CONFIG_H
diff --git a/src/coins.cpp b/src/coins.cpp
index bc430c9c7e..d79e29951b 100644
--- a/src/coins.cpp
+++ b/src/coins.cpp
@@ -31,32 +31,18 @@ void CCoins::CalcMaskSize(unsigned int &nBytes, unsigned int &nNonzeroBytes) con
nBytes += nLastUsedByte;
}
-bool CCoins::Spend(const COutPoint &out, CTxInUndo &undo) {
- if (out.n >= vout.size())
- return false;
- if (vout[out.n].IsNull())
+bool CCoins::Spend(uint32_t nPos)
+{
+ if (nPos >= vout.size() || vout[nPos].IsNull())
return false;
- undo = CTxInUndo(vout[out.n]);
- vout[out.n].SetNull();
+ vout[nPos].SetNull();
Cleanup();
- if (vout.size() == 0) {
- undo.nHeight = nHeight;
- undo.fCoinBase = fCoinBase;
- undo.nVersion = this->nVersion;
- }
return true;
}
-bool CCoins::Spend(int nPos) {
- CTxInUndo undo;
- COutPoint out(0, nPos);
- return Spend(out, undo);
-}
-
-
bool CCoinsView::GetCoins(const uint256 &txid, CCoins &coins) const { return false; }
bool CCoinsView::HaveCoins(const uint256 &txid) const { return false; }
-uint256 CCoinsView::GetBestBlock() const { return uint256(0); }
+uint256 CCoinsView::GetBestBlock() const { return uint256(); }
bool CCoinsView::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { return false; }
bool CCoinsView::GetStats(CCoinsStats &stats) const { return false; }
@@ -71,7 +57,7 @@ bool CCoinsViewBacked::GetStats(CCoinsStats &stats) const { return base->GetStat
CCoinsKeyHasher::CCoinsKeyHasher() : salt(GetRandHash()) {}
-CCoinsViewCache::CCoinsViewCache(CCoinsView *baseIn) : CCoinsViewBacked(baseIn), hasModifier(false), hashBlock(0) { }
+CCoinsViewCache::CCoinsViewCache(CCoinsView *baseIn) : CCoinsViewBacked(baseIn), hasModifier(false) { }
CCoinsViewCache::~CCoinsViewCache()
{
@@ -106,7 +92,6 @@ bool CCoinsViewCache::GetCoins(const uint256 &txid, CCoins &coins) const {
CCoinsModifier CCoinsViewCache::ModifyCoins(const uint256 &txid) {
assert(!hasModifier);
- hasModifier = true;
std::pair<CCoinsMap::iterator, bool> ret = cacheCoins.insert(std::make_pair(txid, CCoinsCacheEntry()));
if (ret.second) {
if (!base->GetCoins(txid, ret.first->second.coins)) {
@@ -142,7 +127,7 @@ bool CCoinsViewCache::HaveCoins(const uint256 &txid) const {
}
uint256 CCoinsViewCache::GetBestBlock() const {
- if (hashBlock == uint256(0))
+ if (hashBlock.IsNull())
hashBlock = base->GetBestBlock();
return hashBlock;
}
@@ -247,7 +232,10 @@ double CCoinsViewCache::GetPriority(const CTransaction &tx, int nHeight) const
return tx.ComputePriority(dResult);
}
-CCoinsModifier::CCoinsModifier(CCoinsViewCache& cache_, CCoinsMap::iterator it_) : cache(cache_), it(it_) {}
+CCoinsModifier::CCoinsModifier(CCoinsViewCache& cache_, CCoinsMap::iterator it_) : cache(cache_), it(it_) {
+ assert(!cache.hasModifier);
+ cache.hasModifier = true;
+}
CCoinsModifier::~CCoinsModifier()
{
diff --git a/src/coins.h b/src/coins.h
index 9b73ae3a87..fe2eaa08e5 100644
--- a/src/coins.h
+++ b/src/coins.h
@@ -9,7 +9,6 @@
#include "compressor.h"
#include "serialize.h"
#include "uint256.h"
-#include "undo.h"
#include <assert.h>
#include <stdint.h>
@@ -237,11 +236,8 @@ public:
Cleanup();
}
- //! mark an outpoint spent, and construct undo information
- bool Spend(const COutPoint &out, CTxInUndo &undo);
-
//! mark a vout spent
- bool Spend(int nPos);
+ bool Spend(uint32_t nPos);
//! check whether a particular output is still available
bool IsAvailable(unsigned int nPos) const {
@@ -301,7 +297,7 @@ struct CCoinsStats
uint256 hashSerialized;
CAmount nTotalAmount;
- CCoinsStats() : nHeight(0), hashBlock(0), nTransactions(0), nTransactionOutputs(0), nSerializedSize(0), hashSerialized(0), nTotalAmount(0) {}
+ CCoinsStats() : nHeight(0), nTransactions(0), nTransactionOutputs(0), nSerializedSize(0), nTotalAmount(0) {}
};
@@ -441,6 +437,11 @@ public:
private:
CCoinsMap::iterator FetchCoins(const uint256 &txid);
CCoinsMap::const_iterator FetchCoins(const uint256 &txid) const;
+
+ /**
+ * By making the copy constructor private, we prevent accidentally using it when one intends to create a cache on top of a base cache.
+ */
+ CCoinsViewCache(const CCoinsViewCache &);
};
#endif // BITCOIN_COINS_H
diff --git a/src/core_io.h b/src/core_io.h
index e0620e86b6..0989cf7437 100644
--- a/src/core_io.h
+++ b/src/core_io.h
@@ -19,6 +19,7 @@ extern CScript ParseScript(std::string s);
extern bool DecodeHexTx(CTransaction& tx, const std::string& strHexTx);
extern bool DecodeHexBlk(CBlock&, const std::string& strHexBlk);
extern uint256 ParseHashUV(const UniValue& v, const std::string& strName);
+extern uint256 ParseHashStr(const std::string&, const std::string& strName);
extern std::vector<unsigned char> ParseHexUV(const UniValue& v, const std::string& strName);
// core_write.cpp
diff --git a/src/core_read.cpp b/src/core_read.cpp
index a49705e045..e064955ff0 100644
--- a/src/core_read.cpp
+++ b/src/core_read.cpp
@@ -20,8 +20,6 @@
#include <boost/algorithm/string/split.hpp>
#include <boost/assign/list_of.hpp>
-using namespace boost;
-using namespace boost::algorithm;
using namespace std;
CScript ParseScript(std::string s)
@@ -44,13 +42,13 @@ CScript ParseScript(std::string s)
string strName(name);
mapOpNames[strName] = (opcodetype)op;
// Convenience: OP_ADD and just ADD are both recognized:
- replace_first(strName, "OP_", "");
+ boost::algorithm::replace_first(strName, "OP_", "");
mapOpNames[strName] = (opcodetype)op;
}
}
vector<string> words;
- split(words, s, is_any_of(" \t\n"), token_compress_on);
+ boost::algorithm::split(words, s, boost::algorithm::is_any_of(" \t\n"), boost::algorithm::token_compress_on);
for (std::vector<std::string>::const_iterator w = words.begin(); w != words.end(); ++w)
{
@@ -58,20 +56,20 @@ CScript ParseScript(std::string s)
{
// Empty string, ignore. (boost::split given '' will return one word)
}
- else if (all(*w, is_digit()) ||
- (starts_with(*w, "-") && all(string(w->begin()+1, w->end()), is_digit())))
+ else if (all(*w, boost::algorithm::is_digit()) ||
+ (boost::algorithm::starts_with(*w, "-") && all(string(w->begin()+1, w->end()), boost::algorithm::is_digit())))
{
// Number
int64_t n = atoi64(*w);
result << n;
}
- else if (starts_with(*w, "0x") && (w->begin()+2 != w->end()) && IsHex(string(w->begin()+2, w->end())))
+ else if (boost::algorithm::starts_with(*w, "0x") && (w->begin()+2 != w->end()) && IsHex(string(w->begin()+2, w->end())))
{
// Raw hex data, inserted NOT pushed onto stack:
std::vector<unsigned char> raw = ParseHex(string(w->begin()+2, w->end()));
result.insert(result.end(), raw.begin(), raw.end());
}
- else if (w->size() >= 2 && starts_with(*w, "'") && ends_with(*w, "'"))
+ else if (w->size() >= 2 && boost::algorithm::starts_with(*w, "'") && boost::algorithm::ends_with(*w, "'"))
{
// Single-quoted string, pushed as data. NOTE: this is poor-man's
// parsing, spaces/tabs/newlines in single-quoted strings won't work.
@@ -131,6 +129,11 @@ uint256 ParseHashUV(const UniValue& v, const string& strName)
string strHex;
if (v.isStr())
strHex = v.getValStr();
+ return ParseHashStr(strHex, strName); // Note: ParseHashStr("") throws a runtime_error
+}
+
+uint256 ParseHashStr(const std::string& strHex, const std::string& strName)
+{
if (!IsHex(strHex)) // Note: IsHex("") is false
throw runtime_error(strName+" must be hexadecimal string (not '"+strHex+"')");
diff --git a/src/core_write.cpp b/src/core_write.cpp
index b6fd7fe877..c3babec2fc 100644
--- a/src/core_write.cpp
+++ b/src/core_write.cpp
@@ -127,7 +127,7 @@ void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry)
}
entry.pushKV("vout", vout);
- if (hashBlock != 0)
+ if (!hashBlock.IsNull())
entry.pushKV("blockhash", hashBlock.GetHex());
entry.pushKV("hex", EncodeHexTx(tx)); // the hex-encoded transaction. used the name "hex" to be consistent with the verbose output of "getrawtransaction".
diff --git a/src/crypter.cpp b/src/crypter.cpp
index 00f7f7f1bd..75d84dbf13 100644
--- a/src/crypter.cpp
+++ b/src/crypter.cpp
@@ -102,7 +102,7 @@ bool CCrypter::Decrypt(const std::vector<unsigned char>& vchCiphertext, CKeyingM
}
-bool EncryptSecret(const CKeyingMaterial& vMasterKey, const CKeyingMaterial &vchPlaintext, const uint256& nIV, std::vector<unsigned char> &vchCiphertext)
+static bool EncryptSecret(const CKeyingMaterial& vMasterKey, const CKeyingMaterial &vchPlaintext, const uint256& nIV, std::vector<unsigned char> &vchCiphertext)
{
CCrypter cKeyCrypter;
std::vector<unsigned char> chIV(WALLET_CRYPTO_KEY_SIZE);
@@ -112,7 +112,7 @@ bool EncryptSecret(const CKeyingMaterial& vMasterKey, const CKeyingMaterial &vch
return cKeyCrypter.Encrypt(*((const CKeyingMaterial*)&vchPlaintext), vchCiphertext);
}
-bool DecryptSecret(const CKeyingMaterial& vMasterKey, const std::vector<unsigned char>& vchCiphertext, const uint256& nIV, CKeyingMaterial& vchPlaintext)
+static bool DecryptSecret(const CKeyingMaterial& vMasterKey, const std::vector<unsigned char>& vchCiphertext, const uint256& nIV, CKeyingMaterial& vchPlaintext)
{
CCrypter cKeyCrypter;
std::vector<unsigned char> chIV(WALLET_CRYPTO_KEY_SIZE);
@@ -122,6 +122,19 @@ bool DecryptSecret(const CKeyingMaterial& vMasterKey, const std::vector<unsigned
return cKeyCrypter.Decrypt(vchCiphertext, *((CKeyingMaterial*)&vchPlaintext));
}
+static bool DecryptKey(const CKeyingMaterial& vMasterKey, const std::vector<unsigned char>& vchCryptedSecret, const CPubKey& vchPubKey, CKey& key)
+{
+ CKeyingMaterial vchSecret;
+ if(!DecryptSecret(vMasterKey, vchCryptedSecret, vchPubKey.GetHash(), vchSecret))
+ return false;
+
+ if (vchSecret.size() != 32)
+ return false;
+
+ key.Set(vchSecret.begin(), vchSecret.end(), vchPubKey.IsCompressed());
+ return key.VerifyPubKey(vchPubKey);
+}
+
bool CCryptoKeyStore::SetCrypted()
{
LOCK(cs_KeyStore);
@@ -161,20 +174,8 @@ bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn)
{
const CPubKey &vchPubKey = (*mi).second.first;
const std::vector<unsigned char> &vchCryptedSecret = (*mi).second.second;
- CKeyingMaterial vchSecret;
- if(!DecryptSecret(vMasterKeyIn, vchCryptedSecret, vchPubKey.GetHash(), vchSecret))
- {
- keyFail = true;
- break;
- }
- if (vchSecret.size() != 32)
- {
- keyFail = true;
- break;
- }
CKey key;
- key.Set(vchSecret.begin(), vchSecret.end(), vchPubKey.IsCompressed());
- if (key.GetPubKey() != vchPubKey)
+ if (!DecryptKey(vMasterKeyIn, vchCryptedSecret, vchPubKey, key))
{
keyFail = true;
break;
@@ -243,13 +244,7 @@ bool CCryptoKeyStore::GetKey(const CKeyID &address, CKey& keyOut) const
{
const CPubKey &vchPubKey = (*mi).second.first;
const std::vector<unsigned char> &vchCryptedSecret = (*mi).second.second;
- CKeyingMaterial vchSecret;
- if (!DecryptSecret(vMasterKey, vchCryptedSecret, vchPubKey.GetHash(), vchSecret))
- return false;
- if (vchSecret.size() != 32)
- return false;
- keyOut.Set(vchSecret.begin(), vchSecret.end(), vchPubKey.IsCompressed());
- return true;
+ return DecryptKey(vMasterKey, vchCryptedSecret, vchPubKey, keyOut);
}
}
return false;
diff --git a/src/crypter.h b/src/crypter.h
index 7b4c2f2613..cbaf1562f0 100644
--- a/src/crypter.h
+++ b/src/crypter.h
@@ -107,9 +107,6 @@ public:
}
};
-bool EncryptSecret(const CKeyingMaterial& vMasterKey, const CKeyingMaterial &vchPlaintext, const uint256& nIV, std::vector<unsigned char> &vchCiphertext);
-bool DecryptSecret(const CKeyingMaterial& vMasterKey, const std::vector<unsigned char>& vchCiphertext, const uint256& nIV, CKeyingMaterial& vchPlaintext);
-
/** Keystore which keeps the private keys encrypted.
* It derives from the basic key store, which is used if no encryption is active.
*/
diff --git a/src/crypto/rfc6979_hmac_sha256.cpp b/src/crypto/rfc6979_hmac_sha256.cpp
deleted file mode 100644
index a8c971c3ba..0000000000
--- a/src/crypto/rfc6979_hmac_sha256.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright (c) 2014 The Bitcoin Core developers
-// Distributed under the MIT software license, see the accompanying
-// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-
-#include "crypto/rfc6979_hmac_sha256.h"
-
-#include <string.h>
-
-#include <algorithm>
-
-static const unsigned char zero[1] = {0x00};
-static const unsigned char one[1] = {0x01};
-
-RFC6979_HMAC_SHA256::RFC6979_HMAC_SHA256(const unsigned char* key, size_t keylen, const unsigned char* msg, size_t msglen) : retry(false)
-{
- memset(V, 0x01, sizeof(V));
- memset(K, 0x00, sizeof(K));
-
- CHMAC_SHA256(K, sizeof(K)).Write(V, sizeof(V)).Write(zero, sizeof(zero)).Write(key, keylen).Write(msg, msglen).Finalize(K);
- CHMAC_SHA256(K, sizeof(K)).Write(V, sizeof(V)).Finalize(V);
- CHMAC_SHA256(K, sizeof(K)).Write(V, sizeof(V)).Write(one, sizeof(one)).Write(key, keylen).Write(msg, msglen).Finalize(K);
- CHMAC_SHA256(K, sizeof(K)).Write(V, sizeof(V)).Finalize(V);
-}
-
-RFC6979_HMAC_SHA256::~RFC6979_HMAC_SHA256()
-{
- memset(V, 0x01, sizeof(V));
- memset(K, 0x00, sizeof(K));
-}
-
-void RFC6979_HMAC_SHA256::Generate(unsigned char* output, size_t outputlen)
-{
- if (retry) {
- CHMAC_SHA256(K, sizeof(K)).Write(V, sizeof(V)).Write(zero, sizeof(zero)).Finalize(K);
- CHMAC_SHA256(K, sizeof(K)).Write(V, sizeof(V)).Finalize(V);
- }
-
- while (outputlen > 0) {
- CHMAC_SHA256(K, sizeof(K)).Write(V, sizeof(V)).Finalize(V);
- size_t len = std::min(outputlen, sizeof(V));
- memcpy(output, V, len);
- output += len;
- outputlen -= len;
- }
-
- retry = true;
-}
diff --git a/src/crypto/rfc6979_hmac_sha256.h b/src/crypto/rfc6979_hmac_sha256.h
deleted file mode 100644
index f3a54a5d11..0000000000
--- a/src/crypto/rfc6979_hmac_sha256.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) 2014 The Bitcoin Core developers
-// Distributed under the MIT software license, see the accompanying
-// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-
-#ifndef BITCOIN_RFC6979_HMAC_SHA256_H
-#define BITCOIN_RFC6979_HMAC_SHA256_H
-
-#include "crypto/hmac_sha256.h"
-
-#include <stdint.h>
-#include <stdlib.h>
-
-/** The RFC 6979 PRNG using HMAC-SHA256. */
-class RFC6979_HMAC_SHA256
-{
-private:
- unsigned char V[CHMAC_SHA256::OUTPUT_SIZE];
- unsigned char K[CHMAC_SHA256::OUTPUT_SIZE];
- bool retry;
-
-public:
- /**
- * Construct a new RFC6979 PRNG, using the given key and message.
- * The message is assumed to be already hashed.
- */
- RFC6979_HMAC_SHA256(const unsigned char* key, size_t keylen, const unsigned char* msg, size_t msglen);
-
- /**
- * Generate a byte array.
- */
- void Generate(unsigned char* output, size_t outputlen);
-
- ~RFC6979_HMAC_SHA256();
-};
-
-#endif // BITCOIN_RFC6979_HMAC_SHA256_H
diff --git a/src/db.cpp b/src/db.cpp
index 94629968d5..a7f885135b 100644
--- a/src/db.cpp
+++ b/src/db.cpp
@@ -24,7 +24,6 @@
#include <openssl/rand.h>
using namespace std;
-using namespace boost;
unsigned int nWalletDBUpdated;
@@ -44,7 +43,7 @@ void CDBEnv::EnvShutdown()
fDbEnvInit = false;
int ret = dbenv.close(0);
if (ret != 0)
- LogPrintf("CDBEnv::EnvShutdown : Error %d shutting down database environment: %s\n", ret, DbEnv::strerror(ret));
+ LogPrintf("CDBEnv::EnvShutdown: Error %d shutting down database environment: %s\n", ret, DbEnv::strerror(ret));
if (!fMockDb)
DbEnv(0).remove(path.string().c_str(), 0);
}
@@ -73,10 +72,10 @@ bool CDBEnv::Open(const boost::filesystem::path& pathIn)
boost::this_thread::interruption_point();
path = pathIn;
- filesystem::path pathLogDir = path / "database";
+ boost::filesystem::path pathLogDir = path / "database";
TryCreateDirectory(pathLogDir);
- filesystem::path pathErrorFile = path / "db.log";
- LogPrintf("CDBEnv::Open : LogDir=%s ErrorFile=%s\n", pathLogDir.string(), pathErrorFile.string());
+ boost::filesystem::path pathErrorFile = path / "db.log";
+ LogPrintf("CDBEnv::Open: LogDir=%s ErrorFile=%s\n", pathLogDir.string(), pathErrorFile.string());
unsigned int nEnvFlags = 0;
if (GetBoolArg("-privdb", true))
@@ -103,7 +102,7 @@ bool CDBEnv::Open(const boost::filesystem::path& pathIn)
nEnvFlags,
S_IRUSR | S_IWUSR);
if (ret != 0)
- return error("CDBEnv::Open : Error %d opening database environment: %s\n", ret, DbEnv::strerror(ret));
+ return error("CDBEnv::Open: Error %d opening database environment: %s\n", ret, DbEnv::strerror(ret));
fDbEnvInit = true;
fMockDb = false;
@@ -113,7 +112,7 @@ bool CDBEnv::Open(const boost::filesystem::path& pathIn)
void CDBEnv::MakeMock()
{
if (fDbEnvInit)
- throw runtime_error("CDBEnv::MakeMock : Already initialized");
+ throw runtime_error("CDBEnv::MakeMock: Already initialized");
boost::this_thread::interruption_point();
@@ -136,7 +135,7 @@ void CDBEnv::MakeMock()
DB_PRIVATE,
S_IRUSR | S_IWUSR);
if (ret > 0)
- throw runtime_error(strprintf("CDBEnv::MakeMock : Error %d opening database environment.", ret));
+ throw runtime_error(strprintf("CDBEnv::MakeMock: Error %d opening database environment.", ret));
fDbEnvInit = true;
fMockDb = true;
@@ -173,14 +172,14 @@ bool CDBEnv::Salvage(std::string strFile, bool fAggressive, std::vector<CDBEnv::
Db db(&dbenv, 0);
int result = db.verify(strFile.c_str(), NULL, &strDump, flags);
if (result == DB_VERIFY_BAD) {
- LogPrintf("CDBEnv::Salvage : Database salvage found errors, all data may not be recoverable.\n");
+ LogPrintf("CDBEnv::Salvage: Database salvage found errors, all data may not be recoverable.\n");
if (!fAggressive) {
- LogPrintf("CDBEnv::Salvage : Rerun with aggressive mode to ignore errors and continue.\n");
+ LogPrintf("CDBEnv::Salvage: Rerun with aggressive mode to ignore errors and continue.\n");
return false;
}
}
if (result != 0 && result != DB_VERIFY_BAD) {
- LogPrintf("CDBEnv::Salvage : Database salvage failed with result %d.\n", result);
+ LogPrintf("CDBEnv::Salvage: Database salvage failed with result %d.\n", result);
return false;
}
@@ -218,10 +217,11 @@ void CDBEnv::CheckpointLSN(const std::string& strFile)
}
-CDB::CDB(const std::string& strFilename, const char* pszMode) : pdb(NULL), activeTxn(NULL)
+CDB::CDB(const std::string& strFilename, const char* pszMode, bool fFlushOnCloseIn) : pdb(NULL), activeTxn(NULL)
{
int ret;
fReadOnly = (!strchr(pszMode, '+') && !strchr(pszMode, 'w'));
+ fFlushOnClose = fFlushOnCloseIn;
if (strFilename.empty())
return;
@@ -233,7 +233,7 @@ CDB::CDB(const std::string& strFilename, const char* pszMode) : pdb(NULL), activ
{
LOCK(bitdb.cs_db);
if (!bitdb.Open(GetDataDir()))
- throw runtime_error("CDB : Failed to open database environment.");
+ throw runtime_error("CDB: Failed to open database environment.");
strFile = strFilename;
++bitdb.mapFileUseCount[strFile];
@@ -246,7 +246,7 @@ CDB::CDB(const std::string& strFilename, const char* pszMode) : pdb(NULL), activ
DbMpoolFile* mpf = pdb->get_mpf();
ret = mpf->set_flags(DB_MPOOL_NOFILE, 1);
if (ret != 0)
- throw runtime_error(strprintf("CDB : Failed to configure for no temp file backing for database %s", strFile));
+ throw runtime_error(strprintf("CDB: Failed to configure for no temp file backing for database %s", strFile));
}
ret = pdb->open(NULL, // Txn pointer
@@ -261,7 +261,7 @@ CDB::CDB(const std::string& strFilename, const char* pszMode) : pdb(NULL), activ
pdb = NULL;
--bitdb.mapFileUseCount[strFile];
strFile = "";
- throw runtime_error(strprintf("CDB : Error %d, can't open database %s", ret, strFile));
+ throw runtime_error(strprintf("CDB: Error %d, can't open database %s", ret, strFile));
}
if (fCreate && !Exists(string("version"))) {
@@ -298,7 +298,8 @@ void CDB::Close()
activeTxn = NULL;
pdb = NULL;
- Flush();
+ if (fFlushOnClose)
+ Flush();
{
LOCK(bitdb.cs_db);
@@ -341,7 +342,7 @@ bool CDB::Rewrite(const string& strFile, const char* pszSkip)
bitdb.mapFileUseCount.erase(strFile);
bool fSuccess = true;
- LogPrintf("CDB::Rewrite : Rewriting %s...\n", strFile);
+ LogPrintf("CDB::Rewrite: Rewriting %s...\n", strFile);
string strFileRes = strFile + ".rewrite";
{ // surround usage of db with extra {}
CDB db(strFile.c_str(), "r");
@@ -354,7 +355,7 @@ bool CDB::Rewrite(const string& strFile, const char* pszSkip)
DB_CREATE, // Flags
0);
if (ret > 0) {
- LogPrintf("CDB::Rewrite : Can't create database file %s\n", strFileRes);
+ LogPrintf("CDB::Rewrite: Can't create database file %s\n", strFileRes);
fSuccess = false;
}
@@ -403,7 +404,7 @@ bool CDB::Rewrite(const string& strFile, const char* pszSkip)
fSuccess = false;
}
if (!fSuccess)
- LogPrintf("CDB::Rewrite : Failed to rewrite database file %s\n", strFileRes);
+ LogPrintf("CDB::Rewrite: Failed to rewrite database file %s\n", strFileRes);
return fSuccess;
}
}
@@ -417,7 +418,7 @@ void CDBEnv::Flush(bool fShutdown)
{
int64_t nStart = GetTimeMillis();
// Flush log data to the actual data file on all files that are not in use
- LogPrint("db", "CDBEnv::Flush : Flush(%s)%s\n", fShutdown ? "true" : "false", fDbEnvInit ? "" : " database not started");
+ LogPrint("db", "CDBEnv::Flush: Flush(%s)%s\n", fShutdown ? "true" : "false", fDbEnvInit ? "" : " database not started");
if (!fDbEnvInit)
return;
{
@@ -426,21 +427,21 @@ void CDBEnv::Flush(bool fShutdown)
while (mi != mapFileUseCount.end()) {
string strFile = (*mi).first;
int nRefCount = (*mi).second;
- LogPrint("db", "CDBEnv::Flush : Flushing %s (refcount = %d)...\n", strFile, nRefCount);
+ LogPrint("db", "CDBEnv::Flush: Flushing %s (refcount = %d)...\n", strFile, nRefCount);
if (nRefCount == 0) {
// Move log data to the dat file
CloseDb(strFile);
- LogPrint("db", "CDBEnv::Flush : %s checkpoint\n", strFile);
+ LogPrint("db", "CDBEnv::Flush: %s checkpoint\n", strFile);
dbenv.txn_checkpoint(0, 0, 0);
- LogPrint("db", "CDBEnv::Flush : %s detach\n", strFile);
+ LogPrint("db", "CDBEnv::Flush: %s detach\n", strFile);
if (!fMockDb)
dbenv.lsn_reset(strFile.c_str(), 0);
- LogPrint("db", "CDBEnv::Flush : %s closed\n", strFile);
+ LogPrint("db", "CDBEnv::Flush: %s closed\n", strFile);
mapFileUseCount.erase(mi++);
} else
mi++;
}
- LogPrint("db", "CDBEnv::Flush : Flush(%s)%s took %15dms\n", fShutdown ? "true" : "false", fDbEnvInit ? "" : " database not started", GetTimeMillis() - nStart);
+ LogPrint("db", "CDBEnv::Flush: Flush(%s)%s took %15dms\n", fShutdown ? "true" : "false", fDbEnvInit ? "" : " database not started", GetTimeMillis() - nStart);
if (fShutdown) {
char** listp;
if (mapFileUseCount.empty()) {
diff --git a/src/db.h b/src/db.h
index 717462ff4f..d208907c89 100644
--- a/src/db.h
+++ b/src/db.h
@@ -23,8 +23,6 @@
class CDiskBlockIndex;
class COutPoint;
-struct CBlockLocator;
-
extern unsigned int nWalletDBUpdated;
void ThreadFlushWalletDB(const std::string& strWalletFile);
@@ -99,8 +97,9 @@ protected:
std::string strFile;
DbTxn* activeTxn;
bool fReadOnly;
+ bool fFlushOnClose;
- explicit CDB(const std::string& strFilename, const char* pszMode = "r+");
+ explicit CDB(const std::string& strFilename, const char* pszMode = "r+", bool fFlushOnCloseIn=true);
~CDB() { Close(); }
public:
diff --git a/src/ecwrapper.cpp b/src/ecwrapper.cpp
index c29390eb98..5e3aec25ba 100644
--- a/src/ecwrapper.cpp
+++ b/src/ecwrapper.cpp
@@ -117,10 +117,34 @@ bool CECKey::SetPubKey(const unsigned char* pubkey, size_t size) {
}
bool CECKey::Verify(const uint256 &hash, const std::vector<unsigned char>& vchSig) {
- // -1 = error, 0 = bad sig, 1 = good
- if (ECDSA_verify(0, (unsigned char*)&hash, sizeof(hash), &vchSig[0], vchSig.size(), pkey) != 1)
+ if (vchSig.empty())
return false;
- return true;
+
+ // New versions of OpenSSL will reject non-canonical DER signatures. de/re-serialize first.
+ unsigned char *norm_der = NULL;
+ ECDSA_SIG *norm_sig = ECDSA_SIG_new();
+ const unsigned char* sigptr = &vchSig[0];
+ assert(norm_sig);
+ if (d2i_ECDSA_SIG(&norm_sig, &sigptr, vchSig.size()) == NULL)
+ {
+ /* As of OpenSSL 1.0.0p d2i_ECDSA_SIG frees and nulls the pointer on
+ * error. But OpenSSL's own use of this function redundantly frees the
+ * result. As ECDSA_SIG_free(NULL) is a no-op, and in the absence of a
+ * clear contract for the function behaving the same way is more
+ * conservative.
+ */
+ ECDSA_SIG_free(norm_sig);
+ return false;
+ }
+ int derlen = i2d_ECDSA_SIG(norm_sig, &norm_der);
+ ECDSA_SIG_free(norm_sig);
+ if (derlen <= 0)
+ return false;
+
+ // -1 = error, 0 = bad sig, 1 = good
+ bool ret = ECDSA_verify(0, (unsigned char*)&hash, sizeof(hash), norm_der, derlen, pkey) == 1;
+ OPENSSL_free(norm_der);
+ return ret;
}
bool CECKey::Recover(const uint256 &hash, const unsigned char *p64, int rec)
diff --git a/src/init.cpp b/src/init.cpp
index a09caeea40..c8f32d8bfd 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -43,7 +43,6 @@
#include <boost/thread.hpp>
#include <openssl/crypto.h>
-using namespace boost;
using namespace std;
#ifdef ENABLE_WALLET
@@ -112,7 +111,28 @@ bool ShutdownRequested()
return fRequestShutdown;
}
+class CCoinsViewErrorCatcher : public CCoinsViewBacked
+{
+public:
+ CCoinsViewErrorCatcher(CCoinsView* view) : CCoinsViewBacked(view) {}
+ bool GetCoins(const uint256 &txid, CCoins &coins) const {
+ try {
+ return CCoinsViewBacked::GetCoins(txid, coins);
+ } catch(const std::runtime_error& e) {
+ uiInterface.ThreadSafeMessageBox(_("Error reading from database, shutting down."), "", CClientUIInterface::MSG_ERROR);
+ LogPrintf("Error reading from database: %s\n", e.what());
+ // Starting the shutdown sequence and returning false to the caller would be
+ // interpreted as 'entry not found' (as opposed to unable to read data), and
+ // could lead to invalid interpration. Just exit immediately, as we can't
+ // continue anyway, and all writes should be atomic.
+ abort();
+ }
+ }
+ // Writes do not need similar protection, as failure to write is handled by the caller.
+};
+
static CCoinsViewDB *pcoinsdbview = NULL;
+static CCoinsViewErrorCatcher *pcoinscatcher = NULL;
void Shutdown()
{
@@ -155,6 +175,8 @@ void Shutdown()
}
delete pcoinsTip;
pcoinsTip = NULL;
+ delete pcoinscatcher;
+ pcoinscatcher = NULL;
delete pcoinsdbview;
pcoinsdbview = NULL;
delete pblocktree;
@@ -212,6 +234,26 @@ bool static Bind(const CService &addr, unsigned int flags) {
return true;
}
+void OnRPCStopped()
+{
+ cvBlockChange.notify_all();
+ LogPrint("rpc", "RPC stopped.\n");
+}
+
+void OnRPCPreCommand(const CRPCCommand& cmd)
+{
+#ifdef ENABLE_WALLET
+ if (cmd.reqWallet && !pwalletMain)
+ throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found (disabled)");
+#endif
+
+ // Observe safe mode
+ string strWarning = GetWarnings("rpc");
+ if (strWarning != "" && !GetBoolArg("-disablesafemode", false) &&
+ !cmd.okSafeMode)
+ throw JSONRPCError(RPC_FORBIDDEN_BY_SAFE_MODE, string("Safe mode: ") + strWarning);
+}
+
std::string HelpMessage(HelpMessageMode mode)
{
// When adding new options to the categories, please keep and ensure alphabetical ordering.
@@ -324,6 +366,7 @@ std::string HelpMessage(HelpMessageMode mode)
if (GetBoolArg("-help-debug", false))
{
strUsage += " -limitfreerelay=<n> " + strprintf(_("Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:%u)"), 15) + "\n";
+ strUsage += " -relaypriority " + strprintf(_("Require high priority for relaying free or low-fee transactions (default:%u)"), 1) + "\n";
strUsage += " -maxsigcachesize=<n> " + strprintf(_("Limit size of signature cache to <n> entries (default: %u)"), 50000) + "\n";
}
strUsage += " -minrelaytxfee=<amt> " + strprintf(_("Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)"), FormatMoney(::minRelayTxFee.GetFeePerK())) + "\n";
@@ -357,6 +400,7 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += " -rpcport=<port> " + strprintf(_("Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)"), 8332, 18332) + "\n";
strUsage += " -rpcallowip=<ip> " + _("Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times") + "\n";
strUsage += " -rpcthreads=<n> " + strprintf(_("Set the number of threads to service RPC calls (default: %d)"), 4) + "\n";
+ strUsage += " -rpckeepalive " + strprintf(_("RPC support for HTTP persistent connections (default: %d)"), 1) + "\n";
strUsage += "\n" + _("RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)") + "\n";
strUsage += " -rpcssl " + _("Use OpenSSL (https) for JSON-RPC connections") + "\n";
@@ -427,12 +471,12 @@ void ThreadImport(std::vector<boost::filesystem::path> vImportFiles)
}
// hardcoded $DATADIR/bootstrap.dat
- filesystem::path pathBootstrap = GetDataDir() / "bootstrap.dat";
- if (filesystem::exists(pathBootstrap)) {
+ boost::filesystem::path pathBootstrap = GetDataDir() / "bootstrap.dat";
+ if (boost::filesystem::exists(pathBootstrap)) {
FILE *file = fopen(pathBootstrap.string().c_str(), "rb");
if (file) {
CImportingNow imp;
- filesystem::path pathBootstrapOld = GetDataDir() / "bootstrap.dat.old";
+ boost::filesystem::path pathBootstrapOld = GetDataDir() / "bootstrap.dat.old";
LogPrintf("Importing bootstrap.dat...\n");
LoadExternalBlockFile(file);
RenameOver(pathBootstrap, pathBootstrapOld);
@@ -778,6 +822,8 @@ bool AppInit2(boost::thread_group& threadGroup)
if (fServer)
{
uiInterface.InitMessage.connect(SetRPCWarmupStatus);
+ RPCServer::OnStopped(&OnRPCStopped);
+ RPCServer::OnPreCommand(&OnRPCPreCommand);
StartRPCThreads();
}
@@ -816,7 +862,7 @@ bool AppInit2(boost::thread_group& threadGroup)
return false;
}
- if (filesystem::exists(GetDataDir() / strWalletFile))
+ if (boost::filesystem::exists(GetDataDir() / strWalletFile))
{
CDBEnv::VerifyResult r = bitdb.Verify(strWalletFile, CWalletDB::Recover);
if (r == CDBEnv::RECOVER_OK)
@@ -937,23 +983,23 @@ bool AppInit2(boost::thread_group& threadGroup)
fReindex = GetBoolArg("-reindex", false);
// Upgrading to 0.8; hard-link the old blknnnn.dat files into /blocks/
- filesystem::path blocksDir = GetDataDir() / "blocks";
- if (!filesystem::exists(blocksDir))
+ boost::filesystem::path blocksDir = GetDataDir() / "blocks";
+ if (!boost::filesystem::exists(blocksDir))
{
- filesystem::create_directories(blocksDir);
+ boost::filesystem::create_directories(blocksDir);
bool linked = false;
for (unsigned int i = 1; i < 10000; i++) {
- filesystem::path source = GetDataDir() / strprintf("blk%04u.dat", i);
- if (!filesystem::exists(source)) break;
- filesystem::path dest = blocksDir / strprintf("blk%05u.dat", i-1);
+ boost::filesystem::path source = GetDataDir() / strprintf("blk%04u.dat", i);
+ if (!boost::filesystem::exists(source)) break;
+ boost::filesystem::path dest = blocksDir / strprintf("blk%05u.dat", i-1);
try {
- filesystem::create_hard_link(source, dest);
+ boost::filesystem::create_hard_link(source, dest);
LogPrintf("Hardlinked %s -> %s\n", source.string(), dest.string());
linked = true;
- } catch (const filesystem::filesystem_error& e) {
+ } catch (const boost::filesystem::filesystem_error& e) {
// Note: hardlink creation failing is not a disaster, it just means
// blocks will get re-downloaded from peers.
- LogPrintf("Error hardlinking blk%04u.dat : %s\n", i, e.what());
+ LogPrintf("Error hardlinking blk%04u.dat: %s\n", i, e.what());
break;
}
}
@@ -990,11 +1036,13 @@ bool AppInit2(boost::thread_group& threadGroup)
UnloadBlockIndex();
delete pcoinsTip;
delete pcoinsdbview;
+ delete pcoinscatcher;
delete pblocktree;
pblocktree = new CBlockTreeDB(nBlockTreeDBCache, false, fReindex);
pcoinsdbview = new CCoinsViewDB(nCoinDBCache, false, fReindex);
- pcoinsTip = new CCoinsViewCache(pcoinsdbview);
+ pcoinscatcher = new CCoinsViewErrorCatcher(pcoinsdbview);
+ pcoinsTip = new CCoinsViewCache(pcoinscatcher);
if (fReindex)
pblocktree->WriteReindexing(true);
@@ -1185,6 +1233,8 @@ bool AppInit2(boost::thread_group& threadGroup)
// Restore wallet transaction metadata after -zapwallettxes=1
if (GetBoolArg("-zapwallettxes", false) && GetArg("-zapwallettxes", "1") != "2")
{
+ CWalletDB walletdb(strWalletFile);
+
BOOST_FOREACH(const CWalletTx& wtxOld, vWtx)
{
uint256 hash = wtxOld.GetHash();
@@ -1200,7 +1250,7 @@ bool AppInit2(boost::thread_group& threadGroup)
copyTo->fFromMe = copyFrom->fFromMe;
copyTo->strFromAccount = copyFrom->strFromAccount;
copyTo->nOrderPos = copyFrom->nOrderPos;
- copyTo->WriteToDisk();
+ copyTo->WriteToDisk(&walletdb);
}
}
}
@@ -1226,6 +1276,11 @@ bool AppInit2(boost::thread_group& threadGroup)
vImportFiles.push_back(strFile);
}
threadGroup.create_thread(boost::bind(&ThreadImport, vImportFiles));
+ if (chainActive.Tip() == NULL) {
+ LogPrintf("Waiting for genesis block to be imported...\n");
+ while (!fRequestShutdown && chainActive.Tip() == NULL)
+ MilliSleep(10);
+ }
// ********************************************************* Step 10: start node
diff --git a/src/key.cpp b/src/key.cpp
index 7f1cef1708..d8319db1a3 100644
--- a/src/key.cpp
+++ b/src/key.cpp
@@ -4,8 +4,8 @@
#include "key.h"
+#include "arith_uint256.h"
#include "crypto/hmac_sha512.h"
-#include "crypto/rfc6979_hmac_sha256.h"
#include "eccryptoverify.h"
#include "pubkey.h"
#include "random.h"
@@ -34,6 +34,7 @@ bool CKey::Check(const unsigned char *vch) {
}
void CKey::MakeNewKey(bool fCompressedIn) {
+ RandAddSeedPerfmon();
do {
GetRandBytes(vch, sizeof(vch));
} while (!Check(vch));
@@ -72,23 +73,28 @@ CPubKey CKey::GetPubKey() const {
return result;
}
+extern "C"
+{
+static int secp256k1_nonce_function_test_case(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, unsigned int attempt, const void *data)
+{
+ const uint32_t *test_case = static_cast<const uint32_t*>(data);
+ uint256 nonce;
+ secp256k1_nonce_function_rfc6979(nonce.begin(), msg32, key32, attempt, NULL);
+ nonce = ArithToUint256(UintToArith256(nonce) + *test_case);
+ memcpy(nonce32, nonce.begin(), 32);
+ return 1;
+}
+}
+
bool CKey::Sign(const uint256 &hash, std::vector<unsigned char>& vchSig, uint32_t test_case) const {
if (!fValid)
return false;
vchSig.resize(72);
- RFC6979_HMAC_SHA256 prng(begin(), 32, (unsigned char*)&hash, 32);
- do {
- uint256 nonce;
- prng.Generate((unsigned char*)&nonce, 32);
- nonce += test_case;
- int nSigLen = 72;
- int ret = secp256k1_ecdsa_sign((const unsigned char*)&hash, (unsigned char*)&vchSig[0], &nSigLen, begin(), (unsigned char*)&nonce);
- nonce = 0;
- if (ret) {
- vchSig.resize(nSigLen);
- return true;
- }
- } while(true);
+ int nSigLen = 72;
+ int ret = secp256k1_ecdsa_sign(hash.begin(), (unsigned char*)&vchSig[0], &nSigLen, begin(), test_case == 0 ? secp256k1_nonce_function_rfc6979 : secp256k1_nonce_function_test_case, test_case == 0 ? NULL : &test_case);
+ assert(ret);
+ vchSig.resize(nSigLen);
+ return true;
}
bool CKey::VerifyPubKey(const CPubKey& pubkey) const {
@@ -99,7 +105,7 @@ bool CKey::VerifyPubKey(const CPubKey& pubkey) const {
std::string str = "Bitcoin key verification\n";
GetRandBytes(rnd, sizeof(rnd));
uint256 hash;
- CHash256().Write((unsigned char*)str.data(), str.size()).Write(rnd, sizeof(rnd)).Finalize((unsigned char*)&hash);
+ CHash256().Write((unsigned char*)str.data(), str.size()).Write(rnd, sizeof(rnd)).Finalize(hash.begin());
std::vector<unsigned char> vchSig;
Sign(hash, vchSig);
return pubkey.Verify(hash, vchSig);
@@ -110,15 +116,8 @@ bool CKey::SignCompact(const uint256 &hash, std::vector<unsigned char>& vchSig)
return false;
vchSig.resize(65);
int rec = -1;
- RFC6979_HMAC_SHA256 prng(begin(), 32, (unsigned char*)&hash, 32);
- do {
- uint256 nonce;
- prng.Generate((unsigned char*)&nonce, 32);
- int ret = secp256k1_ecdsa_sign_compact((const unsigned char*)&hash, &vchSig[1], begin(), (unsigned char*)&nonce, &rec);
- nonce = 0;
- if (ret)
- break;
- } while(true);
+ int ret = secp256k1_ecdsa_sign_compact(hash.begin(), &vchSig[1], begin(), secp256k1_nonce_function_rfc6979, NULL, &rec);
+ assert(ret);
assert(rec != -1);
vchSig[0] = 27 + rec + (fCompressed ? 4 : 0);
return true;
diff --git a/src/keystore.cpp b/src/keystore.cpp
index 482125a39a..7531737e04 100644
--- a/src/keystore.cpp
+++ b/src/keystore.cpp
@@ -7,8 +7,6 @@
#include "crypter.h"
#include "key.h"
-#include "script/script.h"
-#include "script/standard.h"
#include "util.h"
#include <boost/foreach.hpp>
@@ -36,7 +34,7 @@ bool CBasicKeyStore::AddKeyPubKey(const CKey& key, const CPubKey &pubkey)
bool CBasicKeyStore::AddCScript(const CScript& redeemScript)
{
if (redeemScript.size() > MAX_SCRIPT_ELEMENT_SIZE)
- return error("CBasicKeyStore::AddCScript() : redeemScripts > %i bytes are invalid", MAX_SCRIPT_ELEMENT_SIZE);
+ return error("CBasicKeyStore::AddCScript(): redeemScripts > %i bytes are invalid", MAX_SCRIPT_ELEMENT_SIZE);
LOCK(cs_KeyStore);
mapScripts[CScriptID(redeemScript)] = redeemScript;
diff --git a/src/keystore.h b/src/keystore.h
index 6655264d72..4a4b6d20af 100644
--- a/src/keystore.h
+++ b/src/keystore.h
@@ -8,14 +8,13 @@
#include "key.h"
#include "pubkey.h"
+#include "script/script.h"
+#include "script/standard.h"
#include "sync.h"
#include <boost/signals2/signal.hpp>
#include <boost/variant.hpp>
-class CScript;
-class CScriptID;
-
/** A virtual base class for key stores */
class CKeyStore
{
diff --git a/src/main.cpp b/src/main.cpp
index 2410230ef4..fb2b2482e6 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -5,6 +5,7 @@
#include "main.h"
+#include "arith_uint256.h"
#include "addrman.h"
#include "alert.h"
#include "chainparams.h"
@@ -17,6 +18,7 @@
#include "txdb.h"
#include "txmempool.h"
#include "ui_interface.h"
+#include "undo.h"
#include "util.h"
#include "utilmoneystr.h"
@@ -27,7 +29,6 @@
#include <boost/filesystem/fstream.hpp>
#include <boost/thread.hpp>
-using namespace boost;
using namespace std;
#if defined(NDEBUG)
@@ -138,9 +139,14 @@ namespace {
uint256 hash;
CBlockIndex *pindex; //! Optional.
int64_t nTime; //! Time of "getdata" request in microseconds.
+ int nValidatedQueuedBefore; //! Number of blocks queued with validated headers (globally) at the time this one is requested.
+ bool fValidatedHeaders; //! Whether this block has validated headers at the time of request.
};
map<uint256, pair<NodeId, list<QueuedBlock>::iterator> > mapBlocksInFlight;
+ /** Number of blocks in flight with validated headers. */
+ int nQueuedValidatedHeaders = 0;
+
/** Number of preferable block download peers. */
int nPreferredDownload = 0;
@@ -260,7 +266,7 @@ struct CNodeState {
nMisbehavior = 0;
fShouldBan = false;
pindexBestKnownBlock = NULL;
- hashLastUnknownBlock = uint256(0);
+ hashLastUnknownBlock.SetNull();
pindexLastCommonBlock = NULL;
fSyncStarted = false;
nStallingSince = 0;
@@ -322,6 +328,7 @@ void MarkBlockAsReceived(const uint256& hash) {
map<uint256, pair<NodeId, list<QueuedBlock>::iterator> >::iterator itInFlight = mapBlocksInFlight.find(hash);
if (itInFlight != mapBlocksInFlight.end()) {
CNodeState *state = State(itInFlight->second.first);
+ nQueuedValidatedHeaders -= itInFlight->second.second->fValidatedHeaders;
state->vBlocksInFlight.erase(itInFlight->second.second);
state->nBlocksInFlight--;
state->nStallingSince = 0;
@@ -337,7 +344,8 @@ void MarkBlockAsInFlight(NodeId nodeid, const uint256& hash, CBlockIndex *pindex
// Make sure it's not listed somewhere already.
MarkBlockAsReceived(hash);
- QueuedBlock newentry = {hash, pindex, GetTimeMicros()};
+ QueuedBlock newentry = {hash, pindex, GetTimeMicros(), nQueuedValidatedHeaders, pindex != NULL};
+ nQueuedValidatedHeaders += newentry.fValidatedHeaders;
list<QueuedBlock>::iterator it = state->vBlocksInFlight.insert(state->vBlocksInFlight.end(), newentry);
state->nBlocksInFlight++;
mapBlocksInFlight[hash] = std::make_pair(nodeid, it);
@@ -348,12 +356,12 @@ void ProcessBlockAvailability(NodeId nodeid) {
CNodeState *state = State(nodeid);
assert(state != NULL);
- if (state->hashLastUnknownBlock != 0) {
+ if (!state->hashLastUnknownBlock.IsNull()) {
BlockMap::iterator itOld = mapBlockIndex.find(state->hashLastUnknownBlock);
if (itOld != mapBlockIndex.end() && itOld->second->nChainWork > 0) {
if (state->pindexBestKnownBlock == NULL || itOld->second->nChainWork >= state->pindexBestKnownBlock->nChainWork)
state->pindexBestKnownBlock = itOld->second;
- state->hashLastUnknownBlock = uint256(0);
+ state->hashLastUnknownBlock.SetNull();
}
}
}
@@ -624,34 +632,11 @@ unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans)
bool IsStandardTx(const CTransaction& tx, string& reason)
{
- AssertLockHeld(cs_main);
if (tx.nVersion > CTransaction::CURRENT_VERSION || tx.nVersion < 1) {
reason = "version";
return false;
}
- // Treat non-final transactions as non-standard to prevent a specific type
- // of double-spend attack, as well as DoS attacks. (if the transaction
- // can't be mined, the attacker isn't expending resources broadcasting it)
- // Basically we don't want to propagate transactions that can't be included in
- // the next block.
- //
- // However, IsFinalTx() is confusing... Without arguments, it uses
- // chainActive.Height() to evaluate nLockTime; when a block is accepted, chainActive.Height()
- // is set to the value of nHeight in the block. However, when IsFinalTx()
- // is called within CBlock::AcceptBlock(), the height of the block *being*
- // evaluated is what is used. Thus if we want to know if a transaction can
- // be part of the *next* block, we need to call IsFinalTx() with one more
- // than chainActive.Height().
- //
- // Timestamps on the other hand don't get any special treatment, because we
- // can't know what timestamp the next block will have, and there aren't
- // timestamp applications where it matters.
- if (!IsFinalTx(tx, chainActive.Height() + 1)) {
- reason = "non-final";
- return false;
- }
-
// Extremely large transactions with lots of inputs can cost the network
// almost as much to process as they cost the sender in fees, because
// computing signature hashes is O(ninputs*txsize). Limiting transactions
@@ -759,10 +744,10 @@ bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs)
// non-standard. Note that this EvalScript() call will
// be quick, because if there are any operations
// beside "push data" in the scriptSig
- // IsStandard() will have already returned false
+ // IsStandardTx() will have already returned false
// and this method isn't called.
vector<vector<unsigned char> > stack;
- if (!EvalScript(stack, tx.vin[i].scriptSig, false, BaseSignatureChecker()))
+ if (!EvalScript(stack, tx.vin[i].scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker()))
return false;
if (whichType == TX_SCRIPTHASH)
@@ -835,14 +820,14 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state)
{
// Basic checks that don't depend on any context
if (tx.vin.empty())
- return state.DoS(10, error("CheckTransaction() : vin empty"),
+ return state.DoS(10, error("CheckTransaction(): vin empty"),
REJECT_INVALID, "bad-txns-vin-empty");
if (tx.vout.empty())
- return state.DoS(10, error("CheckTransaction() : vout empty"),
+ return state.DoS(10, error("CheckTransaction(): vout empty"),
REJECT_INVALID, "bad-txns-vout-empty");
// Size limits
if (::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE)
- return state.DoS(100, error("CheckTransaction() : size limits failed"),
+ return state.DoS(100, error("CheckTransaction(): size limits failed"),
REJECT_INVALID, "bad-txns-oversize");
// Check for negative or overflow output values
@@ -850,14 +835,14 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state)
BOOST_FOREACH(const CTxOut& txout, tx.vout)
{
if (txout.nValue < 0)
- return state.DoS(100, error("CheckTransaction() : txout.nValue negative"),
+ return state.DoS(100, error("CheckTransaction(): txout.nValue negative"),
REJECT_INVALID, "bad-txns-vout-negative");
if (txout.nValue > MAX_MONEY)
- return state.DoS(100, error("CheckTransaction() : txout.nValue too high"),
+ return state.DoS(100, error("CheckTransaction(): txout.nValue too high"),
REJECT_INVALID, "bad-txns-vout-toolarge");
nValueOut += txout.nValue;
if (!MoneyRange(nValueOut))
- return state.DoS(100, error("CheckTransaction() : txout total out of range"),
+ return state.DoS(100, error("CheckTransaction(): txout total out of range"),
REJECT_INVALID, "bad-txns-txouttotal-toolarge");
}
@@ -866,7 +851,7 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state)
BOOST_FOREACH(const CTxIn& txin, tx.vin)
{
if (vInOutPoints.count(txin.prevout))
- return state.DoS(100, error("CheckTransaction() : duplicate inputs"),
+ return state.DoS(100, error("CheckTransaction(): duplicate inputs"),
REJECT_INVALID, "bad-txns-inputs-duplicate");
vInOutPoints.insert(txin.prevout);
}
@@ -874,14 +859,14 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state)
if (tx.IsCoinBase())
{
if (tx.vin[0].scriptSig.size() < 2 || tx.vin[0].scriptSig.size() > 100)
- return state.DoS(100, error("CheckTransaction() : coinbase script size"),
+ return state.DoS(100, error("CheckTransaction(): coinbase script size"),
REJECT_INVALID, "bad-cb-length");
}
else
{
BOOST_FOREACH(const CTxIn& txin, tx.vin)
if (txin.prevout.IsNull())
- return state.DoS(10, error("CheckTransaction() : prevout is null"),
+ return state.DoS(10, error("CheckTransaction(): prevout is null"),
REJECT_INVALID, "bad-txns-prevout-null");
}
@@ -919,27 +904,47 @@ CAmount GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowF
bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree,
- bool* pfMissingInputs, bool fRejectInsaneFee)
+ bool* pfMissingInputs, bool fRejectAbsurdFee)
{
AssertLockHeld(cs_main);
if (pfMissingInputs)
*pfMissingInputs = false;
if (!CheckTransaction(tx, state))
- return error("AcceptToMemoryPool: : CheckTransaction failed");
+ return error("AcceptToMemoryPool: CheckTransaction failed");
// Coinbase is only valid in a block, not as a loose transaction
if (tx.IsCoinBase())
- return state.DoS(100, error("AcceptToMemoryPool: : coinbase as individual tx"),
+ return state.DoS(100, error("AcceptToMemoryPool: coinbase as individual tx"),
REJECT_INVALID, "coinbase");
// Rather not work on nonstandard transactions (unless -testnet/-regtest)
string reason;
if (Params().RequireStandard() && !IsStandardTx(tx, reason))
return state.DoS(0,
- error("AcceptToMemoryPool : nonstandard transaction: %s", reason),
+ error("AcceptToMemoryPool: nonstandard transaction: %s", reason),
REJECT_NONSTANDARD, reason);
+ // Only accept nLockTime-using transactions that can be mined in the next
+ // block; we don't want our mempool filled up with transactions that can't
+ // be mined yet.
+ //
+ // However, IsFinalTx() is confusing... Without arguments, it uses
+ // chainActive.Height() to evaluate nLockTime; when a block is accepted,
+ // chainActive.Height() is set to the value of nHeight in the block.
+ // However, when IsFinalTx() is called within CBlock::AcceptBlock(), the
+ // height of the block *being* evaluated is what is used. Thus if we want
+ // to know if a transaction can be part of the *next* block, we need to
+ // call IsFinalTx() with one more than chainActive.Height().
+ //
+ // Timestamps on the other hand don't get any special treatment, because we
+ // can't know what timestamp the next block will have, and there aren't
+ // timestamp applications where it matters.
+ if (!IsFinalTx(tx, chainActive.Height() + 1))
+ return state.DoS(0,
+ error("AcceptToMemoryPool: non-final"),
+ REJECT_NONSTANDARD, "non-final");
+
// is it already in the memory pool?
uint256 hash = tx.GetHash();
if (pool.exists(hash))
@@ -986,7 +991,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
// are the actual inputs available?
if (!view.HaveInputs(tx))
- return state.Invalid(error("AcceptToMemoryPool : inputs already spent"),
+ return state.Invalid(error("AcceptToMemoryPool: inputs already spent"),
REJECT_DUPLICATE, "bad-txns-inputs-spent");
// Bring the best block into scope
@@ -1000,19 +1005,19 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
// Check for non-standard pay-to-script-hash in inputs
if (Params().RequireStandard() && !AreInputsStandard(tx, view))
- return error("AcceptToMemoryPool: : nonstandard transaction input");
+ return error("AcceptToMemoryPool: nonstandard transaction input");
// Check that the transaction doesn't have an excessive number of
// sigops, making it impossible to mine. Since the coinbase transaction
- // itself can contain sigops MAX_TX_SIGOPS is less than
+ // itself can contain sigops MAX_STANDARD_TX_SIGOPS is less than
// MAX_BLOCK_SIGOPS; we still consider this an invalid rather than
// merely non-standard transaction.
unsigned int nSigOps = GetLegacySigOpCount(tx);
nSigOps += GetP2SHSigOpCount(tx, view);
- if (nSigOps > MAX_TX_SIGOPS)
+ if (nSigOps > MAX_STANDARD_TX_SIGOPS)
return state.DoS(0,
- error("AcceptToMemoryPool : too many sigops %s, %d > %d",
- hash.ToString(), nSigOps, MAX_TX_SIGOPS),
+ error("AcceptToMemoryPool: too many sigops %s, %d > %d",
+ hash.ToString(), nSigOps, MAX_STANDARD_TX_SIGOPS),
REJECT_NONSTANDARD, "bad-txns-too-many-sigops");
CAmount nValueOut = tx.GetValueOut();
@@ -1025,10 +1030,15 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
// Don't accept it if it can't get into a block
CAmount txMinFee = GetMinRelayFee(tx, nSize, true);
if (fLimitFree && nFees < txMinFee)
- return state.DoS(0, error("AcceptToMemoryPool : not enough fees %s, %d < %d",
+ return state.DoS(0, error("AcceptToMemoryPool: not enough fees %s, %d < %d",
hash.ToString(), nFees, txMinFee),
REJECT_INSUFFICIENTFEE, "insufficient fee");
+ // Require that free transactions have sufficient priority to be mined in the next block.
+ if (GetBoolArg("-relaypriority", true) && nFees < ::minRelayTxFee.GetFee(nSize) && !AllowFree(view.GetPriority(tx, chainActive.Height() + 1))) {
+ return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "insufficient priority");
+ }
+
// Continuously rate-limit free (really, very-low-fee) transactions
// This mitigates 'penny-flooding' -- sending thousands of free transactions just to
// be annoying or make others' transactions take longer to confirm.
@@ -1047,14 +1057,14 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
// -limitfreerelay unit is thousand-bytes-per-minute
// At default rate it would take over a month to fill 1GB
if (dFreeCount >= GetArg("-limitfreerelay", 15)*10*1000)
- return state.DoS(0, error("AcceptToMemoryPool : free transaction rejected by rate limiter"),
- REJECT_INSUFFICIENTFEE, "insufficient priority");
+ return state.DoS(0, error("AcceptToMemoryPool: free transaction rejected by rate limiter"),
+ REJECT_INSUFFICIENTFEE, "rate limited free transaction");
LogPrint("mempool", "Rate limit dFreeCount: %g => %g\n", dFreeCount, dFreeCount+nSize);
dFreeCount += nSize;
}
- if (fRejectInsaneFee && nFees > ::minRelayTxFee.GetFee(nSize) * 10000)
- return error("AcceptToMemoryPool: insane fees %s, %d > %d",
+ if (fRejectAbsurdFee && nFees > ::minRelayTxFee.GetFee(nSize) * 10000)
+ return error("AcceptToMemoryPool: absurdly high fees %s, %d > %d",
hash.ToString(),
nFees, ::minRelayTxFee.GetFee(nSize) * 10000);
@@ -1076,7 +1086,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
// can be exploited as a DoS attack.
if (!CheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true))
{
- return error("AcceptToMemoryPool: : BUG! PLEASE REPORT THIS! ConnectInputs failed against MANDATORY but not STANDARD flags %s", hash.ToString());
+ return error("AcceptToMemoryPool: BUG! PLEASE REPORT THIS! ConnectInputs failed against MANDATORY but not STANDARD flags %s", hash.ToString());
}
// Store transaction in memory
@@ -1113,11 +1123,11 @@ bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock
fseek(file.Get(), postx.nTxOffset, SEEK_CUR);
file >> txOut;
} catch (const std::exception& e) {
- return error("%s : Deserialize or I/O error - %s", __func__, e.what());
+ return error("%s: Deserialize or I/O error - %s", __func__, e.what());
}
hashBlock = header.GetHash();
if (txOut.GetHash() != hash)
- return error("%s : txid mismatch", __func__);
+ return error("%s: txid mismatch", __func__);
return true;
}
}
@@ -1166,7 +1176,7 @@ bool WriteBlockToDisk(CBlock& block, CDiskBlockPos& pos)
// Open history file to append
CAutoFile fileout(OpenBlockFile(pos), SER_DISK, CLIENT_VERSION);
if (fileout.IsNull())
- return error("WriteBlockToDisk : OpenBlockFile failed");
+ return error("WriteBlockToDisk: OpenBlockFile failed");
// Write index header
unsigned int nSize = fileout.GetSerializeSize(block);
@@ -1175,7 +1185,7 @@ bool WriteBlockToDisk(CBlock& block, CDiskBlockPos& pos)
// Write block
long fileOutPos = ftell(fileout.Get());
if (fileOutPos < 0)
- return error("WriteBlockToDisk : ftell failed");
+ return error("WriteBlockToDisk: ftell failed");
pos.nPos = (unsigned int)fileOutPos;
fileout << block;
@@ -1189,19 +1199,19 @@ bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos)
// Open history file to read
CAutoFile filein(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION);
if (filein.IsNull())
- return error("ReadBlockFromDisk : OpenBlockFile failed");
+ return error("ReadBlockFromDisk: OpenBlockFile failed");
// Read block
try {
filein >> block;
}
catch (const std::exception& e) {
- return error("%s : Deserialize or I/O error - %s", __func__, e.what());
+ return error("%s: Deserialize or I/O error - %s", __func__, e.what());
}
// Check the header
if (!CheckProofOfWork(block.GetHash(), block.nBits))
- return error("ReadBlockFromDisk : Errors in block header");
+ return error("ReadBlockFromDisk: Errors in block header");
return true;
}
@@ -1211,7 +1221,7 @@ bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex)
if (!ReadBlockFromDisk(block, pindex->GetBlockPos()))
return false;
if (block.GetHash() != pindex->GetBlockHash())
- return error("ReadBlockFromDisk(CBlock&, CBlockIndex*) : GetHash() doesn't match index");
+ return error("ReadBlockFromDisk(CBlock&, CBlockIndex*): GetHash() doesn't match index");
return true;
}
@@ -1383,9 +1393,20 @@ void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCach
if (!tx.IsCoinBase()) {
txundo.vprevout.reserve(tx.vin.size());
BOOST_FOREACH(const CTxIn &txin, tx.vin) {
- txundo.vprevout.push_back(CTxInUndo());
- bool ret = inputs.ModifyCoins(txin.prevout.hash)->Spend(txin.prevout, txundo.vprevout.back());
- assert(ret);
+ CCoinsModifier coins = inputs.ModifyCoins(txin.prevout.hash);
+ unsigned nPos = txin.prevout.n;
+
+ if (nPos >= coins->vout.size() || coins->vout[nPos].IsNull())
+ assert(false);
+ // mark an outpoint spent, and construct undo information
+ txundo.vprevout.push_back(CTxInUndo(coins->vout[nPos]));
+ coins->Spend(nPos);
+ if (coins->vout.size() == 0) {
+ CTxInUndo& undo = txundo.vprevout.back();
+ undo.nHeight = coins->nHeight;
+ undo.fCoinBase = coins->fCoinBase;
+ undo.nVersion = coins->nVersion;
+ }
}
}
@@ -1393,10 +1414,16 @@ void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCach
inputs.ModifyCoins(tx.GetHash())->FromTx(tx, nHeight);
}
+void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCache &inputs, int nHeight)
+{
+ CTxUndo txundo;
+ UpdateCoins(tx, state, inputs, txundo, nHeight);
+}
+
bool CScriptCheck::operator()() {
const CScript &scriptSig = ptxTo->vin[nIn].scriptSig;
- if (!VerifyScript(scriptSig, scriptPubKey, nFlags, CachingSignatureChecker(*ptxTo, nIn, cacheStore), &error)) {
- return ::error("CScriptCheck() : %s:%d VerifySignature failed: %s", ptxTo->GetHash().ToString(), nIn, ScriptErrorString(error));
+ if (!VerifyScript(scriptSig, scriptPubKey, nFlags, CachingTransactionSignatureChecker(ptxTo, nIn, cacheStore), &error)) {
+ return ::error("CScriptCheck(): %s:%d VerifySignature failed: %s", ptxTo->GetHash().ToString(), nIn, ScriptErrorString(error));
}
return true;
}
@@ -1411,7 +1438,7 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi
// This doesn't trigger the DoS code on purpose; if it did, it would make it easier
// for an attacker to attempt to split the network.
if (!inputs.HaveInputs(tx))
- return state.Invalid(error("CheckInputs() : %s inputs unavailable", tx.GetHash().ToString()));
+ return state.Invalid(error("CheckInputs(): %s inputs unavailable", tx.GetHash().ToString()));
// While checking, GetBestBlock() refers to the parent block.
// This is also true for mempool checks.
@@ -1429,31 +1456,31 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi
if (coins->IsCoinBase()) {
if (nSpendHeight - coins->nHeight < COINBASE_MATURITY)
return state.Invalid(
- error("CheckInputs() : tried to spend coinbase at depth %d", nSpendHeight - coins->nHeight),
+ error("CheckInputs(): tried to spend coinbase at depth %d", nSpendHeight - coins->nHeight),
REJECT_INVALID, "bad-txns-premature-spend-of-coinbase");
}
// Check for negative or overflow input values
nValueIn += coins->vout[prevout.n].nValue;
if (!MoneyRange(coins->vout[prevout.n].nValue) || !MoneyRange(nValueIn))
- return state.DoS(100, error("CheckInputs() : txin values out of range"),
+ return state.DoS(100, error("CheckInputs(): txin values out of range"),
REJECT_INVALID, "bad-txns-inputvalues-outofrange");
}
if (nValueIn < tx.GetValueOut())
- return state.DoS(100, error("CheckInputs() : %s value in (%s) < value out (%s)",
+ return state.DoS(100, error("CheckInputs(): %s value in (%s) < value out (%s)",
tx.GetHash().ToString(), FormatMoney(nValueIn), FormatMoney(tx.GetValueOut())),
REJECT_INVALID, "bad-txns-in-belowout");
// Tally transaction fees
CAmount nTxFee = nValueIn - tx.GetValueOut();
if (nTxFee < 0)
- return state.DoS(100, error("CheckInputs() : %s nTxFee < 0", tx.GetHash().ToString()),
+ return state.DoS(100, error("CheckInputs(): %s nTxFee < 0", tx.GetHash().ToString()),
REJECT_INVALID, "bad-txns-fee-negative");
nFees += nTxFee;
if (!MoneyRange(nFees))
- return state.DoS(100, error("CheckInputs() : nFees out of range"),
+ return state.DoS(100, error("CheckInputs(): nFees out of range"),
REJECT_INVALID, "bad-txns-fee-outofrange");
// The first loop above does all the inexpensive checks.
@@ -1503,7 +1530,96 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi
return true;
}
+namespace {
+
+bool UndoWriteToDisk(const CBlockUndo& blockundo, CDiskBlockPos& pos, const uint256& hashBlock)
+{
+ // Open history file to append
+ CAutoFile fileout(OpenUndoFile(pos), SER_DISK, CLIENT_VERSION);
+ if (fileout.IsNull())
+ return error("%s: OpenUndoFile failed", __func__);
+
+ // Write index header
+ unsigned int nSize = fileout.GetSerializeSize(blockundo);
+ fileout << FLATDATA(Params().MessageStart()) << nSize;
+
+ // Write undo data
+ long fileOutPos = ftell(fileout.Get());
+ if (fileOutPos < 0)
+ return error("%s: ftell failed", __func__);
+ pos.nPos = (unsigned int)fileOutPos;
+ fileout << blockundo;
+
+ // calculate & write checksum
+ CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION);
+ hasher << hashBlock;
+ hasher << blockundo;
+ fileout << hasher.GetHash();
+
+ return true;
+}
+
+bool UndoReadFromDisk(CBlockUndo& blockundo, const CDiskBlockPos& pos, const uint256& hashBlock)
+{
+ // Open history file to read
+ CAutoFile filein(OpenUndoFile(pos, true), SER_DISK, CLIENT_VERSION);
+ if (filein.IsNull())
+ return error("%s: OpenBlockFile failed", __func__);
+
+ // Read block
+ uint256 hashChecksum;
+ try {
+ filein >> blockundo;
+ filein >> hashChecksum;
+ }
+ catch (const std::exception& e) {
+ return error("%s: Deserialize or I/O error - %s", __func__, e.what());
+ }
+
+ // Verify checksum
+ CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION);
+ hasher << hashBlock;
+ hasher << blockundo;
+ if (hashChecksum != hasher.GetHash())
+ return error("%s: Checksum mismatch", __func__);
+
+ return true;
+}
+
+} // anon namespace
+
+/**
+ * Apply the undo operation of a CTxInUndo to the given chain state.
+ * @param undo The undo object.
+ * @param view The coins view to which to apply the changes.
+ * @param out The out point that corresponds to the tx input.
+ * @return True on success.
+ */
+static bool ApplyTxInUndo(const CTxInUndo& undo, CCoinsViewCache& view, const COutPoint& out)
+{
+ bool fClean = true;
+
+ CCoinsModifier coins = view.ModifyCoins(out.hash);
+ if (undo.nHeight != 0) {
+ // undo data contains height: this is the last output of the prevout tx being spent
+ if (!coins->IsPruned())
+ fClean = fClean && error("%s: undo data overwriting existing transaction", __func__);
+ coins->Clear();
+ coins->fCoinBase = undo.fCoinBase;
+ coins->nHeight = undo.nHeight;
+ coins->nVersion = undo.nVersion;
+ } else {
+ if (coins->IsPruned())
+ fClean = fClean && error("%s: undo data adding output to missing transaction", __func__);
+ }
+ if (coins->IsAvailable(out.n))
+ fClean = fClean && error("%s: undo data overwriting existing output", __func__);
+ if (coins->vout.size() < out.n+1)
+ coins->vout.resize(out.n+1);
+ coins->vout[out.n] = undo.txout;
+ return fClean;
+}
bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool* pfClean)
{
@@ -1517,12 +1633,12 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex
CBlockUndo blockUndo;
CDiskBlockPos pos = pindex->GetUndoPos();
if (pos.IsNull())
- return error("DisconnectBlock() : no undo data available");
- if (!blockUndo.ReadFromDisk(pos, pindex->pprev->GetBlockHash()))
- return error("DisconnectBlock() : failure reading undo data");
+ return error("DisconnectBlock(): no undo data available");
+ if (!UndoReadFromDisk(blockUndo, pos, pindex->pprev->GetBlockHash()))
+ return error("DisconnectBlock(): failure reading undo data");
if (blockUndo.vtxundo.size() + 1 != block.vtx.size())
- return error("DisconnectBlock() : block and undo data inconsistent");
+ return error("DisconnectBlock(): block and undo data inconsistent");
// undo transactions in reverse order
for (int i = block.vtx.size() - 1; i >= 0; i--) {
@@ -1530,11 +1646,8 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex
uint256 hash = tx.GetHash();
// Check that all outputs are available and match the outputs in the block itself
- // exactly. Note that transactions with only provably unspendable outputs won't
- // have outputs available even in the block itself, so we handle that case
- // specially with outsEmpty.
+ // exactly.
{
- CCoins outsEmpty;
CCoinsModifier outs = view.ModifyCoins(hash);
outs->ClearUnspendable();
@@ -1545,7 +1658,7 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex
if (outsBlock.nVersion < 0)
outs->nVersion = outsBlock.nVersion;
if (*outs != outsBlock)
- fClean = fClean && error("DisconnectBlock() : added transaction mismatch? database corrupted");
+ fClean = fClean && error("DisconnectBlock(): added transaction mismatch? database corrupted");
// remove outputs
outs->Clear();
@@ -1555,28 +1668,12 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex
if (i > 0) { // not coinbases
const CTxUndo &txundo = blockUndo.vtxundo[i-1];
if (txundo.vprevout.size() != tx.vin.size())
- return error("DisconnectBlock() : transaction and undo data inconsistent");
+ return error("DisconnectBlock(): transaction and undo data inconsistent");
for (unsigned int j = tx.vin.size(); j-- > 0;) {
const COutPoint &out = tx.vin[j].prevout;
const CTxInUndo &undo = txundo.vprevout[j];
- CCoinsModifier coins = view.ModifyCoins(out.hash);
- if (undo.nHeight != 0) {
- // undo data contains height: this is the last output of the prevout tx being spent
- if (!coins->IsPruned())
- fClean = fClean && error("DisconnectBlock() : undo data overwriting existing transaction");
- coins->Clear();
- coins->fCoinBase = undo.fCoinBase;
- coins->nHeight = undo.nHeight;
- coins->nVersion = undo.nVersion;
- } else {
- if (coins->IsPruned())
- fClean = fClean && error("DisconnectBlock() : undo data adding output to missing transaction");
- }
- if (coins->IsAvailable(out.n))
- fClean = fClean && error("DisconnectBlock() : undo data overwriting existing output");
- if (coins->vout.size() < out.n+1)
- coins->vout.resize(out.n+1);
- coins->vout[out.n] = undo.txout;
+ if (!ApplyTxInUndo(undo, view, out))
+ fClean = false;
}
}
}
@@ -1587,9 +1684,9 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex
if (pfClean) {
*pfClean = fClean;
return true;
- } else {
- return fClean;
}
+
+ return fClean;
}
void static FlushBlockFile(bool fFinalize = false)
@@ -1638,13 +1735,14 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
return false;
// verify that the view's current state corresponds to the previous block
- uint256 hashPrevBlock = pindex->pprev == NULL ? uint256(0) : pindex->pprev->GetBlockHash();
+ uint256 hashPrevBlock = pindex->pprev == NULL ? uint256() : pindex->pprev->GetBlockHash();
assert(hashPrevBlock == view.GetBestBlock());
// Special case for the genesis block, skipping connection of its transactions
// (its coinbase is unspendable)
if (block.GetHash() == Params().HashGenesisBlock()) {
- view.SetBestBlock(pindex->GetBlockHash());
+ if (!fJustCheck)
+ view.SetBestBlock(pindex->GetBlockHash());
return true;
}
@@ -1663,13 +1761,13 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
// two in the chain that violate it. This prevents exploiting the issue against nodes in their
// initial block download.
bool fEnforceBIP30 = (!pindex->phashBlock) || // Enforce on CreateNewBlock invocations which don't have a hash.
- !((pindex->nHeight==91842 && pindex->GetBlockHash() == uint256("0x00000000000a4d0a398161ffc163c503763b1f4360639393e0e4c8e300e0caec")) ||
- (pindex->nHeight==91880 && pindex->GetBlockHash() == uint256("0x00000000000743f190a18c5577a3c2d2a1f610ae9601ac046a38084ccb7cd721")));
+ !((pindex->nHeight==91842 && pindex->GetBlockHash() == uint256S("0x00000000000a4d0a398161ffc163c503763b1f4360639393e0e4c8e300e0caec")) ||
+ (pindex->nHeight==91880 && pindex->GetBlockHash() == uint256S("0x00000000000743f190a18c5577a3c2d2a1f610ae9601ac046a38084ccb7cd721")));
if (fEnforceBIP30) {
BOOST_FOREACH(const CTransaction& tx, block.vtx) {
const CCoins* coins = view.AccessCoins(tx.GetHash());
if (coins && !coins->IsPruned())
- return state.DoS(100, error("ConnectBlock() : tried to overwrite transaction"),
+ return state.DoS(100, error("ConnectBlock(): tried to overwrite transaction"),
REJECT_INVALID, "bad-txns-BIP30");
}
}
@@ -1680,6 +1778,11 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
unsigned int flags = fStrictPayToScriptHash ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE;
+ // Start enforcing the DERSIG (BIP66) rules, for block.nVersion=3 blocks, when 75% of the network has upgraded:
+ if (block.nVersion >= 3 && IsSuperMajority(3, pindex->pprev, Params().EnforceBlockUpgradeMajority())) {
+ flags |= SCRIPT_VERIFY_DERSIG;
+ }
+
CBlockUndo blockundo;
CCheckQueueControl<CScriptCheck> control(fScriptChecks && nScriptCheckThreads ? &scriptcheckqueue : NULL);
@@ -1699,13 +1802,13 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
nInputs += tx.vin.size();
nSigOps += GetLegacySigOpCount(tx);
if (nSigOps > MAX_BLOCK_SIGOPS)
- return state.DoS(100, error("ConnectBlock() : too many sigops"),
+ return state.DoS(100, error("ConnectBlock(): too many sigops"),
REJECT_INVALID, "bad-blk-sigops");
if (!tx.IsCoinBase())
{
if (!view.HaveInputs(tx))
- return state.DoS(100, error("ConnectBlock() : inputs missing/spent"),
+ return state.DoS(100, error("ConnectBlock(): inputs missing/spent"),
REJECT_INVALID, "bad-txns-inputs-missingorspent");
if (fStrictPayToScriptHash)
@@ -1715,7 +1818,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
// an incredibly-expensive-to-validate block.
nSigOps += GetP2SHSigOpCount(tx, view);
if (nSigOps > MAX_BLOCK_SIGOPS)
- return state.DoS(100, error("ConnectBlock() : too many sigops"),
+ return state.DoS(100, error("ConnectBlock(): too many sigops"),
REJECT_INVALID, "bad-blk-sigops");
}
@@ -1741,7 +1844,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
if (block.vtx[0].GetValueOut() > GetBlockValue(pindex->nHeight, nFees))
return state.DoS(100,
- error("ConnectBlock() : coinbase pays too much (actual=%d vs limit=%d)",
+ error("ConnectBlock(): coinbase pays too much (actual=%d vs limit=%d)",
block.vtx[0].GetValueOut(), GetBlockValue(pindex->nHeight, nFees)),
REJECT_INVALID, "bad-cb-amount");
@@ -1759,8 +1862,8 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
if (pindex->GetUndoPos().IsNull()) {
CDiskBlockPos pos;
if (!FindUndoPos(state, pindex->nFile, pos, ::GetSerializeSize(blockundo, SER_DISK, CLIENT_VERSION) + 40))
- return error("ConnectBlock() : FindUndoPos failed");
- if (!blockundo.WriteToDisk(pos, pindex->pprev->GetBlockHash()))
+ return error("ConnectBlock(): FindUndoPos failed");
+ if (!UndoWriteToDisk(blockundo, pos, pindex->pprev->GetBlockHash()))
return state.Abort("Failed to write undo data");
// update nUndoPos in block index
@@ -1807,6 +1910,7 @@ enum FlushStateMode {
bool static FlushStateToDisk(CValidationState &state, FlushStateMode mode) {
LOCK(cs_main);
static int64_t nLastWrite = 0;
+ try {
if ((mode == FLUSH_STATE_ALWAYS) ||
((mode == FLUSH_STATE_PERIODIC || mode == FLUSH_STATE_IF_NEEDED) && pcoinsTip->GetCacheSize() > nCoinCacheSize) ||
(mode == FLUSH_STATE_PERIODIC && GetTimeMicros() > nLastWrite + DATABASE_WRITE_INTERVAL * 1000000)) {
@@ -1846,6 +1950,9 @@ bool static FlushStateToDisk(CValidationState &state, FlushStateMode mode) {
}
nLastWrite = GetTimeMicros();
}
+ } catch (const std::runtime_error& e) {
+ return state.Abort(std::string("System error while flushing: ") + e.what());
+ }
return true;
}
@@ -1907,7 +2014,7 @@ bool static DisconnectTip(CValidationState &state) {
{
CCoinsViewCache view(pcoinsTip);
if (!DisconnectBlock(block, state, pindexDelete, view))
- return error("DisconnectTip() : DisconnectBlock %s failed", pindexDelete->GetBlockHash().ToString());
+ return error("DisconnectTip(): DisconnectBlock %s failed", pindexDelete->GetBlockHash().ToString());
assert(view.Flush());
}
LogPrint("bench", "- Disconnect block: %.2fms\n", (GetTimeMicros() - nStart) * 0.001);
@@ -1967,7 +2074,7 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock *
if (!rv) {
if (state.IsInvalid())
InvalidBlockFound(pindexNew, state);
- return error("ConnectTip() : ConnectBlock %s failed", pindexNew->GetBlockHash().ToString());
+ return error("ConnectTip(): ConnectBlock %s failed", pindexNew->GetBlockHash().ToString());
}
mapBlockSource.erase(inv.hash);
nTime3 = GetTimeMicros(); nTimeConnectTotal += nTime3 - nTime2;
@@ -2404,12 +2511,12 @@ bool CheckBlockHeader(const CBlockHeader& block, CValidationState& state, bool f
{
// Check proof of work matches claimed amount
if (fCheckPOW && !CheckProofOfWork(block.GetHash(), block.nBits))
- return state.DoS(50, error("CheckBlockHeader() : proof of work failed"),
+ return state.DoS(50, error("CheckBlockHeader(): proof of work failed"),
REJECT_INVALID, "high-hash");
// Check timestamp
if (block.GetBlockTime() > GetAdjustedTime() + 2 * 60 * 60)
- return state.Invalid(error("CheckBlockHeader() : block timestamp too far in the future"),
+ return state.Invalid(error("CheckBlockHeader(): block timestamp too far in the future"),
REJECT_INVALID, "time-too-new");
return true;
@@ -2429,14 +2536,14 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo
bool mutated;
uint256 hashMerkleRoot2 = block.BuildMerkleTree(&mutated);
if (block.hashMerkleRoot != hashMerkleRoot2)
- return state.DoS(100, error("CheckBlock() : hashMerkleRoot mismatch"),
+ return state.DoS(100, error("CheckBlock(): hashMerkleRoot mismatch"),
REJECT_INVALID, "bad-txnmrklroot", true);
// Check for merkle tree malleability (CVE-2012-2459): repeating sequences
// of transactions in a block without affecting the merkle root of a block,
// while still invalidating it.
if (mutated)
- return state.DoS(100, error("CheckBlock() : duplicate transaction"),
+ return state.DoS(100, error("CheckBlock(): duplicate transaction"),
REJECT_INVALID, "bad-txns-duplicate", true);
}
@@ -2446,22 +2553,22 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo
// Size limits
if (block.vtx.empty() || block.vtx.size() > MAX_BLOCK_SIZE || ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE)
- return state.DoS(100, error("CheckBlock() : size limits failed"),
+ return state.DoS(100, error("CheckBlock(): size limits failed"),
REJECT_INVALID, "bad-blk-length");
// First transaction must be coinbase, the rest must not be
if (block.vtx.empty() || !block.vtx[0].IsCoinBase())
- return state.DoS(100, error("CheckBlock() : first tx is not coinbase"),
+ return state.DoS(100, error("CheckBlock(): first tx is not coinbase"),
REJECT_INVALID, "bad-cb-missing");
for (unsigned int i = 1; i < block.vtx.size(); i++)
if (block.vtx[i].IsCoinBase())
- return state.DoS(100, error("CheckBlock() : more than one coinbase"),
+ return state.DoS(100, error("CheckBlock(): more than one coinbase"),
REJECT_INVALID, "bad-cb-multiple");
// Check transactions
BOOST_FOREACH(const CTransaction& tx, block.vtx)
if (!CheckTransaction(tx, state))
- return error("CheckBlock() : CheckTransaction failed");
+ return error("CheckBlock(): CheckTransaction failed");
unsigned int nSigOps = 0;
BOOST_FOREACH(const CTransaction& tx, block.vtx)
@@ -2469,7 +2576,7 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo
nSigOps += GetLegacySigOpCount(tx);
}
if (nSigOps > MAX_BLOCK_SIGOPS)
- return state.DoS(100, error("CheckBlock() : out-of-bounds SigOpCount"),
+ return state.DoS(100, error("CheckBlock(): out-of-bounds SigOpCount"),
REJECT_INVALID, "bad-blk-sigops", true);
return true;
@@ -2488,28 +2595,35 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta
// Check proof of work
if ((!Params().SkipProofOfWorkCheck()) &&
(block.nBits != GetNextWorkRequired(pindexPrev, &block)))
- return state.DoS(100, error("%s : incorrect proof of work", __func__),
+ return state.DoS(100, error("%s: incorrect proof of work", __func__),
REJECT_INVALID, "bad-diffbits");
// Check timestamp against prev
if (block.GetBlockTime() <= pindexPrev->GetMedianTimePast())
- return state.Invalid(error("%s : block's timestamp is too early", __func__),
+ return state.Invalid(error("%s: block's timestamp is too early", __func__),
REJECT_INVALID, "time-too-old");
// Check that the block chain matches the known block chain up to a checkpoint
if (!Checkpoints::CheckBlock(nHeight, hash))
- return state.DoS(100, error("%s : rejected by checkpoint lock-in at %d", __func__, nHeight),
+ return state.DoS(100, error("%s: rejected by checkpoint lock-in at %d", __func__, nHeight),
REJECT_CHECKPOINT, "checkpoint mismatch");
// Don't accept any forks from the main chain prior to last checkpoint
CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint();
if (pcheckpoint && nHeight < pcheckpoint->nHeight)
- return state.DoS(100, error("%s : forked chain older than last checkpoint (height %d)", __func__, nHeight));
+ return state.DoS(100, error("%s: forked chain older than last checkpoint (height %d)", __func__, nHeight));
// Reject block.nVersion=1 blocks when 95% (75% on testnet) of the network has upgraded:
if (block.nVersion < 2 && IsSuperMajority(2, pindexPrev, Params().RejectBlockOutdatedMajority()))
{
- return state.Invalid(error("%s : rejected nVersion=1 block", __func__),
+ return state.Invalid(error("%s: rejected nVersion=1 block", __func__),
+ REJECT_OBSOLETE, "bad-version");
+ }
+
+ // Reject block.nVersion=2 blocks when 95% (75% on testnet) of the network has upgraded:
+ if (block.nVersion < 3 && IsSuperMajority(3, pindexPrev, Params().RejectBlockOutdatedMajority()))
+ {
+ return state.Invalid(error("%s : rejected nVersion=2 block", __func__),
REJECT_OBSOLETE, "bad-version");
}
@@ -2523,7 +2637,7 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIn
// Check that all transactions are finalized
BOOST_FOREACH(const CTransaction& tx, block.vtx)
if (!IsFinalTx(tx, nHeight, block.GetBlockTime())) {
- return state.DoS(10, error("%s : contains a non-final transaction", __func__), REJECT_INVALID, "bad-txns-nonfinal");
+ return state.DoS(10, error("%s: contains a non-final transaction", __func__), REJECT_INVALID, "bad-txns-nonfinal");
}
// Enforce block.nVersion=2 rule that the coinbase starts with serialized block height
@@ -2533,7 +2647,7 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIn
CScript expect = CScript() << nHeight;
if (block.vtx[0].vin[0].scriptSig.size() < expect.size() ||
!std::equal(expect.begin(), expect.end(), block.vtx[0].vin[0].scriptSig.begin())) {
- return state.DoS(100, error("%s : block height mismatch in coinbase", __func__), REJECT_INVALID, "bad-cb-height");
+ return state.DoS(100, error("%s: block height mismatch in coinbase", __func__), REJECT_INVALID, "bad-cb-height");
}
}
@@ -2553,7 +2667,7 @@ bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBloc
if (ppindex)
*ppindex = pindex;
if (pindex->nStatus & BLOCK_FAILED_MASK)
- return state.Invalid(error("%s : block is marked invalid", __func__), 0, "duplicate");
+ return state.Invalid(error("%s: block is marked invalid", __func__), 0, "duplicate");
return true;
}
@@ -2565,10 +2679,10 @@ bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBloc
if (hash != Params().HashGenesisBlock()) {
BlockMap::iterator mi = mapBlockIndex.find(block.hashPrevBlock);
if (mi == mapBlockIndex.end())
- return state.DoS(10, error("%s : prev block not found", __func__), 0, "bad-prevblk");
+ return state.DoS(10, error("%s: prev block not found", __func__), 0, "bad-prevblk");
pindexPrev = (*mi).second;
if (pindexPrev->nStatus & BLOCK_FAILED_MASK)
- return state.DoS(100, error("%s : prev block invalid", __func__), REJECT_INVALID, "bad-prevblk");
+ return state.DoS(100, error("%s: prev block invalid", __func__), REJECT_INVALID, "bad-prevblk");
}
if (!ContextualCheckBlockHeader(block, state, pindexPrev))
@@ -2594,7 +2708,7 @@ bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex** ppindex,
if (pindex->nStatus & BLOCK_HAVE_DATA) {
// TODO: deal better with duplicate blocks.
- // return state.DoS(20, error("AcceptBlock() : already have block %d %s", pindex->nHeight, pindex->GetBlockHash().ToString()), REJECT_DUPLICATE, "duplicate");
+ // return state.DoS(20, error("AcceptBlock(): already have block %d %s", pindex->nHeight, pindex->GetBlockHash().ToString()), REJECT_DUPLICATE, "duplicate");
return true;
}
@@ -2615,12 +2729,12 @@ bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex** ppindex,
if (dbp != NULL)
blockPos = *dbp;
if (!FindBlockPos(state, blockPos, nBlockSize+8, nHeight, block.GetBlockTime(), dbp != NULL))
- return error("AcceptBlock() : FindBlockPos failed");
+ return error("AcceptBlock(): FindBlockPos failed");
if (dbp == NULL)
if (!WriteBlockToDisk(block, blockPos))
return state.Abort("Failed to write block");
if (!ReceivedBlockTransactions(block, state, pindex, blockPos))
- return error("AcceptBlock() : ReceivedBlockTransactions failed");
+ return error("AcceptBlock(): ReceivedBlockTransactions failed");
} catch (const std::runtime_error& e) {
return state.Abort(std::string("System error: ") + e.what());
}
@@ -2651,7 +2765,7 @@ bool ProcessNewBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDis
LOCK(cs_main);
MarkBlockAsReceived(pblock->GetHash());
if (!checked) {
- return error("%s : CheckBlock FAILED", __func__);
+ return error("%s: CheckBlock FAILED", __func__);
}
// Store to disk
@@ -2661,11 +2775,11 @@ bool ProcessNewBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDis
mapBlockSource[pindex->GetBlockHash()] = pfrom->GetId();
}
if (!ret)
- return error("%s : AcceptBlock FAILED", __func__);
+ return error("%s: AcceptBlock FAILED", __func__);
}
if (!ActivateBestChain(state, pblock))
- return error("%s : ActivateBestChain failed", __func__);
+ return error("%s: ActivateBestChain failed", __func__);
return true;
}
@@ -2713,7 +2827,7 @@ bool AbortNode(const std::string &strMessage, const std::string &userMessage) {
bool CheckDiskSpace(uint64_t nAdditionalBytes)
{
- uint64_t nFreeBytesAvailable = filesystem::space(GetDataDir()).available;
+ uint64_t nFreeBytesAvailable = boost::filesystem::space(GetDataDir()).available;
// Check for nMinDiskSpace bytes (currently 50MB)
if (nFreeBytesAvailable < nMinDiskSpace + nAdditionalBytes)
@@ -2760,7 +2874,7 @@ boost::filesystem::path GetBlockPosFilename(const CDiskBlockPos &pos, const char
CBlockIndex * InsertBlockIndex(uint256 hash)
{
- if (hash == 0)
+ if (hash.IsNull())
return NULL;
// Return existing
@@ -2771,7 +2885,7 @@ CBlockIndex * InsertBlockIndex(uint256 hash)
// Create new
CBlockIndex* pindexNew = new CBlockIndex();
if (!pindexNew)
- throw runtime_error("LoadBlockIndex() : new CBlockIndex failed");
+ throw runtime_error("LoadBlockIndex(): new CBlockIndex failed");
mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first;
pindexNew->phashBlock = &((*mi).first);
@@ -2917,24 +3031,24 @@ bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth
CBlock block;
// check level 0: read from disk
if (!ReadBlockFromDisk(block, pindex))
- return error("VerifyDB() : *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
+ return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
// check level 1: verify block validity
if (nCheckLevel >= 1 && !CheckBlock(block, state))
- return error("VerifyDB() : *** found bad block at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
+ return error("VerifyDB(): *** found bad block at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
// check level 2: verify undo validity
if (nCheckLevel >= 2 && pindex) {
CBlockUndo undo;
CDiskBlockPos pos = pindex->GetUndoPos();
if (!pos.IsNull()) {
- if (!undo.ReadFromDisk(pos, pindex->pprev->GetBlockHash()))
- return error("VerifyDB() : *** found bad undo data at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
+ if (!UndoReadFromDisk(undo, pos, pindex->pprev->GetBlockHash()))
+ return error("VerifyDB(): *** found bad undo data at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
}
}
// check level 3: check for inconsistencies during memory-only disconnect of tip blocks
if (nCheckLevel >= 3 && pindex == pindexState && (coins.GetCacheSize() + pcoinsTip->GetCacheSize()) <= nCoinCacheSize) {
bool fClean = true;
if (!DisconnectBlock(block, state, pindex, coins, &fClean))
- return error("VerifyDB() : *** irrecoverable inconsistency in block data at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
+ return error("VerifyDB(): *** irrecoverable inconsistency in block data at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
pindexState = pindex->pprev;
if (!fClean) {
nGoodTransactions = 0;
@@ -2942,9 +3056,11 @@ bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth
} else
nGoodTransactions += block.vtx.size();
}
+ if (ShutdownRequested())
+ return true;
}
if (pindexFailure)
- return error("VerifyDB() : *** coin database inconsistencies found (last %i blocks, %i good transactions before that)\n", chainActive.Height() - pindexFailure->nHeight + 1, nGoodTransactions);
+ return error("VerifyDB(): *** coin database inconsistencies found (last %i blocks, %i good transactions before that)\n", chainActive.Height() - pindexFailure->nHeight + 1, nGoodTransactions);
// check level 4: try reconnecting blocks
if (nCheckLevel >= 4) {
@@ -2955,9 +3071,9 @@ bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth
pindex = chainActive.Next(pindex);
CBlock block;
if (!ReadBlockFromDisk(block, pindex))
- return error("VerifyDB() : *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
+ return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
if (!ConnectBlock(block, state, pindex, coins))
- return error("VerifyDB() : *** found unconnectable block at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
+ return error("VerifyDB(): *** found unconnectable block at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
}
}
@@ -3003,18 +3119,18 @@ bool InitBlockIndex() {
CDiskBlockPos blockPos;
CValidationState state;
if (!FindBlockPos(state, blockPos, nBlockSize+8, 0, block.GetBlockTime()))
- return error("LoadBlockIndex() : FindBlockPos failed");
+ return error("LoadBlockIndex(): FindBlockPos failed");
if (!WriteBlockToDisk(block, blockPos))
- return error("LoadBlockIndex() : writing genesis block to disk failed");
+ return error("LoadBlockIndex(): writing genesis block to disk failed");
CBlockIndex *pindex = AddToBlockIndex(block);
if (!ReceivedBlockTransactions(block, state, pindex, blockPos))
- return error("LoadBlockIndex() : genesis block not accepted");
+ return error("LoadBlockIndex(): genesis block not accepted");
if (!ActivateBestChain(state, &block))
- return error("LoadBlockIndex() : genesis block cannot be activated");
+ return error("LoadBlockIndex(): genesis block cannot be activated");
// Force a chainstate write so that when we VerifyDB in a moment, it doesn't check stale data
return FlushStateToDisk(state, FLUSH_STATE_ALWAYS);
} catch (const std::runtime_error& e) {
- return error("LoadBlockIndex() : failed to initialize block database: %s", e.what());
+ return error("LoadBlockIndex(): failed to initialize block database: %s", e.what());
}
}
@@ -3114,7 +3230,7 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp)
}
}
} catch (const std::exception& e) {
- LogPrintf("%s : Deserialize or I/O error - %s", __func__, e.what());
+ LogPrintf("%s: Deserialize or I/O error - %s", __func__, e.what());
}
}
} catch (const std::runtime_error& e) {
@@ -3178,7 +3294,7 @@ string GetWarnings(string strFor)
return strStatusBar;
else if (strFor == "rpc")
return strRPC;
- assert(!"GetWarnings() : invalid parameter");
+ assert(!"GetWarnings(): invalid parameter");
return "error";
}
@@ -3292,7 +3408,7 @@ void static ProcessGetData(CNode* pfrom)
vector<CInv> vInv;
vInv.push_back(CInv(MSG_BLOCK, chainActive.Tip()->GetBlockHash()));
pfrom->PushMessage("inv", vInv);
- pfrom->hashContinue = 0;
+ pfrom->hashContinue.SetNull();
}
}
}
@@ -3348,7 +3464,7 @@ void static ProcessGetData(CNode* pfrom)
bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, int64_t nTimeReceived)
{
RandAddSeedPerfmon();
- LogPrint("net", "received: %s (%u bytes) peer=%d\n", strCommand, vRecv.size(), pfrom->id);
+ LogPrint("net", "received: %s (%u bytes) peer=%d\n", SanitizeString(strCommand), vRecv.size(), pfrom->id);
if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0)
{
LogPrintf("dropmessagestest DROPPING RECV MESSAGE\n");
@@ -3473,7 +3589,9 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
pfrom->nStartingHeight, addrMe.ToString(), pfrom->id,
remoteAddr);
- AddTimeData(pfrom->addr, nTime);
+ int64_t nTimeOffset = nTime - GetTime();
+ pfrom->nTimeOffset = nTimeOffset;
+ AddTimeData(pfrom->addr, nTimeOffset);
}
@@ -3525,10 +3643,10 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
// Use deterministic randomness to send to the same nodes for 24 hours
// at a time so the setAddrKnowns of the chosen nodes prevent repeats
static uint256 hashSalt;
- if (hashSalt == 0)
+ if (hashSalt.IsNull())
hashSalt = GetRandHash();
uint64_t hashAddr = addr.GetHash();
- uint256 hashRand = hashSalt ^ (hashAddr<<32) ^ ((GetTime()+hashAddr)/(24*60*60));
+ uint256 hashRand = ArithToUint256(UintToArith256(hashSalt) ^ (hashAddr<<32) ^ ((GetTime()+hashAddr)/(24*60*60)));
hashRand = Hash(BEGIN(hashRand), END(hashRand));
multimap<uint256, CNode*> mapMix;
BOOST_FOREACH(CNode* pnode, vNodes)
@@ -3537,7 +3655,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
continue;
unsigned int nPointer;
memcpy(&nPointer, &pnode, sizeof(nPointer));
- uint256 hashKey = hashRand ^ nPointer;
+ uint256 hashKey = ArithToUint256(UintToArith256(hashRand) ^ nPointer);
hashKey = Hash(BEGIN(hashKey), END(hashKey));
mapMix.insert(make_pair(hashKey, pnode));
}
@@ -3659,7 +3777,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
if (pindex)
pindex = chainActive.Next(pindex);
int nLimit = 500;
- LogPrint("net", "getblocks %d to %s limit %d from peer=%d\n", (pindex ? pindex->nHeight : -1), hashStop==uint256(0) ? "end" : hashStop.ToString(), nLimit, pfrom->id);
+ LogPrint("net", "getblocks %d to %s limit %d from peer=%d\n", (pindex ? pindex->nHeight : -1), hashStop.IsNull() ? "end" : hashStop.ToString(), nLimit, pfrom->id);
for (; pindex; pindex = chainActive.Next(pindex))
{
if (pindex->GetBlockHash() == hashStop)
@@ -3743,7 +3861,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
vWorkQueue.push_back(inv.hash);
vEraseQueue.push_back(inv.hash);
- LogPrint("mempool", "AcceptToMemoryPool: peer=%d %s : accepted %s (poolsz %u)\n",
+ LogPrint("mempool", "AcceptToMemoryPool: peer=%d %s: accepted %s (poolsz %u)\n",
pfrom->id, pfrom->cleanSubVer,
tx.GetHash().ToString(),
mempool.mapTx.size());
@@ -3875,7 +3993,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
// TODO: optimize: if pindexLast is an ancestor of chainActive.Tip or pindexBestHeader, continue
// from there instead.
LogPrint("net", "more getheaders (%d) to end to peer=%d (startheight:%d)\n", pindexLast->nHeight, pfrom->id, pfrom->nStartingHeight);
- pfrom->PushMessage("getheaders", chainActive.GetLocator(pindexLast), uint256(0));
+ pfrom->PushMessage("getheaders", chainActive.GetLocator(pindexLast), uint256());
}
}
@@ -4181,7 +4299,7 @@ bool ProcessMessages(CNode* pfrom)
// Scan for message start
if (memcmp(msg.hdr.pchMessageStart, Params().MessageStart(), MESSAGE_START_SIZE) != 0) {
- LogPrintf("PROCESSMESSAGE: INVALID MESSAGESTART %s peer=%d\n", msg.hdr.GetCommand(), pfrom->id);
+ LogPrintf("PROCESSMESSAGE: INVALID MESSAGESTART %s peer=%d\n", SanitizeString(msg.hdr.GetCommand()), pfrom->id);
fOk = false;
break;
}
@@ -4190,7 +4308,7 @@ bool ProcessMessages(CNode* pfrom)
CMessageHeader& hdr = msg.hdr;
if (!hdr.IsValid())
{
- LogPrintf("PROCESSMESSAGE: ERRORS IN HEADER %s peer=%d\n", hdr.GetCommand(), pfrom->id);
+ LogPrintf("PROCESSMESSAGE: ERRORS IN HEADER %s peer=%d\n", SanitizeString(hdr.GetCommand()), pfrom->id);
continue;
}
string strCommand = hdr.GetCommand();
@@ -4205,8 +4323,8 @@ bool ProcessMessages(CNode* pfrom)
memcpy(&nChecksum, &hash, sizeof(nChecksum));
if (nChecksum != hdr.nChecksum)
{
- LogPrintf("ProcessMessages(%s, %u bytes) : CHECKSUM ERROR nChecksum=%08x hdr.nChecksum=%08x\n",
- strCommand, nMessageSize, nChecksum, hdr.nChecksum);
+ LogPrintf("ProcessMessages(%s, %u bytes): CHECKSUM ERROR nChecksum=%08x hdr.nChecksum=%08x\n",
+ SanitizeString(strCommand), nMessageSize, nChecksum, hdr.nChecksum);
continue;
}
@@ -4223,12 +4341,12 @@ bool ProcessMessages(CNode* pfrom)
if (strstr(e.what(), "end of data"))
{
// Allow exceptions from under-length message on vRecv
- LogPrintf("ProcessMessages(%s, %u bytes) : Exception '%s' caught, normally caused by a message being shorter than its stated length\n", strCommand, nMessageSize, e.what());
+ LogPrintf("ProcessMessages(%s, %u bytes): Exception '%s' caught, normally caused by a message being shorter than its stated length\n", SanitizeString(strCommand), nMessageSize, e.what());
}
else if (strstr(e.what(), "size too large"))
{
// Allow exceptions from over-long size
- LogPrintf("ProcessMessages(%s, %u bytes) : Exception '%s' caught\n", strCommand, nMessageSize, e.what());
+ LogPrintf("ProcessMessages(%s, %u bytes): Exception '%s' caught\n", SanitizeString(strCommand), nMessageSize, e.what());
}
else
{
@@ -4245,7 +4363,7 @@ bool ProcessMessages(CNode* pfrom)
}
if (!fRet)
- LogPrintf("ProcessMessage(%s, %u bytes) FAILED peer=%d\n", strCommand, nMessageSize, pfrom->id);
+ LogPrintf("ProcessMessage(%s, %u bytes) FAILED peer=%d\n", SanitizeString(strCommand), nMessageSize, pfrom->id);
break;
}
@@ -4373,7 +4491,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
nSyncStarted++;
CBlockIndex *pindexStart = pindexBestHeader->pprev ? pindexBestHeader->pprev : pindexBestHeader;
LogPrint("net", "initial getheaders (%d) to peer=%d (startheight:%d)\n", pindexStart->nHeight, pto->id, pto->nStartingHeight);
- pto->PushMessage("getheaders", chainActive.GetLocator(pindexStart), uint256(0));
+ pto->PushMessage("getheaders", chainActive.GetLocator(pindexStart), uint256());
}
}
@@ -4404,11 +4522,11 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
{
// 1/4 of tx invs blast to all immediately
static uint256 hashSalt;
- if (hashSalt == 0)
+ if (hashSalt.IsNull())
hashSalt = GetRandHash();
- uint256 hashRand = inv.hash ^ hashSalt;
+ uint256 hashRand = ArithToUint256(UintToArith256(inv.hash) ^ UintToArith256(hashSalt));
hashRand = Hash(BEGIN(hashRand), END(hashRand));
- bool fTrickleWait = ((hashRand & 3) != 0);
+ bool fTrickleWait = ((UintToArith256(hashRand) & 3) != 0);
if (fTrickleWait)
{
@@ -4442,6 +4560,15 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
LogPrintf("Peer=%d is stalling block download, disconnecting\n", pto->id);
pto->fDisconnect = true;
}
+ // In case there is a block that has been in flight from this peer for (2 + 0.5 * N) times the block interval
+ // (with N the number of validated blocks that were in flight at the time it was requested), disconnect due to
+ // timeout. We compensate for in-flight blocks to prevent killing off peers due to our own downstream link
+ // being saturated. We only count validated in-flight blocks so peers can't advertize nonexisting block hashes
+ // to unreasonably increase our timeout.
+ if (!pto->fDisconnect && state.vBlocksInFlight.size() > 0 && state.vBlocksInFlight.front().nTime < nNow - 500000 * Params().TargetSpacing() * (4 + state.vBlocksInFlight.front().nValidatedQueuedBefore)) {
+ LogPrintf("Timeout downloading block %s from peer=%d, disconnecting\n", state.vBlocksInFlight.front().hash.ToString(), pto->id);
+ pto->fDisconnect = true;
+ }
//
// Message: getdata (blocks)
@@ -4491,61 +4618,6 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
return true;
}
-
-bool CBlockUndo::WriteToDisk(CDiskBlockPos &pos, const uint256 &hashBlock)
-{
- // Open history file to append
- CAutoFile fileout(OpenUndoFile(pos), SER_DISK, CLIENT_VERSION);
- if (fileout.IsNull())
- return error("CBlockUndo::WriteToDisk : OpenUndoFile failed");
-
- // Write index header
- unsigned int nSize = fileout.GetSerializeSize(*this);
- fileout << FLATDATA(Params().MessageStart()) << nSize;
-
- // Write undo data
- long fileOutPos = ftell(fileout.Get());
- if (fileOutPos < 0)
- return error("CBlockUndo::WriteToDisk : ftell failed");
- pos.nPos = (unsigned int)fileOutPos;
- fileout << *this;
-
- // calculate & write checksum
- CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION);
- hasher << hashBlock;
- hasher << *this;
- fileout << hasher.GetHash();
-
- return true;
-}
-
-bool CBlockUndo::ReadFromDisk(const CDiskBlockPos &pos, const uint256 &hashBlock)
-{
- // Open history file to read
- CAutoFile filein(OpenUndoFile(pos, true), SER_DISK, CLIENT_VERSION);
- if (filein.IsNull())
- return error("CBlockUndo::ReadFromDisk : OpenBlockFile failed");
-
- // Read block
- uint256 hashChecksum;
- try {
- filein >> *this;
- filein >> hashChecksum;
- }
- catch (const std::exception& e) {
- return error("%s : Deserialize or I/O error - %s", __func__, e.what());
- }
-
- // Verify checksum
- CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION);
- hasher << hashBlock;
- hasher << *this;
- if (hashChecksum != hasher.GetHash())
- return error("CBlockUndo::ReadFromDisk : Checksum mismatch");
-
- return true;
-}
-
std::string CBlockFileInfo::ToString() const {
return strprintf("CBlockFileInfo(blocks=%u, size=%u, heights=%u...%u, time=%s...%s)", nBlocks, nSize, nHeightFirst, nHeightLast, DateTimeStrFormat("%Y-%m-%d", nTimeFirst), DateTimeStrFormat("%Y-%m-%d", nTimeLast));
}
diff --git a/src/main.h b/src/main.h
index 662d5756f7..936cd43e99 100644
--- a/src/main.h
+++ b/src/main.h
@@ -25,7 +25,6 @@
#include "tinyformat.h"
#include "txmempool.h"
#include "uint256.h"
-#include "undo.h"
#include <algorithm>
#include <exception>
@@ -46,7 +45,6 @@ class CScriptCheck;
class CValidationInterface;
class CValidationState;
-struct CBlockTemplate;
struct CNodeStateStats;
/** Default for -blockmaxsize and -blockminsize, which control the range of sizes the mining code will create **/
@@ -61,7 +59,7 @@ static const unsigned int MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50;
/** Maximum number of signature check operations in an IsStandard() P2SH script */
static const unsigned int MAX_P2SH_SIGOPS = 15;
/** The maximum number of sigops we're willing to relay/mine in a single tx */
-static const unsigned int MAX_TX_SIGOPS = MAX_BLOCK_SIGOPS/5;
+static const unsigned int MAX_STANDARD_TX_SIGOPS = MAX_BLOCK_SIGOPS/5;
/** Default for -maxorphantx, maximum number of orphan transactions kept in memory */
static const unsigned int DEFAULT_MAX_ORPHAN_TRANSACTIONS = 100;
/** The maximum size of a blk?????.dat file (since 0.8) */
@@ -107,7 +105,7 @@ static const unsigned char REJECT_CHECKPOINT = 0x43;
struct BlockHasher
{
- size_t operator()(const uint256& hash) const { return hash.GetLow64(); }
+ size_t operator()(const uint256& hash) const { return hash.GetCheapHash(); }
};
extern CScript COINBASE_FLAGS;
@@ -207,7 +205,7 @@ void FlushStateToDisk();
/** (try to) add transaction to memory pool **/
bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree,
- bool* pfMissingInputs, bool fRejectInsaneFee=false);
+ bool* pfMissingInputs, bool fRejectAbsurdFee=false);
struct CNodeStateStats {
@@ -290,7 +288,7 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi
unsigned int flags, bool cacheStore, std::vector<CScriptCheck> *pvChecks = NULL);
/** Apply the effects of this transaction on the UTXO set represented by view */
-void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCache &inputs, CTxUndo &txundo, int nHeight);
+void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCache &inputs, int nHeight);
/** Context-independent validity checks */
bool CheckTransaction(const CTransaction& tx, CValidationState& state);
@@ -302,24 +300,6 @@ bool IsStandardTx(const CTransaction& tx, std::string& reason);
bool IsFinalTx(const CTransaction &tx, int nBlockHeight = 0, int64_t nBlockTime = 0);
-/** Undo information for a CBlock */
-class CBlockUndo
-{
-public:
- std::vector<CTxUndo> vtxundo; // for all but the coinbase
-
- ADD_SERIALIZE_METHODS;
-
- template <typename Stream, typename Operation>
- inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
- READWRITE(vtxundo);
- }
-
- bool WriteToDisk(CDiskBlockPos &pos, const uint256 &hashBlock);
- bool ReadFromDisk(const CDiskBlockPos &pos, const uint256 &hashBlock);
-};
-
-
/**
* Closure representing one script verification
* Note that this stores references to the spending transaction
@@ -532,17 +512,6 @@ extern CCoinsViewCache *pcoinsTip;
/** Global variable that points to the active block tree (protected by cs_main) */
extern CBlockTreeDB *pblocktree;
-struct CBlockTemplate
-{
- CBlock block;
- std::vector<CAmount> vTxFees;
- std::vector<int64_t> vTxSigOps;
-};
-
-
-
-
-
class CValidationInterface {
protected:
diff --git a/src/merkleblock.cpp b/src/merkleblock.cpp
index 1b7ee27e02..b51b002b95 100644
--- a/src/merkleblock.cpp
+++ b/src/merkleblock.cpp
@@ -76,7 +76,7 @@ uint256 CPartialMerkleTree::TraverseAndExtract(int height, unsigned int pos, uns
if (nBitsUsed >= vBits.size()) {
// overflowed the bits array - failure
fBad = true;
- return 0;
+ return uint256();
}
bool fParentOfMatch = vBits[nBitsUsed++];
if (height==0 || !fParentOfMatch) {
@@ -84,7 +84,7 @@ uint256 CPartialMerkleTree::TraverseAndExtract(int height, unsigned int pos, uns
if (nHashUsed >= vHash.size()) {
// overflowed the hash array - failure
fBad = true;
- return 0;
+ return uint256();
}
const uint256 &hash = vHash[nHashUsed++];
if (height==0 && fParentOfMatch) // in case of height 0, we have a matched txid
@@ -93,10 +93,16 @@ uint256 CPartialMerkleTree::TraverseAndExtract(int height, unsigned int pos, uns
} else {
// otherwise, descend into the subtrees to extract matched txids and hashes
uint256 left = TraverseAndExtract(height-1, pos*2, nBitsUsed, nHashUsed, vMatch), right;
- if (pos*2+1 < CalcTreeWidth(height-1))
+ if (pos*2+1 < CalcTreeWidth(height-1)) {
right = TraverseAndExtract(height-1, pos*2+1, nBitsUsed, nHashUsed, vMatch);
- else
+ if (right == left) {
+ // If the left and right branch should never be identical as the transaction
+ // hashes covered by them must be unique.
+ fBad = true;
+ }
+ } else {
right = left;
+ }
// and combine them before returning
return Hash(BEGIN(left), END(left), BEGIN(right), END(right));
}
@@ -122,16 +128,16 @@ uint256 CPartialMerkleTree::ExtractMatches(std::vector<uint256> &vMatch) {
vMatch.clear();
// An empty set will not work
if (nTransactions == 0)
- return 0;
+ return uint256();
// check for excessively high numbers of transactions
if (nTransactions > MAX_BLOCK_SIZE / 60) // 60 is the lower bound for the size of a serialized CTransaction
- return 0;
+ return uint256();
// there can never be more hashes provided than one for every txid
if (vHash.size() > nTransactions)
- return 0;
+ return uint256();
// there must be at least one bit per node in the partial tree, and at least one node per hash
if (vBits.size() < vHash.size())
- return 0;
+ return uint256();
// calculate height of tree
int nHeight = 0;
while (CalcTreeWidth(nHeight) > 1)
@@ -141,12 +147,12 @@ uint256 CPartialMerkleTree::ExtractMatches(std::vector<uint256> &vMatch) {
uint256 hashMerkleRoot = TraverseAndExtract(nHeight, 0, nBitsUsed, nHashUsed, vMatch);
// verify that no problems occured during the tree traversal
if (fBad)
- return 0;
+ return uint256();
// verify that all bits were consumed (except for the padding caused by serializing it as a byte sequence)
if ((nBitsUsed+7)/8 != (vBits.size()+7)/8)
- return 0;
+ return uint256();
// verify that all hashes were consumed
if (nHashUsed != vHash.size())
- return 0;
+ return uint256();
return hashMerkleRoot;
}
diff --git a/src/miner.cpp b/src/miner.cpp
index 2133b13e62..e359654d7b 100644
--- a/src/miner.cpp
+++ b/src/miner.cpp
@@ -6,7 +6,6 @@
#include "miner.h"
#include "amount.h"
-#include "primitives/block.h"
#include "primitives/transaction.h"
#include "hash.h"
#include "main.h"
@@ -279,8 +278,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
if (!CheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true))
continue;
- CTxUndo txundo;
- UpdateCoins(tx, state, view, txundo, nHeight);
+ UpdateCoins(tx, state, view, nHeight);
// Added
pblock->vtx.push_back(tx);
@@ -334,7 +332,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
CValidationState state;
if (!TestBlockValidity(state, *pblock, pindexPrev, false, false))
- throw std::runtime_error("CreateNewBlock() : TestBlockValidity failed");
+ throw std::runtime_error("CreateNewBlock(): TestBlockValidity failed");
}
return pblocktemplate.release();
@@ -364,8 +362,6 @@ void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int&
//
// Internal miner
//
-double dHashesPerSec = 0.0;
-int64_t nHPSTimerStart = 0;
//
// ScanHash scans nonces looking for a hash with at least some zero bits.
@@ -395,10 +391,8 @@ bool static ScanHash(const CBlockHeader *pblock, uint32_t& nNonce, uint256 *phas
return true;
// If nothing found after trying for a while, return -1
- if ((nNonce & 0xffff) == 0)
- return false;
if ((nNonce & 0xfff) == 0)
- boost::this_thread::interruption_point();
+ return false;
}
}
@@ -412,7 +406,7 @@ CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey)
return CreateNewBlock(scriptPubKey);
}
-bool ProcessBlockFound(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey)
+static bool ProcessBlockFound(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey)
{
LogPrintf("%s\n", pblock->ToString());
LogPrintf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue));
@@ -421,7 +415,7 @@ bool ProcessBlockFound(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey)
{
LOCK(cs_main);
if (pblock->hashPrevBlock != chainActive.Tip()->GetBlockHash())
- return error("BitcoinMiner : generated block is stale");
+ return error("BitcoinMiner: generated block is stale");
}
// Remove key from key pool
@@ -436,7 +430,7 @@ bool ProcessBlockFound(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey)
// Process this block the same as if we had received it from another node
CValidationState state;
if (!ProcessNewBlock(state, NULL, pblock))
- return error("BitcoinMiner : ProcessNewBlock, block not accepted");
+ return error("BitcoinMiner: ProcessNewBlock, block not accepted");
return true;
}
@@ -482,19 +476,14 @@ void static BitcoinMiner(CWallet *pwallet)
// Search
//
int64_t nStart = GetTime();
- uint256 hashTarget = uint256().SetCompact(pblock->nBits);
+ arith_uint256 hashTarget = arith_uint256().SetCompact(pblock->nBits);
uint256 hash;
uint32_t nNonce = 0;
- uint32_t nOldNonce = 0;
while (true) {
- bool fFound = ScanHash(pblock, nNonce, &hash);
- uint32_t nHashesDone = nNonce - nOldNonce;
- nOldNonce = nNonce;
-
// Check if something found
- if (fFound)
+ if (ScanHash(pblock, nNonce, &hash))
{
- if (hash <= hashTarget)
+ if (UintToArith256(hash) <= hashTarget)
{
// Found a solution
pblock->nNonce = nNonce;
@@ -514,35 +503,6 @@ void static BitcoinMiner(CWallet *pwallet)
}
}
- // Meter hashes/sec
- static int64_t nHashCounter;
- if (nHPSTimerStart == 0)
- {
- nHPSTimerStart = GetTimeMillis();
- nHashCounter = 0;
- }
- else
- nHashCounter += nHashesDone;
- if (GetTimeMillis() - nHPSTimerStart > 4000)
- {
- static CCriticalSection cs;
- {
- LOCK(cs);
- if (GetTimeMillis() - nHPSTimerStart > 4000)
- {
- dHashesPerSec = 1000.0 * nHashCounter / (GetTimeMillis() - nHPSTimerStart);
- nHPSTimerStart = GetTimeMillis();
- nHashCounter = 0;
- static int64_t nLogTime;
- if (GetTime() - nLogTime > 30 * 60)
- {
- nLogTime = GetTime();
- LogPrintf("hashmeter %6.0f khash/s\n", dHashesPerSec/1000.0);
- }
- }
- }
- }
-
// Check for stop or if block needs to be rebuilt
boost::this_thread::interruption_point();
// Regtest mode doesn't require peers
diff --git a/src/miner.h b/src/miner.h
index 02dedb1712..5d5c9c86c7 100644
--- a/src/miner.h
+++ b/src/miner.h
@@ -6,16 +6,21 @@
#ifndef BITCOIN_MINER_H
#define BITCOIN_MINER_H
+#include "primitives/block.h"
+
#include <stdint.h>
-class CBlock;
-class CBlockHeader;
class CBlockIndex;
class CReserveKey;
class CScript;
class CWallet;
-struct CBlockTemplate;
+struct CBlockTemplate
+{
+ CBlock block;
+ std::vector<CAmount> vTxFees;
+ std::vector<int64_t> vTxSigOps;
+};
/** Run the miner threads */
void GenerateBitcoins(bool fGenerate, CWallet* pwallet, int nThreads);
@@ -24,11 +29,6 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn);
CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey);
/** Modify the extranonce in a block */
void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce);
-/** Check mined block */
-bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey);
void UpdateTime(CBlockHeader* block, const CBlockIndex* pindexPrev);
-extern double dHashesPerSec;
-extern int64_t nHPSTimerStart;
-
#endif // BITCOIN_MINER_H
diff --git a/src/net.cpp b/src/net.cpp
index 474a3e4288..3c3666615e 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -49,7 +49,6 @@
#endif
#endif
-using namespace boost;
using namespace std;
namespace {
@@ -158,56 +157,6 @@ CAddress GetLocalAddress(const CNetAddr *paddrPeer)
return ret;
}
-bool RecvLine(SOCKET hSocket, string& strLine)
-{
- strLine = "";
- while (true)
- {
- char c;
- int nBytes = recv(hSocket, &c, 1, 0);
- if (nBytes > 0)
- {
- if (c == '\n')
- continue;
- if (c == '\r')
- return true;
- strLine += c;
- if (strLine.size() >= 9000)
- return true;
- }
- else if (nBytes <= 0)
- {
- boost::this_thread::interruption_point();
- if (nBytes < 0)
- {
- int nErr = WSAGetLastError();
- if (nErr == WSAEMSGSIZE)
- continue;
- if (nErr == WSAEWOULDBLOCK || nErr == WSAEINTR || nErr == WSAEINPROGRESS)
- {
- MilliSleep(10);
- continue;
- }
- }
- if (!strLine.empty())
- return true;
- if (nBytes == 0)
- {
- // socket closed
- LogPrint("net", "socket closed\n");
- return false;
- }
- else
- {
- // socket error
- int nErr = WSAGetLastError();
- LogPrint("net", "recv failed: %s\n", NetworkErrorString(nErr));
- return false;
- }
- }
- }
-}
-
int GetnScore(const CService& addr)
{
LOCK(cs_mapLocalHost);
@@ -522,6 +471,7 @@ void CNode::copyStats(CNodeStats &stats)
X(nLastSend);
X(nLastRecv);
X(nTimeConnected);
+ X(nTimeOffset);
X(addrName);
X(nVersion);
X(cleanSubVer);
@@ -1070,7 +1020,7 @@ void ThreadMapPort()
catch (const boost::thread_interrupted&)
{
r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port.c_str(), "TCP", 0);
- LogPrintf("UPNP_DeletePortMapping() returned : %d\n", r);
+ LogPrintf("UPNP_DeletePortMapping() returned: %d\n", r);
freeUPNPDevlist(devlist); devlist = 0;
FreeUPNPUrls(&urls);
throw;
@@ -1847,21 +1797,21 @@ bool CAddrDB::Write(const CAddrMan& addr)
FILE *file = fopen(pathTmp.string().c_str(), "wb");
CAutoFile fileout(file, SER_DISK, CLIENT_VERSION);
if (fileout.IsNull())
- return error("%s : Failed to open file %s", __func__, pathTmp.string());
+ return error("%s: Failed to open file %s", __func__, pathTmp.string());
// Write and commit header, data
try {
fileout << ssPeers;
}
catch (const std::exception& e) {
- return error("%s : Serialize or I/O error - %s", __func__, e.what());
+ return error("%s: Serialize or I/O error - %s", __func__, e.what());
}
FileCommit(fileout.Get());
fileout.fclose();
// replace existing peers.dat, if any, with new peers.dat.XXXX
if (!RenameOver(pathTmp, pathAddr))
- return error("%s : Rename-into-place failed", __func__);
+ return error("%s: Rename-into-place failed", __func__);
return true;
}
@@ -1872,7 +1822,7 @@ bool CAddrDB::Read(CAddrMan& addr)
FILE *file = fopen(pathAddr.string().c_str(), "rb");
CAutoFile filein(file, SER_DISK, CLIENT_VERSION);
if (filein.IsNull())
- return error("%s : Failed to open file %s", __func__, pathAddr.string());
+ return error("%s: Failed to open file %s", __func__, pathAddr.string());
// use file size to size memory buffer
int fileSize = boost::filesystem::file_size(pathAddr);
@@ -1890,7 +1840,7 @@ bool CAddrDB::Read(CAddrMan& addr)
filein >> hashIn;
}
catch (const std::exception& e) {
- return error("%s : Deserialize or I/O error - %s", __func__, e.what());
+ return error("%s: Deserialize or I/O error - %s", __func__, e.what());
}
filein.fclose();
@@ -1899,7 +1849,7 @@ bool CAddrDB::Read(CAddrMan& addr)
// verify stored checksum matches input data
uint256 hashTmp = Hash(ssPeers.begin(), ssPeers.end());
if (hashIn != hashTmp)
- return error("%s : Checksum mismatch, data corrupted", __func__);
+ return error("%s: Checksum mismatch, data corrupted", __func__);
unsigned char pchMsgTmp[4];
try {
@@ -1908,13 +1858,13 @@ bool CAddrDB::Read(CAddrMan& addr)
// ... verify the network matches ours
if (memcmp(pchMsgTmp, Params().MessageStart(), sizeof(pchMsgTmp)))
- return error("%s : Invalid network magic number", __func__);
+ return error("%s: Invalid network magic number", __func__);
// de-serialize address data into one CAddrMan object
ssPeers >> addr;
}
catch (const std::exception& e) {
- return error("%s : Deserialize or I/O error - %s", __func__, e.what());
+ return error("%s: Deserialize or I/O error - %s", __func__, e.what());
}
return true;
@@ -1933,6 +1883,7 @@ CNode::CNode(SOCKET hSocketIn, CAddress addrIn, std::string addrNameIn, bool fIn
nSendBytes = 0;
nRecvBytes = 0;
nTimeConnected = GetTime();
+ nTimeOffset = 0;
addr = addrIn;
addrName = addrNameIn == "" ? addr.ToStringIPPort() : addrNameIn;
nVersion = 0;
@@ -1947,7 +1898,7 @@ CNode::CNode(SOCKET hSocketIn, CAddress addrIn, std::string addrNameIn, bool fIn
nRefCount = 0;
nSendSize = 0;
nSendOffset = 0;
- hashContinue = 0;
+ hashContinue = uint256();
nStartingHeight = -1;
fGetAddr = false;
fRelayTxes = false;
@@ -2020,7 +1971,7 @@ void CNode::BeginMessage(const char* pszCommand) EXCLUSIVE_LOCK_FUNCTION(cs_vSen
ENTER_CRITICAL_SECTION(cs_vSend);
assert(ssSend.size() == 0);
ssSend << CMessageHeader(pszCommand, 0);
- LogPrint("net", "sending: %s ", pszCommand);
+ LogPrint("net", "sending: %s ", SanitizeString(pszCommand));
}
void CNode::AbortMessage() UNLOCK_FUNCTION(cs_vSend)
diff --git a/src/net.h b/src/net.h
index fed5a5959f..b78665b5c6 100644
--- a/src/net.h
+++ b/src/net.h
@@ -61,7 +61,6 @@ unsigned int ReceiveFloodSize();
unsigned int SendBufferSize();
void AddOneShot(std::string strDest);
-bool RecvLine(SOCKET hSocket, std::string& strLine);
void AddressCurrentlyConnected(const CService& addr);
CNode* FindNode(const CNetAddr& ip);
CNode* FindNode(const std::string& addrName);
@@ -154,6 +153,7 @@ public:
int64_t nLastSend;
int64_t nLastRecv;
int64_t nTimeConnected;
+ int64_t nTimeOffset;
std::string addrName;
int nVersion;
std::string cleanSubVer;
@@ -235,6 +235,7 @@ public:
int64_t nLastSend;
int64_t nLastRecv;
int64_t nTimeConnected;
+ int64_t nTimeOffset;
CAddress addr;
std::string addrName;
CService addrLocal;
diff --git a/src/pow.cpp b/src/pow.cpp
index e91e3d893c..e49f0d104c 100644
--- a/src/pow.cpp
+++ b/src/pow.cpp
@@ -5,6 +5,7 @@
#include "pow.h"
+#include "arith_uint256.h"
#include "chain.h"
#include "chainparams.h"
#include "primitives/block.h"
@@ -56,8 +57,8 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead
nActualTimespan = Params().TargetTimespan()*4;
// Retarget
- uint256 bnNew;
- uint256 bnOld;
+ arith_uint256 bnNew;
+ arith_uint256 bnOld;
bnNew.SetCompact(pindexLast->nBits);
bnOld = bnNew;
bnNew *= nActualTimespan;
@@ -79,7 +80,7 @@ bool CheckProofOfWork(uint256 hash, unsigned int nBits)
{
bool fNegative;
bool fOverflow;
- uint256 bnTarget;
+ arith_uint256 bnTarget;
if (Params().SkipProofOfWorkCheck())
return true;
@@ -88,25 +89,25 @@ bool CheckProofOfWork(uint256 hash, unsigned int nBits)
// Check range
if (fNegative || bnTarget == 0 || fOverflow || bnTarget > Params().ProofOfWorkLimit())
- return error("CheckProofOfWork() : nBits below minimum work");
+ return error("CheckProofOfWork(): nBits below minimum work");
// Check proof of work matches claimed amount
- if (hash > bnTarget)
- return error("CheckProofOfWork() : hash doesn't match nBits");
+ if (UintToArith256(hash) > bnTarget)
+ return error("CheckProofOfWork(): hash doesn't match nBits");
return true;
}
-uint256 GetBlockProof(const CBlockIndex& block)
+arith_uint256 GetBlockProof(const CBlockIndex& block)
{
- uint256 bnTarget;
+ arith_uint256 bnTarget;
bool fNegative;
bool fOverflow;
bnTarget.SetCompact(block.nBits, &fNegative, &fOverflow);
if (fNegative || fOverflow || bnTarget == 0)
return 0;
// We need to compute 2**256 / (bnTarget+1), but we can't represent 2**256
- // as it's too large for a uint256. However, as 2**256 is at least as large
+ // as it's too large for a arith_uint256. However, as 2**256 is at least as large
// as bnTarget+1, it is equal to ((2**256 - bnTarget - 1) / (bnTarget+1)) + 1,
// or ~bnTarget / (nTarget+1) + 1.
return (~bnTarget / (bnTarget + 1)) + 1;
diff --git a/src/pow.h b/src/pow.h
index 89b219f808..3337a30a5e 100644
--- a/src/pow.h
+++ b/src/pow.h
@@ -11,11 +11,12 @@
class CBlockHeader;
class CBlockIndex;
class uint256;
+class arith_uint256;
unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock);
/** Check whether a block hash satisfies the proof-of-work requirement specified by nBits */
bool CheckProofOfWork(uint256 hash, unsigned int nBits);
-uint256 GetBlockProof(const CBlockIndex& block);
+arith_uint256 GetBlockProof(const CBlockIndex& block);
#endif // BITCOIN_POW_H
diff --git a/src/primitives/block.cpp b/src/primitives/block.cpp
index 2b6a302ee9..3b4a360395 100644
--- a/src/primitives/block.cpp
+++ b/src/primitives/block.cpp
@@ -74,7 +74,7 @@ uint256 CBlock::BuildMerkleTree(bool* fMutated) const
if (fMutated) {
*fMutated = mutated;
}
- return (vMerkleTree.empty() ? 0 : vMerkleTree.back());
+ return (vMerkleTree.empty() ? uint256() : vMerkleTree.back());
}
std::vector<uint256> CBlock::GetMerkleBranch(int nIndex) const
@@ -96,7 +96,7 @@ std::vector<uint256> CBlock::GetMerkleBranch(int nIndex) const
uint256 CBlock::CheckMerkleBranch(uint256 hash, const std::vector<uint256>& vMerkleBranch, int nIndex)
{
if (nIndex == -1)
- return 0;
+ return uint256();
for (std::vector<uint256>::const_iterator it(vMerkleBranch.begin()); it != vMerkleBranch.end(); ++it)
{
if (nIndex & 1)
diff --git a/src/primitives/block.h b/src/primitives/block.h
index 1449882bd0..c7ed6f723a 100644
--- a/src/primitives/block.h
+++ b/src/primitives/block.h
@@ -24,7 +24,7 @@ class CBlockHeader
{
public:
// header
- static const int32_t CURRENT_VERSION=2;
+ static const int32_t CURRENT_VERSION=3;
int32_t nVersion;
uint256 hashPrevBlock;
uint256 hashMerkleRoot;
@@ -53,8 +53,8 @@ public:
void SetNull()
{
nVersion = CBlockHeader::CURRENT_VERSION;
- hashPrevBlock = 0;
- hashMerkleRoot = 0;
+ hashPrevBlock.SetNull();
+ hashMerkleRoot.SetNull();
nTime = 0;
nBits = 0;
nNonce = 0;
@@ -162,7 +162,7 @@ struct CBlockLocator
vHave.clear();
}
- bool IsNull()
+ bool IsNull() const
{
return vHave.empty();
}
diff --git a/src/primitives/transaction.cpp b/src/primitives/transaction.cpp
index 230aedd896..606dbea798 100644
--- a/src/primitives/transaction.cpp
+++ b/src/primitives/transaction.cpp
@@ -72,7 +72,7 @@ void CTransaction::UpdateHash() const
*const_cast<uint256*>(&hash) = SerializeHash(*this);
}
-CTransaction::CTransaction() : hash(0), nVersion(CTransaction::CURRENT_VERSION), vin(), vout(), nLockTime(0) { }
+CTransaction::CTransaction() : nVersion(CTransaction::CURRENT_VERSION), vin(), vout(), nLockTime(0) { }
CTransaction::CTransaction(const CMutableTransaction &tx) : nVersion(tx.nVersion), vin(tx.vin), vout(tx.vout), nLockTime(tx.nLockTime) {
UpdateHash();
@@ -94,7 +94,7 @@ CAmount CTransaction::GetValueOut() const
{
nValueOut += it->nValue;
if (!MoneyRange(it->nValue) || !MoneyRange(nValueOut))
- throw std::runtime_error("CTransaction::GetValueOut() : value out of range");
+ throw std::runtime_error("CTransaction::GetValueOut(): value out of range");
}
return nValueOut;
}
diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h
index da35012300..1b5a47e0da 100644
--- a/src/primitives/transaction.h
+++ b/src/primitives/transaction.h
@@ -28,8 +28,8 @@ public:
READWRITE(FLATDATA(*this));
}
- void SetNull() { hash = 0; n = (uint32_t) -1; }
- bool IsNull() const { return (hash == 0 && n == (uint32_t) -1); }
+ void SetNull() { hash.SetNull(); n = (uint32_t) -1; }
+ bool IsNull() const { return (hash.IsNull() && n == (uint32_t) -1); }
friend bool operator<(const COutPoint& a, const COutPoint& b)
{
diff --git a/src/protocol.cpp b/src/protocol.cpp
index 71c6bd152b..74ac706d60 100644
--- a/src/protocol.cpp
+++ b/src/protocol.cpp
@@ -66,7 +66,7 @@ bool CMessageHeader::IsValid() const
// Message size
if (nMessageSize > MAX_SIZE)
{
- LogPrintf("CMessageHeader::IsValid() : (%s, %u bytes) nMessageSize > MAX_SIZE\n", GetCommand(), nMessageSize);
+ LogPrintf("CMessageHeader::IsValid(): (%s, %u bytes) nMessageSize > MAX_SIZE\n", GetCommand(), nMessageSize);
return false;
}
@@ -96,7 +96,7 @@ void CAddress::Init()
CInv::CInv()
{
type = 0;
- hash = 0;
+ hash.SetNull();
}
CInv::CInv(int typeIn, const uint256& hashIn)
@@ -117,7 +117,7 @@ CInv::CInv(const std::string& strType, const uint256& hashIn)
}
}
if (i == ARRAYLEN(ppszTypeName))
- throw std::out_of_range(strprintf("CInv::CInv(string, uint256) : unknown type '%s'", strType));
+ throw std::out_of_range(strprintf("CInv::CInv(string, uint256): unknown type '%s'", strType));
hash = hashIn;
}
@@ -134,7 +134,7 @@ bool CInv::IsKnownType() const
const char* CInv::GetCommand() const
{
if (!IsKnownType())
- throw std::out_of_range(strprintf("CInv::GetCommand() : type=%d unknown type", type));
+ throw std::out_of_range(strprintf("CInv::GetCommand(): type=%d unknown type", type));
return ppszTypeName[type];
}
diff --git a/src/pubkey.h b/src/pubkey.h
index 69b73a4e1c..b0768d4f47 100644
--- a/src/pubkey.h
+++ b/src/pubkey.h
@@ -27,7 +27,7 @@
class CKeyID : public uint160
{
public:
- CKeyID() : uint160(0) {}
+ CKeyID() : uint160() {}
CKeyID(const uint160& in) : uint160(in) {}
};
diff --git a/src/qt/addresstablemodel.cpp b/src/qt/addresstablemodel.cpp
index bfb5bf3fec..162ecdba4e 100644
--- a/src/qt/addresstablemodel.cpp
+++ b/src/qt/addresstablemodel.cpp
@@ -114,7 +114,7 @@ public:
case CT_NEW:
if(inModel)
{
- qWarning() << "AddressTablePriv::updateEntry : Warning: Got CT_NEW, but entry is already in model";
+ qWarning() << "AddressTablePriv::updateEntry: Warning: Got CT_NEW, but entry is already in model";
break;
}
parent->beginInsertRows(QModelIndex(), lowerIndex, lowerIndex);
@@ -124,7 +124,7 @@ public:
case CT_UPDATED:
if(!inModel)
{
- qWarning() << "AddressTablePriv::updateEntry : Warning: Got CT_UPDATED, but entry is not in model";
+ qWarning() << "AddressTablePriv::updateEntry: Warning: Got CT_UPDATED, but entry is not in model";
break;
}
lower->type = newEntryType;
@@ -134,7 +134,7 @@ public:
case CT_DELETED:
if(!inModel)
{
- qWarning() << "AddressTablePriv::updateEntry : Warning: Got CT_DELETED, but entry is not in model";
+ qWarning() << "AddressTablePriv::updateEntry: Warning: Got CT_DELETED, but entry is not in model";
break;
}
parent->beginRemoveRows(QModelIndex(), lowerIndex, upperIndex-1);
diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp
index 1adf4e00cb..73c684e489 100644
--- a/src/qt/bitcoin.cpp
+++ b/src/qt/bitcoin.cpp
@@ -89,10 +89,24 @@ static std::string Translate(const char* psz)
return QCoreApplication::translate("bitcoin-core", psz).toStdString();
}
+static QString GetLangTerritory()
+{
+ QSettings settings;
+ // Get desired locale (e.g. "de_DE")
+ // 1) System default language
+ QString lang_territory = QLocale::system().name();
+ // 2) Language from QSettings
+ QString lang_territory_qsettings = settings.value("language", "").toString();
+ if(!lang_territory_qsettings.isEmpty())
+ lang_territory = lang_territory_qsettings;
+ // 3) -lang command line argument
+ lang_territory = QString::fromStdString(GetArg("-lang", lang_territory.toStdString()));
+ return lang_territory;
+}
+
/** Set up translations */
static void initTranslations(QTranslator &qtTranslatorBase, QTranslator &qtTranslator, QTranslator &translatorBase, QTranslator &translator)
{
- QSettings settings;
// Remove old translators
QApplication::removeTranslator(&qtTranslatorBase);
@@ -102,13 +116,7 @@ static void initTranslations(QTranslator &qtTranslatorBase, QTranslator &qtTrans
// Get desired locale (e.g. "de_DE")
// 1) System default language
- QString lang_territory = QLocale::system().name();
- // 2) Language from QSettings
- QString lang_territory_qsettings = settings.value("language", "").toString();
- if(!lang_territory_qsettings.isEmpty())
- lang_territory = lang_territory_qsettings;
- // 3) -lang command line argument
- lang_territory = QString::fromStdString(GetArg("-lang", lang_territory.toStdString()));
+ QString lang_territory = GetLangTerritory();
// Convert to "de" only by truncating "_DE"
QString lang = lang_territory;
@@ -498,8 +506,6 @@ int main(int argc, char *argv[])
Q_INIT_RESOURCE(bitcoin);
Q_INIT_RESOURCE(bitcoin_locale);
- GUIUtil::SubstituteFonts();
-
BitcoinApplication app(argc, argv);
#if QT_VERSION > 0x050100
// Generate high-dpi pixmaps
@@ -521,6 +527,7 @@ int main(int argc, char *argv[])
QApplication::setOrganizationName(QAPP_ORG_NAME);
QApplication::setOrganizationDomain(QAPP_ORG_DOMAIN);
QApplication::setApplicationName(QAPP_APP_NAME_DEFAULT);
+ GUIUtil::SubstituteFonts(GetLangTerritory());
/// 4. Initialization of translations, so that intro dialog is in user's language
// Now that QSettings are accessible, initialize translations
diff --git a/src/qt/bitcoin.qrc b/src/qt/bitcoin.qrc
index b54f2e2ed6..63af146fd0 100644
--- a/src/qt/bitcoin.qrc
+++ b/src/qt/bitcoin.qrc
@@ -35,9 +35,6 @@
<file alias="tx_input">res/icons/tx_input.png</file>
<file alias="tx_output">res/icons/tx_output.png</file>
<file alias="tx_inout">res/icons/tx_inout.png</file>
- <file alias="unit_btc">res/icons/unit_btc.png</file>
- <file alias="unit_mbtc">res/icons/unit_mbtc.png</file>
- <file alias="unit_ubtc">res/icons/unit_ubtc.png</file>
<file alias="lock_closed">res/icons/lock_closed.png</file>
<file alias="lock_open">res/icons/lock_open.png</file>
<file alias="key">res/icons/key.png</file>
@@ -49,9 +46,6 @@
<file alias="about_qt">res/icons/about_qt.png</file>
<file alias="verify">res/icons/verify.png</file>
</qresource>
- <qresource prefix="/images">
- <file alias="about">res/images/about.png</file>
- </qresource>
<qresource prefix="/movies">
<file alias="spinner-000">res/movies/spinner-000.png</file>
<file alias="spinner-001">res/movies/spinner-001.png</file>
diff --git a/src/qt/bitcoinamountfield.cpp b/src/qt/bitcoinamountfield.cpp
index fdb9bcd6d6..d31a1e018b 100644
--- a/src/qt/bitcoinamountfield.cpp
+++ b/src/qt/bitcoinamountfield.cpp
@@ -20,6 +20,7 @@
class AmountSpinBox: public QAbstractSpinBox
{
Q_OBJECT
+
public:
explicit AmountSpinBox(QWidget *parent):
QAbstractSpinBox(parent),
@@ -72,23 +73,6 @@ public:
setValue(val);
}
- StepEnabled stepEnabled() const
- {
- StepEnabled rv = 0;
- if(text().isEmpty()) // Allow step-up with empty field
- return StepUpEnabled;
- bool valid = false;
- CAmount val = value(&valid);
- if(valid)
- {
- if(val > 0)
- rv |= StepDownEnabled;
- if(val < BitcoinUnits::maxMoney())
- rv |= StepUpEnabled;
- }
- return rv;
- }
-
void setDisplayUnit(int unit)
{
bool valid = false;
@@ -139,6 +123,7 @@ public:
}
return cachedMinimumSizeHint;
}
+
private:
int currentUnit;
CAmount singleStep;
@@ -179,6 +164,26 @@ protected:
return QAbstractSpinBox::event(event);
}
+ StepEnabled stepEnabled() const
+ {
+ if (isReadOnly()) // Disable steps when AmountSpinBox is read-only
+ return StepNone;
+ if (text().isEmpty()) // Allow step-up with empty field
+ return StepUpEnabled;
+
+ StepEnabled rv = 0;
+ bool valid = false;
+ CAmount val = value(&valid);
+ if(valid)
+ {
+ if(val > 0)
+ rv |= StepDownEnabled;
+ if(val < BitcoinUnits::maxMoney())
+ rv |= StepUpEnabled;
+ }
+ return rv;
+ }
+
signals:
void valueChanged();
};
@@ -273,7 +278,6 @@ void BitcoinAmountField::setValue(const CAmount& value)
void BitcoinAmountField::setReadOnly(bool fReadOnly)
{
amount->setReadOnly(fReadOnly);
- unit->setEnabled(!fReadOnly);
}
void BitcoinAmountField::unitChanged(int idx)
diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp
index 3b8fd985a0..09f784387e 100644
--- a/src/qt/bitcoingui.cpp
+++ b/src/qt/bitcoingui.cpp
@@ -76,12 +76,14 @@ BitcoinGUI::BitcoinGUI(const NetworkStyle *networkStyle, QWidget *parent) :
historyAction(0),
quitAction(0),
sendCoinsAction(0),
+ sendCoinsMenuAction(0),
usedSendingAddressesAction(0),
usedReceivingAddressesAction(0),
signMessageAction(0),
verifyMessageAction(0),
aboutAction(0),
receiveCoinsAction(0),
+ receiveCoinsMenuAction(0),
optionsAction(0),
toggleHideAction(0),
encryptWalletAction(0),
@@ -162,6 +164,9 @@ BitcoinGUI::BitcoinGUI(const NetworkStyle *networkStyle, QWidget *parent) :
// Create status bar
statusBar();
+
+ // Disable size grip because it looks ugly and nobody needs it
+ statusBar()->setSizeGripEnabled(false);
// Status bar notification icons
QFrame *frameBlocks = new QFrame();
@@ -256,6 +261,10 @@ void BitcoinGUI::createActions(const NetworkStyle *networkStyle)
sendCoinsAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_2));
tabGroup->addAction(sendCoinsAction);
+ sendCoinsMenuAction = new QAction(TextColorIcon(":/icons/send"), sendCoinsAction->text(), this);
+ sendCoinsMenuAction->setStatusTip(sendCoinsAction->statusTip());
+ sendCoinsMenuAction->setToolTip(sendCoinsMenuAction->statusTip());
+
receiveCoinsAction = new QAction(SingleColorIcon(":/icons/receiving_addresses"), tr("&Receive"), this);
receiveCoinsAction->setStatusTip(tr("Request payments (generates QR codes and bitcoin: URIs)"));
receiveCoinsAction->setToolTip(receiveCoinsAction->statusTip());
@@ -263,6 +272,10 @@ void BitcoinGUI::createActions(const NetworkStyle *networkStyle)
receiveCoinsAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_3));
tabGroup->addAction(receiveCoinsAction);
+ receiveCoinsMenuAction = new QAction(TextColorIcon(":/icons/receiving_addresses"), receiveCoinsAction->text(), this);
+ receiveCoinsMenuAction->setStatusTip(receiveCoinsAction->statusTip());
+ receiveCoinsMenuAction->setToolTip(receiveCoinsMenuAction->statusTip());
+
historyAction = new QAction(SingleColorIcon(":/icons/history"), tr("&Transactions"), this);
historyAction->setStatusTip(tr("Browse transaction history"));
historyAction->setToolTip(historyAction->statusTip());
@@ -277,8 +290,12 @@ void BitcoinGUI::createActions(const NetworkStyle *networkStyle)
connect(overviewAction, SIGNAL(triggered()), this, SLOT(gotoOverviewPage()));
connect(sendCoinsAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
connect(sendCoinsAction, SIGNAL(triggered()), this, SLOT(gotoSendCoinsPage()));
+ connect(sendCoinsMenuAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
+ connect(sendCoinsMenuAction, SIGNAL(triggered()), this, SLOT(gotoSendCoinsPage()));
connect(receiveCoinsAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
connect(receiveCoinsAction, SIGNAL(triggered()), this, SLOT(gotoReceiveCoinsPage()));
+ connect(receiveCoinsMenuAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
+ connect(receiveCoinsMenuAction, SIGNAL(triggered()), this, SLOT(gotoReceiveCoinsPage()));
connect(historyAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
connect(historyAction, SIGNAL(triggered()), this, SLOT(gotoHistoryPage()));
#endif // ENABLE_WALLET
@@ -475,7 +492,9 @@ void BitcoinGUI::setWalletActionsEnabled(bool enabled)
{
overviewAction->setEnabled(enabled);
sendCoinsAction->setEnabled(enabled);
+ sendCoinsMenuAction->setEnabled(enabled);
receiveCoinsAction->setEnabled(enabled);
+ receiveCoinsMenuAction->setEnabled(enabled);
historyAction->setEnabled(enabled);
encryptWalletAction->setEnabled(enabled);
backupWalletAction->setEnabled(enabled);
@@ -522,8 +541,8 @@ void BitcoinGUI::createTrayIconMenu()
// Configuration of the tray icon (or dock icon) icon menu
trayIconMenu->addAction(toggleHideAction);
trayIconMenu->addSeparator();
- trayIconMenu->addAction(sendCoinsAction);
- trayIconMenu->addAction(receiveCoinsAction);
+ trayIconMenu->addAction(sendCoinsMenuAction);
+ trayIconMenu->addAction(receiveCoinsMenuAction);
trayIconMenu->addSeparator();
trayIconMenu->addAction(signMessageAction);
trayIconMenu->addAction(verifyMessageAction);
@@ -1027,6 +1046,16 @@ UnitDisplayStatusBarControl::UnitDisplayStatusBarControl() :
{
createContextMenu();
setToolTip(tr("Unit to show amounts in. Click to select another unit."));
+ QList<BitcoinUnits::Unit> units = BitcoinUnits::availableUnits();
+ int max_width = 0;
+ const QFontMetrics fm(font());
+ foreach (const BitcoinUnits::Unit unit, units)
+ {
+ max_width = qMax(max_width, fm.width(BitcoinUnits::name(unit)));
+ }
+ setMinimumSize(max_width, 0);
+ setAlignment(Qt::AlignRight | Qt::AlignVCenter);
+ setStyleSheet(QString("QLabel { color : %1 }").arg(SingleColor().name()));
}
/** So that it responds to button clicks */
@@ -1066,7 +1095,7 @@ void UnitDisplayStatusBarControl::setOptionsModel(OptionsModel *optionsModel)
/** When Display Units are changed on OptionsModel it will refresh the display text of the control on the status bar */
void UnitDisplayStatusBarControl::updateDisplayUnit(int newUnits)
{
- setPixmap(SingleColorIcon(":/icons/unit_" + BitcoinUnits::id(newUnits)).pixmap(31,STATUSBAR_ICONSIZE));
+ setText(BitcoinUnits::name(newUnits));
}
/** Shows context menu with Display Unit options by the mouse coordinates */
diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h
index 7509a00734..3216a7398e 100644
--- a/src/qt/bitcoingui.h
+++ b/src/qt/bitcoingui.h
@@ -90,12 +90,14 @@ private:
QAction *historyAction;
QAction *quitAction;
QAction *sendCoinsAction;
+ QAction *sendCoinsMenuAction;
QAction *usedSendingAddressesAction;
QAction *usedReceivingAddressesAction;
QAction *signMessageAction;
QAction *verifyMessageAction;
QAction *aboutAction;
QAction *receiveCoinsAction;
+ QAction *receiveCoinsMenuAction;
QAction *optionsAction;
QAction *toggleHideAction;
QAction *encryptWalletAction;
diff --git a/src/qt/bitcoinunits.cpp b/src/qt/bitcoinunits.cpp
index 758fba7058..425b45d918 100644
--- a/src/qt/bitcoinunits.cpp
+++ b/src/qt/bitcoinunits.cpp
@@ -36,17 +36,6 @@ bool BitcoinUnits::valid(int unit)
}
}
-QString BitcoinUnits::id(int unit)
-{
- switch(unit)
- {
- case BTC: return QString("btc");
- case mBTC: return QString("mbtc");
- case uBTC: return QString("ubtc");
- default: return QString("???");
- }
-}
-
QString BitcoinUnits::name(int unit)
{
switch(unit)
diff --git a/src/qt/bitcoinunits.h b/src/qt/bitcoinunits.h
index a01fcc8cf9..1871c33a78 100644
--- a/src/qt/bitcoinunits.h
+++ b/src/qt/bitcoinunits.h
@@ -76,8 +76,6 @@ public:
static QList<Unit> availableUnits();
//! Is unit ID valid?
static bool valid(int unit);
- //! Identifier, e.g. for image names
- static QString id(int unit);
//! Short name
static QString name(int unit);
//! Longer description
diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp
index 493cdd6dd2..03d94f2e13 100644
--- a/src/qt/clientmodel.cpp
+++ b/src/qt/clientmodel.cpp
@@ -212,14 +212,14 @@ static void ShowProgress(ClientModel *clientmodel, const std::string &title, int
static void NotifyNumConnectionsChanged(ClientModel *clientmodel, int newNumConnections)
{
- // Too noisy: qDebug() << "NotifyNumConnectionsChanged : " + QString::number(newNumConnections);
+ // Too noisy: qDebug() << "NotifyNumConnectionsChanged: " + QString::number(newNumConnections);
QMetaObject::invokeMethod(clientmodel, "updateNumConnections", Qt::QueuedConnection,
Q_ARG(int, newNumConnections));
}
static void NotifyAlertChanged(ClientModel *clientmodel, const uint256 &hash, ChangeType status)
{
- qDebug() << "NotifyAlertChanged : " + QString::fromStdString(hash.GetHex()) + " status=" + QString::number(status);
+ qDebug() << "NotifyAlertChanged: " + QString::fromStdString(hash.GetHex()) + " status=" + QString::number(status);
QMetaObject::invokeMethod(clientmodel, "updateAlert", Qt::QueuedConnection,
Q_ARG(QString, QString::fromStdString(hash.GetHex())),
Q_ARG(int, status));
diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp
index 60e7d62a7a..3f4f082b8c 100644
--- a/src/qt/coincontroldialog.cpp
+++ b/src/qt/coincontroldialog.cpp
@@ -117,6 +117,10 @@ CoinControlDialog::CoinControlDialog(QWidget *parent) :
// (un)select all
connect(ui->pushButtonSelectAll, SIGNAL(clicked()), this, SLOT(buttonSelectAllClicked()));
+ // change coin control first column label due Qt4 bug.
+ // see https://github.com/bitcoin/bitcoin/issues/5716
+ ui->treeWidget->headerItem()->setText(COLUMN_CHECKBOX, QString());
+
ui->treeWidget->setColumnWidth(COLUMN_CHECKBOX, 84);
ui->treeWidget->setColumnWidth(COLUMN_AMOUNT, 100);
ui->treeWidget->setColumnWidth(COLUMN_LABEL, 170);
@@ -213,7 +217,7 @@ void CoinControlDialog::showMenu(const QPoint &point)
if (item->text(COLUMN_TXHASH).length() == 64) // transaction hash is 64 characters (this means its a child node, so its not a parent node in tree mode)
{
copyTransactionHashAction->setEnabled(true);
- if (model->isLockedCoin(uint256(item->text(COLUMN_TXHASH).toStdString()), item->text(COLUMN_VOUT_INDEX).toUInt()))
+ if (model->isLockedCoin(uint256S(item->text(COLUMN_TXHASH).toStdString()), item->text(COLUMN_VOUT_INDEX).toUInt()))
{
lockAction->setEnabled(false);
unlockAction->setEnabled(true);
@@ -272,7 +276,7 @@ void CoinControlDialog::lockCoin()
if (contextMenuItem->checkState(COLUMN_CHECKBOX) == Qt::Checked)
contextMenuItem->setCheckState(COLUMN_CHECKBOX, Qt::Unchecked);
- COutPoint outpt(uint256(contextMenuItem->text(COLUMN_TXHASH).toStdString()), contextMenuItem->text(COLUMN_VOUT_INDEX).toUInt());
+ COutPoint outpt(uint256S(contextMenuItem->text(COLUMN_TXHASH).toStdString()), contextMenuItem->text(COLUMN_VOUT_INDEX).toUInt());
model->lockCoin(outpt);
contextMenuItem->setDisabled(true);
contextMenuItem->setIcon(COLUMN_CHECKBOX, SingleColorIcon(":/icons/lock_closed"));
@@ -282,7 +286,7 @@ void CoinControlDialog::lockCoin()
// context menu action: unlock coin
void CoinControlDialog::unlockCoin()
{
- COutPoint outpt(uint256(contextMenuItem->text(COLUMN_TXHASH).toStdString()), contextMenuItem->text(COLUMN_VOUT_INDEX).toUInt());
+ COutPoint outpt(uint256S(contextMenuItem->text(COLUMN_TXHASH).toStdString()), contextMenuItem->text(COLUMN_VOUT_INDEX).toUInt());
model->unlockCoin(outpt);
contextMenuItem->setDisabled(false);
contextMenuItem->setIcon(COLUMN_CHECKBOX, QIcon());
@@ -304,19 +308,19 @@ void CoinControlDialog::clipboardAmount()
// copy label "Fee" to clipboard
void CoinControlDialog::clipboardFee()
{
- GUIUtil::setClipboard(ui->labelCoinControlFee->text().left(ui->labelCoinControlFee->text().indexOf(" ")).replace("~", ""));
+ GUIUtil::setClipboard(ui->labelCoinControlFee->text().left(ui->labelCoinControlFee->text().indexOf(" ")).replace(ASYMP_UTF8, ""));
}
// copy label "After fee" to clipboard
void CoinControlDialog::clipboardAfterFee()
{
- GUIUtil::setClipboard(ui->labelCoinControlAfterFee->text().left(ui->labelCoinControlAfterFee->text().indexOf(" ")).replace("~", ""));
+ GUIUtil::setClipboard(ui->labelCoinControlAfterFee->text().left(ui->labelCoinControlAfterFee->text().indexOf(" ")).replace(ASYMP_UTF8, ""));
}
// copy label "Bytes" to clipboard
void CoinControlDialog::clipboardBytes()
{
- GUIUtil::setClipboard(ui->labelCoinControlBytes->text().replace("~", ""));
+ GUIUtil::setClipboard(ui->labelCoinControlBytes->text().replace(ASYMP_UTF8, ""));
}
// copy label "Priority" to clipboard
@@ -334,7 +338,7 @@ void CoinControlDialog::clipboardLowOutput()
// copy label "Change" to clipboard
void CoinControlDialog::clipboardChange()
{
- GUIUtil::setClipboard(ui->labelCoinControlChange->text().left(ui->labelCoinControlChange->text().indexOf(" ")).replace("~", ""));
+ GUIUtil::setClipboard(ui->labelCoinControlChange->text().left(ui->labelCoinControlChange->text().indexOf(" ")).replace(ASYMP_UTF8, ""));
}
// treeview: sort
@@ -388,7 +392,7 @@ void CoinControlDialog::viewItemChanged(QTreeWidgetItem* item, int column)
{
if (column == COLUMN_CHECKBOX && item->text(COLUMN_TXHASH).length() == 64) // transaction hash is 64 characters (this means its a child node, so its not a parent node in tree mode)
{
- COutPoint outpt(uint256(item->text(COLUMN_TXHASH).toStdString()), item->text(COLUMN_VOUT_INDEX).toUInt());
+ COutPoint outpt(uint256S(item->text(COLUMN_TXHASH).toStdString()), item->text(COLUMN_VOUT_INDEX).toUInt());
if (item->checkState(COLUMN_CHECKBOX) == Qt::Unchecked)
coinControl->UnSelect(outpt);
@@ -600,16 +604,16 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
l2->setText(BitcoinUnits::formatWithUnit(nDisplayUnit, nAmount)); // Amount
l3->setText(BitcoinUnits::formatWithUnit(nDisplayUnit, nPayFee)); // Fee
l4->setText(BitcoinUnits::formatWithUnit(nDisplayUnit, nAfterFee)); // After Fee
- l5->setText(((nBytes > 0) ? "~" : "") + QString::number(nBytes)); // Bytes
+ l5->setText(((nBytes > 0) ? ASYMP_UTF8 : "") + QString::number(nBytes)); // Bytes
l6->setText(sPriorityLabel); // Priority
l7->setText(fDust ? tr("yes") : tr("no")); // Dust
l8->setText(BitcoinUnits::formatWithUnit(nDisplayUnit, nChange)); // Change
if (nPayFee > 0 && !(payTxFee.GetFeePerK() > 0 && fPayAtLeastCustomFee && nBytes < 1000))
{
- l3->setText("~" + l3->text());
- l4->setText("~" + l4->text());
+ l3->setText(ASYMP_UTF8 + l3->text());
+ l4->setText(ASYMP_UTF8 + l4->text());
if (nChange > 0)
- l8->setText("~" + l8->text());
+ l8->setText(ASYMP_UTF8 + l8->text());
}
// turn labels "red"
diff --git a/src/qt/coincontroldialog.h b/src/qt/coincontroldialog.h
index 0974443066..5a91876f1f 100644
--- a/src/qt/coincontroldialog.h
+++ b/src/qt/coincontroldialog.h
@@ -25,6 +25,8 @@ namespace Ui {
class CoinControlDialog;
}
+#define ASYMP_UTF8 "\xE2\x89\x88"
+
class CoinControlDialog : public QDialog
{
Q_OBJECT
diff --git a/src/qt/coincontroltreewidget.cpp b/src/qt/coincontroltreewidget.cpp
index 6cbcf7128d..5dcbf0c3f1 100644
--- a/src/qt/coincontroltreewidget.cpp
+++ b/src/qt/coincontroltreewidget.cpp
@@ -17,7 +17,8 @@ void CoinControlTreeWidget::keyPressEvent(QKeyEvent *event)
{
event->ignore();
int COLUMN_CHECKBOX = 0;
- this->currentItem()->setCheckState(COLUMN_CHECKBOX, ((this->currentItem()->checkState(COLUMN_CHECKBOX) == Qt::Checked) ? Qt::Unchecked : Qt::Checked));
+ if(this->currentItem())
+ this->currentItem()->setCheckState(COLUMN_CHECKBOX, ((this->currentItem()->checkState(COLUMN_CHECKBOX) == Qt::Checked) ? Qt::Unchecked : Qt::Checked));
}
else if (event->key() == Qt::Key_Escape) // press esc -> close dialog
{
@@ -29,4 +30,4 @@ void CoinControlTreeWidget::keyPressEvent(QKeyEvent *event)
{
this->QTreeWidget::keyPressEvent(event);
}
-} \ No newline at end of file
+}
diff --git a/src/qt/forms/addressbookpage.ui b/src/qt/forms/addressbookpage.ui
index 52fdc6ef06..264edeb720 100644
--- a/src/qt/forms/addressbookpage.ui
+++ b/src/qt/forms/addressbookpage.ui
@@ -27,7 +27,7 @@
<enum>Qt::CustomContextMenu</enum>
</property>
<property name="toolTip">
- <string>Double-click to edit address or label</string>
+ <string>Right-click to edit address or label</string>
</property>
<property name="tabKeyNavigation">
<bool>false</bool>
diff --git a/src/qt/forms/helpmessagedialog.ui b/src/qt/forms/helpmessagedialog.ui
index 81dbd90b12..dc7df9d6c8 100644
--- a/src/qt/forms/helpmessagedialog.ui
+++ b/src/qt/forms/helpmessagedialog.ui
@@ -6,36 +6,91 @@
<rect>
<x>0</x>
<y>0</y>
- <width>800</width>
+ <width>780</width>
<height>400</height>
</rect>
</property>
- <property name="font">
- <font>
- <pointsize>10</pointsize>
- </font>
- </property>
<property name="windowTitle">
<string notr="true">Bitcoin Core - Command-line options</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="leftMargin">
+ <number>12</number>
+ </property>
+ <property name="topMargin">
+ <number>12</number>
+ </property>
+ <property name="rightMargin">
+ <number>12</number>
+ </property>
+ <property name="bottomMargin">
+ <number>12</number>
+ </property>
<item>
- <widget class="QLabel" name="graphic">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Ignored">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
+ <layout class="QVBoxLayout" name="verticalLayoutLogo" stretch="0,0">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>4</number>
</property>
- <property name="pixmap">
- <pixmap resource="../bitcoin.qrc">:/images/about</pixmap>
+ <property name="rightMargin">
+ <number>0</number>
</property>
- </widget>
+ <item>
+ <widget class="QLabel" name="aboutLogo">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Ignored">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>100</width>
+ <height>100</height>
+ </size>
+ </property>
+ <property name="pixmap">
+ <pixmap resource="../bitcoin.qrc">:/icons/bitcoin</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QFrame" name="frame">
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
+ <widget class="QTextEdit" name="helpMessage">
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
<widget class="QScrollArea" name="scrollArea">
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOn</enum>
</property>
@@ -43,23 +98,18 @@
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>659</width>
- <height>348</height>
- </rect>
- </property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
- <widget class="QLabel" name="helpMessageLabel">
+ <widget class="QLabel" name="aboutMessage">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>
</property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
+ </property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
@@ -73,6 +123,22 @@
</widget>
</item>
<item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>4</width>
+ <height>4</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
<widget class="QDialogButtonBox" name="okButton">
<property name="orientation">
<enum>Qt::Horizontal</enum>
diff --git a/src/qt/forms/optionsdialog.ui b/src/qt/forms/optionsdialog.ui
index 19421dc813..55c4f5ac58 100644
--- a/src/qt/forms/optionsdialog.ui
+++ b/src/qt/forms/optionsdialog.ui
@@ -330,7 +330,7 @@
<item>
<widget class="QCheckBox" name="minimizeOnClose">
<property name="toolTip">
- <string>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu.</string>
+ <string>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.</string>
</property>
<property name="text">
<string>M&amp;inimize on close</string>
diff --git a/src/qt/forms/rpcconsole.ui b/src/qt/forms/rpcconsole.ui
index eb7c92cfec..c1eb185501 100644
--- a/src/qt/forms/rpcconsole.ui
+++ b/src/qt/forms/rpcconsole.ui
@@ -1043,7 +1043,30 @@
</property>
</widget>
</item>
- <item row="14" column="1">
+ <item row="14" column="0">
+ <widget class="QLabel" name="label_timeoffset">
+ <property name="text">
+ <string>Time Offset</string>
+ </property>
+ </widget>
+ </item>
+ <item row="14" column="2">
+ <widget class="QLabel" name="timeoffset">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="15" column="1">
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
diff --git a/src/qt/forms/signverifymessagedialog.ui b/src/qt/forms/signverifymessagedialog.ui
index 40b2da3228..92f6430c51 100644
--- a/src/qt/forms/signverifymessagedialog.ui
+++ b/src/qt/forms/signverifymessagedialog.ui
@@ -30,7 +30,7 @@
<item>
<widget class="QLabel" name="infoLabel_SM">
<property name="text">
- <string>You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</string>
+ <string>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.</string>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>
@@ -237,7 +237,7 @@
<item>
<widget class="QLabel" name="infoLabel_VM">
<property name="text">
- <string>Enter the signing 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.</string>
+ <string>Enter the receiver's address, message (ensure you copy line breaks, spaces, tabs, etc. exactly) and signature below to verify the message. Be careful not to read more into the signature than what is in the signed message itself, to avoid being tricked by a man-in-the-middle attack. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction!</string>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>
diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp
index a3ede9fd62..2a13f43ea4 100644
--- a/src/qt/guiutil.cpp
+++ b/src/qt/guiutil.cpp
@@ -67,6 +67,9 @@ static boost::filesystem::detail::utf8_codecvt_facet utf8;
#if defined(Q_OS_MAC)
extern double NSAppKitVersionNumber;
+#if !defined(NSAppKitVersionNumber10_8)
+#define NSAppKitVersionNumber10_8 1187
+#endif
#if !defined(NSAppKitVersionNumber10_9)
#define NSAppKitVersionNumber10_9 1265
#endif
@@ -383,7 +386,7 @@ void openDebugLogfile()
QDesktopServices::openUrl(QUrl::fromLocalFile(boostPathToQString(pathDebug)));
}
-void SubstituteFonts()
+void SubstituteFonts(const QString& language)
{
#if defined(Q_OS_MAC)
// Background:
@@ -393,12 +396,28 @@ void SubstituteFonts()
// If this fallback is not properly loaded, some characters may fail to
// render correctly.
//
+// The same thing happened with 10.10. .Helvetica Neue DeskInterface is now default.
+//
// Solution: If building with the 10.7 SDK or lower and the user's platform
// is 10.9 or higher at runtime, substitute the correct font. This needs to
// happen before the QApplication is created.
#if defined(MAC_OS_X_VERSION_MAX_ALLOWED) && MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_8
- if (floor(NSAppKitVersionNumber) >= NSAppKitVersionNumber10_9)
- QFont::insertSubstitution(".Lucida Grande UI", "Lucida Grande");
+ if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_8)
+ {
+ if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_9)
+ /* On a 10.9 - 10.9.x system */
+ QFont::insertSubstitution(".Lucida Grande UI", "Lucida Grande");
+ else
+ {
+ /* 10.10 or later system */
+ if (language == "zh_CN" || language == "zh_TW" || language == "zh_HK") // traditional or simplified Chinese
+ QFont::insertSubstitution(".Helvetica Neue DeskInterface", "Heiti SC");
+ else if (language == "ja") // Japanesee
+ QFont::insertSubstitution(".Helvetica Neue DeskInterface", "Songti SC");
+ else
+ QFont::insertSubstitution(".Helvetica Neue DeskInterface", "Lucida Grande");
+ }
+ }
#endif
#endif
}
@@ -696,7 +715,18 @@ LSSharedFileListItemRef findStartupItemInList(LSSharedFileListRef list, CFURLRef
LSSharedFileListItemRef item = (LSSharedFileListItemRef)CFArrayGetValueAtIndex(listSnapshot, i);
UInt32 resolutionFlags = kLSSharedFileListNoUserInteraction | kLSSharedFileListDoNotMountVolumes;
CFURLRef currentItemURL = NULL;
- LSSharedFileListItemResolve(item, resolutionFlags, &currentItemURL, NULL);
+
+#if defined(MAC_OS_X_VERSION_MAX_ALLOWED) && MAC_OS_X_VERSION_MAX_ALLOWED >= 10100
+ if(&LSSharedFileListItemCopyResolvedURL)
+ currentItemURL = LSSharedFileListItemCopyResolvedURL(item, resolutionFlags, NULL);
+#if defined(MAC_OS_X_VERSION_MIN_REQUIRED) && MAC_OS_X_VERSION_MIN_REQUIRED < 10100
+ else
+ LSSharedFileListItemResolve(item, resolutionFlags, &currentItemURL, NULL);
+#endif
+#else
+ LSSharedFileListItemResolve(item, resolutionFlags, &currentItemURL, NULL);
+#endif
+
if(currentItemURL && CFEqual(currentItemURL, findUrl)) {
// found
CFRelease(currentItemURL);
@@ -843,4 +873,9 @@ QString formatPingTime(double dPingTime)
return dPingTime == 0 ? QObject::tr("N/A") : QString(QObject::tr("%1 ms")).arg(QString::number((int)(dPingTime * 1000), 10));
}
+QString formatTimeOffset(int64_t nTimeOffset)
+{
+ return QString(QObject::tr("%1 s")).arg(QString::number((int)nTimeOffset, 10));
+}
+
} // namespace GUIUtil
diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h
index 4f8c683147..bcbb540c37 100644
--- a/src/qt/guiutil.h
+++ b/src/qt/guiutil.h
@@ -107,7 +107,7 @@ namespace GUIUtil
void openDebugLogfile();
// Replace invalid default fonts with known good ones
- void SubstituteFonts();
+ void SubstituteFonts(const QString& language);
/** Qt event filter that intercepts ToolTipChange events, and replaces the tooltip with a rich text
representation if needed. This assures that Qt can word-wrap long tooltip messages.
@@ -188,7 +188,10 @@ namespace GUIUtil
/* Format a CNodeCombinedStats.dPingTime into a user-readable string or display N/A, if 0*/
QString formatPingTime(double dPingTime);
-
+
+ /* Format a CNodeCombinedStats.nTimeOffset into a user-readable string. */
+ QString formatTimeOffset(int64_t nTimeOffset);
+
#if defined(Q_OS_MAC) && QT_VERSION >= 0x050000
// workaround for Qt OSX Bug:
// https://bugreports.qt-project.org/browse/QTBUG-15631
diff --git a/src/qt/paymentrequestplus.cpp b/src/qt/paymentrequestplus.cpp
index 35846bc153..4c1e898020 100644
--- a/src/qt/paymentrequestplus.cpp
+++ b/src/qt/paymentrequestplus.cpp
@@ -9,6 +9,8 @@
#include "paymentrequestplus.h"
+#include "util.h"
+
#include <stdexcept>
#include <openssl/x509.h>
@@ -30,18 +32,18 @@ bool PaymentRequestPlus::parse(const QByteArray& data)
{
bool parseOK = paymentRequest.ParseFromArray(data.data(), data.size());
if (!parseOK) {
- qWarning() << "PaymentRequestPlus::parse : Error parsing payment request";
+ qWarning() << "PaymentRequestPlus::parse: Error parsing payment request";
return false;
}
if (paymentRequest.payment_details_version() > 1) {
- qWarning() << "PaymentRequestPlus::parse : Received up-version payment details, version=" << paymentRequest.payment_details_version();
+ qWarning() << "PaymentRequestPlus::parse: Received up-version payment details, version=" << paymentRequest.payment_details_version();
return false;
}
parseOK = details.ParseFromString(paymentRequest.serialized_payment_details());
if (!parseOK)
{
- qWarning() << "PaymentRequestPlus::parse : Error parsing payment details";
+ qWarning() << "PaymentRequestPlus::parse: Error parsing payment details";
paymentRequest.Clear();
return false;
}
@@ -81,17 +83,17 @@ bool PaymentRequestPlus::getMerchant(X509_STORE* certStore, QString& merchant) c
digestAlgorithm = EVP_sha1();
}
else if (paymentRequest.pki_type() == "none") {
- qWarning() << "PaymentRequestPlus::getMerchant : Payment request: pki_type == none";
+ qWarning() << "PaymentRequestPlus::getMerchant: Payment request: pki_type == none";
return false;
}
else {
- qWarning() << "PaymentRequestPlus::getMerchant : Payment request: unknown pki_type " << QString::fromStdString(paymentRequest.pki_type());
+ qWarning() << "PaymentRequestPlus::getMerchant: Payment request: unknown pki_type " << QString::fromStdString(paymentRequest.pki_type());
return false;
}
payments::X509Certificates certChain;
if (!certChain.ParseFromString(paymentRequest.pki_data())) {
- qWarning() << "PaymentRequestPlus::getMerchant : Payment request: error parsing pki_data";
+ qWarning() << "PaymentRequestPlus::getMerchant: Payment request: error parsing pki_data";
return false;
}
@@ -101,12 +103,12 @@ bool PaymentRequestPlus::getMerchant(X509_STORE* certStore, QString& merchant) c
QByteArray certData(certChain.certificate(i).data(), certChain.certificate(i).size());
QSslCertificate qCert(certData, QSsl::Der);
if (currentTime < qCert.effectiveDate() || currentTime > qCert.expiryDate()) {
- qWarning() << "PaymentRequestPlus::getMerchant : Payment request: certificate expired or not yet active: " << qCert;
+ qWarning() << "PaymentRequestPlus::getMerchant: Payment request: certificate expired or not yet active: " << qCert;
return false;
}
#if QT_VERSION >= 0x050000
if (qCert.isBlacklisted()) {
- qWarning() << "PaymentRequestPlus::getMerchant : Payment request: certificate blacklisted: " << qCert;
+ qWarning() << "PaymentRequestPlus::getMerchant: Payment request: certificate blacklisted: " << qCert;
return false;
}
#endif
@@ -116,7 +118,7 @@ bool PaymentRequestPlus::getMerchant(X509_STORE* certStore, QString& merchant) c
certs.push_back(cert);
}
if (certs.empty()) {
- qWarning() << "PaymentRequestPlus::getMerchant : Payment request: empty certificate chain";
+ qWarning() << "PaymentRequestPlus::getMerchant: Payment request: empty certificate chain";
return false;
}
@@ -132,7 +134,7 @@ bool PaymentRequestPlus::getMerchant(X509_STORE* certStore, QString& merchant) c
// load the signing cert into it and verify.
X509_STORE_CTX *store_ctx = X509_STORE_CTX_new();
if (!store_ctx) {
- qWarning() << "PaymentRequestPlus::getMerchant : Payment request: error creating X509_STORE_CTX";
+ qWarning() << "PaymentRequestPlus::getMerchant: Payment request: error creating X509_STORE_CTX";
return false;
}
@@ -150,7 +152,13 @@ bool PaymentRequestPlus::getMerchant(X509_STORE* certStore, QString& merchant) c
int result = X509_verify_cert(store_ctx);
if (result != 1) {
int error = X509_STORE_CTX_get_error(store_ctx);
- throw SSLVerifyError(X509_verify_cert_error_string(error));
+ // For testing payment requests, we allow self signed root certs!
+ // This option is just shown in the UI options, if -help-debug is enabled.
+ if (!(error == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT && GetBoolArg("-allowselfsignedrootcertificates", false))) {
+ throw SSLVerifyError(X509_verify_cert_error_string(error));
+ } else {
+ qDebug() << "PaymentRequestPlus::getMerchant: Allowing self signed root certificate, because -allowselfsignedrootcertificates is true.";
+ }
}
X509_NAME *certname = X509_get_subject_name(signing_cert);
@@ -183,7 +191,7 @@ bool PaymentRequestPlus::getMerchant(X509_STORE* certStore, QString& merchant) c
}
catch (const SSLVerifyError& err) {
fResult = false;
- qWarning() << "PaymentRequestPlus::getMerchant : SSL error: " << err.what();
+ qWarning() << "PaymentRequestPlus::getMerchant: SSL error: " << err.what();
}
if (website)
diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp
index 3f8e89535e..9aab944f6b 100644
--- a/src/qt/paymentserver.cpp
+++ b/src/qt/paymentserver.cpp
@@ -46,7 +46,6 @@
#include <QUrlQuery>
#endif
-using namespace boost;
using namespace std;
const int BITCOIN_IPC_CONNECT_TIMEOUT = 1000; // milliseconds
@@ -98,7 +97,7 @@ static QList<QString> savedPaymentRequests;
static void ReportInvalidCertificate(const QSslCertificate& cert)
{
- qDebug() << "ReportInvalidCertificate : Payment server found an invalid certificate: " << cert.subjectInfo(QSslCertificate::CommonName);
+ qDebug() << "ReportInvalidCertificate: Payment server found an invalid certificate: " << cert.subjectInfo(QSslCertificate::CommonName);
}
//
@@ -125,19 +124,22 @@ void PaymentServer::LoadRootCAs(X509_STORE* _store)
// and get 'I don't like X.509 certificates, don't trust anybody' behavior:
QString certFile = QString::fromStdString(GetArg("-rootcertificates", "-system-"));
- if (certFile.isEmpty())
- return; // Empty store
+ // Empty store
+ if (certFile.isEmpty()) {
+ qDebug() << QString("PaymentServer::%1: Payment request authentication via X.509 certificates disabled.").arg(__func__);
+ return;
+ }
QList<QSslCertificate> certList;
- if (certFile != "-system-")
- {
+ if (certFile != "-system-") {
+ qDebug() << QString("PaymentServer::%1: Using \"%2\" as trusted root certificate.").arg(__func__).arg(certFile);
+
certList = QSslCertificate::fromPath(certFile);
// Use those certificates when fetching payment requests, too:
QSslSocket::setDefaultCaCertificates(certList);
- }
- else
- certList = QSslSocket::systemCaCertificates ();
+ } else
+ certList = QSslSocket::systemCaCertificates();
int nRootCerts = 0;
const QDateTime currentTime = QDateTime::currentDateTime();
@@ -169,7 +171,7 @@ void PaymentServer::LoadRootCAs(X509_STORE* _store)
continue;
}
}
- qWarning() << "PaymentServer::LoadRootCAs : Loaded " << nRootCerts << " root certificates";
+ qWarning() << "PaymentServer::LoadRootCAs: Loaded " << nRootCerts << " root certificates";
// Project for another day:
// Fetch certificate revocation lists, and add them to certStore.
@@ -242,7 +244,7 @@ void PaymentServer::ipcParseCommandLine(int argc, char* argv[])
{
// Printing to debug.log is about the best we can do here, the
// GUI hasn't started yet so we can't pop up a message box.
- qWarning() << "PaymentServer::ipcSendCommandLine : Payment request file does not exist: " << arg;
+ qWarning() << "PaymentServer::ipcSendCommandLine: Payment request file does not exist: " << arg;
}
}
}
@@ -366,10 +368,10 @@ void PaymentServer::initNetManager()
if (optionsModel->getProxySettings(proxy)) {
netManager->setProxy(proxy);
- qDebug() << "PaymentServer::initNetManager : Using SOCKS5 proxy" << proxy.hostName() << ":" << proxy.port();
+ qDebug() << "PaymentServer::initNetManager: Using SOCKS5 proxy" << proxy.hostName() << ":" << proxy.port();
}
else
- qDebug() << "PaymentServer::initNetManager : No active proxy server found.";
+ qDebug() << "PaymentServer::initNetManager: No active proxy server found.";
connect(netManager, SIGNAL(finished(QNetworkReply*)),
this, SLOT(netRequestFinished(QNetworkReply*)));
@@ -413,12 +415,12 @@ void PaymentServer::handleURIOrFile(const QString& s)
if (fetchUrl.isValid())
{
- qDebug() << "PaymentServer::handleURIOrFile : fetchRequest(" << fetchUrl << ")";
+ qDebug() << "PaymentServer::handleURIOrFile: fetchRequest(" << fetchUrl << ")";
fetchRequest(fetchUrl);
}
else
{
- qWarning() << "PaymentServer::handleURIOrFile : Invalid URL: " << fetchUrl;
+ qWarning() << "PaymentServer::handleURIOrFile: Invalid URL: " << fetchUrl;
emit message(tr("URI handling"),
tr("Payment request fetch URL is invalid: %1").arg(fetchUrl.toString()),
CClientUIInterface::ICON_WARNING);
@@ -519,27 +521,23 @@ bool PaymentServer::processPaymentRequest(PaymentRequestPlus& request, SendCoins
return false;
if (request.IsInitialized()) {
- const payments::PaymentDetails& details = request.getDetails();
-
// Payment request network matches client network?
- if (details.network() != Params().NetworkIDString())
- {
+ if (!verifyNetwork(request.getDetails())) {
emit message(tr("Payment request rejected"), tr("Payment request network doesn't match client network."),
CClientUIInterface::MSG_ERROR);
return false;
}
- // Expired payment request?
- if (details.has_expires() && (int64_t)details.expires() < GetTime())
- {
- emit message(tr("Payment request rejected"), tr("Payment request has expired."),
+ // Make sure any payment requests involved are still valid.
+ // This is re-checked just before sending coins in WalletModel::sendCoins().
+ if (verifyExpired(request.getDetails())) {
+ emit message(tr("Payment request rejected"), tr("Payment request expired."),
CClientUIInterface::MSG_ERROR);
return false;
}
- }
- else {
+ } else {
emit message(tr("Payment request error"), tr("Payment request is not initialized."),
CClientUIInterface::MSG_ERROR);
@@ -571,6 +569,14 @@ bool PaymentServer::processPaymentRequest(PaymentRequestPlus& request, SendCoins
return false;
}
+ // Bitcoin amounts are stored as (optional) uint64 in the protobuf messages (see paymentrequest.proto),
+ // but CAmount is defined as int64_t. Because of that we need to verify that amounts are in a valid range
+ // and no overflow has happened.
+ if (!verifyAmount(sendingTo.second)) {
+ emit message(tr("Payment request rejected"), tr("Invalid payment request."), CClientUIInterface::MSG_ERROR);
+ return false;
+ }
+
// Extract and check amounts
CTxOut txOut(sendingTo.second, sendingTo.first);
if (txOut.IsDust(::minRelayTxFee)) {
@@ -582,15 +588,20 @@ bool PaymentServer::processPaymentRequest(PaymentRequestPlus& request, SendCoins
}
recipient.amount += sendingTo.second;
+ // Also verify that the final amount is still in a valid range after adding additional amounts.
+ if (!verifyAmount(recipient.amount)) {
+ emit message(tr("Payment request rejected"), tr("Invalid payment request."), CClientUIInterface::MSG_ERROR);
+ return false;
+ }
}
// Store addresses and format them to fit nicely into the GUI
recipient.address = addresses.join("<br />");
if (!recipient.authenticatedMerchant.isEmpty()) {
- qDebug() << "PaymentServer::processPaymentRequest : Secure payment request from " << recipient.authenticatedMerchant;
+ qDebug() << "PaymentServer::processPaymentRequest: Secure payment request from " << recipient.authenticatedMerchant;
}
else {
- qDebug() << "PaymentServer::processPaymentRequest : Insecure payment request to " << addresses.join(", ");
+ qDebug() << "PaymentServer::processPaymentRequest: Insecure payment request to " << addresses.join(", ");
}
return true;
@@ -645,7 +656,7 @@ void PaymentServer::fetchPaymentACK(CWallet* wallet, SendCoinsRecipient recipien
else {
// This should never happen, because sending coins should have
// just unlocked the wallet and refilled the keypool.
- qWarning() << "PaymentServer::fetchPaymentACK : Error getting refund key, refund_to not set";
+ qWarning() << "PaymentServer::fetchPaymentACK: Error getting refund key, refund_to not set";
}
}
@@ -657,7 +668,7 @@ void PaymentServer::fetchPaymentACK(CWallet* wallet, SendCoinsRecipient recipien
}
else {
// This should never happen, either.
- qWarning() << "PaymentServer::fetchPaymentACK : Error serializing payment message";
+ qWarning() << "PaymentServer::fetchPaymentACK: Error serializing payment message";
}
}
@@ -667,8 +678,7 @@ void PaymentServer::netRequestFinished(QNetworkReply* reply)
// BIP70 DoS protection
if (reply->size() > BIP70_MAX_PAYMENTREQUEST_SIZE) {
- QString msg = tr("Payment request %2 is too large (%3 bytes, allowed %4 bytes).")
- .arg(__func__)
+ QString msg = tr("Payment request %1 is too large (%2 bytes, allowed %3 bytes).")
.arg(reply->request().url().toString())
.arg(reply->size())
.arg(BIP70_MAX_PAYMENTREQUEST_SIZE);
@@ -697,7 +707,7 @@ void PaymentServer::netRequestFinished(QNetworkReply* reply)
SendCoinsRecipient recipient;
if (!request.parse(data))
{
- qWarning() << "PaymentServer::netRequestFinished : Error parsing payment request";
+ qWarning() << "PaymentServer::netRequestFinished: Error parsing payment request";
emit message(tr("Payment request error"),
tr("Payment request cannot be parsed!"),
CClientUIInterface::MSG_ERROR);
@@ -715,7 +725,7 @@ void PaymentServer::netRequestFinished(QNetworkReply* reply)
QString msg = tr("Bad response from server %1")
.arg(reply->request().url().toString());
- qWarning() << "PaymentServer::netRequestFinished : " << msg;
+ qWarning() << "PaymentServer::netRequestFinished: " << msg;
emit message(tr("Payment request error"), msg, CClientUIInterface::MSG_ERROR);
}
else
@@ -731,7 +741,7 @@ void PaymentServer::reportSslErrors(QNetworkReply* reply, const QList<QSslError>
QString errString;
foreach (const QSslError& err, errs) {
- qWarning() << "PaymentServer::reportSslErrors : " << err;
+ qWarning() << "PaymentServer::reportSslErrors: " << err;
errString += err.errorString() + "\n";
}
emit message(tr("Network request error"), errString, CClientUIInterface::MSG_ERROR);
@@ -747,3 +757,39 @@ void PaymentServer::handlePaymentACK(const QString& paymentACKMsg)
// currently we don't futher process or store the paymentACK message
emit message(tr("Payment acknowledged"), paymentACKMsg, CClientUIInterface::ICON_INFORMATION | CClientUIInterface::MODAL);
}
+
+bool PaymentServer::verifyNetwork(const payments::PaymentDetails& requestDetails)
+{
+ bool fVerified = requestDetails.network() == Params().NetworkIDString();
+ if (!fVerified) {
+ qWarning() << QString("PaymentServer::%1: Payment request network \"%2\" doesn't match client network \"%3\".")
+ .arg(__func__)
+ .arg(QString::fromStdString(requestDetails.network()))
+ .arg(QString::fromStdString(Params().NetworkIDString()));
+ }
+ return fVerified;
+}
+
+bool PaymentServer::verifyExpired(const payments::PaymentDetails& requestDetails)
+{
+ bool fVerified = (requestDetails.has_expires() && (int64_t)requestDetails.expires() < GetTime());
+ if (fVerified) {
+ const QString requestExpires = QString::fromStdString(DateTimeStrFormat("%Y-%m-%d %H:%M:%S", (int64_t)requestDetails.expires()));
+ qWarning() << QString("PaymentServer::%1: Payment request expired \"%2\".")
+ .arg(__func__)
+ .arg(requestExpires);
+ }
+ return fVerified;
+}
+
+bool PaymentServer::verifyAmount(const CAmount& requestAmount)
+{
+ bool fVerified = MoneyRange(requestAmount);
+ if (!fVerified) {
+ qWarning() << QString("PaymentServer::%1: Payment request amount out of allowed range (%2, allowed 0 - %3).")
+ .arg(__func__)
+ .arg(requestAmount)
+ .arg(MAX_MONEY);
+ }
+ return fVerified;
+}
diff --git a/src/qt/paymentserver.h b/src/qt/paymentserver.h
index 2fc24395f6..6bf5ac2eea 100644
--- a/src/qt/paymentserver.h
+++ b/src/qt/paymentserver.h
@@ -91,6 +91,13 @@ public:
// This is now public, because we use it in paymentservertests.cpp
static bool readPaymentRequestFromFile(const QString& filename, PaymentRequestPlus& request);
+ // Verify that the payment request network matches the client network
+ static bool verifyNetwork(const payments::PaymentDetails& requestDetails);
+ // Verify if the payment request is expired
+ static bool verifyExpired(const payments::PaymentDetails& requestDetails);
+ // Verify the payment request amount is valid
+ static bool verifyAmount(const CAmount& requestAmount);
+
signals:
// Fired when a valid payment request is received
void receivedPaymentRequest(SendCoinsRecipient);
diff --git a/src/qt/res/icons/about.png b/src/qt/res/icons/about.png
index eeef943355..83eb3c07ee 100644
--- a/src/qt/res/icons/about.png
+++ b/src/qt/res/icons/about.png
Binary files differ
diff --git a/src/qt/res/icons/about_qt.png b/src/qt/res/icons/about_qt.png
index d3665e9892..dd27a99d0a 100644
--- a/src/qt/res/icons/about_qt.png
+++ b/src/qt/res/icons/about_qt.png
Binary files differ
diff --git a/src/qt/res/icons/add.png b/src/qt/res/icons/add.png
index ef995cc0b5..1442b4e85e 100644
--- a/src/qt/res/icons/add.png
+++ b/src/qt/res/icons/add.png
Binary files differ
diff --git a/src/qt/res/icons/address-book.png b/src/qt/res/icons/address-book.png
index 0c9238c18e..b11c7d5356 100644
--- a/src/qt/res/icons/address-book.png
+++ b/src/qt/res/icons/address-book.png
Binary files differ
diff --git a/src/qt/res/icons/bitcoin.png b/src/qt/res/icons/bitcoin.png
index 705a20260a..435621af23 100644
--- a/src/qt/res/icons/bitcoin.png
+++ b/src/qt/res/icons/bitcoin.png
Binary files differ
diff --git a/src/qt/res/icons/clock1.png b/src/qt/res/icons/clock1.png
index 65adba5e21..ceae5ed0d9 100644
--- a/src/qt/res/icons/clock1.png
+++ b/src/qt/res/icons/clock1.png
Binary files differ
diff --git a/src/qt/res/icons/clock2.png b/src/qt/res/icons/clock2.png
index 196a79ce4a..159f69a8fc 100644
--- a/src/qt/res/icons/clock2.png
+++ b/src/qt/res/icons/clock2.png
Binary files differ
diff --git a/src/qt/res/icons/clock3.png b/src/qt/res/icons/clock3.png
index 3d04655ed9..d668e35ffc 100644
--- a/src/qt/res/icons/clock3.png
+++ b/src/qt/res/icons/clock3.png
Binary files differ
diff --git a/src/qt/res/icons/clock4.png b/src/qt/res/icons/clock4.png
index c3210c5af1..5ebf8ed7ac 100644
--- a/src/qt/res/icons/clock4.png
+++ b/src/qt/res/icons/clock4.png
Binary files differ
diff --git a/src/qt/res/icons/clock5.png b/src/qt/res/icons/clock5.png
index 84a9fa2842..96f15ef7d9 100644
--- a/src/qt/res/icons/clock5.png
+++ b/src/qt/res/icons/clock5.png
Binary files differ
diff --git a/src/qt/res/icons/configure.png b/src/qt/res/icons/configure.png
index fe9c6ec5ec..5333c83d5e 100644
--- a/src/qt/res/icons/configure.png
+++ b/src/qt/res/icons/configure.png
Binary files differ
diff --git a/src/qt/res/icons/connect0.png b/src/qt/res/icons/connect0.png
index 99bb2575d6..58e2c3e965 100644
--- a/src/qt/res/icons/connect0.png
+++ b/src/qt/res/icons/connect0.png
Binary files differ
diff --git a/src/qt/res/icons/connect1.png b/src/qt/res/icons/connect1.png
index dffc692c76..949e7a922d 100644
--- a/src/qt/res/icons/connect1.png
+++ b/src/qt/res/icons/connect1.png
Binary files differ
diff --git a/src/qt/res/icons/connect2.png b/src/qt/res/icons/connect2.png
index 3594fb117c..143b2054fb 100644
--- a/src/qt/res/icons/connect2.png
+++ b/src/qt/res/icons/connect2.png
Binary files differ
diff --git a/src/qt/res/icons/connect3.png b/src/qt/res/icons/connect3.png
index 3594fb117c..143b2054fb 100644
--- a/src/qt/res/icons/connect3.png
+++ b/src/qt/res/icons/connect3.png
Binary files differ
diff --git a/src/qt/res/icons/connect4.png b/src/qt/res/icons/connect4.png
index 0c667c7e06..f96e3455ce 100644
--- a/src/qt/res/icons/connect4.png
+++ b/src/qt/res/icons/connect4.png
Binary files differ
diff --git a/src/qt/res/icons/debugwindow.png b/src/qt/res/icons/debugwindow.png
index 576e57ab03..290fe60864 100644
--- a/src/qt/res/icons/debugwindow.png
+++ b/src/qt/res/icons/debugwindow.png
Binary files differ
diff --git a/src/qt/res/icons/edit.png b/src/qt/res/icons/edit.png
index 4df2229e98..46582716ef 100644
--- a/src/qt/res/icons/edit.png
+++ b/src/qt/res/icons/edit.png
Binary files differ
diff --git a/src/qt/res/icons/editcopy.png b/src/qt/res/icons/editcopy.png
index db0c51772c..74ac8b2774 100644
--- a/src/qt/res/icons/editcopy.png
+++ b/src/qt/res/icons/editcopy.png
Binary files differ
diff --git a/src/qt/res/icons/editpaste.png b/src/qt/res/icons/editpaste.png
index be8634674d..7b47f4d52b 100644
--- a/src/qt/res/icons/editpaste.png
+++ b/src/qt/res/icons/editpaste.png
Binary files differ
diff --git a/src/qt/res/icons/export.png b/src/qt/res/icons/export.png
index 18d0596194..ac76cc1eff 100644
--- a/src/qt/res/icons/export.png
+++ b/src/qt/res/icons/export.png
Binary files differ
diff --git a/src/qt/res/icons/eye.png b/src/qt/res/icons/eye.png
index 7036708de5..f2f139dbb2 100644
--- a/src/qt/res/icons/eye.png
+++ b/src/qt/res/icons/eye.png
Binary files differ
diff --git a/src/qt/res/icons/eye_minus.png b/src/qt/res/icons/eye_minus.png
index bdbe073627..795bf6436a 100644
--- a/src/qt/res/icons/eye_minus.png
+++ b/src/qt/res/icons/eye_minus.png
Binary files differ
diff --git a/src/qt/res/icons/eye_plus.png b/src/qt/res/icons/eye_plus.png
index 2ba5e68c76..eaab69297a 100644
--- a/src/qt/res/icons/eye_plus.png
+++ b/src/qt/res/icons/eye_plus.png
Binary files differ
diff --git a/src/qt/res/icons/filesave.png b/src/qt/res/icons/filesave.png
index a53390f594..779cca1d52 100644
--- a/src/qt/res/icons/filesave.png
+++ b/src/qt/res/icons/filesave.png
Binary files differ
diff --git a/src/qt/res/icons/history.png b/src/qt/res/icons/history.png
index cb723abc5f..68d841fa85 100644
--- a/src/qt/res/icons/history.png
+++ b/src/qt/res/icons/history.png
Binary files differ
diff --git a/src/qt/res/icons/info.png b/src/qt/res/icons/info.png
index 085fa8ea73..692b50c2a9 100644
--- a/src/qt/res/icons/info.png
+++ b/src/qt/res/icons/info.png
Binary files differ
diff --git a/src/qt/res/icons/key.png b/src/qt/res/icons/key.png
index d21f81364d..f301c4f38c 100644
--- a/src/qt/res/icons/key.png
+++ b/src/qt/res/icons/key.png
Binary files differ
diff --git a/src/qt/res/icons/lock_closed.png b/src/qt/res/icons/lock_closed.png
index 77914ab2ce..1bd98b21a6 100644
--- a/src/qt/res/icons/lock_closed.png
+++ b/src/qt/res/icons/lock_closed.png
Binary files differ
diff --git a/src/qt/res/icons/lock_open.png b/src/qt/res/icons/lock_open.png
index 50615b7336..a7045133b1 100644
--- a/src/qt/res/icons/lock_open.png
+++ b/src/qt/res/icons/lock_open.png
Binary files differ
diff --git a/src/qt/res/icons/open.png b/src/qt/res/icons/open.png
index 390d3dab64..4d958f0e18 100644
--- a/src/qt/res/icons/open.png
+++ b/src/qt/res/icons/open.png
Binary files differ
diff --git a/src/qt/res/icons/overview.png b/src/qt/res/icons/overview.png
index 36e1003c3c..411595413d 100644
--- a/src/qt/res/icons/overview.png
+++ b/src/qt/res/icons/overview.png
Binary files differ
diff --git a/src/qt/res/icons/quit.png b/src/qt/res/icons/quit.png
index 6e44a2d329..55e34de4b8 100644
--- a/src/qt/res/icons/quit.png
+++ b/src/qt/res/icons/quit.png
Binary files differ
diff --git a/src/qt/res/icons/receive.png b/src/qt/res/icons/receive.png
index a53390f594..f4e6f58d05 100644
--- a/src/qt/res/icons/receive.png
+++ b/src/qt/res/icons/receive.png
Binary files differ
diff --git a/src/qt/res/icons/remove.png b/src/qt/res/icons/remove.png
index 3849cdd6d8..8e738d6301 100644
--- a/src/qt/res/icons/remove.png
+++ b/src/qt/res/icons/remove.png
Binary files differ
diff --git a/src/qt/res/icons/send.png b/src/qt/res/icons/send.png
index 18d0596194..ac76cc1eff 100644
--- a/src/qt/res/icons/send.png
+++ b/src/qt/res/icons/send.png
Binary files differ
diff --git a/src/qt/res/icons/synced.png b/src/qt/res/icons/synced.png
index d33914f0b4..5ac28d36a3 100644
--- a/src/qt/res/icons/synced.png
+++ b/src/qt/res/icons/synced.png
Binary files differ
diff --git a/src/qt/res/icons/transaction0.png b/src/qt/res/icons/transaction0.png
index fd41da0680..1091b86e68 100644
--- a/src/qt/res/icons/transaction0.png
+++ b/src/qt/res/icons/transaction0.png
Binary files differ
diff --git a/src/qt/res/icons/transaction2.png b/src/qt/res/icons/transaction2.png
index d33914f0b4..5ac28d36a3 100644
--- a/src/qt/res/icons/transaction2.png
+++ b/src/qt/res/icons/transaction2.png
Binary files differ
diff --git a/src/qt/res/icons/transaction_conflicted.png b/src/qt/res/icons/transaction_conflicted.png
index 6e44a2d329..55e34de4b8 100644
--- a/src/qt/res/icons/transaction_conflicted.png
+++ b/src/qt/res/icons/transaction_conflicted.png
Binary files differ
diff --git a/src/qt/res/icons/tx_inout.png b/src/qt/res/icons/tx_inout.png
index cecd332ad1..0a6e72a898 100644
--- a/src/qt/res/icons/tx_inout.png
+++ b/src/qt/res/icons/tx_inout.png
Binary files differ
diff --git a/src/qt/res/icons/tx_input.png b/src/qt/res/icons/tx_input.png
index 1b4cfd967c..9e9ee92932 100644
--- a/src/qt/res/icons/tx_input.png
+++ b/src/qt/res/icons/tx_input.png
Binary files differ
diff --git a/src/qt/res/icons/tx_mined.png b/src/qt/res/icons/tx_mined.png
index 421a9cf639..5a6ef521c0 100644
--- a/src/qt/res/icons/tx_mined.png
+++ b/src/qt/res/icons/tx_mined.png
Binary files differ
diff --git a/src/qt/res/icons/tx_output.png b/src/qt/res/icons/tx_output.png
index 06d9d0adf2..6f66ab6547 100644
--- a/src/qt/res/icons/tx_output.png
+++ b/src/qt/res/icons/tx_output.png
Binary files differ
diff --git a/src/qt/res/icons/unit_btc.png b/src/qt/res/icons/unit_btc.png
deleted file mode 100644
index f3246fa999..0000000000
--- a/src/qt/res/icons/unit_btc.png
+++ /dev/null
Binary files differ
diff --git a/src/qt/res/icons/unit_mbtc.png b/src/qt/res/icons/unit_mbtc.png
deleted file mode 100644
index 4e82b65274..0000000000
--- a/src/qt/res/icons/unit_mbtc.png
+++ /dev/null
Binary files differ
diff --git a/src/qt/res/icons/unit_ubtc.png b/src/qt/res/icons/unit_ubtc.png
deleted file mode 100644
index 96b254770d..0000000000
--- a/src/qt/res/icons/unit_ubtc.png
+++ /dev/null
Binary files differ
diff --git a/src/qt/res/icons/verify.png b/src/qt/res/icons/verify.png
index 9ff35c2793..8e2cb2cc14 100644
--- a/src/qt/res/icons/verify.png
+++ b/src/qt/res/icons/verify.png
Binary files differ
diff --git a/src/qt/res/images/about.png b/src/qt/res/images/about.png
deleted file mode 100644
index fdede66172..0000000000
--- a/src/qt/res/images/about.png
+++ /dev/null
Binary files differ
diff --git a/src/qt/res/movies/spinner-000.png b/src/qt/res/movies/spinner-000.png
index b296a58481..1e92d859da 100644
--- a/src/qt/res/movies/spinner-000.png
+++ b/src/qt/res/movies/spinner-000.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-001.png b/src/qt/res/movies/spinner-001.png
index 4f6f9a487b..d167f20541 100644
--- a/src/qt/res/movies/spinner-001.png
+++ b/src/qt/res/movies/spinner-001.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-002.png b/src/qt/res/movies/spinner-002.png
index 4f14e3ca93..4a1f1f8e56 100644
--- a/src/qt/res/movies/spinner-002.png
+++ b/src/qt/res/movies/spinner-002.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-003.png b/src/qt/res/movies/spinner-003.png
index d7756e73bf..fb1c2cd4ad 100644
--- a/src/qt/res/movies/spinner-003.png
+++ b/src/qt/res/movies/spinner-003.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-004.png b/src/qt/res/movies/spinner-004.png
index 4b381b81b2..4df2132344 100644
--- a/src/qt/res/movies/spinner-004.png
+++ b/src/qt/res/movies/spinner-004.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-005.png b/src/qt/res/movies/spinner-005.png
index cbdb5b5797..5d6f41e0dc 100644
--- a/src/qt/res/movies/spinner-005.png
+++ b/src/qt/res/movies/spinner-005.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-006.png b/src/qt/res/movies/spinner-006.png
index 55d4540c92..c1f7d18899 100644
--- a/src/qt/res/movies/spinner-006.png
+++ b/src/qt/res/movies/spinner-006.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-007.png b/src/qt/res/movies/spinner-007.png
index b25f59a445..1e794b2626 100644
--- a/src/qt/res/movies/spinner-007.png
+++ b/src/qt/res/movies/spinner-007.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-008.png b/src/qt/res/movies/spinner-008.png
index 6493184a7a..df12ea8719 100644
--- a/src/qt/res/movies/spinner-008.png
+++ b/src/qt/res/movies/spinner-008.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-009.png b/src/qt/res/movies/spinner-009.png
index 938c49f9d3..18fc3a7d16 100644
--- a/src/qt/res/movies/spinner-009.png
+++ b/src/qt/res/movies/spinner-009.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-010.png b/src/qt/res/movies/spinner-010.png
index 7eb645eda5..a79c845fe8 100644
--- a/src/qt/res/movies/spinner-010.png
+++ b/src/qt/res/movies/spinner-010.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-011.png b/src/qt/res/movies/spinner-011.png
index fd4b63ca5a..57baf66895 100644
--- a/src/qt/res/movies/spinner-011.png
+++ b/src/qt/res/movies/spinner-011.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-012.png b/src/qt/res/movies/spinner-012.png
index 10d26a3a53..9deae7853a 100644
--- a/src/qt/res/movies/spinner-012.png
+++ b/src/qt/res/movies/spinner-012.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-013.png b/src/qt/res/movies/spinner-013.png
index 863a9d2908..0659d48dec 100644
--- a/src/qt/res/movies/spinner-013.png
+++ b/src/qt/res/movies/spinner-013.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-014.png b/src/qt/res/movies/spinner-014.png
index d01086cb98..bc1ef51bde 100644
--- a/src/qt/res/movies/spinner-014.png
+++ b/src/qt/res/movies/spinner-014.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-015.png b/src/qt/res/movies/spinner-015.png
index 402dbea693..24b57b62c2 100644
--- a/src/qt/res/movies/spinner-015.png
+++ b/src/qt/res/movies/spinner-015.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-016.png b/src/qt/res/movies/spinner-016.png
index 1db20e6078..d622872651 100644
--- a/src/qt/res/movies/spinner-016.png
+++ b/src/qt/res/movies/spinner-016.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-017.png b/src/qt/res/movies/spinner-017.png
index e2c2e2ef78..f48f688db2 100644
--- a/src/qt/res/movies/spinner-017.png
+++ b/src/qt/res/movies/spinner-017.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-018.png b/src/qt/res/movies/spinner-018.png
index 6f1fe73756..a2c8f38b1d 100644
--- a/src/qt/res/movies/spinner-018.png
+++ b/src/qt/res/movies/spinner-018.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-019.png b/src/qt/res/movies/spinner-019.png
index 5f18f65608..9d7cc35d82 100644
--- a/src/qt/res/movies/spinner-019.png
+++ b/src/qt/res/movies/spinner-019.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-020.png b/src/qt/res/movies/spinner-020.png
index c12ae20016..1a07acc454 100644
--- a/src/qt/res/movies/spinner-020.png
+++ b/src/qt/res/movies/spinner-020.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-021.png b/src/qt/res/movies/spinner-021.png
index d81ceade23..9cea8f2543 100644
--- a/src/qt/res/movies/spinner-021.png
+++ b/src/qt/res/movies/spinner-021.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-022.png b/src/qt/res/movies/spinner-022.png
index 69c6657942..60250f6dea 100644
--- a/src/qt/res/movies/spinner-022.png
+++ b/src/qt/res/movies/spinner-022.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-023.png b/src/qt/res/movies/spinner-023.png
index 7bed5bae85..fc290a0cf2 100644
--- a/src/qt/res/movies/spinner-023.png
+++ b/src/qt/res/movies/spinner-023.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-024.png b/src/qt/res/movies/spinner-024.png
index b3be8d3e8e..c5dcf1eae9 100644
--- a/src/qt/res/movies/spinner-024.png
+++ b/src/qt/res/movies/spinner-024.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-025.png b/src/qt/res/movies/spinner-025.png
index 3a7fa9ab0d..7f3577a4de 100644
--- a/src/qt/res/movies/spinner-025.png
+++ b/src/qt/res/movies/spinner-025.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-026.png b/src/qt/res/movies/spinner-026.png
index dd92fc4fc1..1663ddf44c 100644
--- a/src/qt/res/movies/spinner-026.png
+++ b/src/qt/res/movies/spinner-026.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-027.png b/src/qt/res/movies/spinner-027.png
index 9adefee268..d0e6da4503 100644
--- a/src/qt/res/movies/spinner-027.png
+++ b/src/qt/res/movies/spinner-027.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-028.png b/src/qt/res/movies/spinner-028.png
index 83e7cdd583..2a7aba50e2 100644
--- a/src/qt/res/movies/spinner-028.png
+++ b/src/qt/res/movies/spinner-028.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-029.png b/src/qt/res/movies/spinner-029.png
index 6cbdbb0fe1..c8ca15c1e1 100644
--- a/src/qt/res/movies/spinner-029.png
+++ b/src/qt/res/movies/spinner-029.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-030.png b/src/qt/res/movies/spinner-030.png
index e4a09a44bc..c847c99a93 100644
--- a/src/qt/res/movies/spinner-030.png
+++ b/src/qt/res/movies/spinner-030.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-031.png b/src/qt/res/movies/spinner-031.png
index 3c3d505741..403443144e 100644
--- a/src/qt/res/movies/spinner-031.png
+++ b/src/qt/res/movies/spinner-031.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-032.png b/src/qt/res/movies/spinner-032.png
index 7460f80da3..f9db080567 100644
--- a/src/qt/res/movies/spinner-032.png
+++ b/src/qt/res/movies/spinner-032.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-033.png b/src/qt/res/movies/spinner-033.png
index d327e8fb08..43f57719e7 100644
--- a/src/qt/res/movies/spinner-033.png
+++ b/src/qt/res/movies/spinner-033.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-034.png b/src/qt/res/movies/spinner-034.png
index d8432751da..c26656ff17 100644
--- a/src/qt/res/movies/spinner-034.png
+++ b/src/qt/res/movies/spinner-034.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-035.png b/src/qt/res/movies/spinner-035.png
index c89c959c94..e471f950a3 100644
--- a/src/qt/res/movies/spinner-035.png
+++ b/src/qt/res/movies/spinner-035.png
Binary files differ
diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp
index a5e3ae2b35..9f3991c4c5 100644
--- a/src/qt/rpcconsole.cpp
+++ b/src/qt/rpcconsole.cpp
@@ -610,6 +610,7 @@ void RPCConsole::updateNodeDetail(const CNodeCombinedStats *stats)
ui->peerBytesRecv->setText(FormatBytes(stats->nodeStats.nRecvBytes));
ui->peerConnTime->setText(GUIUtil::formatDurationStr(GetTime() - stats->nodeStats.nTimeConnected));
ui->peerPingTime->setText(GUIUtil::formatPingTime(stats->nodeStats.dPingTime));
+ ui->timeoffset->setText(GUIUtil::formatTimeOffset(stats->nodeStats.nTimeOffset));
ui->peerVersion->setText(QString("%1").arg(stats->nodeStats.nVersion));
ui->peerSubversion->setText(QString::fromStdString(stats->nodeStats.cleanSubVer));
ui->peerDirection->setText(stats->nodeStats.fInbound ? tr("Inbound") : tr("Outbound"));
diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp
index ffee56131d..5aef2d7539 100644
--- a/src/qt/sendcoinsdialog.cpp
+++ b/src/qt/sendcoinsdialog.cpp
@@ -526,8 +526,12 @@ void SendCoinsDialog::processSendCoinsReturn(const WalletModel::SendCoinsReturn
msgParams.first = tr("The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here.");
msgParams.second = CClientUIInterface::MSG_ERROR;
break;
- case WalletModel::InsaneFee:
- msgParams.first = tr("A fee higher than %1 is considered an insanely high fee.").arg(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), 10000000));
+ case WalletModel::AbsurdFee:
+ msgParams.first = tr("A fee higher than %1 is considered an absurdly high fee.").arg(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), 10000000));
+ break;
+ case WalletModel::PaymentRequestExpired:
+ msgParams.first = tr("Payment request expired!");
+ msgParams.second = CClientUIInterface::MSG_ERROR;
break;
// included to prevent a compiler warning.
case WalletModel::OK:
@@ -657,19 +661,19 @@ void SendCoinsDialog::coinControlClipboardAmount()
// Coin Control: copy label "Fee" to clipboard
void SendCoinsDialog::coinControlClipboardFee()
{
- GUIUtil::setClipboard(ui->labelCoinControlFee->text().left(ui->labelCoinControlFee->text().indexOf(" ")).replace("~", ""));
+ GUIUtil::setClipboard(ui->labelCoinControlFee->text().left(ui->labelCoinControlFee->text().indexOf(" ")).replace(ASYMP_UTF8, ""));
}
// Coin Control: copy label "After fee" to clipboard
void SendCoinsDialog::coinControlClipboardAfterFee()
{
- GUIUtil::setClipboard(ui->labelCoinControlAfterFee->text().left(ui->labelCoinControlAfterFee->text().indexOf(" ")).replace("~", ""));
+ GUIUtil::setClipboard(ui->labelCoinControlAfterFee->text().left(ui->labelCoinControlAfterFee->text().indexOf(" ")).replace(ASYMP_UTF8, ""));
}
// Coin Control: copy label "Bytes" to clipboard
void SendCoinsDialog::coinControlClipboardBytes()
{
- GUIUtil::setClipboard(ui->labelCoinControlBytes->text().replace("~", ""));
+ GUIUtil::setClipboard(ui->labelCoinControlBytes->text().replace(ASYMP_UTF8, ""));
}
// Coin Control: copy label "Priority" to clipboard
@@ -687,7 +691,7 @@ void SendCoinsDialog::coinControlClipboardLowOutput()
// Coin Control: copy label "Change" to clipboard
void SendCoinsDialog::coinControlClipboardChange()
{
- GUIUtil::setClipboard(ui->labelCoinControlChange->text().left(ui->labelCoinControlChange->text().indexOf(" ")).replace("~", ""));
+ GUIUtil::setClipboard(ui->labelCoinControlChange->text().left(ui->labelCoinControlChange->text().indexOf(" ")).replace(ASYMP_UTF8, ""));
}
// Coin Control: settings menu - coin control enabled/disabled by user
diff --git a/src/qt/splashscreen.cpp b/src/qt/splashscreen.cpp
index 366ed3df3d..e6a7fcaec5 100644
--- a/src/qt/splashscreen.cpp
+++ b/src/qt/splashscreen.cpp
@@ -42,7 +42,7 @@ SplashScreen::SplashScreen(Qt::WindowFlags f, const NetworkStyle *networkStyle)
QString copyrightText = QChar(0xA9)+QString(" 2009-%1 ").arg(COPYRIGHT_YEAR) + QString(tr("The Bitcoin Core developers"));
QString titleAddText = networkStyle->getTitleAddText();
- QString font = "Arial";
+ QString font = QApplication::font().toString();
// create a bitmap according to device pixelratio
QSize splashSize(480*devicePixelRatio,320*devicePixelRatio);
diff --git a/src/qt/test/paymentrequestdata.h b/src/qt/test/paymentrequestdata.h
index 37544cdebb..c548ffe429 100644
--- a/src/qt/test/paymentrequestdata.h
+++ b/src/qt/test/paymentrequestdata.h
@@ -6,16 +6,16 @@
// Data for paymentservertests.cpp
//
-// Base64/DER-encoded fake certificate authority certificate.
+// Base64/DER-encoded fake certificate authority certificates.
// Convert pem to base64/der with:
-// cat file.pem | openssl x509 -inform PEM -outform DER | openssl enc -base64
-//
+// openssl x509 -in cert.pem -inform PEM -outform DER | openssl enc -base64
+
// Serial Number: 10302349811211485352 (0x8ef94c91b112c0a8)
// Issuer: CN=PaymentRequest Test CA
// Subject: CN=PaymentRequest Test CA
// Not Valid After : Dec 8 16:37:24 2022 GMT
//
-const char* caCert_BASE64 =
+const char* caCert1_BASE64 =
"\
MIIB0DCCATmgAwIBAgIJAI75TJGxEsCoMA0GCSqGSIb3DQEBCwUAMCExHzAdBgNV\
BAMTFlBheW1lbnRSZXF1ZXN0IFRlc3QgQ0EwHhcNMTIxMjEwMTYzNzI0WhcNMjIx\
@@ -29,11 +29,36 @@ RtQcf0AJ9olzUMY4syehxbzUJP6aeXhZEYiMvdvcv9D55clq6+WLLlNT3jBgAaVn\
p3waRjPD4bUX3nv+ojz5s4puw7Qq5QUZlhGsMzPvwDGCmZkL\
";
+// Serial Number: f0:da:97:e4:38:d7:64:16
+// Issuer: CN=PaymentRequest Test CA
+// Subject: CN=PaymentRequest Test CA
+// Not Valid After : Jan 8 18:21:06 2025 GMT
+//
+const char* caCert2_BASE64 =
+"\
+MIIC1TCCAb2gAwIBAgIJAPDal+Q412QWMA0GCSqGSIb3DQEBCwUAMCExHzAdBgNV\
+BAMMFlBheW1lbnRSZXF1ZXN0IFRlc3QgQ0EwHhcNMTUwMTExMTgyMTA2WhcNMjUw\
+MTA4MTgyMTA2WjAhMR8wHQYDVQQDDBZQYXltZW50UmVxdWVzdCBUZXN0IENBMIIB\
+IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1S9wVLfTplJuT/1OaaBgl/Mb\
+I392v8S9kHbzYz7B4OTMslaO7piz0v3SO3TKMh0dswjiRdHrIgpO7XdIUQiU/ugg\
+xDw0kuNehfz1ycaGedlFFtFHTNXqLyIUF3dlwHhQwaomM6RXoJmxLny5BhYHEcmk\
+yWwr3Cdjd9gAZpblugVJB9C1e40uyL8ao4PHdLzOqO27iSe6riP8SwwisJZEbMaz\
+AZpgNEEMbIXPJEFvm5HTRXSMtQCOTSZYMFF0M2yrtmlECnz7hWP19b9bcoDzZQB4\
+ylIsFG/7q2jV7MC/e2STZv+niJiHL08RUdoFpAgzaxMgqj63C7B55HgNDNHJYQID\
+AQABoxAwDjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBGejPxLxj9\
++crv6gUeEBMZPiUx7pUgcI22Wm5yymP96B4fwI3Y0DBehq20d76vbWGPN17Z6pH3\
+ge7PVY1SYqXtS6hXTo4olCm/BZADli+2Bs2xCiaa+Ltve4ufVej+bKJXN/YnrhvO\
+Kq+klQkuuHywU+GJV/NQeBqToIrSOBgi477NgLFCCCmmx2QWsxHoCFGfuRCBVseT\
+z2k/tMuALCDXGeZBRPTsGHu1y4cj84swAeoDK5QSQcI+Ub7GKc+zkoj02sdDLiMo\
+3wokYPcIy47oclhmb4xubHc+y7nF610yZBoC/zgbhbawnZ65hDDWkdQ/SVAnWZD7\
+9PFfmNnYPTQH\
+";
+
//
// This payment request validates directly against the
-// above certificate authority.
+// caCert1 certificate authority.
//
-const char* paymentrequest1_BASE64 =
+const char* paymentrequest1_cert1_BASE64 =
"\
Egt4NTA5K3NoYTI1NhrxAwruAzCCAeowggFToAMCAQICAQEwDQYJKoZIhvcNAQEL\
BQAwITEfMB0GA1UEAxMWUGF5bWVudFJlcXVlc3QgVGVzdCBDQTAeFw0xMjEyMTAx\
@@ -55,7 +80,7 @@ SiWVbw0tX/68iSQEGGfh9n6ee/8Myb3ICdw=\
//
// Signed, but expired, merchant cert in the request
//
-const char* paymentrequest2_BASE64 =
+const char* paymentrequest2_cert1_BASE64 =
"\
Egt4NTA5K3NoYTI1NhrsAwrpAzCCAeUwggFOoAMCAQICAQMwDQYJKoZIhvcNAQEL\
BQAwITEfMB0GA1UEAxMWUGF5bWVudFJlcXVlc3QgVGVzdCBDQTAeFw0xMzAyMjMy\
@@ -75,9 +100,9 @@ tejrSPOBNSJ3Mi/q5u2Yl4gJZY2b\
";
//
-// 10-long chain, all intermediates valid
+// 10-long certificate chain, all intermediates valid
//
-const char* paymentrequest3_BASE64 =
+const char* paymentrequest3_cert1_BASE64 =
"\
Egt4NTA5K3NoYTI1Nhq8JAr/AzCCAfswggFkoAMCAQICAQEwDQYJKoZIhvcNAQEL\
BQAwPzEUMBIGA1UEAwwLdGVzdGNhOC5vcmcxJzAlBgNVBAoMHlBheW1lbnQgUmVx\
@@ -184,9 +209,9 @@ chhR/aHOuEMTxmc12K4rNlgYtHCsxLP9zd+6u0cva3TucZ6EzS8PKEib/+r12/52\
";
//
-// Long chain, with an invalid (expired) cert in the middle
+// Long certificate chain, with an expired certificate in the middle
//
-const char* paymentrequest4_BASE64 =
+const char* paymentrequest4_cert1_BASE64 =
"\
Egt4NTA5K3NoYTI1NhqeJAr/AzCCAfswggFkoAMCAQICAQEwDQYJKoZIhvcNAQEL\
BQAwPzEUMBIGA1UEAwwLdGVzdGNhOC5vcmcxJzAlBgNVBAoMHlBheW1lbnQgUmVx\
@@ -291,7 +316,10 @@ HXQjsfdR58qZQS9CS5DAtRUf0R8+43/wijO/hb49VNaNXmY+/cPHMkahP2aV3tZi\
FAyZblLik9A7ZvF+UsjeFQiHB5wzWQvbqk5wQ4yabHIXoYv/E0q+eQ==\
";
-const char* paymentrequest5_BASE64 =
+//
+// Validly signed, but by a CA not in our root CA list
+//
+const char* paymentrequest5_cert1_BASE64 =
"\
Egt4NTA5K3NoYTI1NhrxAwruAzCCAeowggFToAMCAQICAQEwDQYJKoZIhvcNAQEL\
BQAwITEfMB0GA1UEAxMWUGF5bWVudFJlcXVlc3QgVGVzdCBDQTAeFw0xMzA0MTkx\
@@ -309,3 +337,124 @@ ssymvca1S/1KeM3n8Ydi2fi1JUzAAr59xPvNJRUeqCLP9upHn5z7br3P12Oz9A20\
5/4wL4ClPRPVnOHgij0bEg+y0tGESqmF1rfOfXDszlo2U92wCxS07kq79YAZJ1Zo\
XYh860/Q4wvc7lfiTe+dXBzPKAKhMy91yETY\
";
+
+//
+// Contains a testnet paytoaddress, so payment request network doesn't match client network
+//
+const char* paymentrequest1_cert2_BASE64 =
+"\
+Egt4NTA5K3NoYTI1NhrQBArNBDCCAkkwggExoAMCAQICAQEwDQYJKoZIhvcNAQEL\
+BQAwITEfMB0GA1UEAwwWUGF5bWVudFJlcXVlc3QgVGVzdCBDQTAeFw0xNTAxMTEx\
+ODIxMDhaFw0yNTAxMDgxODIxMDhaMCExHzAdBgNVBAMMFlBheW1lbnRSZXF1ZXN0\
+IFRlc3QgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMsZqzkzeBGo+i2N\
+mUak3Ciodr1V7S062VOy7N0OQYNDQHYkgDFAUET7cEb5VJaHPv5m3ppTBpU9xBcf\
+wbHHUt4VjA+mhRmYrl1khjvZM+X8kEqvWn20BtcM9R6r0yIYec8UERDDHBleL/P8\
+RkxEnVLjYTV9zigCXfMsgYb3EQShAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJ\
+KoZIhvcNAQELBQADggEBABUJpl3QCqsoDSxAsQdV6zKT4VGV76AzoGj7etQsQY+r\
++S26VfWh/fMobEzuxFChr0USgLJ6FoK78hAtoZvt1lrye9yqFv/ig3WLWsJKWHHb\
+3RT6oR03CIwZXFSUasi08QDVLxafwsU5OMcPLucF3a1lRL1ccYrNgVCCx1+X7Bos\
+tIgDGRQQ4AyoHTcfVd2hEGeUv7k14mOxFsAp6851yosHq9Q2kwmdH+rHEJbjof87\
+yyKLagc4owyXBZYkQmkeHWCNqnuRmO5vUsfVb0UUrkD64o7Th/NjwooA7SCiUXl6\
+dfygT1b7ggpx7GC+sP2DsIM47IAZ55drjqX5u2f+Ba0iPQoEdGVzdBIhCIDWwowE\
+Ehl2qRQErGqUUwSsaMpDvWIaGnJGNQqi8oisGNeMy6UFKgxKdXN0IFRlc3Rpbmcq\
+gAFwThsozZxkZxzCn4R8WxNiLFV6m0ye9fEtSbolfaW+EjBMpO03lr/dwNnrclhg\
+ew+A05xfZztrAt16XKEY7qKJ/eY2nLd0fVAIu/nIt+7/VYVXT83zLrWc150aRS7W\
+AdJbL3JOJLs6Eyp5zrPbfI8faRttFAdONKDrJgIpuW1E3g==\
+";
+
+//
+// Expired payment request (expires is set to 1 = 1970-01-01 00:00:01)
+//
+const char* paymentrequest2_cert2_BASE64 =
+"\
+Egt4NTA5K3NoYTI1NhrQBArNBDCCAkkwggExoAMCAQICAQEwDQYJKoZIhvcNAQEL\
+BQAwITEfMB0GA1UEAwwWUGF5bWVudFJlcXVlc3QgVGVzdCBDQTAeFw0xNTAxMTEx\
+ODIxMDhaFw0yNTAxMDgxODIxMDhaMCExHzAdBgNVBAMMFlBheW1lbnRSZXF1ZXN0\
+IFRlc3QgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMsZqzkzeBGo+i2N\
+mUak3Ciodr1V7S062VOy7N0OQYNDQHYkgDFAUET7cEb5VJaHPv5m3ppTBpU9xBcf\
+wbHHUt4VjA+mhRmYrl1khjvZM+X8kEqvWn20BtcM9R6r0yIYec8UERDDHBleL/P8\
+RkxEnVLjYTV9zigCXfMsgYb3EQShAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJ\
+KoZIhvcNAQELBQADggEBABUJpl3QCqsoDSxAsQdV6zKT4VGV76AzoGj7etQsQY+r\
++S26VfWh/fMobEzuxFChr0USgLJ6FoK78hAtoZvt1lrye9yqFv/ig3WLWsJKWHHb\
+3RT6oR03CIwZXFSUasi08QDVLxafwsU5OMcPLucF3a1lRL1ccYrNgVCCx1+X7Bos\
+tIgDGRQQ4AyoHTcfVd2hEGeUv7k14mOxFsAp6851yosHq9Q2kwmdH+rHEJbjof87\
+yyKLagc4owyXBZYkQmkeHWCNqnuRmO5vUsfVb0UUrkD64o7Th/NjwooA7SCiUXl6\
+dfygT1b7ggpx7GC+sP2DsIM47IAZ55drjqX5u2f+Ba0iQgoEdGVzdBIgCICt4gQS\
+GXapFASsapRTBKxoykO9YhoackY1CqLyiKwYiNLUpQUgASoQVGVzdGluZyB0ZXN0\
+bmV0ISqAATXq9A5nmJgtmee/bQTeHeif4w1YYFPBlKghwx6qbVgXTWnwBJtOQhhV\
+sZdzbTl95ENR7/Y7VJupW9kDWobCK7zUUhLAzUlwmLlcx6itHw8LTUF5HK+AwsZm\
+Zs85lISGvOS0NZW/ENa6l+oQRnL87oqVZr/EDGiuqjz6T0ThQi0l\
+";
+
+//
+// Unexpired payment request (expires is set to 0x7FFFFFFFFFFFFFFF = max. int64_t)
+//
+const char* paymentrequest3_cert2_BASE64 =
+"\
+Egt4NTA5K3NoYTI1NhrQBArNBDCCAkkwggExoAMCAQICAQEwDQYJKoZIhvcNAQEL\
+BQAwITEfMB0GA1UEAwwWUGF5bWVudFJlcXVlc3QgVGVzdCBDQTAeFw0xNTAxMTEx\
+ODIxMDhaFw0yNTAxMDgxODIxMDhaMCExHzAdBgNVBAMMFlBheW1lbnRSZXF1ZXN0\
+IFRlc3QgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMsZqzkzeBGo+i2N\
+mUak3Ciodr1V7S062VOy7N0OQYNDQHYkgDFAUET7cEb5VJaHPv5m3ppTBpU9xBcf\
+wbHHUt4VjA+mhRmYrl1khjvZM+X8kEqvWn20BtcM9R6r0yIYec8UERDDHBleL/P8\
+RkxEnVLjYTV9zigCXfMsgYb3EQShAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJ\
+KoZIhvcNAQELBQADggEBABUJpl3QCqsoDSxAsQdV6zKT4VGV76AzoGj7etQsQY+r\
++S26VfWh/fMobEzuxFChr0USgLJ6FoK78hAtoZvt1lrye9yqFv/ig3WLWsJKWHHb\
+3RT6oR03CIwZXFSUasi08QDVLxafwsU5OMcPLucF3a1lRL1ccYrNgVCCx1+X7Bos\
+tIgDGRQQ4AyoHTcfVd2hEGeUv7k14mOxFsAp6851yosHq9Q2kwmdH+rHEJbjof87\
+yyKLagc4owyXBZYkQmkeHWCNqnuRmO5vUsfVb0UUrkD64o7Th/NjwooA7SCiUXl6\
+dfygT1b7ggpx7GC+sP2DsIM47IAZ55drjqX5u2f+Ba0iSgoEdGVzdBIgCICt4gQS\
+GXapFASsapRTBKxoykO9YhoackY1CqLyiKwYyNfZpQUg//////////9/KhBUZXN0\
+aW5nIHRlc3RuZXQhKoABNwi8WnMW4aMvbmvorTiiWJLFhofLFnsoWCJnj3rWLnLh\
+n3w6q/fZ26p50ERL/noxdTUfeFsKnlECkUu/fOcOrqyYDiwvxI0SZ034DleVyFU1\
+Z3T+X0zcL8oe7bX01Yf+s2V+5JXQXarKnKBrZCGgv2ARjFNSZe7E7vGg5K4Q6Q8=\
+";
+
+//
+// Unexpired payment request (expires is set to 0x8000000000000000 > max. int64_t, allowed uint64)
+//
+const char* paymentrequest4_cert2_BASE64 =
+"\
+Egt4NTA5K3NoYTI1NhrQBArNBDCCAkkwggExoAMCAQICAQEwDQYJKoZIhvcNAQEL\
+BQAwITEfMB0GA1UEAwwWUGF5bWVudFJlcXVlc3QgVGVzdCBDQTAeFw0xNTAxMTEx\
+ODIxMDhaFw0yNTAxMDgxODIxMDhaMCExHzAdBgNVBAMMFlBheW1lbnRSZXF1ZXN0\
+IFRlc3QgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMsZqzkzeBGo+i2N\
+mUak3Ciodr1V7S062VOy7N0OQYNDQHYkgDFAUET7cEb5VJaHPv5m3ppTBpU9xBcf\
+wbHHUt4VjA+mhRmYrl1khjvZM+X8kEqvWn20BtcM9R6r0yIYec8UERDDHBleL/P8\
+RkxEnVLjYTV9zigCXfMsgYb3EQShAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJ\
+KoZIhvcNAQELBQADggEBABUJpl3QCqsoDSxAsQdV6zKT4VGV76AzoGj7etQsQY+r\
++S26VfWh/fMobEzuxFChr0USgLJ6FoK78hAtoZvt1lrye9yqFv/ig3WLWsJKWHHb\
+3RT6oR03CIwZXFSUasi08QDVLxafwsU5OMcPLucF3a1lRL1ccYrNgVCCx1+X7Bos\
+tIgDGRQQ4AyoHTcfVd2hEGeUv7k14mOxFsAp6851yosHq9Q2kwmdH+rHEJbjof87\
+yyKLagc4owyXBZYkQmkeHWCNqnuRmO5vUsfVb0UUrkD64o7Th/NjwooA7SCiUXl6\
+dfygT1b7ggpx7GC+sP2DsIM47IAZ55drjqX5u2f+Ba0iSwoEdGVzdBIgCICt4gQS\
+GXapFASsapRTBKxoykO9YhoackY1CqLyiKwYt+HZpQUggICAgICAgICAASoQVGVz\
+dGluZyB0ZXN0bmV0ISqAAXSQG8+GFA18VaKarlYrOz293rNMIub0swKGcQm8jAGX\
+HSLaRgHfUDeEPr4hydy4dtfu59KNwe2xsHOHu/SpO4L8SrA4Dm9A7SlNBVWdcLbw\
+d2hj739GDLz0b5KuJ2SG6VknMRQM976w/m2qlq0ccVGaaZ2zMIGfpzL3p6adwx/5\
+";
+
+//
+// Payment request with amount overflow (amount is set to 21000001 BTC)
+//
+const char* paymentrequest5_cert2_BASE64 =
+"\
+Egt4NTA5K3NoYTI1NhrQBArNBDCCAkkwggExoAMCAQICAQEwDQYJKoZIhvcNAQEL\
+BQAwITEfMB0GA1UEAwwWUGF5bWVudFJlcXVlc3QgVGVzdCBDQTAeFw0xNTAxMTEx\
+ODIxMDhaFw0yNTAxMDgxODIxMDhaMCExHzAdBgNVBAMMFlBheW1lbnRSZXF1ZXN0\
+IFRlc3QgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMsZqzkzeBGo+i2N\
+mUak3Ciodr1V7S062VOy7N0OQYNDQHYkgDFAUET7cEb5VJaHPv5m3ppTBpU9xBcf\
+wbHHUt4VjA+mhRmYrl1khjvZM+X8kEqvWn20BtcM9R6r0yIYec8UERDDHBleL/P8\
+RkxEnVLjYTV9zigCXfMsgYb3EQShAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJ\
+KoZIhvcNAQELBQADggEBABUJpl3QCqsoDSxAsQdV6zKT4VGV76AzoGj7etQsQY+r\
++S26VfWh/fMobEzuxFChr0USgLJ6FoK78hAtoZvt1lrye9yqFv/ig3WLWsJKWHHb\
+3RT6oR03CIwZXFSUasi08QDVLxafwsU5OMcPLucF3a1lRL1ccYrNgVCCx1+X7Bos\
+tIgDGRQQ4AyoHTcfVd2hEGeUv7k14mOxFsAp6851yosHq9Q2kwmdH+rHEJbjof87\
+yyKLagc4owyXBZYkQmkeHWCNqnuRmO5vUsfVb0UUrkD64o7Th/NjwooA7SCiUXl6\
+dfygT1b7ggpx7GC+sP2DsIM47IAZ55drjqX5u2f+Ba0iTAoEdGVzdBIkCIDC9P+F\
+vt0DEhl2qRQErGqUUwSsaMpDvWIaGnJGNQqi8oisGLzcrKYFKhhUZXN0aW5nIGFt\
+b3VudCBvdmVyZmxvdyEqgAG8S7WEDUC6tCL6q2CTBjop/AitgEy31RL9IqYruytR\
+iEBFUrBDJZU+UEezGwr7/zoECjo5ZY3PmtZcM2sILNjyweJF6XVzGqTxUw6pN6sW\
+XR2T3Gy2LzRvhVA25QgGqpz0/juS2BtmNbsZPkN9gMMwKimgzc+PuCzmEKwPK9cQ\
+YQ==\
+";
diff --git a/src/qt/test/paymentservertests.cpp b/src/qt/test/paymentservertests.cpp
index 70254cd75d..e2ec439b2e 100644
--- a/src/qt/test/paymentservertests.cpp
+++ b/src/qt/test/paymentservertests.cpp
@@ -7,7 +7,10 @@
#include "optionsmodel.h"
#include "paymentrequestdata.h"
+#include "amount.h"
#include "random.h"
+#include "script/script.h"
+#include "script/standard.h"
#include "util.h"
#include "utilstrencodings.h"
@@ -65,38 +68,44 @@ void PaymentServerTests::paymentServerTests()
OptionsModel optionsModel;
PaymentServer* server = new PaymentServer(NULL, false);
X509_STORE* caStore = X509_STORE_new();
- X509_STORE_add_cert(caStore, parse_b64der_cert(caCert_BASE64));
+ X509_STORE_add_cert(caStore, parse_b64der_cert(caCert1_BASE64));
PaymentServer::LoadRootCAs(caStore);
server->setOptionsModel(&optionsModel);
server->uiReady();
- // Now feed PaymentRequests to server, and observe signals it produces:
- std::vector<unsigned char> data = DecodeBase64(paymentrequest1_BASE64);
- SendCoinsRecipient r = handleRequest(server, data);
+ std::vector<unsigned char> data;
+ SendCoinsRecipient r;
QString merchant;
+
+ // Now feed PaymentRequests to server, and observe signals it produces
+
+ // This payment request validates directly against the
+ // caCert1 certificate authority:
+ data = DecodeBase64(paymentrequest1_cert1_BASE64);
+ r = handleRequest(server, data);
r.paymentRequest.getMerchant(caStore, merchant);
QCOMPARE(merchant, QString("testmerchant.org"));
- // Version of the above, with an expired certificate:
- data = DecodeBase64(paymentrequest2_BASE64);
+ // Signed, but expired, merchant cert in the request:
+ data = DecodeBase64(paymentrequest2_cert1_BASE64);
r = handleRequest(server, data);
r.paymentRequest.getMerchant(caStore, merchant);
QCOMPARE(merchant, QString(""));
- // Long certificate chain:
- data = DecodeBase64(paymentrequest3_BASE64);
+ // 10-long certificate chain, all intermediates valid:
+ data = DecodeBase64(paymentrequest3_cert1_BASE64);
r = handleRequest(server, data);
r.paymentRequest.getMerchant(caStore, merchant);
QCOMPARE(merchant, QString("testmerchant8.org"));
// Long certificate chain, with an expired certificate in the middle:
- data = DecodeBase64(paymentrequest4_BASE64);
+ data = DecodeBase64(paymentrequest4_cert1_BASE64);
r = handleRequest(server, data);
r.paymentRequest.getMerchant(caStore, merchant);
QCOMPARE(merchant, QString(""));
// Validly signed, but by a CA not in our root CA list:
- data = DecodeBase64(paymentrequest5_BASE64);
+ data = DecodeBase64(paymentrequest5_cert1_BASE64);
r = handleRequest(server, data);
r.paymentRequest.getMerchant(caStore, merchant);
QCOMPARE(merchant, QString(""));
@@ -104,12 +113,71 @@ void PaymentServerTests::paymentServerTests()
// Try again with no root CA's, verifiedMerchant should be empty:
caStore = X509_STORE_new();
PaymentServer::LoadRootCAs(caStore);
- data = DecodeBase64(paymentrequest1_BASE64);
+ data = DecodeBase64(paymentrequest1_cert1_BASE64);
r = handleRequest(server, data);
r.paymentRequest.getMerchant(caStore, merchant);
QCOMPARE(merchant, QString(""));
- // Just get some random data big enough to trigger BIP70 DoS protection
+ // Load second root certificate
+ caStore = X509_STORE_new();
+ X509_STORE_add_cert(caStore, parse_b64der_cert(caCert2_BASE64));
+ PaymentServer::LoadRootCAs(caStore);
+
+ QByteArray byteArray;
+
+ // For the tests below we just need the payment request data from
+ // paymentrequestdata.h parsed + stored in r.paymentRequest.
+ //
+ // These tests require us to bypass the following normal client execution flow
+ // shown below to be able to explicitly just trigger a certain condition!
+ //
+ // handleRequest()
+ // -> PaymentServer::eventFilter()
+ // -> PaymentServer::handleURIOrFile()
+ // -> PaymentServer::readPaymentRequestFromFile()
+ // -> PaymentServer::processPaymentRequest()
+
+ // Contains a testnet paytoaddress, so payment request network doesn't match client network:
+ data = DecodeBase64(paymentrequest1_cert2_BASE64);
+ byteArray = QByteArray((const char*)&data[0], data.size());
+ r.paymentRequest.parse(byteArray);
+ // Ensure the request is initialized, because network "main" is default, even for
+ // uninizialized payment requests and that will fail our test here.
+ QVERIFY(r.paymentRequest.IsInitialized());
+ QCOMPARE(PaymentServer::verifyNetwork(r.paymentRequest.getDetails()), false);
+
+ // Expired payment request (expires is set to 1 = 1970-01-01 00:00:01):
+ data = DecodeBase64(paymentrequest2_cert2_BASE64);
+ byteArray = QByteArray((const char*)&data[0], data.size());
+ r.paymentRequest.parse(byteArray);
+ // Ensure the request is initialized
+ QVERIFY(r.paymentRequest.IsInitialized());
+ // compares 1 < GetTime() == false (treated as expired payment request)
+ QCOMPARE(PaymentServer::verifyExpired(r.paymentRequest.getDetails()), true);
+
+ // Unexpired payment request (expires is set to 0x7FFFFFFFFFFFFFFF = max. int64_t):
+ // 9223372036854775807 (uint64), 9223372036854775807 (int64_t) and -1 (int32_t)
+ // -1 is 1969-12-31 23:59:59 (for a 32 bit time values)
+ data = DecodeBase64(paymentrequest3_cert2_BASE64);
+ byteArray = QByteArray((const char*)&data[0], data.size());
+ r.paymentRequest.parse(byteArray);
+ // Ensure the request is initialized
+ QVERIFY(r.paymentRequest.IsInitialized());
+ // compares 9223372036854775807 < GetTime() == false (treated as unexpired payment request)
+ QCOMPARE(PaymentServer::verifyExpired(r.paymentRequest.getDetails()), false);
+
+ // Unexpired payment request (expires is set to 0x8000000000000000 > max. int64_t, allowed uint64):
+ // 9223372036854775808 (uint64), -9223372036854775808 (int64_t) and 0 (int32_t)
+ // 0 is 1970-01-01 00:00:00 (for a 32 bit time values)
+ data = DecodeBase64(paymentrequest4_cert2_BASE64);
+ byteArray = QByteArray((const char*)&data[0], data.size());
+ r.paymentRequest.parse(byteArray);
+ // Ensure the request is initialized
+ QVERIFY(r.paymentRequest.IsInitialized());
+ // compares -9223372036854775808 < GetTime() == true (treated as expired payment request)
+ QCOMPARE(PaymentServer::verifyExpired(r.paymentRequest.getDetails()), true);
+
+ // Test BIP70 DoS protection:
unsigned char randData[BIP70_MAX_PAYMENTREQUEST_SIZE + 1];
GetRandBytes(randData, sizeof(randData));
// Write data to a temp file:
@@ -117,9 +185,22 @@ void PaymentServerTests::paymentServerTests()
tempFile.open();
tempFile.write((const char*)randData, sizeof(randData));
tempFile.close();
- // Trigger BIP70 DoS protection
QCOMPARE(PaymentServer::readPaymentRequestFromFile(tempFile.fileName(), r.paymentRequest), false);
+ // Payment request with amount overflow (amount is set to 21000001 BTC):
+ data = DecodeBase64(paymentrequest5_cert2_BASE64);
+ byteArray = QByteArray((const char*)&data[0], data.size());
+ r.paymentRequest.parse(byteArray);
+ // Ensure the request is initialized
+ QVERIFY(r.paymentRequest.IsInitialized());
+ // Extract address and amount from the request
+ QList<std::pair<CScript, CAmount> > sendingTos = r.paymentRequest.getPayTo();
+ foreach (const PAIRTYPE(CScript, CAmount)& sendingTo, sendingTos) {
+ CTxDestination dest;
+ if (ExtractDestination(sendingTo.first, dest))
+ QCOMPARE(PaymentServer::verifyAmount(sendingTo.second), false);
+ }
+
delete server;
}
diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp
index 6771e77180..df1afbfaaa 100644
--- a/src/qt/transactiontablemodel.cpp
+++ b/src/qt/transactiontablemodel.cpp
@@ -94,7 +94,7 @@ public:
*/
void updateWallet(const uint256 &hash, int status, bool showTransaction)
{
- qDebug() << "TransactionTablePriv::updateWallet : " + QString::fromStdString(hash.ToString()) + " " + QString::number(status);
+ qDebug() << "TransactionTablePriv::updateWallet: " + QString::fromStdString(hash.ToString()) + " " + QString::number(status);
// Find bounds of this transaction in model
QList<TransactionRecord>::iterator lower = qLowerBound(
@@ -122,7 +122,7 @@ public:
case CT_NEW:
if(inModel)
{
- qWarning() << "TransactionTablePriv::updateWallet : Warning: Got CT_NEW, but transaction is already in model";
+ qWarning() << "TransactionTablePriv::updateWallet: Warning: Got CT_NEW, but transaction is already in model";
break;
}
if(showTransaction)
@@ -132,7 +132,7 @@ public:
std::map<uint256, CWalletTx>::iterator mi = wallet->mapWallet.find(hash);
if(mi == wallet->mapWallet.end())
{
- qWarning() << "TransactionTablePriv::updateWallet : Warning: Got CT_NEW, but transaction is not in wallet";
+ qWarning() << "TransactionTablePriv::updateWallet: Warning: Got CT_NEW, but transaction is not in wallet";
break;
}
// Added -- insert at the right position
@@ -154,7 +154,7 @@ public:
case CT_DELETED:
if(!inModel)
{
- qWarning() << "TransactionTablePriv::updateWallet : Warning: Got CT_DELETED, but transaction is not in model";
+ qWarning() << "TransactionTablePriv::updateWallet: Warning: Got CT_DELETED, but transaction is not in model";
break;
}
// Removed -- remove entire transaction from table
@@ -664,7 +664,7 @@ public:
void invoke(QObject *ttm)
{
QString strHash = QString::fromStdString(hash.GetHex());
- qDebug() << "NotifyTransactionChanged : " + strHash + " status= " + QString::number(status);
+ qDebug() << "NotifyTransactionChanged: " + strHash + " status= " + QString::number(status);
QMetaObject::invokeMethod(ttm, "updateTransaction", Qt::QueuedConnection,
Q_ARG(QString, strHash),
Q_ARG(int, status),
diff --git a/src/qt/transactionview.h b/src/qt/transactionview.h
index 2858982f09..092d919042 100644
--- a/src/qt/transactionview.h
+++ b/src/qt/transactionview.h
@@ -49,10 +49,10 @@ public:
};
enum ColumnWidths {
- STATUS_COLUMN_WIDTH = 23,
+ STATUS_COLUMN_WIDTH = 30,
WATCHONLY_COLUMN_WIDTH = 23,
DATE_COLUMN_WIDTH = 120,
- TYPE_COLUMN_WIDTH = 120,
+ TYPE_COLUMN_WIDTH = 113,
AMOUNT_MINIMUM_COLUMN_WIDTH = 120,
MINIMUM_COLUMN_WIDTH = 23
};
diff --git a/src/qt/utilitydialog.cpp b/src/qt/utilitydialog.cpp
index e6cec8173e..63dd6efb52 100644
--- a/src/qt/utilitydialog.cpp
+++ b/src/qt/utilitydialog.cpp
@@ -12,12 +12,15 @@
#include "clientversion.h"
#include "init.h"
+#include "util.h"
#include <stdio.h>
#include <QCloseEvent>
#include <QLabel>
#include <QRegExp>
+#include <QTextTable>
+#include <QTextCursor>
#include <QVBoxLayout>
/** "Help message" or "About" dialog box */
@@ -52,28 +55,89 @@ HelpMessageDialog::HelpMessageDialog(QWidget *parent, bool about) :
// Replace newlines with HTML breaks
licenseInfoHTML.replace("\n\n", "<br><br>");
- ui->helpMessageLabel->setTextFormat(Qt::RichText);
+ ui->aboutMessage->setTextFormat(Qt::RichText);
ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
text = version + "\n" + licenseInfo;
- ui->helpMessageLabel->setText(version + "<br><br>" + licenseInfoHTML);
- ui->helpMessageLabel->setWordWrap(true);
+ ui->aboutMessage->setText(version + "<br><br>" + licenseInfoHTML);
+ ui->aboutMessage->setWordWrap(true);
+ ui->helpMessage->setVisible(false);
} else {
setWindowTitle(tr("Command-line options"));
- QString header = tr("Usage:") + "\n" +
- " bitcoin-qt [" + tr("command-line options") + "] " + "\n";
+ QTextCursor cursor(ui->helpMessage->document());
+ cursor.insertText(version);
+ cursor.insertBlock();
+ cursor.insertText(tr("Usage:") + '\n' +
+ " bitcoin-qt [" + tr("command-line options") + "]\n");
+
+ cursor.insertBlock();
+ QTextTableFormat tf;
+ tf.setBorderStyle(QTextFrameFormat::BorderStyle_None);
+ tf.setCellPadding(2);
+ QVector<QTextLength> widths;
+ widths << QTextLength(QTextLength::PercentageLength, 35);
+ widths << QTextLength(QTextLength::PercentageLength, 65);
+ tf.setColumnWidthConstraints(widths);
+ QTextTable *table = cursor.insertTable(2, 2, tf);
QString coreOptions = QString::fromStdString(HelpMessage(HMM_BITCOIN_QT));
-
- QString uiOptions = tr("UI options") + ":\n" +
- " -choosedatadir " + tr("Choose data directory on startup (default: 0)") + "\n" +
- " -lang=<lang> " + tr("Set language, for example \"de_DE\" (default: system locale)") + "\n" +
- " -min " + tr("Start minimized") + "\n" +
- " -rootcertificates=<file> " + tr("Set SSL root certificates for payment request (default: -system-)") + "\n" +
- " -splash " + tr("Show splash screen on startup (default: 1)");
-
- ui->helpMessageLabel->setFont(GUIUtil::bitcoinAddressFont());
- text = version + "\n" + header + "\n" + coreOptions + "\n" + uiOptions;
- ui->helpMessageLabel->setText(text);
+ bool first = true;
+ QTextCharFormat bold;
+ bold.setFontWeight(QFont::Bold);
+ // note that coreOptions is not translated.
+ foreach (const QString &line, coreOptions.split('\n')) {
+ if (!first) {
+ table->appendRows(1);
+ cursor.movePosition(QTextCursor::NextRow);
+ }
+ first = false;
+
+ if (line.startsWith(" ")) {
+ int index = line.indexOf(' ', 3);
+ if (index > 0) {
+ cursor.insertText(line.left(index).trimmed());
+ cursor.movePosition(QTextCursor::NextCell);
+ cursor.insertText(line.mid(index).trimmed());
+ continue;
+ }
+ }
+ cursor.movePosition(QTextCursor::NextCell, QTextCursor::KeepAnchor);
+ table->mergeCells(cursor);
+ cursor.insertText(line.trimmed(), bold);
+ }
+
+ table->appendRows(6);
+ cursor.movePosition(QTextCursor::NextRow);
+ cursor.insertText(tr("UI options") + ":", bold);
+ cursor.movePosition(QTextCursor::NextRow);
+ if (GetBoolArg("-help-debug", false)) {
+ cursor.insertText("-allowselfsignedrootcertificates");
+ cursor.movePosition(QTextCursor::NextCell);
+ cursor.insertText(tr("Allow self signed root certificates (default: 0)"));
+ cursor.movePosition(QTextCursor::NextCell);
+ }
+ cursor.insertText("-choosedatadir");
+ cursor.movePosition(QTextCursor::NextCell);
+ cursor.insertText(tr("Choose data directory on startup (default: 0)"));
+ cursor.movePosition(QTextCursor::NextCell);
+ cursor.insertText("-lang=<lang>");
+ cursor.movePosition(QTextCursor::NextCell);
+ cursor.insertText(tr("Set language, for example \"de_DE\" (default: system locale)"));
+ cursor.movePosition(QTextCursor::NextCell);
+ cursor.insertText("-min");
+ cursor.movePosition(QTextCursor::NextCell);
+ cursor.insertText(tr("Start minimized"));
+ cursor.movePosition(QTextCursor::NextCell);
+ cursor.insertText("-rootcertificates=<file>");
+ cursor.movePosition(QTextCursor::NextCell);
+ cursor.insertText(tr("Set SSL root certificates for payment request (default: -system-)"));
+ cursor.movePosition(QTextCursor::NextCell);
+ cursor.insertText("-splash");
+ cursor.movePosition(QTextCursor::NextCell);
+ cursor.insertText(tr("Show splash screen on startup (default: 1)"));
+
+ ui->helpMessage->moveCursor(QTextCursor::Start);
+ ui->scrollArea->setVisible(false);
+ ui->aboutLogo->setVisible(false);
}
}
diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp
index 6006a7bd7b..79f5191fc0 100644
--- a/src/qt/walletmodel.cpp
+++ b/src/qt/walletmodel.cpp
@@ -6,6 +6,7 @@
#include "addresstablemodel.h"
#include "guiconstants.h"
+#include "paymentserver.h"
#include "recentrequeststablemodel.h"
#include "transactiontablemodel.h"
@@ -278,9 +279,9 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact
return TransactionCreationFailed;
}
- // reject insane fee > 0.1 bitcoin
+ // reject absurdly high fee > 0.1 bitcoin
if (nFeeRequired > 10000000)
- return InsaneFee;
+ return AbsurdFee;
}
return SendCoinsReturn(OK);
@@ -294,11 +295,16 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(WalletModelTransaction &tran
LOCK2(cs_main, wallet->cs_wallet);
CWalletTx *newTx = transaction.getTransaction();
- // Store PaymentRequests in wtx.vOrderForm in wallet.
foreach(const SendCoinsRecipient &rcp, transaction.getRecipients())
{
if (rcp.paymentRequest.IsInitialized())
{
+ // Make sure any payment requests involved are still valid.
+ if (PaymentServer::verifyExpired(rcp.paymentRequest.getDetails())) {
+ return PaymentRequestExpired;
+ }
+
+ // Store PaymentRequests in wtx.vOrderForm in wallet.
std::string key("PaymentRequest");
std::string value;
rcp.paymentRequest.SerializeToString(&value);
@@ -446,7 +452,7 @@ static void NotifyAddressBookChanged(WalletModel *walletmodel, CWallet *wallet,
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=" + strPurpose + " status=" + QString::number(status);
QMetaObject::invokeMethod(walletmodel, "updateAddressBook", Qt::QueuedConnection,
Q_ARG(QString, strAddress),
Q_ARG(QString, strLabel),
diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h
index d8df25f660..4a9a12beaa 100644
--- a/src/qt/walletmodel.h
+++ b/src/qt/walletmodel.h
@@ -40,7 +40,7 @@ public:
explicit SendCoinsRecipient(const QString &addr, const QString &label, const CAmount& amount, const QString &message):
address(addr), label(label), amount(amount), message(message), nVersion(SendCoinsRecipient::CURRENT_VERSION) {}
- // If from an insecure payment request, this is used for storing
+ // If from an unauthenticated payment request, this is used for storing
// the addresses, e.g. address-A<br />address-B<br />address-C.
// Info: As we don't need to process addresses in here when using
// payment requests, we can abuse it for displaying an address list.
@@ -111,7 +111,8 @@ public:
DuplicateAddress,
TransactionCreationFailed, // Error returned when wallet is still locked
TransactionCommitFailed,
- InsaneFee
+ AbsurdFee,
+ PaymentRequestExpired
};
enum EncryptionStatus
diff --git a/src/rest.cpp b/src/rest.cpp
index c9535c3b45..adc2d56284 100644
--- a/src/rest.cpp
+++ b/src/rest.cpp
@@ -266,7 +266,7 @@ static bool rest_tx(AcceptedConnection* conn,
throw RESTERR(HTTP_BAD_REQUEST, "Invalid hash: " + hashStr);
CTransaction tx;
- uint256 hashBlock = 0;
+ uint256 hashBlock = uint256();
if (!GetTransaction(hash, tx, hashBlock, true))
throw RESTERR(HTTP_NOT_FOUND, hashStr + " not found");
diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp
index 71fb7c8233..293d6d5619 100644
--- a/src/rpcblockchain.cpp
+++ b/src/rpcblockchain.cpp
@@ -70,7 +70,7 @@ Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDe
if(txDetails)
{
Object objTx;
- TxToJSON(tx, uint256(0), objTx);
+ TxToJSON(tx, uint256(), objTx);
txs.push_back(objTx);
}
else
@@ -105,6 +105,7 @@ Value getblockcount(const Array& params, bool fHelp)
+ HelpExampleRpc("getblockcount", "")
);
+ LOCK(cs_main);
return chainActive.Height();
}
@@ -121,6 +122,7 @@ Value getbestblockhash(const Array& params, bool fHelp)
+ HelpExampleRpc("getbestblockhash", "")
);
+ LOCK(cs_main);
return chainActive.Tip()->GetBlockHash().GetHex();
}
@@ -137,6 +139,7 @@ Value getdifficulty(const Array& params, bool fHelp)
+ HelpExampleRpc("getdifficulty", "")
);
+ LOCK(cs_main);
return GetDifficulty();
}
@@ -173,6 +176,8 @@ Value getrawmempool(const Array& params, bool fHelp)
+ HelpExampleRpc("getrawmempool", "true")
);
+ LOCK(cs_main);
+
bool fVerbose = false;
if (params.size() > 0)
fVerbose = params[0].get_bool();
@@ -233,6 +238,8 @@ Value getblockhash(const Array& params, bool fHelp)
+ HelpExampleRpc("getblockhash", "1000")
);
+ LOCK(cs_main);
+
int nHeight = params[0].get_int();
if (nHeight < 0 || nHeight > chainActive.Height())
throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range");
@@ -277,8 +284,10 @@ Value getblock(const Array& params, bool fHelp)
+ HelpExampleRpc("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
);
+ LOCK(cs_main);
+
std::string strHash = params[0].get_str();
- uint256 hash(strHash);
+ uint256 hash(uint256S(strHash));
bool fVerbose = true;
if (params.size() > 1)
@@ -326,6 +335,8 @@ Value gettxoutsetinfo(const Array& params, bool fHelp)
+ HelpExampleRpc("gettxoutsetinfo", "")
);
+ LOCK(cs_main);
+
Object ret;
CCoinsStats stats;
@@ -380,10 +391,12 @@ Value gettxout(const Array& params, bool fHelp)
+ HelpExampleRpc("gettxout", "\"txid\", 1")
);
+ LOCK(cs_main);
+
Object ret;
std::string strHash = params[0].get_str();
- uint256 hash(strHash);
+ uint256 hash(uint256S(strHash));
int n = params[1].get_int();
bool fMempool = true;
if (params.size() > 2)
@@ -436,6 +449,8 @@ Value verifychain(const Array& params, bool fHelp)
+ HelpExampleRpc("verifychain", "")
);
+ LOCK(cs_main);
+
int nCheckLevel = GetArg("-checklevel", 3);
int nCheckDepth = GetArg("-checkblocks", 288);
if (params.size() > 0)
@@ -467,6 +482,8 @@ Value getblockchaininfo(const Array& params, bool fHelp)
+ HelpExampleRpc("getblockchaininfo", "")
);
+ LOCK(cs_main);
+
Object obj;
obj.push_back(Pair("chain", Params().NetworkIDString()));
obj.push_back(Pair("blocks", (int)chainActive.Height()));
@@ -526,6 +543,8 @@ Value getchaintips(const Array& params, bool fHelp)
+ HelpExampleRpc("getchaintips", "")
);
+ LOCK(cs_main);
+
/* Build up a list of chain tips. We start with the list of all
known blocks, and successively remove blocks that appear as pprev
of another block. */
@@ -619,7 +638,7 @@ Value invalidateblock(const Array& params, bool fHelp)
);
std::string strHash = params[0].get_str();
- uint256 hash(strHash);
+ uint256 hash(uint256S(strHash));
CValidationState state;
{
@@ -658,7 +677,7 @@ Value reconsiderblock(const Array& params, bool fHelp)
);
std::string strHash = params[0].get_str();
- uint256 hash(strHash);
+ uint256 hash(uint256S(strHash));
CValidationState state;
{
diff --git a/src/rpcdump.cpp b/src/rpcdump.cpp
index 8666779cc1..b9c92a06c5 100644
--- a/src/rpcdump.cpp
+++ b/src/rpcdump.cpp
@@ -91,6 +91,8 @@ Value importprivkey(const Array& params, bool fHelp)
+ HelpExampleRpc("importprivkey", "\"mykey\", \"testing\", false")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
EnsureWalletIsUnlocked();
string strSecret = params[0].get_str();
@@ -158,6 +160,8 @@ Value importaddress(const Array& params, bool fHelp)
+ HelpExampleRpc("importaddress", "\"myaddress\", \"testing\", false")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
CScript script;
CBitcoinAddress address(params[0].get_str());
@@ -223,6 +227,8 @@ Value importwallet(const Array& params, bool fHelp)
+ HelpExampleRpc("importwallet", "\"test\"")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
EnsureWalletIsUnlocked();
ifstream file;
@@ -322,6 +328,8 @@ Value dumpprivkey(const Array& params, bool fHelp)
+ HelpExampleRpc("dumpprivkey", "\"myaddress\"")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
EnsureWalletIsUnlocked();
string strAddress = params[0].get_str();
@@ -351,6 +359,8 @@ Value dumpwallet(const Array& params, bool fHelp)
+ HelpExampleRpc("dumpwallet", "\"test\"")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
EnsureWalletIsUnlocked();
ofstream file;
diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp
index 17552bc388..e3ae5cff42 100644
--- a/src/rpcmining.cpp
+++ b/src/rpcmining.cpp
@@ -44,7 +44,7 @@ Value GetNetworkHashPS(int lookup, int height) {
// If lookup is -1, then use blocks since last difficulty change.
if (lookup <= 0)
- lookup = pb->nHeight % 2016 + 1;
+ lookup = pb->nHeight % Params().Interval() + 1;
// If lookup is larger than chain, then set it to chain length.
if (lookup > pb->nHeight)
@@ -64,7 +64,7 @@ Value GetNetworkHashPS(int lookup, int height) {
if (minTime == maxTime)
return 0;
- uint256 workDiff = pb->nChainWork - pb0->nChainWork;
+ arith_uint256 workDiff = pb->nChainWork - pb0->nChainWork;
int64_t timeDiff = maxTime - minTime;
return (int64_t)(workDiff.getdouble() / timeDiff);
@@ -88,6 +88,7 @@ Value getnetworkhashps(const Array& params, bool fHelp)
+ HelpExampleRpc("getnetworkhashps", "")
);
+ LOCK(cs_main);
return GetNetworkHashPS(params.size() > 0 ? params[0].get_int() : 120, params.size() > 1 ? params[1].get_int() : -1);
}
@@ -107,6 +108,7 @@ Value getgenerate(const Array& params, bool fHelp)
+ HelpExampleRpc("getgenerate", "")
);
+ LOCK(cs_main);
return GetBoolArg("-gen", false);
}
@@ -200,25 +202,6 @@ Value setgenerate(const Array& params, bool fHelp)
return Value::null;
}
-
-Value gethashespersec(const Array& params, bool fHelp)
-{
- if (fHelp || params.size() != 0)
- throw runtime_error(
- "gethashespersec\n"
- "\nReturns a recent hashes per second performance measurement while generating.\n"
- "See the getgenerate and setgenerate calls to turn generation on and off.\n"
- "\nResult:\n"
- "n (numeric) The recent hashes per second when generation is on (will return 0 if generation is off)\n"
- "\nExamples:\n"
- + HelpExampleCli("gethashespersec", "")
- + HelpExampleRpc("gethashespersec", "")
- );
-
- if (GetTimeMillis() - nHPSTimerStart > 8000)
- return (int64_t)0;
- return (int64_t)dHashesPerSec;
-}
#endif
@@ -237,7 +220,6 @@ Value getmininginfo(const Array& params, bool fHelp)
" \"errors\": \"...\" (string) Current errors\n"
" \"generate\": true|false (boolean) If the generation is on or off (see getgenerate or setgenerate calls)\n"
" \"genproclimit\": n (numeric) The processor limit for generation. -1 if no generation. (see getgenerate or setgenerate calls)\n"
- " \"hashespersec\": n (numeric) The hashes per second of the generation, or 0 if no generation.\n"
" \"pooledtx\": n (numeric) The size of the mem pool\n"
" \"testnet\": true|false (boolean) If using testnet or not\n"
" \"chain\": \"xxxx\", (string) current network name as defined in BIP70 (main, test, regtest)\n"
@@ -247,6 +229,9 @@ Value getmininginfo(const Array& params, bool fHelp)
+ HelpExampleRpc("getmininginfo", "")
);
+
+ LOCK(cs_main);
+
Object obj;
obj.push_back(Pair("blocks", (int)chainActive.Height()));
obj.push_back(Pair("currentblocksize", (uint64_t)nLastBlockSize));
@@ -260,7 +245,6 @@ Value getmininginfo(const Array& params, bool fHelp)
obj.push_back(Pair("chain", Params().NetworkIDString()));
#ifdef ENABLE_WALLET
obj.push_back(Pair("generate", getgenerate(params, false)));
- obj.push_back(Pair("hashespersec", gethashespersec(params, false)));
#endif
return obj;
}
@@ -288,9 +272,9 @@ Value prioritisetransaction(const Array& params, bool fHelp)
+ HelpExampleRpc("prioritisetransaction", "\"txid\", 0.0, 10000")
);
- uint256 hash;
- hash.SetHex(params[0].get_str());
+ LOCK(cs_main);
+ uint256 hash = ParseHashStr(params[0].get_str(), "txid");
CAmount nAmount = params[2].get_int64();
mempool.PrioritiseTransaction(hash, params[0].get_str(), params[1].get_real(), nAmount);
@@ -379,6 +363,8 @@ Value getblocktemplate(const Array& params, bool fHelp)
+ HelpExampleRpc("getblocktemplate", "")
);
+ LOCK(cs_main);
+
std::string strMode = "template";
Value lpval = Value::null;
if (params.size() > 0)
@@ -460,10 +446,6 @@ Value getblocktemplate(const Array& params, bool fHelp)
}
// Release the wallet and main lock while waiting
-#ifdef ENABLE_WALLET
- if(pwalletMain)
- LEAVE_CRITICAL_SECTION(pwalletMain->cs_wallet);
-#endif
LEAVE_CRITICAL_SECTION(cs_main);
{
checktxtime = boost::get_system_time() + boost::posix_time::minutes(1);
@@ -481,10 +463,6 @@ Value getblocktemplate(const Array& params, bool fHelp)
}
}
ENTER_CRITICAL_SECTION(cs_main);
-#ifdef ENABLE_WALLET
- if(pwalletMain)
- ENTER_CRITICAL_SECTION(pwalletMain->cs_wallet);
-#endif
if (!IsRPCRunning())
throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Shutting down");
@@ -563,7 +541,7 @@ Value getblocktemplate(const Array& params, bool fHelp)
Object aux;
aux.push_back(Pair("flags", HexStr(COINBASE_FLAGS.begin(), COINBASE_FLAGS.end())));
- uint256 hashTarget = uint256().SetCompact(pblock->nBits);
+ arith_uint256 hashTarget = arith_uint256().SetCompact(pblock->nBits);
static Array aMutable;
if (aMutable.empty())
diff --git a/src/rpcmisc.cpp b/src/rpcmisc.cpp
index b8805b9d51..8d260b1cc9 100644
--- a/src/rpcmisc.cpp
+++ b/src/rpcmisc.cpp
@@ -23,8 +23,6 @@
#include "json/json_spirit_utils.h"
#include "json/json_spirit_value.h"
-using namespace boost;
-using namespace boost::assign;
using namespace json_spirit;
using namespace std;
@@ -71,6 +69,12 @@ Value getinfo(const Array& params, bool fHelp)
+ HelpExampleRpc("getinfo", "")
);
+#ifdef ENABLE_WALLET
+ LOCK2(cs_main, pwalletMain ? &pwalletMain->cs_wallet : NULL);
+#else
+ LOCK(cs_main);
+#endif
+
proxyType proxy;
GetProxy(NET_IPV4, proxy);
@@ -162,17 +166,24 @@ Value validateaddress(const Array& params, bool fHelp)
"{\n"
" \"isvalid\" : true|false, (boolean) If the address is valid or not. If not, this is the only property returned.\n"
" \"address\" : \"bitcoinaddress\", (string) The bitcoin address validated\n"
+ " \"scriptPubKey\" : \"hex\", (string) The hex encoded scriptPubKey generated by the address\n"
" \"ismine\" : true|false, (boolean) If the address is yours or not\n"
" \"isscript\" : true|false, (boolean) If the key is a script\n"
" \"pubkey\" : \"publickeyhex\", (string) The hex value of the raw public key\n"
" \"iscompressed\" : true|false, (boolean) If the address is compressed\n"
- " \"account\" : \"account\" (string) The account associated with the address, \"\" is the default account\n"
+ " \"account\" : \"account\" (string) DEPRECATED. The account associated with the address, \"\" is the default account\n"
"}\n"
"\nExamples:\n"
+ HelpExampleCli("validateaddress", "\"1PSSGeFHDnKNxiEyFrD1wcEaHr9hrQDDWc\"")
+ HelpExampleRpc("validateaddress", "\"1PSSGeFHDnKNxiEyFrD1wcEaHr9hrQDDWc\"")
);
+#ifdef ENABLE_WALLET
+ LOCK2(cs_main, pwalletMain ? &pwalletMain->cs_wallet : NULL);
+#else
+ LOCK(cs_main);
+#endif
+
CBitcoinAddress address(params[0].get_str());
bool isValid = address.IsValid();
@@ -183,6 +194,10 @@ Value validateaddress(const Array& params, bool fHelp)
CTxDestination dest = address.Get();
string currentAddress = address.ToString();
ret.push_back(Pair("address", currentAddress));
+
+ CScript scriptPubKey = GetScriptForDestination(dest);
+ ret.push_back(Pair("scriptPubKey", HexStr(scriptPubKey.begin(), scriptPubKey.end())));
+
#ifdef ENABLE_WALLET
isminetype mine = pwalletMain ? IsMine(*pwalletMain, dest) : ISMINE_NO;
ret.push_back(Pair("ismine", (mine & ISMINE_SPENDABLE) ? true : false));
@@ -326,6 +341,8 @@ Value verifymessage(const Array& params, bool fHelp)
+ HelpExampleRpc("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\", \"signature\", \"my message\"")
);
+ LOCK(cs_main);
+
string strAddress = params[0].get_str();
string strSign = params[1].get_str();
string strMessage = params[2].get_str();
@@ -369,6 +386,8 @@ Value setmocktime(const Array& params, bool fHelp)
if (!Params().MineBlocksOnDemand())
throw runtime_error("setmocktime for regression testing (-regtest mode) only");
+ LOCK(cs_main);
+
RPCTypeCheck(params, boost::assign::list_of(int_type));
SetMockTime(params[0].get_int64());
diff --git a/src/rpcnet.cpp b/src/rpcnet.cpp
index 2886f7adab..6306fd4406 100644
--- a/src/rpcnet.cpp
+++ b/src/rpcnet.cpp
@@ -34,7 +34,8 @@ Value getconnectioncount(const Array& params, bool fHelp)
+ HelpExampleRpc("getconnectioncount", "")
);
- LOCK(cs_vNodes);
+ LOCK2(cs_main, cs_vNodes);
+
return (int)vNodes.size();
}
@@ -52,7 +53,8 @@ Value ping(const Array& params, bool fHelp)
);
// Request that each node send a ping during next message processing pass
- LOCK(cs_vNodes);
+ LOCK2(cs_main, cs_vNodes);
+
BOOST_FOREACH(CNode* pNode, vNodes) {
pNode->fPingQueued = true;
}
@@ -91,6 +93,7 @@ Value getpeerinfo(const Array& params, bool fHelp)
" \"bytessent\": n, (numeric) The total bytes sent\n"
" \"bytesrecv\": n, (numeric) The total bytes received\n"
" \"conntime\": ttt, (numeric) The connection time in seconds since epoch (Jan 1 1970 GMT)\n"
+ " \"timeoffset\": ttt, (numeric) The time offset in seconds\n"
" \"pingtime\": n, (numeric) ping time\n"
" \"pingwait\": n, (numeric) ping wait\n"
" \"version\": v, (numeric) The peer version, such as 7001\n"
@@ -112,6 +115,8 @@ Value getpeerinfo(const Array& params, bool fHelp)
+ HelpExampleRpc("getpeerinfo", "")
);
+ LOCK(cs_main);
+
vector<CNodeStats> vstats;
CopyNodeStats(vstats);
@@ -131,6 +136,7 @@ Value getpeerinfo(const Array& params, bool fHelp)
obj.push_back(Pair("bytessent", stats.nSendBytes));
obj.push_back(Pair("bytesrecv", stats.nRecvBytes));
obj.push_back(Pair("conntime", stats.nTimeConnected));
+ obj.push_back(Pair("timeoffset", stats.nTimeOffset));
obj.push_back(Pair("pingtime", stats.dPingTime));
if (stats.dPingWait > 0.0)
obj.push_back(Pair("pingwait", stats.dPingWait));
@@ -409,6 +415,8 @@ Value getnetworkinfo(const Array& params, bool fHelp)
+ HelpExampleRpc("getnetworkinfo", "")
);
+ LOCK(cs_main);
+
Object obj;
obj.push_back(Pair("version", CLIENT_VERSION));
obj.push_back(Pair("subversion",
diff --git a/src/rpcprotocol.cpp b/src/rpcprotocol.cpp
index c4d6f06b12..95d6b9e531 100644
--- a/src/rpcprotocol.cpp
+++ b/src/rpcprotocol.cpp
@@ -26,8 +26,6 @@
#include "json/json_spirit_writer_template.h"
using namespace std;
-using namespace boost;
-using namespace boost::asio;
using namespace json_spirit;
//! Number of bytes to allocate and read at most at once in post data
diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp
index b87a8baac3..4a079f5c81 100644
--- a/src/rpcrawtransaction.cpp
+++ b/src/rpcrawtransaction.cpp
@@ -25,8 +25,6 @@
#include "json/json_spirit_utils.h"
#include "json/json_spirit_value.h"
-using namespace boost;
-using namespace boost::assign;
using namespace json_spirit;
using namespace std;
@@ -89,7 +87,7 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry)
}
entry.push_back(Pair("vout", vout));
- if (hashBlock != 0) {
+ if (!hashBlock.IsNull()) {
entry.push_back(Pair("blockhash", hashBlock.GetHex()));
BlockMap::iterator mi = mapBlockIndex.find(hashBlock);
if (mi != mapBlockIndex.end() && (*mi).second) {
@@ -171,6 +169,8 @@ Value getrawtransaction(const Array& params, bool fHelp)
+ HelpExampleRpc("getrawtransaction", "\"mytxid\", 1")
);
+ LOCK(cs_main);
+
uint256 hash = ParseHashV(params[0], "parameter 1");
bool fVerbose = false;
@@ -178,7 +178,7 @@ Value getrawtransaction(const Array& params, bool fHelp)
fVerbose = (params[1].get_int() != 0);
CTransaction tx;
- uint256 hashBlock = 0;
+ uint256 hashBlock;
if (!GetTransaction(hash, tx, hashBlock, true))
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available about transaction");
@@ -218,7 +218,7 @@ Value listunspent(const Array& params, bool fHelp)
" \"txid\" : \"txid\", (string) the transaction id \n"
" \"vout\" : n, (numeric) the vout value\n"
" \"address\" : \"address\", (string) the bitcoin address\n"
- " \"account\" : \"account\", (string) The associated account, or \"\" for the default account\n"
+ " \"account\" : \"account\", (string) DEPRECATED. The associated account, or \"\" for the default account\n"
" \"scriptPubKey\" : \"key\", (string) the script key\n"
" \"amount\" : x.xxx, (numeric) the transaction amount in btc\n"
" \"confirmations\" : n (numeric) The number of confirmations\n"
@@ -232,7 +232,7 @@ Value listunspent(const Array& params, bool fHelp)
+ HelpExampleRpc("listunspent", "6, 9999999 \"[\\\"1PGFqEzfmQch1gKD3ra4k18PNj3tTUUSqg\\\",\\\"1LtvqCaApEdUGFkpKMM4MstjcaL4dKg8SP\\\"]\"")
);
- RPCTypeCheck(params, list_of(int_type)(int_type)(array_type));
+ RPCTypeCheck(params, boost::assign::list_of(int_type)(int_type)(array_type));
int nMinDepth = 1;
if (params.size() > 0)
@@ -258,6 +258,7 @@ Value listunspent(const Array& params, bool fHelp)
Array results;
vector<COutput> vecOutputs;
assert(pwalletMain != NULL);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
pwalletMain->AvailableCoins(vecOutputs, false);
BOOST_FOREACH(const COutput& out, vecOutputs) {
if (out.nDepth < nMinDepth || out.nDepth > nMaxDepth)
@@ -336,7 +337,8 @@ Value createrawtransaction(const Array& params, bool fHelp)
+ HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\", \"{\\\"address\\\":0.01}\"")
);
- RPCTypeCheck(params, list_of(array_type)(obj_type));
+ LOCK(cs_main);
+ RPCTypeCheck(params, boost::assign::list_of(array_type)(obj_type));
Array inputs = params[0].get_array();
Object sendTo = params[1].get_obj();
@@ -430,7 +432,8 @@ Value decoderawtransaction(const Array& params, bool fHelp)
+ HelpExampleRpc("decoderawtransaction", "\"hexstring\"")
);
- RPCTypeCheck(params, list_of(str_type));
+ LOCK(cs_main);
+ RPCTypeCheck(params, boost::assign::list_of(str_type));
CTransaction tx;
@@ -438,7 +441,7 @@ Value decoderawtransaction(const Array& params, bool fHelp)
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
Object result;
- TxToJSON(tx, 0, result);
+ TxToJSON(tx, uint256(), result);
return result;
}
@@ -468,7 +471,8 @@ Value decodescript(const Array& params, bool fHelp)
+ HelpExampleRpc("decodescript", "\"hexstring\"")
);
- RPCTypeCheck(params, list_of(str_type));
+ LOCK(cs_main);
+ RPCTypeCheck(params, boost::assign::list_of(str_type));
Object r;
CScript script;
@@ -534,7 +538,12 @@ Value signrawtransaction(const Array& params, bool fHelp)
+ HelpExampleRpc("signrawtransaction", "\"myhex\"")
);
- RPCTypeCheck(params, list_of(str_type)(array_type)(array_type)(str_type), true);
+#ifdef ENABLE_WALLET
+ LOCK2(cs_main, pwalletMain ? &pwalletMain->cs_wallet : NULL);
+#else
+ LOCK(cs_main);
+#endif
+ RPCTypeCheck(params, boost::assign::list_of(str_type)(array_type)(array_type)(str_type), true);
vector<unsigned char> txData(ParseHexV(params[0], "argument 1"));
CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION);
@@ -593,7 +602,7 @@ Value signrawtransaction(const Array& params, bool fHelp)
}
}
#ifdef ENABLE_WALLET
- else
+ else if (pwalletMain)
EnsureWalletIsUnlocked();
#endif
@@ -606,7 +615,7 @@ Value signrawtransaction(const Array& params, bool fHelp)
Object prevOut = p.get_obj();
- RPCTypeCheck(prevOut, map_list_of("txid", str_type)("vout", int_type)("scriptPubKey", str_type));
+ RPCTypeCheck(prevOut, boost::assign::map_list_of("txid", str_type)("vout", int_type)("scriptPubKey", str_type));
uint256 txid = ParseHashO(prevOut, "txid");
@@ -634,7 +643,7 @@ Value signrawtransaction(const Array& params, bool fHelp)
// if redeemScript given and not using the local wallet (private keys
// given), add redeemScript to the tempKeystore so it can be signed:
if (fGivenKeys && scriptPubKey.IsPayToScriptHash()) {
- RPCTypeCheck(prevOut, map_list_of("txid", str_type)("vout", int_type)("scriptPubKey", str_type)("redeemScript",str_type));
+ RPCTypeCheck(prevOut, boost::assign::map_list_of("txid", str_type)("vout", int_type)("scriptPubKey", str_type)("redeemScript",str_type));
Value v = find_value(prevOut, "redeemScript");
if (!(v == Value::null)) {
vector<unsigned char> rsData(ParseHexV(v, "redeemScript"));
@@ -690,7 +699,7 @@ Value signrawtransaction(const Array& params, bool fHelp)
BOOST_FOREACH(const CMutableTransaction& txv, txVariants) {
txin.scriptSig = CombineSignatures(prevPubKey, mergedTx, i, txin.scriptSig, txv.vin[i].scriptSig);
}
- if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, SignatureChecker(mergedTx, i)))
+ if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, MutableTransactionSignatureChecker(&mergedTx, i)))
fComplete = false;
}
@@ -724,7 +733,8 @@ Value sendrawtransaction(const Array& params, bool fHelp)
+ HelpExampleRpc("sendrawtransaction", "\"signedhex\"")
);
- RPCTypeCheck(params, list_of(str_type)(bool_type));
+ LOCK(cs_main);
+ RPCTypeCheck(params, boost::assign::list_of(str_type)(bool_type));
// parse hex string from parameter
CTransaction tx;
diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp
index c5d74afba9..20e9252d7e 100644
--- a/src/rpcserver.cpp
+++ b/src/rpcserver.cpp
@@ -7,9 +7,11 @@
#include "base58.h"
#include "init.h"
-#include "main.h"
+#include "random.h"
+#include "sync.h"
#include "ui_interface.h"
#include "util.h"
+#include "utilstrencodings.h"
#ifdef ENABLE_WALLET
#include "wallet.h"
#endif
@@ -23,12 +25,13 @@
#include <boost/iostreams/concepts.hpp>
#include <boost/iostreams/stream.hpp>
#include <boost/shared_ptr.hpp>
+#include <boost/signals2/signal.hpp>
#include <boost/thread.hpp>
#include "json/json_spirit_writer_template.h"
-using namespace boost;
using namespace boost::asio;
using namespace json_spirit;
+using namespace RPCServer;
using namespace std;
static std::string strRPCUserColonPass;
@@ -39,7 +42,7 @@ static std::string rpcWarmupStatus("RPC server started");
static CCriticalSection cs_rpcWarmup;
//! These are created by StartRPCThreads, destroyed in StopRPCThreads
-static asio::io_service* rpc_io_service = NULL;
+static boost::asio::io_service* rpc_io_service = NULL;
static map<string, boost::shared_ptr<deadline_timer> > deadlineTimers;
static ssl::context* rpc_ssl_context = NULL;
static boost::thread_group* rpc_worker_group = NULL;
@@ -47,6 +50,34 @@ static boost::asio::io_service::work *rpc_dummy_work = NULL;
static std::vector<CSubNet> rpc_allow_subnets; //!< List of subnets to allow RPC connections from
static std::vector< boost::shared_ptr<ip::tcp::acceptor> > rpc_acceptors;
+static struct CRPCSignals
+{
+ boost::signals2::signal<void ()> Started;
+ boost::signals2::signal<void ()> Stopped;
+ boost::signals2::signal<void (const CRPCCommand&)> PreCommand;
+ boost::signals2::signal<void (const CRPCCommand&)> PostCommand;
+} g_rpcSignals;
+
+void RPCServer::OnStarted(boost::function<void ()> slot)
+{
+ g_rpcSignals.Started.connect(slot);
+}
+
+void RPCServer::OnStopped(boost::function<void ()> slot)
+{
+ g_rpcSignals.Stopped.connect(slot);
+}
+
+void RPCServer::OnPreCommand(boost::function<void (const CRPCCommand&)> slot)
+{
+ g_rpcSignals.PreCommand.connect(boost::bind(slot, _1));
+}
+
+void RPCServer::OnPostCommand(boost::function<void (const CRPCCommand&)> slot)
+{
+ g_rpcSignals.PostCommand.connect(boost::bind(slot, _1));
+}
+
void RPCTypeCheck(const Array& params,
const list<Value_type>& typesExpected,
bool fAllowNull)
@@ -240,113 +271,110 @@ Value stop(const Array& params, bool fHelp)
* Call Table
*/
static const CRPCCommand vRPCCommands[] =
-{ // category name actor (function) okSafeMode threadSafe reqWallet
- // --------------------- ------------------------ ----------------------- ---------- ---------- ---------
+{ // category name actor (function) okSafeMode reqWallet
+ // --------------------- ------------------------ ----------------------- ---------- ---------
/* Overall control/query calls */
- { "control", "getinfo", &getinfo, true, false, false }, /* uses wallet if enabled */
- { "control", "help", &help, true, true, false },
- { "control", "stop", &stop, true, true, false },
+ { "control", "getinfo", &getinfo, true, false }, /* uses wallet if enabled */
+ { "control", "help", &help, true, false },
+ { "control", "stop", &stop, true, false },
/* P2P networking */
- { "network", "getnetworkinfo", &getnetworkinfo, true, false, false },
- { "network", "addnode", &addnode, true, true, false },
- { "network", "getaddednodeinfo", &getaddednodeinfo, true, true, false },
- { "network", "getconnectioncount", &getconnectioncount, true, false, false },
- { "network", "getnettotals", &getnettotals, true, true, false },
- { "network", "getpeerinfo", &getpeerinfo, true, false, false },
- { "network", "ping", &ping, true, false, false },
+ { "network", "getnetworkinfo", &getnetworkinfo, true, false },
+ { "network", "addnode", &addnode, true, false },
+ { "network", "getaddednodeinfo", &getaddednodeinfo, true, false },
+ { "network", "getconnectioncount", &getconnectioncount, true, false },
+ { "network", "getnettotals", &getnettotals, true, false },
+ { "network", "getpeerinfo", &getpeerinfo, true, false },
+ { "network", "ping", &ping, true, false },
/* Block chain and UTXO */
- { "blockchain", "getblockchaininfo", &getblockchaininfo, true, false, false },
- { "blockchain", "getbestblockhash", &getbestblockhash, true, false, false },
- { "blockchain", "getblockcount", &getblockcount, true, false, false },
- { "blockchain", "getblock", &getblock, true, false, false },
- { "blockchain", "getblockhash", &getblockhash, true, false, false },
- { "blockchain", "getchaintips", &getchaintips, true, false, false },
- { "blockchain", "getdifficulty", &getdifficulty, true, false, false },
- { "blockchain", "getmempoolinfo", &getmempoolinfo, true, true, false },
- { "blockchain", "getrawmempool", &getrawmempool, true, false, false },
- { "blockchain", "gettxout", &gettxout, true, false, false },
- { "blockchain", "gettxoutsetinfo", &gettxoutsetinfo, true, false, false },
- { "blockchain", "verifychain", &verifychain, true, false, false },
- { "blockchain", "invalidateblock", &invalidateblock, true, true, false },
- { "blockchain", "reconsiderblock", &reconsiderblock, true, true, false },
+ { "blockchain", "getblockchaininfo", &getblockchaininfo, true, false },
+ { "blockchain", "getbestblockhash", &getbestblockhash, true, false },
+ { "blockchain", "getblockcount", &getblockcount, true, false },
+ { "blockchain", "getblock", &getblock, true, false },
+ { "blockchain", "getblockhash", &getblockhash, true, false },
+ { "blockchain", "getchaintips", &getchaintips, true, false },
+ { "blockchain", "getdifficulty", &getdifficulty, true, false },
+ { "blockchain", "getmempoolinfo", &getmempoolinfo, true, false },
+ { "blockchain", "getrawmempool", &getrawmempool, true, false },
+ { "blockchain", "gettxout", &gettxout, true, false },
+ { "blockchain", "gettxoutsetinfo", &gettxoutsetinfo, true, false },
+ { "blockchain", "verifychain", &verifychain, true, false },
/* Mining */
- { "mining", "getblocktemplate", &getblocktemplate, true, false, false },
- { "mining", "getmininginfo", &getmininginfo, true, false, false },
- { "mining", "getnetworkhashps", &getnetworkhashps, true, false, false },
- { "mining", "prioritisetransaction", &prioritisetransaction, true, false, false },
- { "mining", "submitblock", &submitblock, true, true, false },
+ { "mining", "getblocktemplate", &getblocktemplate, true, false },
+ { "mining", "getmininginfo", &getmininginfo, true, false },
+ { "mining", "getnetworkhashps", &getnetworkhashps, true, false },
+ { "mining", "prioritisetransaction", &prioritisetransaction, true, false },
+ { "mining", "submitblock", &submitblock, true, false },
#ifdef ENABLE_WALLET
/* Coin generation */
- { "generating", "getgenerate", &getgenerate, true, false, false },
- { "generating", "gethashespersec", &gethashespersec, true, false, false },
- { "generating", "setgenerate", &setgenerate, true, true, false },
+ { "generating", "getgenerate", &getgenerate, true, false },
+ { "generating", "setgenerate", &setgenerate, true, false },
#endif
/* Raw transactions */
- { "rawtransactions", "createrawtransaction", &createrawtransaction, true, false, false },
- { "rawtransactions", "decoderawtransaction", &decoderawtransaction, true, false, false },
- { "rawtransactions", "decodescript", &decodescript, true, false, false },
- { "rawtransactions", "getrawtransaction", &getrawtransaction, true, false, false },
- { "rawtransactions", "sendrawtransaction", &sendrawtransaction, false, false, false },
- { "rawtransactions", "signrawtransaction", &signrawtransaction, false, false, false }, /* uses wallet if enabled */
+ { "rawtransactions", "createrawtransaction", &createrawtransaction, true, false },
+ { "rawtransactions", "decoderawtransaction", &decoderawtransaction, true, false },
+ { "rawtransactions", "decodescript", &decodescript, true, false },
+ { "rawtransactions", "getrawtransaction", &getrawtransaction, true, false },
+ { "rawtransactions", "sendrawtransaction", &sendrawtransaction, false, false },
+ { "rawtransactions", "signrawtransaction", &signrawtransaction, false, false }, /* uses wallet if enabled */
/* Utility functions */
- { "util", "createmultisig", &createmultisig, true, true , false },
- { "util", "validateaddress", &validateaddress, true, false, false }, /* uses wallet if enabled */
- { "util", "verifymessage", &verifymessage, true, false, false },
- { "util", "estimatefee", &estimatefee, true, true, false },
- { "util", "estimatepriority", &estimatepriority, true, true, false },
+ { "util", "createmultisig", &createmultisig, true, false },
+ { "util", "validateaddress", &validateaddress, true, false }, /* uses wallet if enabled */
+ { "util", "verifymessage", &verifymessage, true, false },
+ { "util", "estimatefee", &estimatefee, true, false },
+ { "util", "estimatepriority", &estimatepriority, true, false },
/* Not shown in help */
- { "hidden", "invalidateblock", &invalidateblock, true, true, false },
- { "hidden", "reconsiderblock", &reconsiderblock, true, true, false },
- { "hidden", "setmocktime", &setmocktime, true, false, false },
+ { "hidden", "invalidateblock", &invalidateblock, true, false },
+ { "hidden", "reconsiderblock", &reconsiderblock, true, false },
+ { "hidden", "setmocktime", &setmocktime, true, false },
#ifdef ENABLE_WALLET
/* Wallet */
- { "wallet", "addmultisigaddress", &addmultisigaddress, true, false, true },
- { "wallet", "backupwallet", &backupwallet, true, false, true },
- { "wallet", "dumpprivkey", &dumpprivkey, true, false, true },
- { "wallet", "dumpwallet", &dumpwallet, true, false, true },
- { "wallet", "encryptwallet", &encryptwallet, true, false, true },
- { "wallet", "getaccountaddress", &getaccountaddress, true, false, true },
- { "wallet", "getaccount", &getaccount, true, false, true },
- { "wallet", "getaddressesbyaccount", &getaddressesbyaccount, true, false, true },
- { "wallet", "getbalance", &getbalance, false, false, true },
- { "wallet", "getnewaddress", &getnewaddress, true, false, true },
- { "wallet", "getrawchangeaddress", &getrawchangeaddress, true, false, true },
- { "wallet", "getreceivedbyaccount", &getreceivedbyaccount, false, false, true },
- { "wallet", "getreceivedbyaddress", &getreceivedbyaddress, false, false, true },
- { "wallet", "gettransaction", &gettransaction, false, false, true },
- { "wallet", "getunconfirmedbalance", &getunconfirmedbalance, false, false, true },
- { "wallet", "getwalletinfo", &getwalletinfo, false, false, true },
- { "wallet", "importprivkey", &importprivkey, true, false, true },
- { "wallet", "importwallet", &importwallet, true, false, true },
- { "wallet", "importaddress", &importaddress, true, false, true },
- { "wallet", "keypoolrefill", &keypoolrefill, true, false, true },
- { "wallet", "listaccounts", &listaccounts, false, false, true },
- { "wallet", "listaddressgroupings", &listaddressgroupings, false, false, true },
- { "wallet", "listlockunspent", &listlockunspent, false, false, true },
- { "wallet", "listreceivedbyaccount", &listreceivedbyaccount, false, false, true },
- { "wallet", "listreceivedbyaddress", &listreceivedbyaddress, false, false, true },
- { "wallet", "listsinceblock", &listsinceblock, false, false, true },
- { "wallet", "listtransactions", &listtransactions, false, false, true },
- { "wallet", "listunspent", &listunspent, false, false, true },
- { "wallet", "lockunspent", &lockunspent, true, false, true },
- { "wallet", "move", &movecmd, false, false, true },
- { "wallet", "sendfrom", &sendfrom, false, false, true },
- { "wallet", "sendmany", &sendmany, false, false, true },
- { "wallet", "sendtoaddress", &sendtoaddress, false, false, true },
- { "wallet", "setaccount", &setaccount, true, false, true },
- { "wallet", "settxfee", &settxfee, true, false, true },
- { "wallet", "signmessage", &signmessage, true, false, true },
- { "wallet", "walletlock", &walletlock, true, false, true },
- { "wallet", "walletpassphrasechange", &walletpassphrasechange, true, false, true },
- { "wallet", "walletpassphrase", &walletpassphrase, true, false, true },
+ { "wallet", "addmultisigaddress", &addmultisigaddress, true, true },
+ { "wallet", "backupwallet", &backupwallet, true, true },
+ { "wallet", "dumpprivkey", &dumpprivkey, true, true },
+ { "wallet", "dumpwallet", &dumpwallet, true, true },
+ { "wallet", "encryptwallet", &encryptwallet, true, true },
+ { "wallet", "getaccountaddress", &getaccountaddress, true, true },
+ { "wallet", "getaccount", &getaccount, true, true },
+ { "wallet", "getaddressesbyaccount", &getaddressesbyaccount, true, true },
+ { "wallet", "getbalance", &getbalance, false, true },
+ { "wallet", "getnewaddress", &getnewaddress, true, true },
+ { "wallet", "getrawchangeaddress", &getrawchangeaddress, true, true },
+ { "wallet", "getreceivedbyaccount", &getreceivedbyaccount, false, true },
+ { "wallet", "getreceivedbyaddress", &getreceivedbyaddress, false, true },
+ { "wallet", "gettransaction", &gettransaction, false, true },
+ { "wallet", "getunconfirmedbalance", &getunconfirmedbalance, false, true },
+ { "wallet", "getwalletinfo", &getwalletinfo, false, true },
+ { "wallet", "importprivkey", &importprivkey, true, true },
+ { "wallet", "importwallet", &importwallet, true, true },
+ { "wallet", "importaddress", &importaddress, true, true },
+ { "wallet", "keypoolrefill", &keypoolrefill, true, true },
+ { "wallet", "listaccounts", &listaccounts, false, true },
+ { "wallet", "listaddressgroupings", &listaddressgroupings, false, true },
+ { "wallet", "listlockunspent", &listlockunspent, false, true },
+ { "wallet", "listreceivedbyaccount", &listreceivedbyaccount, false, true },
+ { "wallet", "listreceivedbyaddress", &listreceivedbyaddress, false, true },
+ { "wallet", "listsinceblock", &listsinceblock, false, true },
+ { "wallet", "listtransactions", &listtransactions, false, true },
+ { "wallet", "listunspent", &listunspent, false, true },
+ { "wallet", "lockunspent", &lockunspent, true, true },
+ { "wallet", "move", &movecmd, false, true },
+ { "wallet", "sendfrom", &sendfrom, false, true },
+ { "wallet", "sendmany", &sendmany, false, true },
+ { "wallet", "sendtoaddress", &sendtoaddress, false, true },
+ { "wallet", "setaccount", &setaccount, true, true },
+ { "wallet", "settxfee", &settxfee, true, true },
+ { "wallet", "signmessage", &signmessage, true, true },
+ { "wallet", "walletlock", &walletlock, true, true },
+ { "wallet", "walletpassphrasechange", &walletpassphrasechange, true, true },
+ { "wallet", "walletpassphrase", &walletpassphrase, true, true },
#endif // ENABLE_WALLET
};
@@ -428,7 +456,7 @@ class AcceptedConnectionImpl : public AcceptedConnection
{
public:
AcceptedConnectionImpl(
- asio::io_service& io_service,
+ boost::asio::io_service& io_service,
ssl::context &context,
bool fUseSSL) :
sslStream(io_service, context),
@@ -453,11 +481,11 @@ public:
}
typename Protocol::endpoint peer;
- asio::ssl::stream<typename Protocol::socket> sslStream;
+ boost::asio::ssl::stream<typename Protocol::socket> sslStream;
private:
SSLIOStreamDevice<Protocol> _d;
- iostreams::stream< SSLIOStreamDevice<Protocol> > _stream;
+ boost::iostreams::stream< SSLIOStreamDevice<Protocol> > _stream;
};
void ServiceConnection(AcceptedConnection *conn);
@@ -504,7 +532,7 @@ static void RPCAcceptHandler(boost::shared_ptr< basic_socket_acceptor<Protocol,
const boost::system::error_code& error)
{
// Immediately start accepting new connections, except when we're cancelled or our socket is closed.
- if (error != asio::error::operation_aborted && acceptor->is_open())
+ if (error != boost::asio::error::operation_aborted && acceptor->is_open())
RPCListen(acceptor, context, fUseSSL);
AcceptedConnectionImpl<ip::tcp>* tcp_conn = dynamic_cast< AcceptedConnectionImpl<ip::tcp>* >(conn.get());
@@ -535,7 +563,7 @@ static ip::tcp::endpoint ParseEndpoint(const std::string &strEndpoint, int defau
std::string addr;
int port = defaultPort;
SplitHostPort(strEndpoint, port, addr);
- return ip::tcp::endpoint(asio::ip::address::from_string(addr), port);
+ return ip::tcp::endpoint(boost::asio::ip::address::from_string(addr), port);
}
void StartRPCThreads()
@@ -590,7 +618,7 @@ void StartRPCThreads()
}
assert(rpc_io_service == NULL);
- rpc_io_service = new asio::io_service();
+ rpc_io_service = new boost::asio::io_service();
rpc_ssl_context = new ssl::context(*rpc_io_service, ssl::context::sslv23);
const bool fUseSSL = GetBoolArg("-rpcssl", false);
@@ -599,14 +627,14 @@ void StartRPCThreads()
{
rpc_ssl_context->set_options(ssl::context::no_sslv2 | ssl::context::no_sslv3);
- filesystem::path pathCertFile(GetArg("-rpcsslcertificatechainfile", "server.cert"));
- if (!pathCertFile.is_complete()) pathCertFile = filesystem::path(GetDataDir()) / pathCertFile;
- if (filesystem::exists(pathCertFile)) rpc_ssl_context->use_certificate_chain_file(pathCertFile.string());
+ boost::filesystem::path pathCertFile(GetArg("-rpcsslcertificatechainfile", "server.cert"));
+ if (!pathCertFile.is_complete()) pathCertFile = boost::filesystem::path(GetDataDir()) / pathCertFile;
+ if (boost::filesystem::exists(pathCertFile)) rpc_ssl_context->use_certificate_chain_file(pathCertFile.string());
else LogPrintf("ThreadRPCServer ERROR: missing server certificate file %s\n", pathCertFile.string());
- filesystem::path pathPKFile(GetArg("-rpcsslprivatekeyfile", "server.pem"));
- if (!pathPKFile.is_complete()) pathPKFile = filesystem::path(GetDataDir()) / pathPKFile;
- if (filesystem::exists(pathPKFile)) rpc_ssl_context->use_private_key_file(pathPKFile.string(), ssl::context::pem);
+ boost::filesystem::path pathPKFile(GetArg("-rpcsslprivatekeyfile", "server.pem"));
+ if (!pathPKFile.is_complete()) pathPKFile = boost::filesystem::path(GetDataDir()) / pathPKFile;
+ if (boost::filesystem::exists(pathPKFile)) rpc_ssl_context->use_private_key_file(pathPKFile.string(), ssl::context::pem);
else LogPrintf("ThreadRPCServer ERROR: missing server private key file %s\n", pathPKFile.string());
string strCiphers = GetArg("-rpcsslciphers", "TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH");
@@ -618,8 +646,8 @@ void StartRPCThreads()
int defaultPort = GetArg("-rpcport", BaseParams().RPCPort());
if (!mapArgs.count("-rpcallowip")) // Default to loopback if not allowing external IPs
{
- vEndpoints.push_back(ip::tcp::endpoint(asio::ip::address_v6::loopback(), defaultPort));
- vEndpoints.push_back(ip::tcp::endpoint(asio::ip::address_v4::loopback(), defaultPort));
+ vEndpoints.push_back(ip::tcp::endpoint(boost::asio::ip::address_v6::loopback(), defaultPort));
+ vEndpoints.push_back(ip::tcp::endpoint(boost::asio::ip::address_v4::loopback(), defaultPort));
if (mapArgs.count("-rpcbind"))
{
LogPrintf("WARNING: option -rpcbind was ignored because -rpcallowip was not specified, refusing to allow everyone to connect\n");
@@ -641,8 +669,8 @@ void StartRPCThreads()
}
}
} else { // No specific bind address specified, bind to any
- vEndpoints.push_back(ip::tcp::endpoint(asio::ip::address_v6::any(), defaultPort));
- vEndpoints.push_back(ip::tcp::endpoint(asio::ip::address_v4::any(), defaultPort));
+ vEndpoints.push_back(ip::tcp::endpoint(boost::asio::ip::address_v6::any(), defaultPort));
+ vEndpoints.push_back(ip::tcp::endpoint(boost::asio::ip::address_v4::any(), defaultPort));
// Prefer making the socket dual IPv6/IPv4 instead of binding
// to both addresses seperately.
bBindAny = true;
@@ -650,20 +678,22 @@ void StartRPCThreads()
bool fListening = false;
std::string strerr;
+ std::string straddress;
BOOST_FOREACH(const ip::tcp::endpoint &endpoint, vEndpoints)
{
- asio::ip::address bindAddress = endpoint.address();
- LogPrintf("Binding RPC on address %s port %i (IPv4+IPv6 bind any: %i)\n", bindAddress.to_string(), endpoint.port(), bBindAny);
- boost::system::error_code v6_only_error;
- boost::shared_ptr<ip::tcp::acceptor> acceptor(new ip::tcp::acceptor(*rpc_io_service));
-
try {
+ boost::asio::ip::address bindAddress = endpoint.address();
+ straddress = bindAddress.to_string();
+ LogPrintf("Binding RPC on address %s port %i (IPv4+IPv6 bind any: %i)\n", straddress, endpoint.port(), bBindAny);
+ boost::system::error_code v6_only_error;
+ boost::shared_ptr<ip::tcp::acceptor> acceptor(new ip::tcp::acceptor(*rpc_io_service));
+
acceptor->open(endpoint.protocol());
acceptor->set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
// Try making the socket dual IPv6/IPv4 when listening on the IPv6 "any" address
acceptor->set_option(boost::asio::ip::v6_only(
- !bBindAny || bindAddress != asio::ip::address_v6::any()), v6_only_error);
+ !bBindAny || bindAddress != boost::asio::ip::address_v6::any()), v6_only_error);
acceptor->bind(endpoint);
acceptor->listen(socket_base::max_connections);
@@ -673,13 +703,13 @@ void StartRPCThreads()
fListening = true;
rpc_acceptors.push_back(acceptor);
// If dual IPv6/IPv4 bind successful, skip binding to IPv4 separately
- if(bBindAny && bindAddress == asio::ip::address_v6::any() && !v6_only_error)
+ if(bBindAny && bindAddress == boost::asio::ip::address_v6::any() && !v6_only_error)
break;
}
catch (const boost::system::system_error& e)
{
- LogPrintf("ERROR: Binding RPC on address %s port %i failed: %s\n", bindAddress.to_string(), endpoint.port(), e.what());
- strerr = strprintf(_("An error occurred while setting up the RPC address %s port %u for listening: %s"), bindAddress.to_string(), endpoint.port(), e.what());
+ LogPrintf("ERROR: Binding RPC on address %s port %i failed: %s\n", straddress, endpoint.port(), e.what());
+ strerr = strprintf(_("An error occurred while setting up the RPC address %s port %u for listening: %s"), straddress, endpoint.port(), e.what());
}
}
@@ -691,20 +721,21 @@ void StartRPCThreads()
rpc_worker_group = new boost::thread_group();
for (int i = 0; i < GetArg("-rpcthreads", 4); i++)
- rpc_worker_group->create_thread(boost::bind(&asio::io_service::run, rpc_io_service));
+ rpc_worker_group->create_thread(boost::bind(&boost::asio::io_service::run, rpc_io_service));
fRPCRunning = true;
+ g_rpcSignals.Started();
}
void StartDummyRPCThread()
{
if(rpc_io_service == NULL)
{
- rpc_io_service = new asio::io_service();
+ rpc_io_service = new boost::asio::io_service();
/* Create dummy "work" to keep the thread from exiting when no timeouts active,
* see http://www.boost.org/doc/libs/1_51_0/doc/html/boost_asio/reference/io_service.html#boost_asio.reference.io_service.stopping_the_io_service_from_running_out_of_work */
- rpc_dummy_work = new asio::io_service::work(*rpc_io_service);
+ rpc_dummy_work = new boost::asio::io_service::work(*rpc_io_service);
rpc_worker_group = new boost::thread_group();
- rpc_worker_group->create_thread(boost::bind(&asio::io_service::run, rpc_io_service));
+ rpc_worker_group->create_thread(boost::bind(&boost::asio::io_service::run, rpc_io_service));
fRPCRunning = true;
}
}
@@ -717,7 +748,7 @@ void StopRPCThreads()
// First, cancel all timers and acceptors
// This is not done automatically by ->stop(), and in some cases the destructor of
- // asio::io_service can hang if this is skipped.
+ // boost::asio::io_service can hang if this is skipped.
boost::system::error_code ec;
BOOST_FOREACH(const boost::shared_ptr<ip::tcp::acceptor> &acceptor, rpc_acceptors)
{
@@ -735,7 +766,7 @@ void StopRPCThreads()
deadlineTimers.clear();
rpc_io_service->stop();
- cvBlockChange.notify_all();
+ g_rpcSignals.Stopped();
if (rpc_worker_group != NULL)
rpc_worker_group->join_all();
delete rpc_dummy_work; rpc_dummy_work = NULL;
@@ -785,7 +816,7 @@ void RPCRunLater(const std::string& name, boost::function<void(void)> func, int6
deadlineTimers.insert(make_pair(name,
boost::shared_ptr<deadline_timer>(new deadline_timer(*rpc_io_service))));
}
- deadlineTimers[name]->expires_from_now(posix_time::seconds(nSeconds));
+ deadlineTimers[name]->expires_from_now(boost::posix_time::seconds(nSeconds));
deadlineTimers[name]->async_wait(boost::bind(RPCRunHandler, _1, func));
}
@@ -818,7 +849,7 @@ void JSONRequest::parse(const Value& valRequest)
throw JSONRPCError(RPC_INVALID_REQUEST, "Method must be a string");
strMethod = valMethod.get_str();
if (strMethod != "getblocktemplate")
- LogPrint("rpc", "ThreadRPCServer method=%s\n", strMethod);
+ LogPrint("rpc", "ThreadRPCServer method=%s\n", SanitizeString(strMethod));
// Parse params
Value valParams = find_value(request, "params");
@@ -952,7 +983,7 @@ void ServiceConnection(AcceptedConnection *conn)
ReadHTTPMessage(conn->stream(), mapHeaders, strRequest, nProto, MAX_SIZE);
// HTTP Keep-Alive is false; close connection immediately
- if (mapHeaders["connection"] == "close")
+ if ((mapHeaders["connection"] == "close") || (!GetBoolArg("-rpckeepalive", true)))
fRun = false;
// Process via JSON-RPC API
@@ -978,45 +1009,20 @@ json_spirit::Value CRPCTable::execute(const std::string &strMethod, const json_s
const CRPCCommand *pcmd = tableRPC[strMethod];
if (!pcmd)
throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found");
-#ifdef ENABLE_WALLET
- if (pcmd->reqWallet && !pwalletMain)
- throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found (disabled)");
-#endif
- // Observe safe mode
- string strWarning = GetWarnings("rpc");
- if (strWarning != "" && !GetBoolArg("-disablesafemode", false) &&
- !pcmd->okSafeMode)
- throw JSONRPCError(RPC_FORBIDDEN_BY_SAFE_MODE, string("Safe mode: ") + strWarning);
+ g_rpcSignals.PreCommand(*pcmd);
try
{
// Execute
- Value result;
- {
- if (pcmd->threadSafe)
- result = pcmd->actor(params, false);
-#ifdef ENABLE_WALLET
- else if (!pwalletMain) {
- LOCK(cs_main);
- result = pcmd->actor(params, false);
- } else {
- LOCK2(cs_main, pwalletMain->cs_wallet);
- result = pcmd->actor(params, false);
- }
-#else // ENABLE_WALLET
- else {
- LOCK(cs_main);
- result = pcmd->actor(params, false);
- }
-#endif // !ENABLE_WALLET
- }
- return result;
+ return pcmd->actor(params, false);
}
catch (const std::exception& e)
{
throw JSONRPCError(RPC_MISC_ERROR, e.what());
}
+
+ g_rpcSignals.PostCommand(*pcmd);
}
std::string HelpExampleCli(string methodname, string args){
diff --git a/src/rpcserver.h b/src/rpcserver.h
index fb561ab939..f63438ecb8 100644
--- a/src/rpcserver.h
+++ b/src/rpcserver.h
@@ -19,6 +19,16 @@
#include "json/json_spirit_utils.h"
#include "json/json_spirit_writer_template.h"
+class CRPCCommand;
+
+namespace RPCServer
+{
+ void OnStarted(boost::function<void ()> slot);
+ void OnStopped(boost::function<void ()> slot);
+ void OnPreCommand(boost::function<void (const CRPCCommand&)> slot);
+ void OnPostCommand(boost::function<void (const CRPCCommand&)> slot);
+}
+
class CBlockIndex;
class CNetAddr;
@@ -88,7 +98,6 @@ public:
std::string name;
rpcfn_type actor;
bool okSafeMode;
- bool threadSafe;
bool reqWallet;
};
@@ -154,7 +163,6 @@ extern json_spirit::Value importwallet(const json_spirit::Array& params, bool fH
extern json_spirit::Value getgenerate(const json_spirit::Array& params, bool fHelp); // in rpcmining.cpp
extern json_spirit::Value setgenerate(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value getnetworkhashps(const json_spirit::Array& params, bool fHelp);
-extern json_spirit::Value gethashespersec(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value getmininginfo(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value prioritisetransaction(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value getblocktemplate(const json_spirit::Array& params, bool fHelp);
diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp
index 63da8a20b5..1afc3c910e 100644
--- a/src/rpcwallet.cpp
+++ b/src/rpcwallet.cpp
@@ -23,8 +23,6 @@
#include "json/json_spirit_value.h"
using namespace std;
-using namespace boost;
-using namespace boost::assign;
using namespace json_spirit;
int64_t nWalletUnlockTime;
@@ -81,19 +79,19 @@ Value getnewaddress(const Array& params, bool fHelp)
throw runtime_error(
"getnewaddress ( \"account\" )\n"
"\nReturns a new Bitcoin address for receiving payments.\n"
- "If 'account' is specified (recommended), it is added to the address book \n"
+ "If 'account' is specified (DEPRECATED), it is added to the address book \n"
"so payments received with the address will be credited to 'account'.\n"
"\nArguments:\n"
- "1. \"account\" (string, optional) The account name for the address to be linked to. if not provided, the default account \"\" is used. It can also be set to the empty string \"\" to represent the default account. The account does not need to exist, it will be created if there is no account by the given name.\n"
+ "1. \"account\" (string, optional) DEPRECATED. The account name for the address to be linked to. If not provided, the default account \"\" is used. It can also be set to the empty string \"\" to represent the default account. The account does not need to exist, it will be created if there is no account by the given name.\n"
"\nResult:\n"
"\"bitcoinaddress\" (string) The new bitcoin address\n"
"\nExamples:\n"
+ HelpExampleCli("getnewaddress", "")
- + HelpExampleCli("getnewaddress", "\"\"")
- + HelpExampleCli("getnewaddress", "\"myaccount\"")
- + HelpExampleRpc("getnewaddress", "\"myaccount\"")
+ + HelpExampleRpc("getnewaddress", "")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
// Parse the account first so we don't generate a key if there's an error
string strAccount;
if (params.size() > 0)
@@ -156,7 +154,7 @@ Value getaccountaddress(const Array& params, bool fHelp)
if (fHelp || params.size() != 1)
throw runtime_error(
"getaccountaddress \"account\"\n"
- "\nReturns the current Bitcoin address for receiving payments to this account.\n"
+ "\nDEPRECATED. Returns the current Bitcoin address for receiving payments to this account.\n"
"\nArguments:\n"
"1. \"account\" (string, required) The account name for the address. It can also be set to the empty string \"\" to represent the default account. The account does not need to exist, it will be created and a new address created if there is no account by the given name.\n"
"\nResult:\n"
@@ -168,13 +166,14 @@ Value getaccountaddress(const Array& params, bool fHelp)
+ HelpExampleRpc("getaccountaddress", "\"myaccount\"")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
// Parse the account first so we don't generate a key if there's an error
string strAccount = AccountFromValue(params[0]);
Value ret;
ret = GetAccountAddress(strAccount).ToString();
-
return ret;
}
@@ -193,6 +192,8 @@ Value getrawchangeaddress(const Array& params, bool fHelp)
+ HelpExampleRpc("getrawchangeaddress", "")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
if (!pwalletMain->IsLocked())
pwalletMain->TopUpKeyPool();
@@ -214,7 +215,7 @@ Value setaccount(const Array& params, bool fHelp)
if (fHelp || params.size() < 1 || params.size() > 2)
throw runtime_error(
"setaccount \"bitcoinaddress\" \"account\"\n"
- "\nSets the account associated with the given address.\n"
+ "\nDEPRECATED. Sets the account associated with the given address.\n"
"\nArguments:\n"
"1. \"bitcoinaddress\" (string, required) The bitcoin address to be associated with an account.\n"
"2. \"account\" (string, required) The account to assign the address to.\n"
@@ -223,11 +224,12 @@ Value setaccount(const Array& params, bool fHelp)
+ HelpExampleRpc("setaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\", \"tabby\"")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
CBitcoinAddress address(params[0].get_str());
if (!address.IsValid())
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
-
string strAccount;
if (params.size() > 1)
strAccount = AccountFromValue(params[1]);
@@ -256,7 +258,7 @@ Value getaccount(const Array& params, bool fHelp)
if (fHelp || params.size() != 1)
throw runtime_error(
"getaccount \"bitcoinaddress\"\n"
- "\nReturns the account associated with the given address.\n"
+ "\nDEPRECATED. Returns the account associated with the given address.\n"
"\nArguments:\n"
"1. \"bitcoinaddress\" (string, required) The bitcoin address for account lookup.\n"
"\nResult:\n"
@@ -266,6 +268,8 @@ Value getaccount(const Array& params, bool fHelp)
+ HelpExampleRpc("getaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\"")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
CBitcoinAddress address(params[0].get_str());
if (!address.IsValid())
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
@@ -283,7 +287,7 @@ Value getaddressesbyaccount(const Array& params, bool fHelp)
if (fHelp || params.size() != 1)
throw runtime_error(
"getaddressesbyaccount \"account\"\n"
- "\nReturns the list of addresses for the given account.\n"
+ "\nDEPRECATED. Returns the list of addresses for the given account.\n"
"\nArguments:\n"
"1. \"account\" (string, required) The account name.\n"
"\nResult:\n"
@@ -296,6 +300,8 @@ Value getaddressesbyaccount(const Array& params, bool fHelp)
+ HelpExampleRpc("getaddressesbyaccount", "\"tabby\"")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
string strAccount = AccountFromValue(params[0]);
// Find all addresses that have the given account
@@ -323,7 +329,7 @@ void SendMoney(const CTxDestination &address, CAmount nValue, CWalletTx& wtxNew)
if (pwalletMain->IsLocked())
{
strError = "Error: Wallet locked, unable to create transaction!";
- LogPrintf("SendMoney() : %s", strError);
+ LogPrintf("SendMoney(): %s", strError);
throw JSONRPCError(RPC_WALLET_ERROR, strError);
}
@@ -337,7 +343,7 @@ void SendMoney(const CTxDestination &address, CAmount nValue, CWalletTx& wtxNew)
{
if (nValue + nFeeRequired > pwalletMain->GetBalance())
strError = strprintf("Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds!", FormatMoney(nFeeRequired));
- LogPrintf("SendMoney() : %s\n", strError);
+ LogPrintf("SendMoney(): %s\n", strError);
throw JSONRPCError(RPC_WALLET_ERROR, strError);
}
if (!pwalletMain->CommitTransaction(wtxNew, reservekey))
@@ -367,6 +373,8 @@ Value sendtoaddress(const Array& params, bool fHelp)
+ HelpExampleRpc("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\", 0.1, \"donation\", \"seans outpost\"")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
CBitcoinAddress address(params[0].get_str());
if (!address.IsValid())
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
@@ -402,7 +410,7 @@ Value listaddressgroupings(const Array& params, bool fHelp)
" [\n"
" \"bitcoinaddress\", (string) The bitcoin address\n"
" amount, (numeric) The amount in btc\n"
- " \"account\" (string, optional) The account\n"
+ " \"account\" (string, optional) The account (DEPRECATED)\n"
" ]\n"
" ,...\n"
" ]\n"
@@ -413,6 +421,8 @@ Value listaddressgroupings(const Array& params, bool fHelp)
+ HelpExampleRpc("listaddressgroupings", "")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
Array jsonGroupings;
map<CTxDestination, CAmount> balances = pwalletMain->GetAddressBalances();
BOOST_FOREACH(set<CTxDestination> grouping, pwalletMain->GetAddressGroupings())
@@ -458,6 +468,8 @@ Value signmessage(const Array& params, bool fHelp)
+ HelpExampleRpc("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\", \"my message\"")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
EnsureWalletIsUnlocked();
string strAddress = params[0].get_str();
@@ -508,6 +520,8 @@ Value getreceivedbyaddress(const Array& params, bool fHelp)
+ HelpExampleRpc("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\", 6")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
// Bitcoin address
CBitcoinAddress address = CBitcoinAddress(params[0].get_str());
if (!address.IsValid())
@@ -544,7 +558,7 @@ Value getreceivedbyaccount(const Array& params, bool fHelp)
if (fHelp || params.size() < 1 || params.size() > 2)
throw runtime_error(
"getreceivedbyaccount \"account\" ( minconf )\n"
- "\nReturns the total amount received by addresses with <account> in transactions with at least [minconf] confirmations.\n"
+ "\nDEPRECATED. Returns the total amount received by addresses with <account> in transactions with at least [minconf] confirmations.\n"
"\nArguments:\n"
"1. \"account\" (string, required) The selected account, may be the default account using \"\".\n"
"2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n"
@@ -561,6 +575,8 @@ Value getreceivedbyaccount(const Array& params, bool fHelp)
+ HelpExampleRpc("getreceivedbyaccount", "\"tabby\", 6")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
// Minimum confirmations
int nMinDepth = 1;
if (params.size() > 1)
@@ -629,28 +645,26 @@ Value getbalance(const Array& params, bool fHelp)
throw runtime_error(
"getbalance ( \"account\" minconf includeWatchonly )\n"
"\nIf account is not specified, returns the server's total available balance.\n"
- "If account is specified, returns the balance in the account.\n"
+ "If account is specified (DEPRECATED), returns the balance in the account.\n"
"Note that the account \"\" is not the same as leaving the parameter out.\n"
"The server total may be different to the balance in the default \"\" account.\n"
"\nArguments:\n"
- "1. \"account\" (string, optional) The selected account, or \"*\" for entire wallet. It may be the default account using \"\".\n"
+ "1. \"account\" (string, optional) DEPRECATED. The selected account, or \"*\" for entire wallet. It may be the default account using \"\".\n"
"2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n"
"3. includeWatchonly (bool, optional, default=false) Also include balance in watchonly addresses (see 'importaddress')\n"
"\nResult:\n"
"amount (numeric) The total amount in btc received for this account.\n"
"\nExamples:\n"
- "\nThe total amount in the server across all accounts\n"
+ "\nThe total amount in the wallet\n"
+ HelpExampleCli("getbalance", "") +
- "\nThe total amount in the server across all accounts, with at least 5 confirmations\n"
+ "\nThe total amount in the wallet at least 5 blocks confirmed\n"
+ HelpExampleCli("getbalance", "\"*\" 6") +
- "\nThe total amount in the default account with at least 1 confirmation\n"
- + HelpExampleCli("getbalance", "\"\"") +
- "\nThe total amount in the account named tabby with at least 6 confirmations\n"
- + HelpExampleCli("getbalance", "\"tabby\" 6") +
"\nAs a json rpc call\n"
- + HelpExampleRpc("getbalance", "\"tabby\", 6")
+ + HelpExampleRpc("getbalance", "\"*\", 6")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
if (params.size() == 0)
return ValueFromAmount(pwalletMain->GetBalance());
@@ -703,6 +717,9 @@ Value getunconfirmedbalance(const Array &params, bool fHelp)
throw runtime_error(
"getunconfirmedbalance\n"
"Returns the server's total unconfirmed balance\n");
+
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
return ValueFromAmount(pwalletMain->GetUnconfirmedBalance());
}
@@ -712,7 +729,7 @@ Value movecmd(const Array& params, bool fHelp)
if (fHelp || params.size() < 3 || params.size() > 5)
throw runtime_error(
"move \"fromaccount\" \"toaccount\" amount ( minconf \"comment\" )\n"
- "\nMove a specified amount from one account in your wallet to another.\n"
+ "\nDEPRECATED. Move a specified amount from one account in your wallet to another.\n"
"\nArguments:\n"
"1. \"fromaccount\" (string, required) The name of the account to move funds from. May be the default account using \"\".\n"
"2. \"toaccount\" (string, required) The name of the account to move funds to. May be the default account using \"\".\n"
@@ -729,6 +746,8 @@ Value movecmd(const Array& params, bool fHelp)
+ HelpExampleRpc("move", "\"timotei\", \"akiko\", 0.01, 6, \"happy birthday!\"")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
string strFrom = AccountFromValue(params[0]);
string strTo = AccountFromValue(params[1]);
CAmount nAmount = AmountFromValue(params[2]);
@@ -777,7 +796,7 @@ Value sendfrom(const Array& params, bool fHelp)
if (fHelp || params.size() < 3 || params.size() > 6)
throw runtime_error(
"sendfrom \"fromaccount\" \"tobitcoinaddress\" amount ( minconf \"comment\" \"comment-to\" )\n"
- "\nSent an amount from an account to a bitcoin address.\n"
+ "\nDEPRECATED (use sendtoaddress). Sent an amount from an account to a bitcoin address.\n"
"The amount is a real and is rounded to the nearest 0.00000001."
+ HelpRequiringPassphrase() + "\n"
"\nArguments:\n"
@@ -801,6 +820,8 @@ Value sendfrom(const Array& params, bool fHelp)
+ HelpExampleRpc("sendfrom", "\"tabby\", \"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\", 0.01, 6, \"donation\", \"seans outpost\"")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
string strAccount = AccountFromValue(params[0]);
CBitcoinAddress address(params[1].get_str());
if (!address.IsValid())
@@ -838,7 +859,7 @@ Value sendmany(const Array& params, bool fHelp)
"\nSend multiple times. Amounts are double-precision floating point numbers."
+ HelpRequiringPassphrase() + "\n"
"\nArguments:\n"
- "1. \"fromaccount\" (string, required) The account to send the funds from, can be \"\" for the default account\n"
+ "1. \"fromaccount\" (string, required) DEPRECATED. The account to send the funds from. Should be \"\" for the default account\n"
"2. \"amounts\" (string, required) A json object with addresses and amounts\n"
" {\n"
" \"address\":amount (numeric) The bitcoin address is the key, the numeric amount in btc is the value\n"
@@ -851,13 +872,15 @@ Value sendmany(const Array& params, bool fHelp)
" the number of addresses.\n"
"\nExamples:\n"
"\nSend two amounts to two different addresses:\n"
- + HelpExampleCli("sendmany", "\"tabby\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\"") +
+ + HelpExampleCli("sendmany", "\"\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\"") +
"\nSend two amounts to two different addresses setting the confirmation and comment:\n"
- + HelpExampleCli("sendmany", "\"tabby\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\" 6 \"testing\"") +
+ + HelpExampleCli("sendmany", "\"\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\" 6 \"testing\"") +
"\nAs a json rpc call\n"
- + HelpExampleRpc("sendmany", "\"tabby\", \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\", 6, \"testing\"")
+ + HelpExampleRpc("sendmany", "\"\", \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\", 6, \"testing\"")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
string strAccount = AccountFromValue(params[0]);
Object sendTo = params[1].get_obj();
int nMinDepth = 1;
@@ -920,7 +943,7 @@ Value addmultisigaddress(const Array& params, bool fHelp)
string msg = "addmultisigaddress nrequired [\"key\",...] ( \"account\" )\n"
"\nAdd a nrequired-to-sign multisignature address to the wallet.\n"
"Each key is a Bitcoin address or hex-encoded public key.\n"
- "If 'account' is specified, assign address to that account.\n"
+ "If 'account' is specified (DEPRECATED), assign address to that account.\n"
"\nArguments:\n"
"1. nrequired (numeric, required) The number of required signatures out of the n keys or addresses.\n"
@@ -929,7 +952,7 @@ Value addmultisigaddress(const Array& params, bool fHelp)
" \"address\" (string) bitcoin address or hex-encoded public key\n"
" ...,\n"
" ]\n"
- "3. \"account\" (string, optional) An account to assign the addresses to.\n"
+ "3. \"account\" (string, optional) DEPRECATED. An account to assign the addresses to.\n"
"\nResult:\n"
"\"bitcoinaddress\" (string) A bitcoin address associated with the keys.\n"
@@ -943,6 +966,8 @@ Value addmultisigaddress(const Array& params, bool fHelp)
throw runtime_error(msg);
}
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
string strAccount;
if (params.size() > 2)
strAccount = AccountFromValue(params[2]);
@@ -1103,9 +1128,9 @@ Value listreceivedbyaddress(const Array& params, bool fHelp)
"\nResult:\n"
"[\n"
" {\n"
- " \"involvesWatchonly\" : \"true\", (bool) Only returned if imported addresses were involved in transaction\n"
+ " \"involvesWatchonly\" : true, (bool) Only returned if imported addresses were involved in transaction\n"
" \"address\" : \"receivingaddress\", (string) The receiving address\n"
- " \"account\" : \"accountname\", (string) The account of the receiving address. The default account is \"\".\n"
+ " \"account\" : \"accountname\", (string) DEPRECATED. The account of the receiving address. The default account is \"\".\n"
" \"amount\" : x.xxx, (numeric) The total amount in btc received by the address\n"
" \"confirmations\" : n (numeric) The number of confirmations of the most recent transaction included\n"
" }\n"
@@ -1118,6 +1143,8 @@ Value listreceivedbyaddress(const Array& params, bool fHelp)
+ HelpExampleRpc("listreceivedbyaddress", "6, true, true")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
return ListReceived(params, false);
}
@@ -1126,7 +1153,7 @@ Value listreceivedbyaccount(const Array& params, bool fHelp)
if (fHelp || params.size() > 3)
throw runtime_error(
"listreceivedbyaccount ( minconf includeempty includeWatchonly)\n"
- "\nList balances by account.\n"
+ "\nDEPRECATED. List balances by account.\n"
"\nArguments:\n"
"1. minconf (numeric, optional, default=1) The minimum number of confirmations before payments are included.\n"
"2. includeempty (boolean, optional, default=false) Whether to include accounts that haven't received any payments.\n"
@@ -1135,7 +1162,7 @@ Value listreceivedbyaccount(const Array& params, bool fHelp)
"\nResult:\n"
"[\n"
" {\n"
- " \"involvesWatchonly\" : \"true\", (bool) Only returned if imported addresses were involved in transaction\n"
+ " \"involvesWatchonly\" : true, (bool) Only returned if imported addresses were involved in transaction\n"
" \"account\" : \"accountname\", (string) The account name of the receiving account\n"
" \"amount\" : x.xxx, (numeric) The total amount received by addresses with this account\n"
" \"confirmations\" : n (numeric) The number of confirmations of the most recent transaction included\n"
@@ -1149,6 +1176,8 @@ Value listreceivedbyaccount(const Array& params, bool fHelp)
+ HelpExampleRpc("listreceivedbyaccount", "6, true, true")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
return ListReceived(params, true);
}
@@ -1253,15 +1282,14 @@ Value listtransactions(const Array& params, bool fHelp)
"listtransactions ( \"account\" count from includeWatchonly)\n"
"\nReturns up to 'count' most recent transactions skipping the first 'from' transactions for account 'account'.\n"
"\nArguments:\n"
- "1. \"account\" (string, optional) The account name. If not included, it will list all transactions for all accounts.\n"
- " If \"\" is set, it will list transactions for the default account.\n"
+ "1. \"account\" (string, optional) DEPRECATED. The account name. Should be \"*\".\n"
"2. count (numeric, optional, default=10) The number of transactions to return\n"
"3. from (numeric, optional, default=0) The number of transactions to skip\n"
"4. includeWatchonly (bool, optional, default=false) Include transactions to watchonly addresses (see 'importaddress')\n"
"\nResult:\n"
"[\n"
" {\n"
- " \"account\":\"accountname\", (string) The account name associated with the transaction. \n"
+ " \"account\":\"accountname\", (string) DEPRECATED. The account name associated with the transaction. \n"
" It will be \"\" for the default account.\n"
" \"address\":\"bitcoinaddress\", (string) The bitcoin address of the transaction. Not present for \n"
" move transactions (category = move).\n"
@@ -1295,14 +1323,14 @@ Value listtransactions(const Array& params, bool fHelp)
"\nExamples:\n"
"\nList the most recent 10 transactions in the systems\n"
+ HelpExampleCli("listtransactions", "") +
- "\nList the most recent 10 transactions for the tabby account\n"
- + HelpExampleCli("listtransactions", "\"tabby\"") +
- "\nList transactions 100 to 120 from the tabby account\n"
- + HelpExampleCli("listtransactions", "\"tabby\" 20 100") +
+ "\nList transactions 100 to 120\n"
+ + HelpExampleCli("listtransactions", "\"*\" 20 100") +
"\nAs a json rpc call\n"
- + HelpExampleRpc("listtransactions", "\"tabby\", 20, 100")
+ + HelpExampleRpc("listtransactions", "\"*\", 20, 100")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
string strAccount = "*";
if (params.size() > 0)
strAccount = params[0].get_str();
@@ -1363,7 +1391,7 @@ Value listaccounts(const Array& params, bool fHelp)
if (fHelp || params.size() > 2)
throw runtime_error(
"listaccounts ( minconf includeWatchonly)\n"
- "\nReturns Object that has account names as keys, account balances as values.\n"
+ "\nDEPRECATED. Returns Object that has account names as keys, account balances as values.\n"
"\nArguments:\n"
"1. minconf (numeric, optional, default=1) Only include transactions with at least this many confirmations\n"
"2. includeWatchonly (bool, optional, default=false) Include balances in watchonly addresses (see 'importaddress')\n"
@@ -1383,6 +1411,8 @@ Value listaccounts(const Array& params, bool fHelp)
+ HelpExampleRpc("listaccounts", "6")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
int nMinDepth = 1;
if (params.size() > 0)
nMinDepth = params[0].get_int();
@@ -1446,7 +1476,7 @@ Value listsinceblock(const Array& params, bool fHelp)
"\nResult:\n"
"{\n"
" \"transactions\": [\n"
- " \"account\":\"accountname\", (string) The account name associated with the transaction. Will be \"\" for the default account.\n"
+ " \"account\":\"accountname\", (string) DEPRECATED. The account name associated with the transaction. Will be \"\" for the default account.\n"
" \"address\":\"bitcoinaddress\", (string) The bitcoin address of the transaction. Not present for move transactions (category = move).\n"
" \"category\":\"send|receive\", (string) The transaction category. 'send' has negative amounts, 'receive' has positive amounts.\n"
" \"amount\": x.xxx, (numeric) The amount in btc. This is negative for the 'send' category, and for the 'move' category for moves \n"
@@ -1471,13 +1501,15 @@ Value listsinceblock(const Array& params, bool fHelp)
+ HelpExampleRpc("listsinceblock", "\"000000000000000bacf66f7497b7dc45ef753ee9a7d38571037cdb1a57f663ad\", 6")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
CBlockIndex *pindex = NULL;
int target_confirms = 1;
isminefilter filter = ISMINE_SPENDABLE;
if (params.size() > 0)
{
- uint256 blockId = 0;
+ uint256 blockId;
blockId.SetHex(params[0].get_str());
BlockMap::iterator it = mapBlockIndex.find(blockId);
@@ -1510,7 +1542,7 @@ Value listsinceblock(const Array& params, bool fHelp)
}
CBlockIndex *pblockLast = chainActive[chainActive.Height() + 1 - target_confirms];
- uint256 lastblock = pblockLast ? pblockLast->GetBlockHash() : 0;
+ uint256 lastblock = pblockLast ? pblockLast->GetBlockHash() : uint256();
Object ret;
ret.push_back(Pair("transactions", transactions));
@@ -1540,7 +1572,7 @@ Value gettransaction(const Array& params, bool fHelp)
" \"timereceived\" : ttt, (numeric) The time received in seconds since epoch (1 Jan 1970 GMT)\n"
" \"details\" : [\n"
" {\n"
- " \"account\" : \"accountname\", (string) The account name involved in the transaction, can be \"\" for the default account.\n"
+ " \"account\" : \"accountname\", (string) DEPRECATED. The account name involved in the transaction, can be \"\" for the default account.\n"
" \"address\" : \"bitcoinaddress\", (string) The bitcoin address involved in the transaction\n"
" \"category\" : \"send|receive\", (string) The category, either 'send' or 'receive'\n"
" \"amount\" : x.xxx (numeric) The amount in btc\n"
@@ -1557,6 +1589,8 @@ Value gettransaction(const Array& params, bool fHelp)
+ HelpExampleRpc("gettransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
uint256 hash;
hash.SetHex(params[0].get_str());
@@ -1605,6 +1639,8 @@ Value backupwallet(const Array& params, bool fHelp)
+ HelpExampleRpc("backupwallet", "\"backup.dat\"")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
string strDest = params[0].get_str();
if (!BackupWallet(*pwalletMain, strDest))
throw JSONRPCError(RPC_WALLET_ERROR, "Error: Wallet backup failed!");
@@ -1627,6 +1663,8 @@ Value keypoolrefill(const Array& params, bool fHelp)
+ HelpExampleRpc("keypoolrefill", "")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
// 0 is interpreted by TopUpKeyPool() as the default keypool size given by -keypool
unsigned int kpSize = 0;
if (params.size() > 0) {
@@ -1674,6 +1712,8 @@ Value walletpassphrase(const Array& params, bool fHelp)
+ HelpExampleRpc("walletpassphrase", "\"my pass phrase\", 60")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
if (fHelp)
return true;
if (!pwalletMain->IsCrypted())
@@ -1721,6 +1761,8 @@ Value walletpassphrasechange(const Array& params, bool fHelp)
+ HelpExampleRpc("walletpassphrasechange", "\"old one\", \"new one\"")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
if (fHelp)
return true;
if (!pwalletMain->IsCrypted())
@@ -1767,6 +1809,8 @@ Value walletlock(const Array& params, bool fHelp)
+ HelpExampleRpc("walletlock", "")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
if (fHelp)
return true;
if (!pwalletMain->IsCrypted())
@@ -1808,6 +1852,8 @@ Value encryptwallet(const Array& params, bool fHelp)
+ HelpExampleRpc("encryptwallet", "\"my pass phrase\"")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
if (fHelp)
return true;
if (pwalletMain->IsCrypted())
@@ -1872,10 +1918,12 @@ Value lockunspent(const Array& params, bool fHelp)
+ HelpExampleRpc("lockunspent", "false, \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
if (params.size() == 1)
- RPCTypeCheck(params, list_of(bool_type));
+ RPCTypeCheck(params, boost::assign::list_of(bool_type));
else
- RPCTypeCheck(params, list_of(bool_type)(array_type));
+ RPCTypeCheck(params, boost::assign::list_of(bool_type)(array_type));
bool fUnlock = params[0].get_bool();
@@ -1892,7 +1940,7 @@ Value lockunspent(const Array& params, bool fHelp)
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected object");
const Object& o = output.get_obj();
- RPCTypeCheck(o, map_list_of("txid", str_type)("vout", int_type));
+ RPCTypeCheck(o, boost::assign::map_list_of("txid", str_type)("vout", int_type));
string txid = find_value(o, "txid").get_str();
if (!IsHex(txid))
@@ -1902,7 +1950,7 @@ Value lockunspent(const Array& params, bool fHelp)
if (nOutput < 0)
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout must be positive");
- COutPoint outpt(uint256(txid), nOutput);
+ COutPoint outpt(uint256S(txid), nOutput);
if (fUnlock)
pwalletMain->UnlockCoin(outpt);
@@ -1941,6 +1989,8 @@ Value listlockunspent(const Array& params, bool fHelp)
+ HelpExampleRpc("listlockunspent", "")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
vector<COutPoint> vOutpts;
pwalletMain->ListLockedCoins(vOutpts);
@@ -1972,6 +2022,8 @@ Value settxfee(const Array& params, bool fHelp)
+ HelpExampleRpc("settxfee", "0.00001")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
// Amount
CAmount nAmount = 0;
if (params[0].get_real() != 0.0)
@@ -1990,7 +2042,9 @@ Value getwalletinfo(const Array& params, bool fHelp)
"\nResult:\n"
"{\n"
" \"walletversion\": xxxxx, (numeric) the wallet version\n"
- " \"balance\": xxxxxxx, (numeric) the total bitcoin balance of the wallet\n"
+ " \"balance\": xxxxxxx, (numeric) the total confirmed bitcoin balance of the wallet\n"
+ " \"unconfirmed_balance\": xxx, (numeric) the total unconfirmed bitcoin balance of the wallet\n"
+ " \"immature_balance\": xxxxxx, (numeric) the total immature balance of the wallet\n"
" \"txcount\": xxxxxxx, (numeric) the total number of transactions in the wallet\n"
" \"keypoololdest\": xxxxxx, (numeric) the timestamp (seconds since GMT epoch) of the oldest pre-generated key in the key pool\n"
" \"keypoolsize\": xxxx, (numeric) how many new keys are pre-generated\n"
@@ -2001,9 +2055,13 @@ Value getwalletinfo(const Array& params, bool fHelp)
+ HelpExampleRpc("getwalletinfo", "")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
Object obj;
obj.push_back(Pair("walletversion", pwalletMain->GetVersion()));
obj.push_back(Pair("balance", ValueFromAmount(pwalletMain->GetBalance())));
+ obj.push_back(Pair("unconfirmed_balance", ValueFromAmount(pwalletMain->GetUnconfirmedBalance())));
+ obj.push_back(Pair("immature_balance", ValueFromAmount(pwalletMain->GetImmatureBalance())));
obj.push_back(Pair("txcount", (int)pwalletMain->mapWallet.size()));
obj.push_back(Pair("keypoololdest", pwalletMain->GetOldestKeyPoolTime()));
obj.push_back(Pair("keypoolsize", (int)pwalletMain->GetKeyPoolSize()));
diff --git a/src/script/bitcoinconsensus.cpp b/src/script/bitcoinconsensus.cpp
index c8dd54a747..b0d5faaf77 100644
--- a/src/script/bitcoinconsensus.cpp
+++ b/src/script/bitcoinconsensus.cpp
@@ -78,7 +78,7 @@ int bitcoinconsensus_verify_script(const unsigned char *scriptPubKey, unsigned i
// Regardless of the verification result, the tx did not error.
set_error(err, bitcoinconsensus_ERR_OK);
- return VerifyScript(tx.vin[nIn].scriptSig, CScript(scriptPubKey, scriptPubKey + scriptPubKeyLen), flags, SignatureChecker(tx, nIn), NULL);
+ return VerifyScript(tx.vin[nIn].scriptSig, CScript(scriptPubKey, scriptPubKey + scriptPubKeyLen), flags, TransactionSignatureChecker(&tx, nIn), NULL);
} catch (const std::exception&) {
return set_error(err, bitcoinconsensus_ERR_TX_DESERIALIZE); // Error deserializing
}
diff --git a/src/script/bitcoinconsensus.h b/src/script/bitcoinconsensus.h
index 9d9c266435..0320577797 100644
--- a/src/script/bitcoinconsensus.h
+++ b/src/script/bitcoinconsensus.h
@@ -46,6 +46,7 @@ enum
{
bitcoinconsensus_SCRIPT_FLAGS_VERIFY_NONE = 0,
bitcoinconsensus_SCRIPT_FLAGS_VERIFY_P2SH = (1U << 0), // evaluate P2SH (BIP16) subscripts
+ bitcoinconsensus_SCRIPT_FLAGS_VERIFY_DERSIG = (1U << 2), // enforce strict DER (BIP66) compliance
};
/// Returns 1 if the input nIn of the serialized transaction pointed to by
diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp
index 80a32e78f9..84a7432fdb 100644
--- a/src/script/interpreter.cpp
+++ b/src/script/interpreter.cpp
@@ -60,7 +60,7 @@ bool CastToBool(const valtype& vch)
static inline void popstack(vector<valtype>& stack)
{
if (stack.empty())
- throw runtime_error("popstack() : stack empty");
+ throw runtime_error("popstack(): stack empty");
stack.pop_back();
}
@@ -93,76 +93,76 @@ bool static IsCompressedOrUncompressedPubKey(const valtype &vchPubKey) {
* in which case a single 0 byte is necessary and even required).
*
* See https://bitcointalk.org/index.php?topic=8392.msg127623#msg127623
+ *
+ * This function is consensus-critical since BIP66.
*/
-bool static IsDERSignature(const valtype &vchSig) {
+bool static IsValidSignatureEncoding(const std::vector<unsigned char> &sig) {
+ // Format: 0x30 [total-length] 0x02 [R-length] [R] 0x02 [S-length] [S] [sighash]
+ // * total-length: 1-byte length descriptor of everything that follows,
+ // excluding the sighash byte.
+ // * R-length: 1-byte length descriptor of the R value that follows.
+ // * R: arbitrary-length big-endian encoded R value. It must use the shortest
+ // possible encoding for a positive integers (which means no null bytes at
+ // the start, except a single one when the next byte has its highest bit set).
+ // * S-length: 1-byte length descriptor of the S value that follows.
+ // * S: arbitrary-length big-endian encoded S value. The same rules apply.
+ // * sighash: 1-byte value indicating what data is hashed (not part of the DER
+ // signature)
- if (vchSig.size() < 9) {
- // Non-canonical signature: too short
- return false;
- }
- if (vchSig.size() > 73) {
- // Non-canonical signature: too long
- return false;
- }
- if (vchSig[0] != 0x30) {
- // Non-canonical signature: wrong type
- return false;
- }
- if (vchSig[1] != vchSig.size()-3) {
- // Non-canonical signature: wrong length marker
- return false;
- }
- unsigned int nLenR = vchSig[3];
- if (5 + nLenR >= vchSig.size()) {
- // Non-canonical signature: S length misplaced
- return false;
- }
- unsigned int nLenS = vchSig[5+nLenR];
- if ((unsigned long)(nLenR+nLenS+7) != vchSig.size()) {
- // Non-canonical signature: R+S length mismatch
- return false;
- }
+ // Minimum and maximum size constraints.
+ if (sig.size() < 9) return false;
+ if (sig.size() > 73) return false;
- const unsigned char *R = &vchSig[4];
- if (R[-2] != 0x02) {
- // Non-canonical signature: R value type mismatch
- return false;
- }
- if (nLenR == 0) {
- // Non-canonical signature: R length is zero
- return false;
- }
- if (R[0] & 0x80) {
- // Non-canonical signature: R value negative
- return false;
- }
- if (nLenR > 1 && (R[0] == 0x00) && !(R[1] & 0x80)) {
- // Non-canonical signature: R value excessively padded
- return false;
- }
+ // A signature is of type 0x30 (compound).
+ if (sig[0] != 0x30) return false;
+
+ // Make sure the length covers the entire signature.
+ if (sig[1] != sig.size() - 3) return false;
+
+ // Extract the length of the R element.
+ unsigned int lenR = sig[3];
+
+ // Make sure the length of the S element is still inside the signature.
+ if (5 + lenR >= sig.size()) return false;
+
+ // Extract the length of the S element.
+ unsigned int lenS = sig[5 + lenR];
+
+ // Verify that the length of the signature matches the sum of the length
+ // of the elements.
+ if ((size_t)(lenR + lenS + 7) != sig.size()) return false;
+
+ // Check whether the R element is an integer.
+ if (sig[2] != 0x02) return false;
+
+ // Zero-length integers are not allowed for R.
+ if (lenR == 0) return false;
+
+ // Negative numbers are not allowed for R.
+ if (sig[4] & 0x80) return false;
+
+ // Null bytes at the start of R are not allowed, unless R would
+ // otherwise be interpreted as a negative number.
+ if (lenR > 1 && (sig[4] == 0x00) && !(sig[5] & 0x80)) return false;
+
+ // Check whether the S element is an integer.
+ if (sig[lenR + 4] != 0x02) return false;
+
+ // Zero-length integers are not allowed for S.
+ if (lenS == 0) return false;
+
+ // Negative numbers are not allowed for S.
+ if (sig[lenR + 6] & 0x80) return false;
+
+ // Null bytes at the start of S are not allowed, unless S would otherwise be
+ // interpreted as a negative number.
+ if (lenS > 1 && (sig[lenR + 6] == 0x00) && !(sig[lenR + 7] & 0x80)) return false;
- const unsigned char *S = &vchSig[6+nLenR];
- if (S[-2] != 0x02) {
- // Non-canonical signature: S value type mismatch
- return false;
- }
- if (nLenS == 0) {
- // Non-canonical signature: S length is zero
- return false;
- }
- if (S[0] & 0x80) {
- // Non-canonical signature: S value negative
- return false;
- }
- if (nLenS > 1 && (S[0] == 0x00) && !(S[1] & 0x80)) {
- // Non-canonical signature: S value excessively padded
- return false;
- }
return true;
}
bool static IsLowDERSignature(const valtype &vchSig, ScriptError* serror) {
- if (!IsDERSignature(vchSig)) {
+ if (!IsValidSignatureEncoding(vchSig)) {
return set_error(serror, SCRIPT_ERR_SIG_DER);
}
unsigned int nLenR = vchSig[3];
@@ -189,7 +189,12 @@ bool static IsDefinedHashtypeSignature(const valtype &vchSig) {
}
bool static CheckSignatureEncoding(const valtype &vchSig, unsigned int flags, ScriptError* serror) {
- if ((flags & (SCRIPT_VERIFY_DERSIG | SCRIPT_VERIFY_LOW_S | SCRIPT_VERIFY_STRICTENC)) != 0 && !IsDERSignature(vchSig)) {
+ // Empty signature. Not strictly DER encoded, but allowed to provide a
+ // compact way to provide an invalid signature for use with CHECK(MULTI)SIG
+ if (vchSig.size() == 0) {
+ return true;
+ }
+ if ((flags & (SCRIPT_VERIFY_DERSIG | SCRIPT_VERIFY_LOW_S | SCRIPT_VERIFY_STRICTENC)) != 0 && !IsValidSignatureEncoding(vchSig)) {
return set_error(serror, SCRIPT_ERR_SIG_DER);
} else if ((flags & SCRIPT_VERIFY_LOW_S) != 0 && !IsLowDERSignature(vchSig, serror)) {
// serror is set
@@ -1030,16 +1035,17 @@ public:
uint256 SignatureHash(const CScript& scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType)
{
+ static const uint256 one(uint256S("0000000000000000000000000000000000000000000000000000000000000001"));
if (nIn >= txTo.vin.size()) {
// nIn out of range
- return 1;
+ return one;
}
// Check for invalid use of SIGHASH_SINGLE
if ((nHashType & 0x1f) == SIGHASH_SINGLE) {
if (nIn >= txTo.vout.size()) {
// nOut out of range
- return 1;
+ return one;
}
}
@@ -1052,12 +1058,12 @@ uint256 SignatureHash(const CScript& scriptCode, const CTransaction& txTo, unsig
return ss.GetHash();
}
-bool SignatureChecker::VerifySignature(const std::vector<unsigned char>& vchSig, const CPubKey& pubkey, const uint256& sighash) const
+bool TransactionSignatureChecker::VerifySignature(const std::vector<unsigned char>& vchSig, const CPubKey& pubkey, const uint256& sighash) const
{
return pubkey.Verify(sighash, vchSig);
}
-bool SignatureChecker::CheckSig(const vector<unsigned char>& vchSigIn, const vector<unsigned char>& vchPubKey, const CScript& scriptCode) const
+bool TransactionSignatureChecker::CheckSig(const vector<unsigned char>& vchSigIn, const vector<unsigned char>& vchPubKey, const CScript& scriptCode) const
{
CPubKey pubkey(vchPubKey);
if (!pubkey.IsValid())
@@ -1070,7 +1076,7 @@ bool SignatureChecker::CheckSig(const vector<unsigned char>& vchSigIn, const vec
int nHashType = vchSig.back();
vchSig.pop_back();
- uint256 sighash = SignatureHash(scriptCode, txTo, nIn, nHashType);
+ uint256 sighash = SignatureHash(scriptCode, *txTo, nIn, nHashType);
if (!VerifySignature(vchSig, pubkey, sighash))
return false;
@@ -1097,7 +1103,6 @@ bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, unsigne
return false;
if (stack.empty())
return set_error(serror, SCRIPT_ERR_EVAL_FALSE);
-
if (CastToBool(stack.back()) == false)
return set_error(serror, SCRIPT_ERR_EVAL_FALSE);
@@ -1108,24 +1113,37 @@ bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, unsigne
if (!scriptSig.IsPushOnly())
return set_error(serror, SCRIPT_ERR_SIG_PUSHONLY);
- // stackCopy cannot be empty here, because if it was the
+ // Restore stack.
+ swap(stack, stackCopy);
+
+ // stack cannot be empty here, because if it was the
// P2SH HASH <> EQUAL scriptPubKey would be evaluated with
// an empty stack and the EvalScript above would return false.
- assert(!stackCopy.empty());
+ assert(!stack.empty());
- const valtype& pubKeySerialized = stackCopy.back();
+ const valtype& pubKeySerialized = stack.back();
CScript pubKey2(pubKeySerialized.begin(), pubKeySerialized.end());
- popstack(stackCopy);
+ popstack(stack);
- if (!EvalScript(stackCopy, pubKey2, flags, checker, serror))
+ if (!EvalScript(stack, pubKey2, flags, checker, serror))
// serror is set
return false;
- if (stackCopy.empty())
+ if (stack.empty())
return set_error(serror, SCRIPT_ERR_EVAL_FALSE);
- if (!CastToBool(stackCopy.back()))
+ if (!CastToBool(stack.back()))
return set_error(serror, SCRIPT_ERR_EVAL_FALSE);
- else
- return set_success(serror);
+ }
+
+ // The CLEANSTACK check is only performed after potential P2SH evaluation,
+ // as the non-P2SH evaluation of a P2SH script will obviously not result in
+ // a clean stack (the P2SH inputs remain).
+ if ((flags & SCRIPT_VERIFY_CLEANSTACK) != 0) {
+ // Disallow CLEANSTACK without P2SH, as otherwise a switch CLEANSTACK->P2SH+CLEANSTACK
+ // would be possible, which is not a softfork (and P2SH should be one).
+ assert((flags & SCRIPT_VERIFY_P2SH) != 0);
+ if (stack.size() != 1) {
+ return set_error(serror, SCRIPT_ERR_CLEANSTACK);
+ }
}
return set_success(serror);
diff --git a/src/script/interpreter.h b/src/script/interpreter.h
index 3c4e7d466a..fc64438f68 100644
--- a/src/script/interpreter.h
+++ b/src/script/interpreter.h
@@ -7,6 +7,7 @@
#define BITCOIN_SCRIPT_INTERPRETER_H
#include "script_error.h"
+#include "primitives/transaction.h"
#include <vector>
#include <stdint.h>
@@ -67,8 +68,14 @@ enum
// discouraged NOPs fails the script. This verification flag will never be
// a mandatory flag applied to scripts in a block. NOPs that are not
// executed, e.g. within an unexecuted IF ENDIF block, are *not* rejected.
- SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS = (1U << 7)
-
+ SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS = (1U << 7),
+
+ // Require that only a single stack element remains after evaluation. This changes the success criterion from
+ // "At least one stack element must remain, and when interpreted as a boolean, it must be true" to
+ // "Exactly one stack element must remain, and when interpreted as a boolean, it must be true".
+ // (softfork safe, BIP62 rule 6)
+ // Note: CLEANSTACK should never be used without P2SH.
+ SCRIPT_VERIFY_CLEANSTACK = (1U << 8),
};
uint256 SignatureHash(const CScript &scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType);
@@ -84,20 +91,29 @@ public:
virtual ~BaseSignatureChecker() {}
};
-class SignatureChecker : public BaseSignatureChecker
+class TransactionSignatureChecker : public BaseSignatureChecker
{
private:
- const CTransaction& txTo;
+ const CTransaction* txTo;
unsigned int nIn;
protected:
virtual bool VerifySignature(const std::vector<unsigned char>& vchSig, const CPubKey& vchPubKey, const uint256& sighash) const;
public:
- SignatureChecker(const CTransaction& txToIn, unsigned int nInIn) : txTo(txToIn), nIn(nInIn) {}
+ TransactionSignatureChecker(const CTransaction* txToIn, unsigned int nInIn) : txTo(txToIn), nIn(nInIn) {}
bool CheckSig(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode) const;
};
+class MutableTransactionSignatureChecker : public TransactionSignatureChecker
+{
+private:
+ const CTransaction txTo;
+
+public:
+ MutableTransactionSignatureChecker(const CMutableTransaction* txToIn, unsigned int nInIn) : TransactionSignatureChecker(&txTo, nInIn), txTo(*txToIn) {}
+};
+
bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* error = NULL);
bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* error = NULL);
diff --git a/src/script/script.h b/src/script/script.h
index 78fd12cd29..8b36aa2f50 100644
--- a/src/script/script.h
+++ b/src/script/script.h
@@ -391,7 +391,7 @@ public:
CScript& operator<<(opcodetype opcode)
{
if (opcode < 0 || opcode > 0xff)
- throw std::runtime_error("CScript::operator<<() : invalid opcode");
+ throw std::runtime_error("CScript::operator<<(): invalid opcode");
insert(end(), (unsigned char)opcode);
return *this;
}
diff --git a/src/script/script_error.h b/src/script/script_error.h
index 5c260327b6..6365680b29 100644
--- a/src/script/script_error.h
+++ b/src/script/script_error.h
@@ -43,6 +43,7 @@ typedef enum ScriptError_t
SCRIPT_ERR_SIG_HIGH_S,
SCRIPT_ERR_SIG_NULLDUMMY,
SCRIPT_ERR_PUBKEYTYPE,
+ SCRIPT_ERR_CLEANSTACK,
/* softfork safeness */
SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS,
diff --git a/src/script/sigcache.cpp b/src/script/sigcache.cpp
index 75ecdb563d..099b4ad0e3 100644
--- a/src/script/sigcache.cpp
+++ b/src/script/sigcache.cpp
@@ -74,14 +74,14 @@ public:
}
-bool CachingSignatureChecker::VerifySignature(const std::vector<unsigned char>& vchSig, const CPubKey& pubkey, const uint256& sighash) const
+bool CachingTransactionSignatureChecker::VerifySignature(const std::vector<unsigned char>& vchSig, const CPubKey& pubkey, const uint256& sighash) const
{
static CSignatureCache signatureCache;
if (signatureCache.Get(sighash, vchSig, pubkey))
return true;
- if (!SignatureChecker::VerifySignature(vchSig, pubkey, sighash))
+ if (!TransactionSignatureChecker::VerifySignature(vchSig, pubkey, sighash))
return false;
if (store)
diff --git a/src/script/sigcache.h b/src/script/sigcache.h
index 3bd11caff5..b299038daa 100644
--- a/src/script/sigcache.h
+++ b/src/script/sigcache.h
@@ -12,13 +12,13 @@
class CPubKey;
-class CachingSignatureChecker : public SignatureChecker
+class CachingTransactionSignatureChecker : public TransactionSignatureChecker
{
private:
bool store;
public:
- CachingSignatureChecker(const CTransaction& txToIn, unsigned int nInIn, bool storeIn=true) : SignatureChecker(txToIn, nInIn), store(storeIn) {}
+ CachingTransactionSignatureChecker(const CTransaction* txToIn, unsigned int nInIn, bool storeIn=true) : TransactionSignatureChecker(txToIn, nInIn), store(storeIn) {}
bool VerifySignature(const std::vector<unsigned char>& vchSig, const CPubKey& vchPubKey, const uint256& sighash) const;
};
diff --git a/src/script/sign.cpp b/src/script/sign.cpp
index adddd4ec78..14119f7e2c 100644
--- a/src/script/sign.cpp
+++ b/src/script/sign.cpp
@@ -123,7 +123,7 @@ bool SignSignature(const CKeyStore &keystore, const CScript& fromPubKey, CMutabl
}
// Test solution
- return VerifyScript(txin.scriptSig, fromPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, SignatureChecker(txTo, nIn));
+ return VerifyScript(txin.scriptSig, fromPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, MutableTransactionSignatureChecker(&txTo, nIn));
}
bool SignSignature(const CKeyStore &keystore, const CTransaction& txFrom, CMutableTransaction& txTo, unsigned int nIn, int nHashType)
@@ -174,7 +174,7 @@ static CScript CombineMultisig(const CScript& scriptPubKey, const CTransaction&
if (sigs.count(pubkey))
continue; // Already got a sig for this pubkey
- if (SignatureChecker(txTo, nIn).CheckSig(sig, pubkey, scriptPubKey))
+ if (TransactionSignatureChecker(&txTo, nIn).CheckSig(sig, pubkey, scriptPubKey))
{
sigs[pubkey] = sig;
break;
diff --git a/src/script/standard.h b/src/script/standard.h
index 1d29ef57aa..a8b0acc981 100644
--- a/src/script/standard.h
+++ b/src/script/standard.h
@@ -20,12 +20,12 @@ class CScript;
class CScriptID : public uint160
{
public:
- CScriptID() : uint160(0) {}
+ CScriptID() : uint160() {}
CScriptID(const CScript& in);
CScriptID(const uint160& in) : uint160(in) {}
};
-static const unsigned int MAX_OP_RETURN_RELAY = 40; //! bytes
+static const unsigned int MAX_OP_RETURN_RELAY = 80; //! bytes
extern unsigned nMaxDatacarrierBytes;
/**
@@ -45,10 +45,12 @@ static const unsigned int MANDATORY_SCRIPT_VERIFY_FLAGS = SCRIPT_VERIFY_P2SH;
* blocks and we must accept those blocks.
*/
static const unsigned int STANDARD_SCRIPT_VERIFY_FLAGS = MANDATORY_SCRIPT_VERIFY_FLAGS |
+ SCRIPT_VERIFY_DERSIG |
SCRIPT_VERIFY_STRICTENC |
SCRIPT_VERIFY_MINIMALDATA |
SCRIPT_VERIFY_NULLDUMMY |
- SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS;
+ SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS |
+ SCRIPT_VERIFY_CLEANSTACK;
/** For convenience, standard but not mandatory verify flags. */
static const unsigned int STANDARD_NOT_MANDATORY_VERIFY_FLAGS = STANDARD_SCRIPT_VERIFY_FLAGS & ~MANDATORY_SCRIPT_VERIFY_FLAGS;
diff --git a/src/secp256k1/.gitignore b/src/secp256k1/.gitignore
index f0a54077a5..b9f7d243ec 100644
--- a/src/secp256k1/.gitignore
+++ b/src/secp256k1/.gitignore
@@ -1,6 +1,7 @@
bench_inv
bench_sign
bench_verify
+bench_recover
tests
*.exe
*.so
diff --git a/src/secp256k1/.travis.yml b/src/secp256k1/.travis.yml
index 28cd61dbc9..40f8dae23f 100644
--- a/src/secp256k1/.travis.yml
+++ b/src/secp256k1/.travis.yml
@@ -4,24 +4,22 @@ compiler:
- gcc
install:
- sudo apt-get install -qq libssl-dev
- - if [ "$BIGNUM" = "gmp" -o "$BIGNUM" = "auto" -o "$FIELD" = "gmp" ]; then sudo apt-get install --no-install-recommends --no-upgrade -qq libgmp-dev; fi
+ - if [ "$BIGNUM" = "gmp" -o "$BIGNUM" = "auto" ]; then sudo apt-get install --no-install-recommends --no-upgrade -qq libgmp-dev; fi
- if [ -n "$EXTRAPACKAGES" ]; then sudo apt-get update && sudo apt-get install --no-install-recommends --no-upgrade $EXTRAPACKAGES; fi
env:
global:
- - FIELD=auto BIGNUM=auto SCALAR=auto ENDOMORPHISM=no BUILD=check EXTRAFLAGS= HOST= EXTRAPACKAGES=
+ - FIELD=auto BIGNUM=auto SCALAR=auto ENDOMORPHISM=no ASM=no BUILD=check EXTRAFLAGS= HOST= EXTRAPACKAGES=
matrix:
- SCALAR=32bit
- SCALAR=64bit
- - FIELD=gmp
- - FIELD=gmp ENDOMORPHISM=yes
- - FIELD=64bit_asm
- - FIELD=64bit_asm ENDOMORPHISM=yes
- FIELD=64bit
- FIELD=64bit ENDOMORPHISM=yes
+ - FIELD=64bit ASM=x86_64
+ - FIELD=64bit ENDOMORPHISM=yes ASM=x86_64
- FIELD=32bit
- FIELD=32bit ENDOMORPHISM=yes
- - BIGNUM=none
- - BIGNUM=none ENDOMORPHISM=yes
+ - BIGNUM=no
+ - BIGNUM=no ENDOMORPHISM=yes
- BUILD=distcheck
- EXTRAFLAGS=CFLAGS=-DDETERMINISTIC
- HOST=i686-linux-gnu EXTRAPACKAGES="gcc-multilib"
diff --git a/src/secp256k1/Makefile.am b/src/secp256k1/Makefile.am
index 390d2c9ffa..985c172eba 100644
--- a/src/secp256k1/Makefile.am
+++ b/src/secp256k1/Makefile.am
@@ -33,8 +33,8 @@ noinst_HEADERS += src/java/org_bitcoin_NativeSecp256k1.h
noinst_HEADERS += src/util.h
noinst_HEADERS += src/testrand.h
noinst_HEADERS += src/testrand_impl.h
-noinst_HEADERS += src/field_gmp.h
-noinst_HEADERS += src/field_gmp_impl.h
+noinst_HEADERS += src/hash.h
+noinst_HEADERS += src/hash_impl.h
noinst_HEADERS += src/field.h
noinst_HEADERS += src/field_impl.h
noinst_HEADERS += src/bench.h
diff --git a/src/secp256k1/build-aux/m4/bitcoin_secp.m4 b/src/secp256k1/build-aux/m4/bitcoin_secp.m4
index 1373478c9c..4a398d6c93 100644
--- a/src/secp256k1/build-aux/m4/bitcoin_secp.m4
+++ b/src/secp256k1/build-aux/m4/bitcoin_secp.m4
@@ -1,12 +1,6 @@
dnl libsecp25k1 helper checks
AC_DEFUN([SECP_INT128_CHECK],[
has_int128=$ac_cv_type___int128
-if test x"$has_int128" != x"yes" && test x"$set_field" = x"64bit"; then
- AC_MSG_ERROR([$set_field field support explicitly requested but is not compatible with this host])
-fi
-if test x"$has_int128" != x"yes" && test x"$set_scalar" = x"64bit"; then
- AC_MSG_ERROR([$set_scalar scalar support explicitly requested but is not compatible with this host])
-fi
])
dnl
@@ -18,11 +12,6 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
__asm__ __volatile__("movq $0x100000000,%1; mulq %%rsi" : "+a"(a) : "S"(tmp) : "cc", "%rdx");
]])],[has_64bit_asm=yes],[has_64bit_asm=no])
AC_MSG_RESULT([$has_64bit_asm])
-if test x"$set_field" == x"64bit_asm"; then
- if test x"$has_64bit_asm" == x"no"; then
- AC_MSG_ERROR([$set_field field support explicitly requested but no x86_64 assembly available])
- fi
-fi
])
dnl
@@ -43,7 +32,7 @@ else
)])
LIBS=
fi
-if test x"$has_libcrypto" == x"yes" && test x"$has_openssl_ec" = x; then
+if test x"$has_libcrypto" = x"yes" && test x"$has_openssl_ec" = x; then
AC_MSG_CHECKING(for EC functions in libcrypto)
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <openssl/ec.h>
@@ -69,11 +58,4 @@ if test x"$has_gmp" != x"yes"; then
CPPFLAGS="$CPPFLAGS_TEMP"
LIBS="$LIBS_TEMP"
fi
-if test x"$set_field" = x"gmp" && test x"$has_gmp" != x"yes"; then
- AC_MSG_ERROR([$set_field field support explicitly requested but libgmp was not found])
-fi
-if test x"$set_bignum" = x"gmp" && test x"$has_gmp" != x"yes"; then
- AC_MSG_ERROR([$set_bignum field support explicitly requested but libgmp was not found])
-fi
])
-
diff --git a/src/secp256k1/configure.ac b/src/secp256k1/configure.ac
index 40e121e806..f691156ff7 100644
--- a/src/secp256k1/configure.ac
+++ b/src/secp256k1/configure.ac
@@ -6,7 +6,7 @@ AC_CANONICAL_HOST
AH_TOP([#ifndef LIBSECP256K1_CONFIG_H])
AH_TOP([#define LIBSECP256K1_CONFIG_H])
AH_BOTTOM([#endif //LIBSECP256K1_CONFIG_H])
-AM_INIT_AUTOMAKE([foreign])
+AM_INIT_AUTOMAKE([foreign subdir-objects])
LT_INIT
dnl make the compilation flags quiet unless V=1 is used
@@ -23,7 +23,7 @@ if test "x$CFLAGS" = "x"; then
fi
AC_PROG_CC_C99
-if test x"$ac_cv_prog_cc_c99" == x"no"; then
+if test x"$ac_cv_prog_cc_c99" = x"no"; then
AC_MSG_ERROR([c99 compiler support required])
fi
@@ -82,9 +82,9 @@ AC_COMPILE_IFELSE([AC_LANG_SOURCE([[char foo;]])],
AC_ARG_ENABLE(benchmark,
- AS_HELP_STRING([--enable-benchmark],[compile benchmark (default is yes)]),
+ AS_HELP_STRING([--enable-benchmark],[compile benchmark (default is no)]),
[use_benchmark=$enableval],
- [use_benchmark=yes])
+ [use_benchmark=no])
AC_ARG_ENABLE(tests,
AS_HELP_STRING([--enable-tests],[compile tests (default is yes)]),
@@ -96,15 +96,18 @@ AC_ARG_ENABLE(endomorphism,
[use_endomorphism=$enableval],
[use_endomorphism=no])
-AC_ARG_WITH([field], [AS_HELP_STRING([--with-field=gmp|64bit|64bit_asm|32bit|auto],
+AC_ARG_WITH([field], [AS_HELP_STRING([--with-field=64bit|32bit|auto],
[Specify Field Implementation. Default is auto])],[req_field=$withval], [req_field=auto])
-AC_ARG_WITH([bignum], [AS_HELP_STRING([--with-bignum=gmp|none|auto],
+AC_ARG_WITH([bignum], [AS_HELP_STRING([--with-bignum=gmp|no|auto],
[Specify Bignum Implementation. Default is auto])],[req_bignum=$withval], [req_bignum=auto])
AC_ARG_WITH([scalar], [AS_HELP_STRING([--with-scalar=64bit|32bit|auto],
[Specify scalar implementation. Default is auto])],[req_scalar=$withval], [req_scalar=auto])
+AC_ARG_WITH([asm], [AS_HELP_STRING([--with-asm=x86_64|no|auto]
+[Specify assembly optimizations to use. Default is auto])],[req_asm=$withval], [req_asm=auto])
+
AC_CHECK_TYPES([__int128])
AC_MSG_CHECKING([for __builtin_expect])
@@ -113,40 +116,54 @@ AC_COMPILE_IFELSE([AC_LANG_SOURCE([[void myfunc() {__builtin_expect(0,0);}]])],
[ AC_MSG_RESULT([no])
])
-if test x"$req_field" = x"auto"; then
+if test x"$req_asm" = x"auto"; then
SECP_64BIT_ASM_CHECK
if test x"$has_64bit_asm" = x"yes"; then
- set_field=64bit_asm
+ set_asm=x86_64
+ fi
+ if test x"$set_asm" = x; then
+ set_asm=no
fi
+else
+ set_asm=$req_asm
+ case $set_asm in
+ x86_64)
+ SECP_64BIT_ASM_CHECK
+ if test x"$has_64bit_asm" != x"yes"; then
+ AC_MSG_ERROR([x86_64 assembly optimization requested but not available])
+ fi
+ ;;
+ no)
+ ;;
+ *)
+ AC_MSG_ERROR([invalid assembly optimization selection])
+ ;;
+ esac
+fi
+if test x"$req_field" = x"auto"; then
+ if test x"set_asm" = x"x86_64"; then
+ set_field=64bit
+ fi
if test x"$set_field" = x; then
SECP_INT128_CHECK
if test x"$has_int128" = x"yes"; then
set_field=64bit
fi
fi
-
- if test x"$set_field" = x; then
- SECP_GMP_CHECK
- if test x"$has_gmp" = x"yes"; then
- set_field=gmp
- fi
- fi
-
if test x"$set_field" = x; then
set_field=32bit
fi
else
set_field=$req_field
case $set_field in
- 64bit_asm)
- SECP_64BIT_ASM_CHECK
- ;;
64bit)
- SECP_INT128_CHECK
- ;;
- gmp)
- SECP_GMP_CHECK
+ if test x"$set_asm" != x"x86_64"; then
+ SECP_INT128_CHECK
+ if test x"$has_int128" != x"yes"; then
+ AC_MSG_ERROR([64bit field explicitly requested but neither __int128 support or x86_64 assembly available])
+ fi
+ fi
;;
32bit)
;;
@@ -157,11 +174,9 @@ else
fi
if test x"$req_scalar" = x"auto"; then
- if test x"$set_scalar" = x; then
- SECP_INT128_CHECK
- if test x"$has_int128" = x"yes"; then
- set_scalar=64bit
- fi
+ SECP_INT128_CHECK
+ if test x"$has_int128" = x"yes"; then
+ set_scalar=64bit
fi
if test x"$set_scalar" = x; then
set_scalar=32bit
@@ -171,6 +186,9 @@ else
case $set_scalar in
64bit)
SECP_INT128_CHECK
+ if test x"$has_int128" != x"yes"; then
+ AC_MSG_ERROR([64bit scalar explicitly requested but __int128 support not available])
+ fi
;;
32bit)
;;
@@ -187,15 +205,18 @@ if test x"$req_bignum" = x"auto"; then
fi
if test x"$set_bignum" = x; then
- set_bignum=none
+ set_bignum=no
fi
else
set_bignum=$req_bignum
case $set_bignum in
gmp)
SECP_GMP_CHECK
+ if test x"$has_gmp" != x"yes"; then
+ AC_MSG_ERROR([gmp bignum explicitly requested but libgmp not available])
+ fi
;;
- none)
+ no)
;;
*)
AC_MSG_ERROR([invalid bignum implementation selection])
@@ -203,20 +224,23 @@ else
esac
fi
+# select assembly optimization
+case $set_asm in
+x86_64)
+ AC_DEFINE(USE_ASM_X86_64, 1, [Define this symbol to enable x86_64 assembly optimizations])
+ ;;
+no)
+ ;;
+*)
+ AC_MSG_ERROR([invalid assembly optimizations])
+ ;;
+esac
+
# select field implementation
case $set_field in
-64bit_asm)
- AC_DEFINE(USE_FIELD_5X52_ASM, 1, [Define this symbol to use the assembly version for the 5x52 field implementation])
- AC_DEFINE(USE_FIELD_5X52, 1, [Define this symbol to use the FIELD_5X52 implementation])
- ;;
64bit)
- AC_DEFINE(USE_FIELD_5X52_INT128, 1, [Define this symbol to use the __int128 version for the 5x52 field implementation])
AC_DEFINE(USE_FIELD_5X52, 1, [Define this symbol to use the FIELD_5X52 implementation])
;;
-gmp)
- AC_DEFINE(HAVE_LIBGMP,1,[Define this symbol if libgmp is installed])
- AC_DEFINE(USE_FIELD_GMP, 1, [Define this symbol to use the FIELD_GMP implementation])
- ;;
32bit)
AC_DEFINE(USE_FIELD_10X26, 1, [Define this symbol to use the FIELD_10X26 implementation])
;;
@@ -233,7 +257,7 @@ gmp)
AC_DEFINE(USE_FIELD_INV_NUM, 1, [Define this symbol to use the num-based field inverse implementation])
AC_DEFINE(USE_SCALAR_INV_NUM, 1, [Define this symbol to use the num-based scalar inverse implementation])
;;
-none)
+no)
AC_DEFINE(USE_NUM_NONE, 1, [Define this symbol to use no num implementation])
AC_DEFINE(USE_FIELD_INV_BUILTIN, 1, [Define this symbol to use the native field inverse implementation])
AC_DEFINE(USE_SCALAR_INV_BUILTIN, 1, [Define this symbol to use the native scalar inverse implementation])
@@ -258,7 +282,7 @@ esac
if test x"$use_tests" = x"yes"; then
SECP_OPENSSL_CHECK
- if test x"$has_openssl_ec" == x"yes"; then
+ if test x"$has_openssl_ec" = x"yes"; then
AC_DEFINE(ENABLE_OPENSSL_TESTS, 1, [Define this symbol if OpenSSL EC functions are available])
SECP_TEST_INCLUDES="$SSL_CFLAGS $CRYPTO_CFLAGS"
SECP_TEST_LIBS="$CRYPTO_LIBS"
@@ -272,7 +296,7 @@ if test x"$use_tests" = x"yes"; then
fi
fi
-if test x"$set_field" = x"gmp" || test x"$set_bignum" = x"gmp"; then
+if test x"$set_bignum" = x"gmp"; then
SECP_LIBS="$SECP_LIBS $GMP_LIBS"
SECP_INCLUDES="$SECP_INCLUDES $GMP_CPPFLAGS"
fi
@@ -281,9 +305,11 @@ if test x"$use_endomorphism" = x"yes"; then
AC_DEFINE(USE_ENDOMORPHISM, 1, [Define this symbol to use endomorphism optimization])
fi
+AC_MSG_NOTICE([Using assembly optimizations: $set_asm])
AC_MSG_NOTICE([Using field implementation: $set_field])
AC_MSG_NOTICE([Using bignum implementation: $set_bignum])
AC_MSG_NOTICE([Using scalar implementation: $set_scalar])
+AC_MSG_NOTICE([Using endomorphism optimizations: $use_endomorphism])
AC_CONFIG_HEADERS([src/libsecp256k1-config.h])
AC_CONFIG_FILES([Makefile libsecp256k1.pc])
@@ -291,9 +317,8 @@ AC_SUBST(SECP_INCLUDES)
AC_SUBST(SECP_LIBS)
AC_SUBST(SECP_TEST_LIBS)
AC_SUBST(SECP_TEST_INCLUDES)
-AM_CONDITIONAL([USE_ASM], [test x"$set_field" == x"64bit_asm"])
AM_CONDITIONAL([USE_TESTS], [test x"$use_tests" != x"no"])
-AM_CONDITIONAL([USE_BENCHMARK], [test x"$use_benchmark" != x"no"])
+AM_CONDITIONAL([USE_BENCHMARK], [test x"$use_benchmark" = x"yes"])
dnl make sure nothing new is exported so that we don't break the cache
PKGCONFIG_PATH_TEMP="$PKG_CONFIG_PATH"
diff --git a/src/secp256k1/include/secp256k1.h b/src/secp256k1/include/secp256k1.h
index dca7ca00e7..cfdae31eaf 100644
--- a/src/secp256k1/include/secp256k1.h
+++ b/src/secp256k1/include/secp256k1.h
@@ -77,42 +77,73 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_verify(
int pubkeylen
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4);
+/** A pointer to a function to deterministically generate a nonce.
+ * Returns: 1 if a nonce was succesfully generated. 0 will cause signing to fail.
+ * In: msg32: the 32-byte message hash being verified (will not be NULL)
+ * key32: pointer to a 32-byte secret key (will not be NULL)
+ * attempt: how many iterations we have tried to find a nonce.
+ * This will almost always be 0, but different attempt values
+ * are required to result in a different nonce.
+ * data: Arbitrary data pointer that is passed through.
+ * Out: nonce32: pointer to a 32-byte array to be filled by the function.
+ * Except for test cases, this function should compute some cryptographic hash of
+ * the message, the key and the attempt.
+ */
+typedef int (*secp256k1_nonce_function_t)(
+ unsigned char *nonce32,
+ const unsigned char *msg32,
+ const unsigned char *key32,
+ unsigned int attempt,
+ const void *data
+);
+
+/** An implementation of RFC6979 (using HMAC-SHA256) as nonce generation function. */
+extern const secp256k1_nonce_function_t secp256k1_nonce_function_rfc6979;
+
+/** A default safe nonce generation function (currently equal to secp256k1_nonce_function_rfc6979). */
+extern const secp256k1_nonce_function_t secp256k1_nonce_function_default;
+
+
/** Create an ECDSA signature.
* Returns: 1: signature created
- * 0: nonce invalid, try another one
+ * 0: the nonce generation function failed
* In: msg32: the 32-byte message hash being signed (cannot be NULL)
* seckey: pointer to a 32-byte secret key (cannot be NULL, assumed to be valid)
- * nonce: pointer to a 32-byte nonce (cannot be NULL, generated with a cryptographic PRNG)
+ * noncefp:pointer to a nonce generation function. If NULL, secp256k1_nonce_function_default is used
+ * ndata: pointer to arbitrary data used by the nonce generation function (can be NULL)
* Out: sig: pointer to an array where the signature will be placed (cannot be NULL)
* In/Out: siglen: pointer to an int with the length of sig, which will be updated
* to contain the actual signature length (<=72).
* Requires starting using SECP256K1_START_SIGN.
*/
-SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_sign(
+int secp256k1_ecdsa_sign(
const unsigned char *msg32,
unsigned char *sig,
int *siglen,
const unsigned char *seckey,
- const unsigned char *nonce
-) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);
+ secp256k1_nonce_function_t noncefp,
+ const void *ndata
+) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
/** Create a compact ECDSA signature (64 byte + recovery id).
* Returns: 1: signature created
- * 0: nonce invalid, try another one
+ * 0: the nonce generation function failed
* In: msg32: the 32-byte message hash being signed (cannot be NULL)
* seckey: pointer to a 32-byte secret key (cannot be NULL, assumed to be valid)
- * nonce: pointer to a 32-byte nonce (cannot be NULL, generated with a cryptographic PRNG)
+ * noncefp:pointer to a nonce generation function. If NULL, secp256k1_nonce_function_default is used
+ * ndata: pointer to arbitrary data used by the nonce generation function (can be NULL)
* Out: sig: pointer to a 64-byte array where the signature will be placed (cannot be NULL)
* recid: pointer to an int, which will be updated to contain the recovery id (can be NULL)
* Requires starting using SECP256K1_START_SIGN.
*/
-SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_sign_compact(
+int secp256k1_ecdsa_sign_compact(
const unsigned char *msg32,
unsigned char *sig64,
const unsigned char *seckey,
- const unsigned char *nonce,
+ secp256k1_nonce_function_t noncefp,
+ const void *ndata,
int *recid
-) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
+) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Recover an ECDSA public key from a compact signature.
* Returns: 1: public key successfully recovered (which guarantees a correct signature).
diff --git a/src/secp256k1/src/bench_sign.c b/src/secp256k1/src/bench_sign.c
index 66e71e1ac4..2276f00b9a 100644
--- a/src/secp256k1/src/bench_sign.c
+++ b/src/secp256k1/src/bench_sign.c
@@ -10,7 +10,6 @@
typedef struct {
unsigned char msg[32];
- unsigned char nonce[32];
unsigned char key[32];
} bench_sign_t;
@@ -18,7 +17,6 @@ static void bench_sign_setup(void* arg) {
bench_sign_t *data = (bench_sign_t*)arg;
for (int i = 0; i < 32; i++) data->msg[i] = i + 1;
- for (int i = 0; i < 32; i++) data->nonce[i] = i + 33;
for (int i = 0; i < 32; i++) data->key[i] = i + 65;
}
@@ -28,9 +26,8 @@ static void bench_sign(void* arg) {
unsigned char sig[64];
for (int i=0; i<20000; i++) {
int recid = 0;
- CHECK(secp256k1_ecdsa_sign_compact(data->msg, sig, data->key, data->nonce, &recid));
+ CHECK(secp256k1_ecdsa_sign_compact(data->msg, sig, data->key, NULL, NULL, &recid));
for (int j = 0; j < 32; j++) {
- data->nonce[j] = data->key[j]; /* Move former key to nonce */
data->msg[j] = sig[j]; /* Move former R to message. */
data->key[j] = sig[j + 32]; /* Move former S to key. */
}
diff --git a/src/secp256k1/src/bench_verify.c b/src/secp256k1/src/bench_verify.c
index b123c4087d..a58ca84347 100644
--- a/src/secp256k1/src/bench_verify.c
+++ b/src/secp256k1/src/bench_verify.c
@@ -14,7 +14,6 @@
typedef struct {
unsigned char msg[32];
unsigned char key[32];
- unsigned char nonce[32];
unsigned char sig[72];
int siglen;
unsigned char pubkey[33];
@@ -42,9 +41,8 @@ int main(void) {
for (int i = 0; i < 32; i++) data.msg[i] = 1 + i;
for (int i = 0; i < 32; i++) data.key[i] = 33 + i;
- for (int i = 0; i < 32; i++) data.nonce[i] = 65 + i;
data.siglen = 72;
- CHECK(secp256k1_ecdsa_sign(data.msg, data.sig, &data.siglen, data.key, data.nonce));
+ secp256k1_ecdsa_sign(data.msg, data.sig, &data.siglen, data.key, NULL, NULL);
data.pubkeylen = 33;
CHECK(secp256k1_ec_pubkey_create(data.pubkey, &data.pubkeylen, data.key, 1));
diff --git a/src/secp256k1/src/ecdsa_impl.h b/src/secp256k1/src/ecdsa_impl.h
index 8825d05fed..674650c1e9 100644
--- a/src/secp256k1/src/ecdsa_impl.h
+++ b/src/secp256k1/src/ecdsa_impl.h
@@ -109,25 +109,53 @@ static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, int *size, const se
return 1;
}
-static int secp256k1_ecdsa_sig_recompute(secp256k1_scalar_t *r2, const secp256k1_ecdsa_sig_t *sig, const secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message) {
+static int secp256k1_ecdsa_sig_verify(const secp256k1_ecdsa_sig_t *sig, const secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message) {
if (secp256k1_scalar_is_zero(&sig->r) || secp256k1_scalar_is_zero(&sig->s))
return 0;
- int ret = 0;
secp256k1_scalar_t sn, u1, u2;
secp256k1_scalar_inverse_var(&sn, &sig->s);
secp256k1_scalar_mul(&u1, &sn, message);
secp256k1_scalar_mul(&u2, &sn, &sig->r);
secp256k1_gej_t pubkeyj; secp256k1_gej_set_ge(&pubkeyj, pubkey);
secp256k1_gej_t pr; secp256k1_ecmult(&pr, &pubkeyj, &u2, &u1);
- if (!secp256k1_gej_is_infinity(&pr)) {
- secp256k1_fe_t xr; secp256k1_gej_get_x_var(&xr, &pr);
- secp256k1_fe_normalize_var(&xr);
- unsigned char xrb[32]; secp256k1_fe_get_b32(xrb, &xr);
- secp256k1_scalar_set_b32(r2, xrb, NULL);
- ret = 1;
+ if (secp256k1_gej_is_infinity(&pr)) {
+ return 0;
+ }
+ unsigned char c[32];
+ secp256k1_scalar_get_b32(c, &sig->r);
+ secp256k1_fe_t xr;
+ secp256k1_fe_set_b32(&xr, c);
+
+ // We now have the recomputed R point in pr, and its claimed x coordinate (modulo n)
+ // in xr. Naively, we would extract the x coordinate from pr (requiring a inversion modulo p),
+ // compute the remainder modulo n, and compare it to xr. However:
+ //
+ // xr == X(pr) mod n
+ // <=> exists h. (xr + h * n < p && xr + h * n == X(pr))
+ // [Since 2 * n > p, h can only be 0 or 1]
+ // <=> (xr == X(pr)) || (xr + n < p && xr + n == X(pr))
+ // [In Jacobian coordinates, X(pr) is pr.x / pr.z^2 mod p]
+ // <=> (xr == pr.x / pr.z^2 mod p) || (xr + n < p && xr + n == pr.x / pr.z^2 mod p)
+ // [Multiplying both sides of the equations by pr.z^2 mod p]
+ // <=> (xr * pr.z^2 mod p == pr.x) || (xr + n < p && (xr + n) * pr.z^2 mod p == pr.x)
+ //
+ // Thus, we can avoid the inversion, but we have to check both cases separately.
+ // secp256k1_gej_eq_x implements the (xr * pr.z^2 mod p == pr.x) test.
+ if (secp256k1_gej_eq_x_var(&xr, &pr)) {
+ // xr.x == xr * xr.z^2 mod p, so the signature is valid.
+ return 1;
+ }
+ if (secp256k1_fe_cmp_var(&xr, &secp256k1_ecdsa_consts->p_minus_order) >= 0) {
+ // xr + p >= n, so we can skip testing the second case.
+ return 0;
+ }
+ secp256k1_fe_add(&xr, &secp256k1_ecdsa_consts->order_as_fe);
+ if (secp256k1_gej_eq_x_var(&xr, &pr)) {
+ // (xr + n) * pr.z^2 mod p == pr.x, so the signature is valid.
+ return 1;
}
- return ret;
+ return 0;
}
static int secp256k1_ecdsa_sig_recover(const secp256k1_ecdsa_sig_t *sig, secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message, int recid) {
@@ -159,13 +187,6 @@ static int secp256k1_ecdsa_sig_recover(const secp256k1_ecdsa_sig_t *sig, secp256
return !secp256k1_gej_is_infinity(&qj);
}
-static int secp256k1_ecdsa_sig_verify(const secp256k1_ecdsa_sig_t *sig, const secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message) {
- secp256k1_scalar_t r2;
- int ret = 0;
- ret = secp256k1_ecdsa_sig_recompute(&r2, sig, pubkey, message) && secp256k1_scalar_eq(&sig->r, &r2);
- return ret;
-}
-
static int secp256k1_ecdsa_sig_sign(secp256k1_ecdsa_sig_t *sig, const secp256k1_scalar_t *seckey, const secp256k1_scalar_t *message, const secp256k1_scalar_t *nonce, int *recid) {
secp256k1_gej_t rp;
secp256k1_ecmult_gen(&rp, nonce);
@@ -177,6 +198,12 @@ static int secp256k1_ecdsa_sig_sign(secp256k1_ecdsa_sig_t *sig, const secp256k1_
secp256k1_fe_get_b32(b, &r.x);
int overflow = 0;
secp256k1_scalar_set_b32(&sig->r, b, &overflow);
+ if (secp256k1_scalar_is_zero(&sig->r)) {
+ /* P.x = order is on the curve, so technically sig->r could end up zero, which would be an invalid signature. */
+ secp256k1_gej_clear(&rp);
+ secp256k1_ge_clear(&r);
+ return 0;
+ }
if (recid)
*recid = (overflow ? 2 : 0) | (secp256k1_fe_is_odd(&r.y) ? 1 : 0);
secp256k1_scalar_t n;
diff --git a/src/secp256k1/src/ecmult_gen_impl.h b/src/secp256k1/src/ecmult_gen_impl.h
index 5a5b16ce14..48436316e1 100644
--- a/src/secp256k1/src/ecmult_gen_impl.h
+++ b/src/secp256k1/src/ecmult_gen_impl.h
@@ -73,7 +73,7 @@ static void secp256k1_ecmult_gen_start(void) {
secp256k1_gej_double_var(&numsbase, &numsbase);
if (j == 62) {
/* In the last iteration, numsbase is (1 - 2^j) * nums instead. */
- secp256k1_gej_neg_var(&numsbase, &numsbase);
+ secp256k1_gej_neg(&numsbase, &numsbase);
secp256k1_gej_add_var(&numsbase, &numsbase, &nums_gej);
}
}
diff --git a/src/secp256k1/src/ecmult_impl.h b/src/secp256k1/src/ecmult_impl.h
index 6536771046..345cfae733 100644
--- a/src/secp256k1/src/ecmult_impl.h
+++ b/src/secp256k1/src/ecmult_impl.h
@@ -70,8 +70,8 @@ static void secp256k1_ecmult_table_precomp_ge_var(secp256k1_ge_t *pre, const sec
(neg)((r), &(pre)[(-(n)-1)/2]); \
} while(0)
-#define ECMULT_TABLE_GET_GEJ(r,pre,n,w) ECMULT_TABLE_GET((r),(pre),(n),(w),secp256k1_gej_neg_var)
-#define ECMULT_TABLE_GET_GE(r,pre,n,w) ECMULT_TABLE_GET((r),(pre),(n),(w),secp256k1_ge_neg_var)
+#define ECMULT_TABLE_GET_GEJ(r,pre,n,w) ECMULT_TABLE_GET((r),(pre),(n),(w),secp256k1_gej_neg)
+#define ECMULT_TABLE_GET_GE(r,pre,n,w) ECMULT_TABLE_GET((r),(pre),(n),(w),secp256k1_ge_neg)
typedef struct {
/* For accelerating the computation of a*P + b*G: */
diff --git a/src/secp256k1/src/field.h b/src/secp256k1/src/field.h
index 53aa29e13f..14e2b813c1 100644
--- a/src/secp256k1/src/field.h
+++ b/src/secp256k1/src/field.h
@@ -22,9 +22,7 @@
#include "libsecp256k1-config.h"
#endif
-#if defined(USE_FIELD_GMP)
-#include "field_gmp.h"
-#elif defined(USE_FIELD_10X26)
+#if defined(USE_FIELD_10X26)
#include "field_10x26.h"
#elif defined(USE_FIELD_5X52)
#include "field_5x52.h"
@@ -50,9 +48,20 @@ static void secp256k1_fe_stop(void);
/** Normalize a field element. */
static void secp256k1_fe_normalize(secp256k1_fe_t *r);
+/** Weakly normalize a field element: reduce it magnitude to 1, but don't fully normalize. */
+static void secp256k1_fe_normalize_weak(secp256k1_fe_t *r);
+
/** Normalize a field element, without constant-time guarantee. */
static void secp256k1_fe_normalize_var(secp256k1_fe_t *r);
+/** Verify whether a field element represents zero i.e. would normalize to a zero value. The field
+ * implementation may optionally normalize the input, but this should not be relied upon. */
+static int secp256k1_fe_normalizes_to_zero(secp256k1_fe_t *r);
+
+/** Verify whether a field element represents zero i.e. would normalize to a zero value. The field
+ * implementation may optionally normalize the input, but this should not be relied upon. */
+static int secp256k1_fe_normalizes_to_zero_var(secp256k1_fe_t *r);
+
/** Set a field element equal to a small integer. Resulting field element is normalized. */
static void secp256k1_fe_set_int(secp256k1_fe_t *r, int a);
@@ -62,8 +71,8 @@ static int secp256k1_fe_is_zero(const secp256k1_fe_t *a);
/** Check the "oddness" of a field element. Requires the input to be normalized. */
static int secp256k1_fe_is_odd(const secp256k1_fe_t *a);
-/** Compare two field elements. Requires both inputs to be normalized */
-static int secp256k1_fe_equal(const secp256k1_fe_t *a, const secp256k1_fe_t *b);
+/** Compare two field elements. Requires magnitude-1 inputs. */
+static int secp256k1_fe_equal_var(const secp256k1_fe_t *a, const secp256k1_fe_t *b);
/** Compare two field elements. Requires both inputs to be normalized */
static int secp256k1_fe_cmp_var(const secp256k1_fe_t *a, const secp256k1_fe_t *b);
diff --git a/src/secp256k1/src/field_10x26_impl.h b/src/secp256k1/src/field_10x26_impl.h
index d20229cda6..9ef60a807a 100644
--- a/src/secp256k1/src/field_10x26_impl.h
+++ b/src/secp256k1/src/field_10x26_impl.h
@@ -31,6 +31,7 @@ static void secp256k1_fe_verify(const secp256k1_fe_t *a) {
r &= (d[8] <= 0x3FFFFFFUL * m);
r &= (d[9] <= 0x03FFFFFUL * m);
r &= (a->magnitude >= 0);
+ r &= (a->magnitude <= 32);
if (a->normalized) {
r &= (a->magnitude <= 1);
if (r && (d[9] == 0x03FFFFFUL)) {
@@ -103,6 +104,37 @@ static void secp256k1_fe_normalize(secp256k1_fe_t *r) {
#endif
}
+static void secp256k1_fe_normalize_weak(secp256k1_fe_t *r) {
+ uint32_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4],
+ t5 = r->n[5], t6 = r->n[6], t7 = r->n[7], t8 = r->n[8], t9 = r->n[9];
+
+ /* Reduce t9 at the start so there will be at most a single carry from the first pass */
+ uint32_t x = t9 >> 22; t9 &= 0x03FFFFFUL;
+
+ /* The first pass ensures the magnitude is 1, ... */
+ t0 += x * 0x3D1UL; t1 += (x << 6);
+ t1 += (t0 >> 26); t0 &= 0x3FFFFFFUL;
+ t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL;
+ t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL;
+ t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL;
+ t5 += (t4 >> 26); t4 &= 0x3FFFFFFUL;
+ t6 += (t5 >> 26); t5 &= 0x3FFFFFFUL;
+ t7 += (t6 >> 26); t6 &= 0x3FFFFFFUL;
+ t8 += (t7 >> 26); t7 &= 0x3FFFFFFUL;
+ t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL;
+
+ /* ... except for a possible carry at bit 22 of t9 (i.e. bit 256 of the field element) */
+ VERIFY_CHECK(t9 >> 23 == 0);
+
+ r->n[0] = t0; r->n[1] = t1; r->n[2] = t2; r->n[3] = t3; r->n[4] = t4;
+ r->n[5] = t5; r->n[6] = t6; r->n[7] = t7; r->n[8] = t8; r->n[9] = t9;
+
+#ifdef VERIFY
+ r->magnitude = 1;
+ secp256k1_fe_verify(r);
+#endif
+}
+
static void secp256k1_fe_normalize_var(secp256k1_fe_t *r) {
uint32_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4],
t5 = r->n[5], t6 = r->n[6], t7 = r->n[7], t8 = r->n[8], t9 = r->n[9];
@@ -159,6 +191,73 @@ static void secp256k1_fe_normalize_var(secp256k1_fe_t *r) {
#endif
}
+static int secp256k1_fe_normalizes_to_zero(secp256k1_fe_t *r) {
+ uint32_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4],
+ t5 = r->n[5], t6 = r->n[6], t7 = r->n[7], t8 = r->n[8], t9 = r->n[9];
+
+ /* Reduce t9 at the start so there will be at most a single carry from the first pass */
+ uint32_t x = t9 >> 22; t9 &= 0x03FFFFFUL;
+
+ /* z0 tracks a possible raw value of 0, z1 tracks a possible raw value of P */
+ uint32_t z0, z1;
+
+ /* The first pass ensures the magnitude is 1, ... */
+ t0 += x * 0x3D1UL; t1 += (x << 6);
+ t1 += (t0 >> 26); t0 &= 0x3FFFFFFUL; z0 = t0; z1 = t0 ^ 0x3D0UL;
+ t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL; z0 |= t1; z1 &= t1 ^ 0x40UL;
+ t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL; z0 |= t2; z1 &= t2;
+ t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL; z0 |= t3; z1 &= t3;
+ t5 += (t4 >> 26); t4 &= 0x3FFFFFFUL; z0 |= t4; z1 &= t4;
+ t6 += (t5 >> 26); t5 &= 0x3FFFFFFUL; z0 |= t5; z1 &= t5;
+ t7 += (t6 >> 26); t6 &= 0x3FFFFFFUL; z0 |= t6; z1 &= t6;
+ t8 += (t7 >> 26); t7 &= 0x3FFFFFFUL; z0 |= t7; z1 &= t7;
+ t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL; z0 |= t8; z1 &= t8;
+ z0 |= t9; z1 &= t9 ^ 0x3C00000UL;
+
+ /* ... except for a possible carry at bit 22 of t9 (i.e. bit 256 of the field element) */
+ VERIFY_CHECK(t9 >> 23 == 0);
+
+ return (z0 == 0) | (z1 == 0x3FFFFFFUL);
+}
+
+static int secp256k1_fe_normalizes_to_zero_var(secp256k1_fe_t *r) {
+ uint32_t t0 = r->n[0], t9 = r->n[9];
+
+ /* Reduce t9 at the start so there will be at most a single carry from the first pass */
+ uint32_t x = t9 >> 22;
+
+ /* The first pass ensures the magnitude is 1, ... */
+ t0 += x * 0x3D1UL;
+
+ /* z0 tracks a possible raw value of 0, z1 tracks a possible raw value of P */
+ uint32_t z0 = t0 & 0x3FFFFFFUL, z1 = z0 ^ 0x3D0UL;
+
+ /* Fast return path should catch the majority of cases */
+ if ((z0 != 0UL) & (z1 != 0x3FFFFFFUL))
+ return 0;
+
+ uint32_t t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4],
+ t5 = r->n[5], t6 = r->n[6], t7 = r->n[7], t8 = r->n[8];
+ t9 &= 0x03FFFFFUL;
+ t1 += (x << 6);
+
+ t1 += (t0 >> 26); t0 = z0;
+ t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL; z0 |= t1; z1 &= t1 ^ 0x40UL;
+ t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL; z0 |= t2; z1 &= t2;
+ t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL; z0 |= t3; z1 &= t3;
+ t5 += (t4 >> 26); t4 &= 0x3FFFFFFUL; z0 |= t4; z1 &= t4;
+ t6 += (t5 >> 26); t5 &= 0x3FFFFFFUL; z0 |= t5; z1 &= t5;
+ t7 += (t6 >> 26); t6 &= 0x3FFFFFFUL; z0 |= t6; z1 &= t6;
+ t8 += (t7 >> 26); t7 &= 0x3FFFFFFUL; z0 |= t7; z1 &= t7;
+ t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL; z0 |= t8; z1 &= t8;
+ z0 |= t9; z1 &= t9 ^ 0x3C00000UL;
+
+ /* ... except for a possible carry at bit 22 of t9 (i.e. bit 256 of the field element) */
+ VERIFY_CHECK(t9 >> 23 == 0);
+
+ return (z0 == 0) | (z1 == 0x3FFFFFFUL);
+}
+
SECP256K1_INLINE static void secp256k1_fe_set_int(secp256k1_fe_t *r, int a) {
r->n[0] = a;
r->n[1] = r->n[2] = r->n[3] = r->n[4] = r->n[5] = r->n[6] = r->n[7] = r->n[8] = r->n[9] = 0;
@@ -196,18 +295,6 @@ SECP256K1_INLINE static void secp256k1_fe_clear(secp256k1_fe_t *a) {
}
}
-SECP256K1_INLINE static int secp256k1_fe_equal(const secp256k1_fe_t *a, const secp256k1_fe_t *b) {
-#ifdef VERIFY
- VERIFY_CHECK(a->normalized);
- VERIFY_CHECK(b->normalized);
- secp256k1_fe_verify(a);
- secp256k1_fe_verify(b);
-#endif
- const uint32_t *t = a->n, *u = b->n;
- return ((t[0]^u[0]) | (t[1]^u[1]) | (t[2]^u[2]) | (t[3]^u[3]) | (t[4]^u[4])
- | (t[5]^u[5]) | (t[6]^u[6]) | (t[7]^u[7]) | (t[8]^u[8]) | (t[9]^u[9])) == 0;
-}
-
static int secp256k1_fe_cmp_var(const secp256k1_fe_t *a, const secp256k1_fe_t *b) {
#ifdef VERIFY
VERIFY_CHECK(a->normalized);
diff --git a/src/secp256k1/src/field_5x52_impl.h b/src/secp256k1/src/field_5x52_impl.h
index 63176d6de4..4db9e6f5ff 100644
--- a/src/secp256k1/src/field_5x52_impl.h
+++ b/src/secp256k1/src/field_5x52_impl.h
@@ -16,12 +16,10 @@
#include "num.h"
#include "field.h"
-#if defined(USE_FIELD_5X52_ASM)
+#if defined(USE_ASM_X86_64)
#include "field_5x52_asm_impl.h"
-#elif defined(USE_FIELD_5X52_INT128)
-#include "field_5x52_int128_impl.h"
#else
-#error "Please select field_5x52 implementation"
+#include "field_5x52_int128_impl.h"
#endif
/** Implements arithmetic modulo FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F,
@@ -45,6 +43,7 @@ static void secp256k1_fe_verify(const secp256k1_fe_t *a) {
r &= (d[3] <= 0xFFFFFFFFFFFFFULL * m);
r &= (d[4] <= 0x0FFFFFFFFFFFFULL * m);
r &= (a->magnitude >= 0);
+ r &= (a->magnitude <= 2048);
if (a->normalized) {
r &= (a->magnitude <= 1);
if (r && (d[4] == 0x0FFFFFFFFFFFFULL) && ((d[3] & d[2] & d[1]) == 0xFFFFFFFFFFFFFULL)) {
@@ -102,6 +101,30 @@ static void secp256k1_fe_normalize(secp256k1_fe_t *r) {
#endif
}
+static void secp256k1_fe_normalize_weak(secp256k1_fe_t *r) {
+ uint64_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4];
+
+ /* Reduce t4 at the start so there will be at most a single carry from the first pass */
+ uint64_t x = t4 >> 48; t4 &= 0x0FFFFFFFFFFFFULL;
+
+ /* The first pass ensures the magnitude is 1, ... */
+ t0 += x * 0x1000003D1ULL;
+ t1 += (t0 >> 52); t0 &= 0xFFFFFFFFFFFFFULL;
+ t2 += (t1 >> 52); t1 &= 0xFFFFFFFFFFFFFULL;
+ t3 += (t2 >> 52); t2 &= 0xFFFFFFFFFFFFFULL;
+ t4 += (t3 >> 52); t3 &= 0xFFFFFFFFFFFFFULL;
+
+ /* ... except for a possible carry at bit 48 of t4 (i.e. bit 256 of the field element) */
+ VERIFY_CHECK(t4 >> 49 == 0);
+
+ r->n[0] = t0; r->n[1] = t1; r->n[2] = t2; r->n[3] = t3; r->n[4] = t4;
+
+#ifdef VERIFY
+ r->magnitude = 1;
+ secp256k1_fe_verify(r);
+#endif
+}
+
static void secp256k1_fe_normalize_var(secp256k1_fe_t *r) {
uint64_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4];
@@ -146,6 +169,60 @@ static void secp256k1_fe_normalize_var(secp256k1_fe_t *r) {
#endif
}
+static int secp256k1_fe_normalizes_to_zero(secp256k1_fe_t *r) {
+ uint64_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4];
+
+ /* Reduce t4 at the start so there will be at most a single carry from the first pass */
+ uint64_t x = t4 >> 48; t4 &= 0x0FFFFFFFFFFFFULL;
+
+ /* z0 tracks a possible raw value of 0, z1 tracks a possible raw value of P */
+ uint64_t z0, z1;
+
+ /* The first pass ensures the magnitude is 1, ... */
+ t0 += x * 0x1000003D1ULL;
+ t1 += (t0 >> 52); t0 &= 0xFFFFFFFFFFFFFULL; z0 = t0; z1 = t0 ^ 0x1000003D0ULL;
+ t2 += (t1 >> 52); t1 &= 0xFFFFFFFFFFFFFULL; z0 |= t1; z1 &= t1;
+ t3 += (t2 >> 52); t2 &= 0xFFFFFFFFFFFFFULL; z0 |= t2; z1 &= t2;
+ t4 += (t3 >> 52); t3 &= 0xFFFFFFFFFFFFFULL; z0 |= t3; z1 &= t3;
+ z0 |= t4; z1 &= t4 ^ 0xF000000000000ULL;
+
+ /* ... except for a possible carry at bit 48 of t4 (i.e. bit 256 of the field element) */
+ VERIFY_CHECK(t4 >> 49 == 0);
+
+ return (z0 == 0) | (z1 == 0xFFFFFFFFFFFFFULL);
+}
+
+static int secp256k1_fe_normalizes_to_zero_var(secp256k1_fe_t *r) {
+ uint64_t t0 = r->n[0], t4 = r->n[4];
+
+ /* Reduce t4 at the start so there will be at most a single carry from the first pass */
+ uint64_t x = t4 >> 48;
+
+ /* The first pass ensures the magnitude is 1, ... */
+ t0 += x * 0x1000003D1ULL;
+
+ /* z0 tracks a possible raw value of 0, z1 tracks a possible raw value of P */
+ uint64_t z0 = t0 & 0xFFFFFFFFFFFFFULL, z1 = z0 ^ 0x1000003D0ULL;
+
+ /* Fast return path should catch the majority of cases */
+ if ((z0 != 0ULL) & (z1 != 0xFFFFFFFFFFFFFULL))
+ return 0;
+
+ uint64_t t1 = r->n[1], t2 = r->n[2], t3 = r->n[3];
+ t4 &= 0x0FFFFFFFFFFFFULL;
+
+ t1 += (t0 >> 52); t0 = z0;
+ t2 += (t1 >> 52); t1 &= 0xFFFFFFFFFFFFFULL; z0 |= t1; z1 &= t1;
+ t3 += (t2 >> 52); t2 &= 0xFFFFFFFFFFFFFULL; z0 |= t2; z1 &= t2;
+ t4 += (t3 >> 52); t3 &= 0xFFFFFFFFFFFFFULL; z0 |= t3; z1 &= t3;
+ z0 |= t4; z1 &= t4 ^ 0xF000000000000ULL;
+
+ /* ... except for a possible carry at bit 48 of t4 (i.e. bit 256 of the field element) */
+ VERIFY_CHECK(t4 >> 49 == 0);
+
+ return (z0 == 0) | (z1 == 0xFFFFFFFFFFFFFULL);
+}
+
SECP256K1_INLINE static void secp256k1_fe_set_int(secp256k1_fe_t *r, int a) {
r->n[0] = a;
r->n[1] = r->n[2] = r->n[3] = r->n[4] = 0;
@@ -183,17 +260,6 @@ SECP256K1_INLINE static void secp256k1_fe_clear(secp256k1_fe_t *a) {
}
}
-SECP256K1_INLINE static int secp256k1_fe_equal(const secp256k1_fe_t *a, const secp256k1_fe_t *b) {
-#ifdef VERIFY
- VERIFY_CHECK(a->normalized);
- VERIFY_CHECK(b->normalized);
- secp256k1_fe_verify(a);
- secp256k1_fe_verify(b);
-#endif
- const uint64_t *t = a->n, *u = b->n;
- return ((t[0]^u[0]) | (t[1]^u[1]) | (t[2]^u[2]) | (t[3]^u[3]) | (t[4]^u[4])) == 0;
-}
-
static int secp256k1_fe_cmp_var(const secp256k1_fe_t *a, const secp256k1_fe_t *b) {
#ifdef VERIFY
VERIFY_CHECK(a->normalized);
diff --git a/src/secp256k1/src/field_gmp.h b/src/secp256k1/src/field_gmp.h
deleted file mode 100644
index b390fd9de8..0000000000
--- a/src/secp256k1/src/field_gmp.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/**********************************************************************
- * Copyright (c) 2013, 2014 Pieter Wuille *
- * Distributed under the MIT software license, see the accompanying *
- * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
- **********************************************************************/
-
-#ifndef _SECP256K1_FIELD_REPR_
-#define _SECP256K1_FIELD_REPR_
-
-#include <gmp.h>
-
-#define FIELD_LIMBS ((256 + GMP_NUMB_BITS - 1) / GMP_NUMB_BITS)
-
-typedef struct {
- mp_limb_t n[FIELD_LIMBS+1];
-} secp256k1_fe_t;
-
-#endif
diff --git a/src/secp256k1/src/field_gmp_impl.h b/src/secp256k1/src/field_gmp_impl.h
deleted file mode 100644
index 73a55c4f00..0000000000
--- a/src/secp256k1/src/field_gmp_impl.h
+++ /dev/null
@@ -1,184 +0,0 @@
-/**********************************************************************
- * Copyright (c) 2013, 2014 Pieter Wuille *
- * Distributed under the MIT software license, see the accompanying *
- * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
- **********************************************************************/
-
-#ifndef _SECP256K1_FIELD_REPR_IMPL_H_
-#define _SECP256K1_FIELD_REPR_IMPL_H_
-
-#include <stdio.h>
-#include <string.h>
-#include "num.h"
-#include "field.h"
-
-static mp_limb_t secp256k1_field_p[FIELD_LIMBS];
-static mp_limb_t secp256k1_field_pc[(33+GMP_NUMB_BITS-1)/GMP_NUMB_BITS];
-
-static void secp256k1_fe_inner_start(void) {
- for (int i=0; i<(33+GMP_NUMB_BITS-1)/GMP_NUMB_BITS; i++)
- secp256k1_field_pc[i] = 0;
- secp256k1_field_pc[0] += 0x3D1UL;
- secp256k1_field_pc[32/GMP_NUMB_BITS] += (((mp_limb_t)1) << (32 % GMP_NUMB_BITS));
- for (int i=0; i<FIELD_LIMBS; i++) {
- secp256k1_field_p[i] = 0;
- }
- mpn_sub(secp256k1_field_p, secp256k1_field_p, FIELD_LIMBS, secp256k1_field_pc, (33+GMP_NUMB_BITS-1)/GMP_NUMB_BITS);
-}
-
-static void secp256k1_fe_inner_stop(void) {
-}
-
-static void secp256k1_fe_normalize(secp256k1_fe_t *r) {
- if (r->n[FIELD_LIMBS] != 0) {
-#if (GMP_NUMB_BITS >= 40)
- mp_limb_t carry = mpn_add_1(r->n, r->n, FIELD_LIMBS, 0x1000003D1ULL * r->n[FIELD_LIMBS]);
- mpn_add_1(r->n, r->n, FIELD_LIMBS, 0x1000003D1ULL * carry);
-#else
- mp_limb_t carry = mpn_add_1(r->n, r->n, FIELD_LIMBS, 0x3D1UL * r->n[FIELD_LIMBS]) +
- mpn_add_1(r->n+(32/GMP_NUMB_BITS), r->n+(32/GMP_NUMB_BITS), FIELD_LIMBS-(32/GMP_NUMB_BITS), r->n[FIELD_LIMBS] << (32 % GMP_NUMB_BITS));
- mpn_add_1(r->n, r->n, FIELD_LIMBS, 0x3D1UL * carry);
- mpn_add_1(r->n+(32/GMP_NUMB_BITS), r->n+(32/GMP_NUMB_BITS), FIELD_LIMBS-(32/GMP_NUMB_BITS), carry << (32%GMP_NUMB_BITS));
-#endif
- r->n[FIELD_LIMBS] = 0;
- }
- if (mpn_cmp(r->n, secp256k1_field_p, FIELD_LIMBS) >= 0)
- mpn_sub(r->n, r->n, FIELD_LIMBS, secp256k1_field_p, FIELD_LIMBS);
-}
-
-static void secp256k1_fe_normalize_var(secp256k1_fe_t *r) {
- secp256k1_fe_normalize(r);
-}
-
-SECP256K1_INLINE static void secp256k1_fe_set_int(secp256k1_fe_t *r, int a) {
- r->n[0] = a;
- for (int i=1; i<FIELD_LIMBS+1; i++)
- r->n[i] = 0;
-}
-
-SECP256K1_INLINE static void secp256k1_fe_clear(secp256k1_fe_t *r) {
- for (int i=0; i<FIELD_LIMBS+1; i++)
- r->n[i] = 0;
-}
-
-SECP256K1_INLINE static int secp256k1_fe_is_zero(const secp256k1_fe_t *a) {
- int ret = 1;
- for (int i=0; i<FIELD_LIMBS+1; i++)
- ret &= (a->n[i] == 0);
- return ret;
-}
-
-SECP256K1_INLINE static int secp256k1_fe_is_odd(const secp256k1_fe_t *a) {
- return a->n[0] & 1;
-}
-
-SECP256K1_INLINE static int secp256k1_fe_equal(const secp256k1_fe_t *a, const secp256k1_fe_t *b) {
- int ret = 1;
- for (int i=0; i<FIELD_LIMBS+1; i++)
- ret &= (a->n[i] == b->n[i]);
- return ret;
-}
-
-SECP256K1_INLINE static int secp256k1_fe_cmp_var(const secp256k1_fe_t *a, const secp256k1_fe_t *b) {
- for (int i=FIELD_LIMBS; i>=0; i--) {
- if (a->n[i] > b->n[i]) return 1;
- if (a->n[i] < b->n[i]) return -1;
- }
- return 0;
-}
-
-static int secp256k1_fe_set_b32(secp256k1_fe_t *r, const unsigned char *a) {
- for (int i=0; i<FIELD_LIMBS+1; i++)
- r->n[i] = 0;
- for (int i=0; i<256; i++) {
- int limb = i/GMP_NUMB_BITS;
- int shift = i%GMP_NUMB_BITS;
- r->n[limb] |= (mp_limb_t)((a[31-i/8] >> (i%8)) & 0x1) << shift;
- }
- return (mpn_cmp(r->n, secp256k1_field_p, FIELD_LIMBS) < 0);
-}
-
-/** Convert a field element to a 32-byte big endian value. Requires the input to be normalized */
-static void secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe_t *a) {
- for (int i=0; i<32; i++) {
- int c = 0;
- for (int j=0; j<8; j++) {
- int limb = (8*i+j)/GMP_NUMB_BITS;
- int shift = (8*i+j)%GMP_NUMB_BITS;
- c |= ((a->n[limb] >> shift) & 0x1) << j;
- }
- r[31-i] = c;
- }
-}
-
-SECP256K1_INLINE static void secp256k1_fe_negate(secp256k1_fe_t *r, const secp256k1_fe_t *a, int m) {
- (void)m;
- *r = *a;
- secp256k1_fe_normalize(r);
- for (int i=0; i<FIELD_LIMBS; i++)
- r->n[i] = ~(r->n[i]);
-#if (GMP_NUMB_BITS >= 33)
- mpn_sub_1(r->n, r->n, FIELD_LIMBS, 0x1000003D0ULL);
-#else
- mpn_sub_1(r->n, r->n, FIELD_LIMBS, 0x3D0UL);
- mpn_sub_1(r->n+(32/GMP_NUMB_BITS), r->n+(32/GMP_NUMB_BITS), FIELD_LIMBS-(32/GMP_NUMB_BITS), 0x1UL << (32%GMP_NUMB_BITS));
-#endif
-}
-
-SECP256K1_INLINE static void secp256k1_fe_mul_int(secp256k1_fe_t *r, int a) {
- mpn_mul_1(r->n, r->n, FIELD_LIMBS+1, a);
-}
-
-SECP256K1_INLINE static void secp256k1_fe_add(secp256k1_fe_t *r, const secp256k1_fe_t *a) {
- mpn_add(r->n, r->n, FIELD_LIMBS+1, a->n, FIELD_LIMBS+1);
-}
-
-static void secp256k1_fe_reduce(secp256k1_fe_t *r, mp_limb_t *tmp) {
- /** <A1 A2 A3 A4> <B1 B2 B3 B4>
- * B1 B2 B3 B4
- * + C * A1 A2 A3 A4
- * + A1 A2 A3 A4
- */
-
-#if (GMP_NUMB_BITS >= 33)
- mp_limb_t o = mpn_addmul_1(tmp, tmp+FIELD_LIMBS, FIELD_LIMBS, 0x1000003D1ULL);
-#else
- mp_limb_t o = mpn_addmul_1(tmp, tmp+FIELD_LIMBS, FIELD_LIMBS, 0x3D1UL) +
- mpn_addmul_1(tmp+(32/GMP_NUMB_BITS), tmp+FIELD_LIMBS, FIELD_LIMBS-(32/GMP_NUMB_BITS), 0x1UL << (32%GMP_NUMB_BITS));
-#endif
- mp_limb_t q[1+(33+GMP_NUMB_BITS-1)/GMP_NUMB_BITS];
- q[(33+GMP_NUMB_BITS-1)/GMP_NUMB_BITS] = mpn_mul_1(q, secp256k1_field_pc, (33+GMP_NUMB_BITS-1)/GMP_NUMB_BITS, o);
-#if (GMP_NUMB_BITS <= 32)
- mp_limb_t o2 = tmp[2*FIELD_LIMBS-(32/GMP_NUMB_BITS)] << (32%GMP_NUMB_BITS);
- q[(33+GMP_NUMB_BITS-1)/GMP_NUMB_BITS] += mpn_addmul_1(q, secp256k1_field_pc, (33+GMP_NUMB_BITS-1)/GMP_NUMB_BITS, o2);
-#endif
- r->n[FIELD_LIMBS] = mpn_add(r->n, tmp, FIELD_LIMBS, q, 1+(33+GMP_NUMB_BITS-1)/GMP_NUMB_BITS);
-}
-
-static void secp256k1_fe_mul(secp256k1_fe_t *r, const secp256k1_fe_t *a, const secp256k1_fe_t * SECP256K1_RESTRICT b) {
- VERIFY_CHECK(r != b);
- secp256k1_fe_t ac = *a;
- secp256k1_fe_t bc = *b;
- secp256k1_fe_normalize(&ac);
- secp256k1_fe_normalize(&bc);
- mp_limb_t tmp[2*FIELD_LIMBS];
- mpn_mul_n(tmp, ac.n, bc.n, FIELD_LIMBS);
- secp256k1_fe_reduce(r, tmp);
-}
-
-static void secp256k1_fe_sqr(secp256k1_fe_t *r, const secp256k1_fe_t *a) {
- secp256k1_fe_t ac = *a;
- secp256k1_fe_normalize(&ac);
- mp_limb_t tmp[2*FIELD_LIMBS];
- mpn_sqr(tmp, ac.n, FIELD_LIMBS);
- secp256k1_fe_reduce(r, tmp);
-}
-
-static void secp256k1_fe_cmov(secp256k1_fe_t *r, const secp256k1_fe_t *a, int flag) {
- mp_limb_t mask0 = flag + ~((mp_limb_t)0), mask1 = ~mask0;
- for (int i = 0; i <= FIELD_LIMBS; i++) {
- r->n[i] = (r->n[i] & mask0) | (a->n[i] & mask1);
- }
-}
-
-#endif
diff --git a/src/secp256k1/src/field_impl.h b/src/secp256k1/src/field_impl.h
index 24d3104ed1..4e2c24aa15 100644
--- a/src/secp256k1/src/field_impl.h
+++ b/src/secp256k1/src/field_impl.h
@@ -13,9 +13,7 @@
#include "util.h"
-#if defined(USE_FIELD_GMP)
-#include "field_gmp_impl.h"
-#elif defined(USE_FIELD_10X26)
+#if defined(USE_FIELD_10X26)
#include "field_10x26_impl.h"
#elif defined(USE_FIELD_5X52)
#include "field_5x52_impl.h"
@@ -66,6 +64,13 @@ static int secp256k1_fe_set_hex(secp256k1_fe_t *r, const char *a, int alen) {
return secp256k1_fe_set_b32(r, tmp);
}
+SECP256K1_INLINE static int secp256k1_fe_equal_var(const secp256k1_fe_t *a, const secp256k1_fe_t *b) {
+ secp256k1_fe_t na;
+ secp256k1_fe_negate(&na, a, 1);
+ secp256k1_fe_add(&na, b);
+ return secp256k1_fe_normalizes_to_zero_var(&na);
+}
+
static int secp256k1_fe_sqrt_var(secp256k1_fe_t *r, const secp256k1_fe_t *a) {
/** The binary representation of (p + 1)/4 has 3 blocks of 1s, with lengths in
@@ -130,10 +135,7 @@ static int secp256k1_fe_sqrt_var(secp256k1_fe_t *r, const secp256k1_fe_t *a) {
/* Check that a square root was actually calculated */
secp256k1_fe_sqr(&t1, r);
- secp256k1_fe_negate(&t1, &t1, 1);
- secp256k1_fe_add(&t1, a);
- secp256k1_fe_normalize_var(&t1);
- return secp256k1_fe_is_zero(&t1);
+ return secp256k1_fe_equal_var(&t1, a);
}
static void secp256k1_fe_inv(secp256k1_fe_t *r, const secp256k1_fe_t *a) {
diff --git a/src/secp256k1/src/group.h b/src/secp256k1/src/group.h
index ecfebcdc0c..6dea6bb5ac 100644
--- a/src/secp256k1/src/group.h
+++ b/src/secp256k1/src/group.h
@@ -60,7 +60,6 @@ static int secp256k1_ge_is_infinity(const secp256k1_ge_t *a);
static int secp256k1_ge_is_valid_var(const secp256k1_ge_t *a);
static void secp256k1_ge_neg(secp256k1_ge_t *r, const secp256k1_ge_t *a);
-static void secp256k1_ge_neg_var(secp256k1_ge_t *r, const secp256k1_ge_t *a);
/** Get a hex representation of a point. *rlen will be overwritten with the real length. */
static void secp256k1_ge_get_hex(char *r, int *rlen, const secp256k1_ge_t *a);
@@ -81,11 +80,11 @@ static void secp256k1_gej_set_xy(secp256k1_gej_t *r, const secp256k1_fe_t *x, co
/** Set a group element (jacobian) equal to another which is given in affine coordinates. */
static void secp256k1_gej_set_ge(secp256k1_gej_t *r, const secp256k1_ge_t *a);
-/** Get the X coordinate of a group element (jacobian). */
-static void secp256k1_gej_get_x_var(secp256k1_fe_t *r, const secp256k1_gej_t *a);
+/** Compare the X coordinate of a group element (jacobian). */
+static int secp256k1_gej_eq_x_var(const secp256k1_fe_t *x, const secp256k1_gej_t *a);
/** Set r equal to the inverse of a (i.e., mirrored around the X axis) */
-static void secp256k1_gej_neg_var(secp256k1_gej_t *r, const secp256k1_gej_t *a);
+static void secp256k1_gej_neg(secp256k1_gej_t *r, const secp256k1_gej_t *a);
/** Check whether a group element is the point at infinity. */
static int secp256k1_gej_is_infinity(const secp256k1_gej_t *a);
diff --git a/src/secp256k1/src/group_impl.h b/src/secp256k1/src/group_impl.h
index 1ab5d5fe7b..fef06df289 100644
--- a/src/secp256k1/src/group_impl.h
+++ b/src/secp256k1/src/group_impl.h
@@ -29,13 +29,7 @@ static int secp256k1_ge_is_infinity(const secp256k1_ge_t *a) {
static void secp256k1_ge_neg(secp256k1_ge_t *r, const secp256k1_ge_t *a) {
*r = *a;
- secp256k1_fe_normalize(&r->y);
- secp256k1_fe_negate(&r->y, &r->y, 1);
-}
-
-static void secp256k1_ge_neg_var(secp256k1_ge_t *r, const secp256k1_ge_t *a) {
- *r = *a;
- secp256k1_fe_normalize_var(&r->y);
+ secp256k1_fe_normalize_weak(&r->y);
secp256k1_fe_negate(&r->y, &r->y, 1);
}
@@ -163,17 +157,19 @@ static void secp256k1_gej_set_ge(secp256k1_gej_t *r, const secp256k1_ge_t *a) {
secp256k1_fe_set_int(&r->z, 1);
}
-static void secp256k1_gej_get_x_var(secp256k1_fe_t *r, const secp256k1_gej_t *a) {
- secp256k1_fe_t zi2; secp256k1_fe_inv_var(&zi2, &a->z); secp256k1_fe_sqr(&zi2, &zi2);
- secp256k1_fe_mul(r, &a->x, &zi2);
+static int secp256k1_gej_eq_x_var(const secp256k1_fe_t *x, const secp256k1_gej_t *a) {
+ VERIFY_CHECK(!a->infinity);
+ secp256k1_fe_t r; secp256k1_fe_sqr(&r, &a->z); secp256k1_fe_mul(&r, &r, x);
+ secp256k1_fe_t r2 = a->x; secp256k1_fe_normalize_weak(&r2);
+ return secp256k1_fe_equal_var(&r, &r2);
}
-static void secp256k1_gej_neg_var(secp256k1_gej_t *r, const secp256k1_gej_t *a) {
+static void secp256k1_gej_neg(secp256k1_gej_t *r, const secp256k1_gej_t *a) {
r->infinity = a->infinity;
r->x = a->x;
r->y = a->y;
r->z = a->z;
- secp256k1_fe_normalize_var(&r->y);
+ secp256k1_fe_normalize_weak(&r->y);
secp256k1_fe_negate(&r->y, &r->y, 1);
}
@@ -195,9 +191,8 @@ static int secp256k1_gej_is_valid_var(const secp256k1_gej_t *a) {
secp256k1_fe_t z6; secp256k1_fe_sqr(&z6, &z2); secp256k1_fe_mul(&z6, &z6, &z2);
secp256k1_fe_mul_int(&z6, 7);
secp256k1_fe_add(&x3, &z6);
- secp256k1_fe_normalize_var(&y2);
- secp256k1_fe_normalize_var(&x3);
- return secp256k1_fe_equal(&y2, &x3);
+ secp256k1_fe_normalize_weak(&x3);
+ return secp256k1_fe_equal_var(&y2, &x3);
}
static int secp256k1_ge_is_valid_var(const secp256k1_ge_t *a) {
@@ -208,9 +203,8 @@ static int secp256k1_ge_is_valid_var(const secp256k1_ge_t *a) {
secp256k1_fe_t x3; secp256k1_fe_sqr(&x3, &a->x); secp256k1_fe_mul(&x3, &x3, &a->x);
secp256k1_fe_t c; secp256k1_fe_set_int(&c, 7);
secp256k1_fe_add(&x3, &c);
- secp256k1_fe_normalize_var(&y2);
- secp256k1_fe_normalize_var(&x3);
- return secp256k1_fe_equal(&y2, &x3);
+ secp256k1_fe_normalize_weak(&x3);
+ return secp256k1_fe_equal_var(&y2, &x3);
}
static void secp256k1_gej_double_var(secp256k1_gej_t *r, const secp256k1_gej_t *a) {
@@ -261,20 +255,16 @@ static void secp256k1_gej_add_var(secp256k1_gej_t *r, const secp256k1_gej_t *a,
secp256k1_fe_t u2; secp256k1_fe_mul(&u2, &b->x, &z12);
secp256k1_fe_t s1; secp256k1_fe_mul(&s1, &a->y, &z22); secp256k1_fe_mul(&s1, &s1, &b->z);
secp256k1_fe_t s2; secp256k1_fe_mul(&s2, &b->y, &z12); secp256k1_fe_mul(&s2, &s2, &a->z);
- secp256k1_fe_normalize_var(&u1);
- secp256k1_fe_normalize_var(&u2);
- if (secp256k1_fe_equal(&u1, &u2)) {
- secp256k1_fe_normalize_var(&s1);
- secp256k1_fe_normalize_var(&s2);
- if (secp256k1_fe_equal(&s1, &s2)) {
+ secp256k1_fe_t h; secp256k1_fe_negate(&h, &u1, 1); secp256k1_fe_add(&h, &u2);
+ secp256k1_fe_t i; secp256k1_fe_negate(&i, &s1, 1); secp256k1_fe_add(&i, &s2);
+ if (secp256k1_fe_normalizes_to_zero_var(&h)) {
+ if (secp256k1_fe_normalizes_to_zero_var(&i)) {
secp256k1_gej_double_var(r, a);
} else {
r->infinity = 1;
}
return;
}
- secp256k1_fe_t h; secp256k1_fe_negate(&h, &u1, 1); secp256k1_fe_add(&h, &u2);
- secp256k1_fe_t i; secp256k1_fe_negate(&i, &s1, 1); secp256k1_fe_add(&i, &s2);
secp256k1_fe_t i2; secp256k1_fe_sqr(&i2, &i);
secp256k1_fe_t h2; secp256k1_fe_sqr(&h2, &h);
secp256k1_fe_t h3; secp256k1_fe_mul(&h3, &h, &h2);
@@ -300,23 +290,20 @@ static void secp256k1_gej_add_ge_var(secp256k1_gej_t *r, const secp256k1_gej_t *
}
r->infinity = 0;
secp256k1_fe_t z12; secp256k1_fe_sqr(&z12, &a->z);
- secp256k1_fe_t u1 = a->x;
+ secp256k1_fe_t u1 = a->x; secp256k1_fe_normalize_weak(&u1);
secp256k1_fe_t u2; secp256k1_fe_mul(&u2, &b->x, &z12);
- secp256k1_fe_t s1 = a->y; secp256k1_fe_normalize_var(&s1);
+ secp256k1_fe_t s1 = a->y; secp256k1_fe_normalize_weak(&s1);
secp256k1_fe_t s2; secp256k1_fe_mul(&s2, &b->y, &z12); secp256k1_fe_mul(&s2, &s2, &a->z);
- secp256k1_fe_normalize_var(&u1);
- secp256k1_fe_normalize_var(&u2);
- if (secp256k1_fe_equal(&u1, &u2)) {
- secp256k1_fe_normalize_var(&s2);
- if (secp256k1_fe_equal(&s1, &s2)) {
+ secp256k1_fe_t h; secp256k1_fe_negate(&h, &u1, 1); secp256k1_fe_add(&h, &u2);
+ secp256k1_fe_t i; secp256k1_fe_negate(&i, &s1, 1); secp256k1_fe_add(&i, &s2);
+ if (secp256k1_fe_normalizes_to_zero_var(&h)) {
+ if (secp256k1_fe_normalizes_to_zero_var(&i)) {
secp256k1_gej_double_var(r, a);
} else {
r->infinity = 1;
}
return;
}
- secp256k1_fe_t h; secp256k1_fe_negate(&h, &u1, 1); secp256k1_fe_add(&h, &u2);
- secp256k1_fe_t i; secp256k1_fe_negate(&i, &s1, 1); secp256k1_fe_add(&i, &s2);
secp256k1_fe_t i2; secp256k1_fe_sqr(&i2, &i);
secp256k1_fe_t h2; secp256k1_fe_sqr(&h2, &h);
secp256k1_fe_t h3; secp256k1_fe_mul(&h3, &h, &h2);
@@ -355,9 +342,9 @@ static void secp256k1_gej_add_ge(secp256k1_gej_t *r, const secp256k1_gej_t *a, c
*/
secp256k1_fe_t zz; secp256k1_fe_sqr(&zz, &a->z); /* z = Z1^2 */
- secp256k1_fe_t u1 = a->x; secp256k1_fe_normalize(&u1); /* u1 = U1 = X1*Z2^2 (1) */
+ secp256k1_fe_t u1 = a->x; secp256k1_fe_normalize_weak(&u1); /* u1 = U1 = X1*Z2^2 (1) */
secp256k1_fe_t u2; secp256k1_fe_mul(&u2, &b->x, &zz); /* u2 = U2 = X2*Z1^2 (1) */
- secp256k1_fe_t s1 = a->y; secp256k1_fe_normalize(&s1); /* s1 = S1 = Y1*Z2^3 (1) */
+ secp256k1_fe_t s1 = a->y; secp256k1_fe_normalize_weak(&s1); /* s1 = S1 = Y1*Z2^3 (1) */
secp256k1_fe_t s2; secp256k1_fe_mul(&s2, &b->y, &zz); /* s2 = Y2*Z2^2 (1) */
secp256k1_fe_mul(&s2, &s2, &a->z); /* s2 = S2 = Y2*Z1^3 (1) */
secp256k1_fe_t z = a->z; /* z = Z = Z1*Z2 (8) */
@@ -371,8 +358,7 @@ static void secp256k1_gej_add_ge(secp256k1_gej_t *r, const secp256k1_gej_t *a, c
secp256k1_fe_add(&rr, &t); /* rr = R = T^2-U1*U2 (3) */
secp256k1_fe_sqr(&t, &rr); /* t = R^2 (1) */
secp256k1_fe_mul(&r->z, &m, &z); /* r->z = M*Z (1) */
- secp256k1_fe_normalize(&r->z);
- int infinity = secp256k1_fe_is_zero(&r->z) * (1 - a->infinity);
+ int infinity = secp256k1_fe_normalizes_to_zero(&r->z) * (1 - a->infinity);
secp256k1_fe_mul_int(&r->z, 2 * (1 - a->infinity)); /* r->z = Z3 = 2*M*Z (2) */
r->x = t; /* r->x = R^2 (1) */
secp256k1_fe_negate(&q, &q, 1); /* q = -Q (2) */
@@ -384,7 +370,7 @@ static void secp256k1_gej_add_ge(secp256k1_gej_t *r, const secp256k1_gej_t *a, c
secp256k1_fe_mul(&t, &t, &rr); /* t = R*(2*R^2-3*Q) (1) */
secp256k1_fe_add(&t, &n); /* t = R*(2*R^2-3*Q)+M^4 (2) */
secp256k1_fe_negate(&r->y, &t, 2); /* r->y = R*(3*Q-2*R^2)-M^4 (3) */
- secp256k1_fe_normalize(&r->y);
+ secp256k1_fe_normalize_weak(&r->y);
secp256k1_fe_mul_int(&r->x, 4 * (1 - a->infinity)); /* r->x = X3 = 4*(R^2-Q) */
secp256k1_fe_mul_int(&r->y, 4 * (1 - a->infinity)); /* r->y = Y3 = 4*R*(3*Q-2*R^2)-4*M^4 (4) */
diff --git a/src/secp256k1/src/hash.h b/src/secp256k1/src/hash.h
new file mode 100644
index 0000000000..d1e65b968a
--- /dev/null
+++ b/src/secp256k1/src/hash.h
@@ -0,0 +1,41 @@
+/**********************************************************************
+ * Copyright (c) 2014 Pieter Wuille *
+ * Distributed under the MIT software license, see the accompanying *
+ * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
+ **********************************************************************/
+
+#ifndef _SECP256K1_HASH_
+#define _SECP256K1_HASH_
+
+#include <stdlib.h>
+#include <stdint.h>
+
+typedef struct {
+ uint32_t s[32];
+ unsigned char buf[64];
+ size_t bytes;
+} secp256k1_sha256_t;
+
+static void secp256k1_sha256_initialize(secp256k1_sha256_t *hash);
+static void secp256k1_sha256_write(secp256k1_sha256_t *hash, const unsigned char *data, size_t size);
+static void secp256k1_sha256_finalize(secp256k1_sha256_t *hash, unsigned char *out32);
+
+typedef struct {
+ secp256k1_sha256_t inner, outer;
+} secp256k1_hmac_sha256_t;
+
+static void secp256k1_hmac_sha256_initialize(secp256k1_hmac_sha256_t *hash, const unsigned char *key, size_t size);
+static void secp256k1_hmac_sha256_write(secp256k1_hmac_sha256_t *hash, const unsigned char *data, size_t size);
+static void secp256k1_hmac_sha256_finalize(secp256k1_hmac_sha256_t *hash, unsigned char *out32);
+
+typedef struct {
+ unsigned char v[32];
+ unsigned char k[32];
+ int retry;
+} secp256k1_rfc6979_hmac_sha256_t;
+
+static void secp256k1_rfc6979_hmac_sha256_initialize(secp256k1_rfc6979_hmac_sha256_t *rng, const unsigned char *key, size_t keylen, const unsigned char *msg, size_t msglen);
+static void secp256k1_rfc6979_hmac_sha256_generate(secp256k1_rfc6979_hmac_sha256_t *rng, unsigned char *out, size_t outlen);
+static void secp256k1_rfc6979_hmac_sha256_finalize(secp256k1_rfc6979_hmac_sha256_t *rng);
+
+#endif
diff --git a/src/secp256k1/src/hash_impl.h b/src/secp256k1/src/hash_impl.h
new file mode 100644
index 0000000000..f35c5f7a82
--- /dev/null
+++ b/src/secp256k1/src/hash_impl.h
@@ -0,0 +1,291 @@
+/**********************************************************************
+ * Copyright (c) 2014 Pieter Wuille *
+ * Distributed under the MIT software license, see the accompanying *
+ * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
+ **********************************************************************/
+
+#ifndef _SECP256K1_HASH_IMPL_H_
+#define _SECP256K1_HASH_IMPL_H_
+
+#include "hash.h"
+
+#include <stdlib.h>
+#include <stdint.h>
+
+#define Ch(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
+#define Maj(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))
+#define Sigma0(x) (((x) >> 2 | (x) << 30) ^ ((x) >> 13 | (x) << 19) ^ ((x) >> 22 | (x) << 10))
+#define Sigma1(x) (((x) >> 6 | (x) << 26) ^ ((x) >> 11 | (x) << 21) ^ ((x) >> 25 | (x) << 7))
+#define sigma0(x) (((x) >> 7 | (x) << 25) ^ ((x) >> 18 | (x) << 14) ^ ((x) >> 3))
+#define sigma1(x) (((x) >> 17 | (x) << 15) ^ ((x) >> 19 | (x) << 13) ^ ((x) >> 10))
+
+#define Round(a,b,c,d,e,f,g,h,k,w) do { \
+ uint32_t t1 = (h) + Sigma1(e) + Ch((e), (f), (g)) + (k) + (w); \
+ uint32_t t2 = Sigma0(a) + Maj((a), (b), (c)); \
+ (d) += t1; \
+ (h) = t1 + t2; \
+} while(0)
+
+#define ReadBE32(p) (((uint32_t)((p)[0])) << 24 | ((uint32_t)((p)[1])) << 16 | ((uint32_t)((p)[2])) << 8 | ((uint32_t)((p)[3])))
+#define WriteBE32(p, v) do { (p)[0] = (v) >> 24; (p)[1] = (v) >> 16; (p)[2] = (v) >> 8; (p)[3] = (v); } while(0)
+
+static void secp256k1_sha256_initialize(secp256k1_sha256_t *hash) {
+ hash->s[0] = 0x6a09e667ul;
+ hash->s[1] = 0xbb67ae85ul;
+ hash->s[2] = 0x3c6ef372ul;
+ hash->s[3] = 0xa54ff53aul;
+ hash->s[4] = 0x510e527ful;
+ hash->s[5] = 0x9b05688cul;
+ hash->s[6] = 0x1f83d9abul;
+ hash->s[7] = 0x5be0cd19ul;
+ hash->bytes = 0;
+}
+
+/** Perform one SHA-256 transformation, processing a 64-byte chunk. */
+static void secp256k1_sha256_transform(uint32_t* s, const unsigned char* chunk) {
+ uint32_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4], f = s[5], g = s[6], h = s[7];
+ uint32_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15;
+
+ Round(a, b, c, d, e, f, g, h, 0x428a2f98, w0 = ReadBE32(chunk + 0));
+ Round(h, a, b, c, d, e, f, g, 0x71374491, w1 = ReadBE32(chunk + 4));
+ Round(g, h, a, b, c, d, e, f, 0xb5c0fbcf, w2 = ReadBE32(chunk + 8));
+ Round(f, g, h, a, b, c, d, e, 0xe9b5dba5, w3 = ReadBE32(chunk + 12));
+ Round(e, f, g, h, a, b, c, d, 0x3956c25b, w4 = ReadBE32(chunk + 16));
+ Round(d, e, f, g, h, a, b, c, 0x59f111f1, w5 = ReadBE32(chunk + 20));
+ Round(c, d, e, f, g, h, a, b, 0x923f82a4, w6 = ReadBE32(chunk + 24));
+ Round(b, c, d, e, f, g, h, a, 0xab1c5ed5, w7 = ReadBE32(chunk + 28));
+ Round(a, b, c, d, e, f, g, h, 0xd807aa98, w8 = ReadBE32(chunk + 32));
+ Round(h, a, b, c, d, e, f, g, 0x12835b01, w9 = ReadBE32(chunk + 36));
+ Round(g, h, a, b, c, d, e, f, 0x243185be, w10 = ReadBE32(chunk + 40));
+ Round(f, g, h, a, b, c, d, e, 0x550c7dc3, w11 = ReadBE32(chunk + 44));
+ Round(e, f, g, h, a, b, c, d, 0x72be5d74, w12 = ReadBE32(chunk + 48));
+ Round(d, e, f, g, h, a, b, c, 0x80deb1fe, w13 = ReadBE32(chunk + 52));
+ Round(c, d, e, f, g, h, a, b, 0x9bdc06a7, w14 = ReadBE32(chunk + 56));
+ Round(b, c, d, e, f, g, h, a, 0xc19bf174, w15 = ReadBE32(chunk + 60));
+
+ Round(a, b, c, d, e, f, g, h, 0xe49b69c1, w0 += sigma1(w14) + w9 + sigma0(w1));
+ Round(h, a, b, c, d, e, f, g, 0xefbe4786, w1 += sigma1(w15) + w10 + sigma0(w2));
+ Round(g, h, a, b, c, d, e, f, 0x0fc19dc6, w2 += sigma1(w0) + w11 + sigma0(w3));
+ Round(f, g, h, a, b, c, d, e, 0x240ca1cc, w3 += sigma1(w1) + w12 + sigma0(w4));
+ Round(e, f, g, h, a, b, c, d, 0x2de92c6f, w4 += sigma1(w2) + w13 + sigma0(w5));
+ Round(d, e, f, g, h, a, b, c, 0x4a7484aa, w5 += sigma1(w3) + w14 + sigma0(w6));
+ Round(c, d, e, f, g, h, a, b, 0x5cb0a9dc, w6 += sigma1(w4) + w15 + sigma0(w7));
+ Round(b, c, d, e, f, g, h, a, 0x76f988da, w7 += sigma1(w5) + w0 + sigma0(w8));
+ Round(a, b, c, d, e, f, g, h, 0x983e5152, w8 += sigma1(w6) + w1 + sigma0(w9));
+ Round(h, a, b, c, d, e, f, g, 0xa831c66d, w9 += sigma1(w7) + w2 + sigma0(w10));
+ Round(g, h, a, b, c, d, e, f, 0xb00327c8, w10 += sigma1(w8) + w3 + sigma0(w11));
+ Round(f, g, h, a, b, c, d, e, 0xbf597fc7, w11 += sigma1(w9) + w4 + sigma0(w12));
+ Round(e, f, g, h, a, b, c, d, 0xc6e00bf3, w12 += sigma1(w10) + w5 + sigma0(w13));
+ Round(d, e, f, g, h, a, b, c, 0xd5a79147, w13 += sigma1(w11) + w6 + sigma0(w14));
+ Round(c, d, e, f, g, h, a, b, 0x06ca6351, w14 += sigma1(w12) + w7 + sigma0(w15));
+ Round(b, c, d, e, f, g, h, a, 0x14292967, w15 += sigma1(w13) + w8 + sigma0(w0));
+
+ Round(a, b, c, d, e, f, g, h, 0x27b70a85, w0 += sigma1(w14) + w9 + sigma0(w1));
+ Round(h, a, b, c, d, e, f, g, 0x2e1b2138, w1 += sigma1(w15) + w10 + sigma0(w2));
+ Round(g, h, a, b, c, d, e, f, 0x4d2c6dfc, w2 += sigma1(w0) + w11 + sigma0(w3));
+ Round(f, g, h, a, b, c, d, e, 0x53380d13, w3 += sigma1(w1) + w12 + sigma0(w4));
+ Round(e, f, g, h, a, b, c, d, 0x650a7354, w4 += sigma1(w2) + w13 + sigma0(w5));
+ Round(d, e, f, g, h, a, b, c, 0x766a0abb, w5 += sigma1(w3) + w14 + sigma0(w6));
+ Round(c, d, e, f, g, h, a, b, 0x81c2c92e, w6 += sigma1(w4) + w15 + sigma0(w7));
+ Round(b, c, d, e, f, g, h, a, 0x92722c85, w7 += sigma1(w5) + w0 + sigma0(w8));
+ Round(a, b, c, d, e, f, g, h, 0xa2bfe8a1, w8 += sigma1(w6) + w1 + sigma0(w9));
+ Round(h, a, b, c, d, e, f, g, 0xa81a664b, w9 += sigma1(w7) + w2 + sigma0(w10));
+ Round(g, h, a, b, c, d, e, f, 0xc24b8b70, w10 += sigma1(w8) + w3 + sigma0(w11));
+ Round(f, g, h, a, b, c, d, e, 0xc76c51a3, w11 += sigma1(w9) + w4 + sigma0(w12));
+ Round(e, f, g, h, a, b, c, d, 0xd192e819, w12 += sigma1(w10) + w5 + sigma0(w13));
+ Round(d, e, f, g, h, a, b, c, 0xd6990624, w13 += sigma1(w11) + w6 + sigma0(w14));
+ Round(c, d, e, f, g, h, a, b, 0xf40e3585, w14 += sigma1(w12) + w7 + sigma0(w15));
+ Round(b, c, d, e, f, g, h, a, 0x106aa070, w15 += sigma1(w13) + w8 + sigma0(w0));
+
+ Round(a, b, c, d, e, f, g, h, 0x19a4c116, w0 += sigma1(w14) + w9 + sigma0(w1));
+ Round(h, a, b, c, d, e, f, g, 0x1e376c08, w1 += sigma1(w15) + w10 + sigma0(w2));
+ Round(g, h, a, b, c, d, e, f, 0x2748774c, w2 += sigma1(w0) + w11 + sigma0(w3));
+ Round(f, g, h, a, b, c, d, e, 0x34b0bcb5, w3 += sigma1(w1) + w12 + sigma0(w4));
+ Round(e, f, g, h, a, b, c, d, 0x391c0cb3, w4 += sigma1(w2) + w13 + sigma0(w5));
+ Round(d, e, f, g, h, a, b, c, 0x4ed8aa4a, w5 += sigma1(w3) + w14 + sigma0(w6));
+ Round(c, d, e, f, g, h, a, b, 0x5b9cca4f, w6 += sigma1(w4) + w15 + sigma0(w7));
+ Round(b, c, d, e, f, g, h, a, 0x682e6ff3, w7 += sigma1(w5) + w0 + sigma0(w8));
+ Round(a, b, c, d, e, f, g, h, 0x748f82ee, w8 += sigma1(w6) + w1 + sigma0(w9));
+ Round(h, a, b, c, d, e, f, g, 0x78a5636f, w9 += sigma1(w7) + w2 + sigma0(w10));
+ Round(g, h, a, b, c, d, e, f, 0x84c87814, w10 += sigma1(w8) + w3 + sigma0(w11));
+ Round(f, g, h, a, b, c, d, e, 0x8cc70208, w11 += sigma1(w9) + w4 + sigma0(w12));
+ Round(e, f, g, h, a, b, c, d, 0x90befffa, w12 += sigma1(w10) + w5 + sigma0(w13));
+ Round(d, e, f, g, h, a, b, c, 0xa4506ceb, w13 += sigma1(w11) + w6 + sigma0(w14));
+ Round(c, d, e, f, g, h, a, b, 0xbef9a3f7, w14 + sigma1(w12) + w7 + sigma0(w15));
+ Round(b, c, d, e, f, g, h, a, 0xc67178f2, w15 + sigma1(w13) + w8 + sigma0(w0));
+
+ s[0] += a;
+ s[1] += b;
+ s[2] += c;
+ s[3] += d;
+ s[4] += e;
+ s[5] += f;
+ s[6] += g;
+ s[7] += h;
+}
+
+static void secp256k1_sha256_write(secp256k1_sha256_t *hash, const unsigned char *data, size_t len) {
+ const unsigned char* end = data + len;
+ size_t bufsize = hash->bytes % 64;
+ if (bufsize && bufsize + len >= 64) {
+ // Fill the buffer, and process it.
+ memcpy(hash->buf + bufsize, data, 64 - bufsize);
+ hash->bytes += 64 - bufsize;
+ data += 64 - bufsize;
+ secp256k1_sha256_transform(hash->s, hash->buf);
+ bufsize = 0;
+ }
+ while (end >= data + 64) {
+ // Process full chunks directly from the source.
+ secp256k1_sha256_transform(hash->s, data);
+ hash->bytes += 64;
+ data += 64;
+ }
+ if (end > data) {
+ // Fill the buffer with what remains.
+ memcpy(hash->buf + bufsize, data, end - data);
+ hash->bytes += end - data;
+ }
+}
+
+static void secp256k1_sha256_finalize(secp256k1_sha256_t *hash, unsigned char *out32) {
+ static const unsigned char pad[64] = {0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ unsigned char sizedesc[8];
+ WriteBE32(sizedesc, hash->bytes >> 29);
+ WriteBE32(sizedesc + 4, hash->bytes << 3);
+ secp256k1_sha256_write(hash, pad, 1 + ((119 - (hash->bytes % 64)) % 64));
+ secp256k1_sha256_write(hash, sizedesc, 8);
+ WriteBE32(out32, hash->s[0]);
+ hash->s[0] = 0;
+ WriteBE32(out32 + 4, hash->s[1]);
+ hash->s[1] = 0;
+ WriteBE32(out32 + 8, hash->s[2]);
+ hash->s[2] = 0;
+ WriteBE32(out32 + 12, hash->s[3]);
+ hash->s[3] = 0;
+ WriteBE32(out32 + 16, hash->s[4]);
+ hash->s[4] = 0;
+ WriteBE32(out32 + 20, hash->s[5]);
+ hash->s[5] = 0;
+ WriteBE32(out32 + 24, hash->s[6]);
+ hash->s[6] = 0;
+ WriteBE32(out32 + 28, hash->s[7]);
+ hash->s[7] = 0;
+}
+
+static void secp256k1_hmac_sha256_initialize(secp256k1_hmac_sha256_t *hash, const unsigned char *key, size_t keylen) {
+ unsigned char rkey[64];
+ if (keylen <= 64) {
+ memcpy(rkey, key, keylen);
+ memset(rkey + keylen, 0, 64 - keylen);
+ } else {
+ secp256k1_sha256_t sha256;
+ secp256k1_sha256_initialize(&sha256);
+ secp256k1_sha256_write(&sha256, key, keylen);
+ secp256k1_sha256_finalize(&sha256, rkey);
+ memset(rkey + 32, 0, 32);
+ }
+
+ secp256k1_sha256_initialize(&hash->outer);
+ for (int n = 0; n < 64; n++)
+ rkey[n] ^= 0x5c;
+ secp256k1_sha256_write(&hash->outer, rkey, 64);
+
+ secp256k1_sha256_initialize(&hash->inner);
+ for (int n = 0; n < 64; n++)
+ rkey[n] ^= 0x5c ^ 0x36;
+ secp256k1_sha256_write(&hash->inner, rkey, 64);
+ memset(rkey, 0, 64);
+}
+
+static void secp256k1_hmac_sha256_write(secp256k1_hmac_sha256_t *hash, const unsigned char *data, size_t size) {
+ secp256k1_sha256_write(&hash->inner, data, size);
+}
+
+static void secp256k1_hmac_sha256_finalize(secp256k1_hmac_sha256_t *hash, unsigned char *out32) {
+ unsigned char temp[32];
+ secp256k1_sha256_finalize(&hash->inner, temp);
+ secp256k1_sha256_write(&hash->outer, temp, 32);
+ memset(temp, 0, 32);
+ secp256k1_sha256_finalize(&hash->outer, out32);
+}
+
+
+static void secp256k1_rfc6979_hmac_sha256_initialize(secp256k1_rfc6979_hmac_sha256_t *rng, const unsigned char *key, size_t keylen, const unsigned char *msg, size_t msglen) {
+ static const unsigned char zero[1] = {0x00};
+ static const unsigned char one[1] = {0x01};
+
+ memset(rng->v, 0x01, 32);
+ memset(rng->k, 0x00, 32);
+
+ secp256k1_hmac_sha256_t hmac;
+ secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32);
+ secp256k1_hmac_sha256_write(&hmac, rng->v, 32);
+ secp256k1_hmac_sha256_write(&hmac, zero, 1);
+ secp256k1_hmac_sha256_write(&hmac, key, keylen);
+ secp256k1_hmac_sha256_write(&hmac, msg, msglen);
+ secp256k1_hmac_sha256_finalize(&hmac, rng->k);
+ secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32);
+ secp256k1_hmac_sha256_write(&hmac, rng->v, 32);
+ secp256k1_hmac_sha256_finalize(&hmac, rng->v);
+
+ secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32);
+ secp256k1_hmac_sha256_write(&hmac, rng->v, 32);
+ secp256k1_hmac_sha256_write(&hmac, one, 1);
+ secp256k1_hmac_sha256_write(&hmac, key, keylen);
+ secp256k1_hmac_sha256_write(&hmac, msg, msglen);
+ secp256k1_hmac_sha256_finalize(&hmac, rng->k);
+ secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32);
+ secp256k1_hmac_sha256_write(&hmac, rng->v, 32);
+ secp256k1_hmac_sha256_finalize(&hmac, rng->v);
+ rng->retry = 0;
+}
+
+static void secp256k1_rfc6979_hmac_sha256_generate(secp256k1_rfc6979_hmac_sha256_t *rng, unsigned char *out, size_t outlen) {
+ static const unsigned char zero[1] = {0x00};
+ if (rng->retry) {
+ secp256k1_hmac_sha256_t hmac;
+ secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32);
+ secp256k1_hmac_sha256_write(&hmac, rng->v, 32);
+ secp256k1_hmac_sha256_write(&hmac, zero, 1);
+ secp256k1_hmac_sha256_finalize(&hmac, rng->k);
+ secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32);
+ secp256k1_hmac_sha256_write(&hmac, rng->v, 32);
+ secp256k1_hmac_sha256_finalize(&hmac, rng->v);
+ }
+
+ while (outlen > 0) {
+ secp256k1_hmac_sha256_t hmac;
+ secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32);
+ secp256k1_hmac_sha256_write(&hmac, rng->v, 32);
+ secp256k1_hmac_sha256_finalize(&hmac, rng->v);
+ int now = outlen;
+ if (now > 32) {
+ now = 32;
+ }
+ memcpy(out, rng->v, now);
+ out += now;
+ outlen -= now;
+ }
+
+ rng->retry = 1;
+}
+
+static void secp256k1_rfc6979_hmac_sha256_finalize(secp256k1_rfc6979_hmac_sha256_t *rng) {
+ memset(rng->k, 0, 32);
+ memset(rng->v, 0, 32);
+ rng->retry = 0;
+}
+
+
+#undef Round
+#undef sigma0
+#undef sigma1
+#undef Sigma0
+#undef Sigma1
+#undef Ch
+#undef Maj
+#undef ReadBE32
+#undef WriteBE32
+
+#endif
diff --git a/src/secp256k1/src/secp256k1.c b/src/secp256k1/src/secp256k1.c
index 0328db88fc..58bcd8d009 100644
--- a/src/secp256k1/src/secp256k1.c
+++ b/src/secp256k1/src/secp256k1.c
@@ -17,6 +17,7 @@
#include "ecmult_gen_impl.h"
#include "ecdsa_impl.h"
#include "eckey_impl.h"
+#include "hash_impl.h"
void secp256k1_start(unsigned int flags) {
secp256k1_fe_start();
@@ -69,26 +70,54 @@ end:
return ret;
}
-int secp256k1_ecdsa_sign(const unsigned char *msg32, unsigned char *signature, int *signaturelen, const unsigned char *seckey, const unsigned char *nonce) {
+static int nonce_function_rfc6979(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, unsigned int counter, const void *data) {
+ (void)data;
+ secp256k1_rfc6979_hmac_sha256_t rng;
+ secp256k1_rfc6979_hmac_sha256_initialize(&rng, key32, 32, msg32, 32);
+ for (unsigned int i = 0; i <= counter; i++) {
+ secp256k1_rfc6979_hmac_sha256_generate(&rng, nonce32, 32);
+ }
+ secp256k1_rfc6979_hmac_sha256_finalize(&rng);
+ return 1;
+}
+
+const secp256k1_nonce_function_t secp256k1_nonce_function_rfc6979 = nonce_function_rfc6979;
+const secp256k1_nonce_function_t secp256k1_nonce_function_default = nonce_function_rfc6979;
+
+int secp256k1_ecdsa_sign(const unsigned char *msg32, unsigned char *signature, int *signaturelen, const unsigned char *seckey, secp256k1_nonce_function_t noncefp, const void* noncedata) {
DEBUG_CHECK(secp256k1_ecmult_gen_consts != NULL);
DEBUG_CHECK(msg32 != NULL);
DEBUG_CHECK(signature != NULL);
DEBUG_CHECK(signaturelen != NULL);
DEBUG_CHECK(seckey != NULL);
- DEBUG_CHECK(nonce != NULL);
+ if (noncefp == NULL) {
+ noncefp = secp256k1_nonce_function_default;
+ }
secp256k1_scalar_t sec, non, msg;
secp256k1_scalar_set_b32(&sec, seckey, NULL);
- int overflow = 0;
- secp256k1_scalar_set_b32(&non, nonce, &overflow);
secp256k1_scalar_set_b32(&msg, msg32, NULL);
- int ret = !secp256k1_scalar_is_zero(&non) && !overflow;
+ int overflow = 0;
+ int ret = 0;
+ unsigned int count = 0;
secp256k1_ecdsa_sig_t sig;
- if (ret) {
- ret = secp256k1_ecdsa_sig_sign(&sig, &sec, &msg, &non, NULL);
+ while (1) {
+ unsigned char nonce32[32];
+ ret = noncefp(nonce32, msg32, seckey, count, noncedata);
+ if (!ret) {
+ break;
+ }
+ secp256k1_scalar_set_b32(&non, nonce32, &overflow);
+ memset(nonce32, 0, 32);
+ if (!secp256k1_scalar_is_zero(&non) && !overflow) {
+ if (secp256k1_ecdsa_sig_sign(&sig, &sec, &msg, &non, NULL)) {
+ break;
+ }
+ }
+ count++;
}
if (ret) {
- secp256k1_ecdsa_sig_serialize(signature, signaturelen, &sig);
+ ret = secp256k1_ecdsa_sig_serialize(signature, signaturelen, &sig);
}
secp256k1_scalar_clear(&msg);
secp256k1_scalar_clear(&non);
@@ -96,22 +125,36 @@ int secp256k1_ecdsa_sign(const unsigned char *msg32, unsigned char *signature, i
return ret;
}
-int secp256k1_ecdsa_sign_compact(const unsigned char *msg32, unsigned char *sig64, const unsigned char *seckey, const unsigned char *nonce, int *recid) {
+int secp256k1_ecdsa_sign_compact(const unsigned char *msg32, unsigned char *sig64, const unsigned char *seckey, secp256k1_nonce_function_t noncefp, const void* noncedata, int *recid) {
DEBUG_CHECK(secp256k1_ecmult_gen_consts != NULL);
DEBUG_CHECK(msg32 != NULL);
DEBUG_CHECK(sig64 != NULL);
DEBUG_CHECK(seckey != NULL);
- DEBUG_CHECK(nonce != NULL);
+ if (noncefp == NULL) {
+ noncefp = secp256k1_nonce_function_default;
+ }
secp256k1_scalar_t sec, non, msg;
secp256k1_scalar_set_b32(&sec, seckey, NULL);
- int overflow = 0;
- secp256k1_scalar_set_b32(&non, nonce, &overflow);
secp256k1_scalar_set_b32(&msg, msg32, NULL);
- int ret = !secp256k1_scalar_is_zero(&non) && !overflow;
+ int overflow = 0;
+ int ret = 0;
+ unsigned int count = 0;
secp256k1_ecdsa_sig_t sig;
- if (ret) {
- ret = secp256k1_ecdsa_sig_sign(&sig, &sec, &msg, &non, recid);
+ while (1) {
+ unsigned char nonce32[32];
+ ret = noncefp(nonce32, msg32, seckey, count, noncedata);
+ if (!ret) {
+ break;
+ }
+ secp256k1_scalar_set_b32(&non, nonce32, &overflow);
+ memset(nonce32, 0, 32);
+ if (!secp256k1_scalar_is_zero(&non) && !overflow) {
+ if (secp256k1_ecdsa_sig_sign(&sig, &sec, &msg, &non, recid)) {
+ break;
+ }
+ }
+ count++;
}
if (ret) {
secp256k1_scalar_get_b32(sig64, &sig.r);
diff --git a/src/secp256k1/src/tests.c b/src/secp256k1/src/tests.c
index 7ebb19ff99..cff32f1d06 100644
--- a/src/secp256k1/src/tests.c
+++ b/src/secp256k1/src/tests.c
@@ -36,12 +36,19 @@ void random_field_element_test(secp256k1_fe_t *fe) {
}
void random_field_element_magnitude(secp256k1_fe_t *fe) {
+ int n = secp256k1_rand32() % 9;
secp256k1_fe_normalize(fe);
- int n = secp256k1_rand32() % 4;
- for (int i = 0; i < n; i++) {
- secp256k1_fe_negate(fe, fe, 1 + 2*i);
- secp256k1_fe_negate(fe, fe, 2 + 2*i);
+ if (n == 0) {
+ return;
}
+ secp256k1_fe_t zero;
+ secp256k1_fe_clear(&zero);
+ secp256k1_fe_negate(&zero, &zero, 0);
+ secp256k1_fe_mul_int(&zero, n - 1);
+ secp256k1_fe_add(fe, &zero);
+#ifdef VERIFY
+ CHECK(fe->magnitude == n);
+#endif
}
void random_group_element_test(secp256k1_ge_t *ge) {
@@ -91,6 +98,121 @@ void random_scalar_order(secp256k1_scalar_t *num) {
} while(1);
}
+/***** HASH TESTS *****/
+
+void run_sha256_tests(void) {
+ static const char *inputs[8] = {
+ "", "abc", "message digest", "secure hash algorithm", "SHA256 is considered to be safe",
+ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+ "For this sample, this 63-byte string will be used as input data",
+ "This is exactly 64 bytes long, not counting the terminating byte"
+ };
+ static const unsigned char outputs[8][32] = {
+ {0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55},
+ {0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c, 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad},
+ {0xf7, 0x84, 0x6f, 0x55, 0xcf, 0x23, 0xe1, 0x4e, 0xeb, 0xea, 0xb5, 0xb4, 0xe1, 0x55, 0x0c, 0xad, 0x5b, 0x50, 0x9e, 0x33, 0x48, 0xfb, 0xc4, 0xef, 0xa3, 0xa1, 0x41, 0x3d, 0x39, 0x3c, 0xb6, 0x50},
+ {0xf3, 0x0c, 0xeb, 0x2b, 0xb2, 0x82, 0x9e, 0x79, 0xe4, 0xca, 0x97, 0x53, 0xd3, 0x5a, 0x8e, 0xcc, 0x00, 0x26, 0x2d, 0x16, 0x4c, 0xc0, 0x77, 0x08, 0x02, 0x95, 0x38, 0x1c, 0xbd, 0x64, 0x3f, 0x0d},
+ {0x68, 0x19, 0xd9, 0x15, 0xc7, 0x3f, 0x4d, 0x1e, 0x77, 0xe4, 0xe1, 0xb5, 0x2d, 0x1f, 0xa0, 0xf9, 0xcf, 0x9b, 0xea, 0xea, 0xd3, 0x93, 0x9f, 0x15, 0x87, 0x4b, 0xd9, 0x88, 0xe2, 0xa2, 0x36, 0x30},
+ {0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8, 0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39, 0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67, 0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1},
+ {0xf0, 0x8a, 0x78, 0xcb, 0xba, 0xee, 0x08, 0x2b, 0x05, 0x2a, 0xe0, 0x70, 0x8f, 0x32, 0xfa, 0x1e, 0x50, 0xc5, 0xc4, 0x21, 0xaa, 0x77, 0x2b, 0xa5, 0xdb, 0xb4, 0x06, 0xa2, 0xea, 0x6b, 0xe3, 0x42},
+ {0xab, 0x64, 0xef, 0xf7, 0xe8, 0x8e, 0x2e, 0x46, 0x16, 0x5e, 0x29, 0xf2, 0xbc, 0xe4, 0x18, 0x26, 0xbd, 0x4c, 0x7b, 0x35, 0x52, 0xf6, 0xb3, 0x82, 0xa9, 0xe7, 0xd3, 0xaf, 0x47, 0xc2, 0x45, 0xf8}
+ };
+ for (int i = 0; i < 8; i++) {
+ secp256k1_sha256_t hasher;
+ secp256k1_sha256_initialize(&hasher);
+ secp256k1_sha256_write(&hasher, (const unsigned char*)(inputs[i]), strlen(inputs[i]));
+ unsigned char out[32];
+ secp256k1_sha256_finalize(&hasher, out);
+ CHECK(memcmp(out, outputs[i], 32) == 0);
+ if (strlen(inputs[i]) > 0) {
+ secp256k1_sha256_initialize(&hasher);
+ int split = secp256k1_rand32() % strlen(inputs[i]);
+ secp256k1_sha256_write(&hasher, (const unsigned char*)(inputs[i]), split);
+ secp256k1_sha256_write(&hasher, (const unsigned char*)(inputs[i] + split), strlen(inputs[i]) - split);
+ secp256k1_sha256_finalize(&hasher, out);
+ CHECK(memcmp(out, outputs[i], 32) == 0);
+ }
+ }
+}
+
+void run_hmac_sha256_tests(void) {
+ static const char *keys[6] = {
+ "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b",
+ "\x4a\x65\x66\x65",
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
+ "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19",
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ };
+ static const char *inputs[6] = {
+ "\x48\x69\x20\x54\x68\x65\x72\x65",
+ "\x77\x68\x61\x74\x20\x64\x6f\x20\x79\x61\x20\x77\x61\x6e\x74\x20\x66\x6f\x72\x20\x6e\x6f\x74\x68\x69\x6e\x67\x3f",
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd",
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd",
+ "\x54\x65\x73\x74\x20\x55\x73\x69\x6e\x67\x20\x4c\x61\x72\x67\x65\x72\x20\x54\x68\x61\x6e\x20\x42\x6c\x6f\x63\x6b\x2d\x53\x69\x7a\x65\x20\x4b\x65\x79\x20\x2d\x20\x48\x61\x73\x68\x20\x4b\x65\x79\x20\x46\x69\x72\x73\x74",
+ "\x54\x68\x69\x73\x20\x69\x73\x20\x61\x20\x74\x65\x73\x74\x20\x75\x73\x69\x6e\x67\x20\x61\x20\x6c\x61\x72\x67\x65\x72\x20\x74\x68\x61\x6e\x20\x62\x6c\x6f\x63\x6b\x2d\x73\x69\x7a\x65\x20\x6b\x65\x79\x20\x61\x6e\x64\x20\x61\x20\x6c\x61\x72\x67\x65\x72\x20\x74\x68\x61\x6e\x20\x62\x6c\x6f\x63\x6b\x2d\x73\x69\x7a\x65\x20\x64\x61\x74\x61\x2e\x20\x54\x68\x65\x20\x6b\x65\x79\x20\x6e\x65\x65\x64\x73\x20\x74\x6f\x20\x62\x65\x20\x68\x61\x73\x68\x65\x64\x20\x62\x65\x66\x6f\x72\x65\x20\x62\x65\x69\x6e\x67\x20\x75\x73\x65\x64\x20\x62\x79\x20\x74\x68\x65\x20\x48\x4d\x41\x43\x20\x61\x6c\x67\x6f\x72\x69\x74\x68\x6d\x2e"
+ };
+ static const unsigned char outputs[6][32] = {
+ {0xb0, 0x34, 0x4c, 0x61, 0xd8, 0xdb, 0x38, 0x53, 0x5c, 0xa8, 0xaf, 0xce, 0xaf, 0x0b, 0xf1, 0x2b, 0x88, 0x1d, 0xc2, 0x00, 0xc9, 0x83, 0x3d, 0xa7, 0x26, 0xe9, 0x37, 0x6c, 0x2e, 0x32, 0xcf, 0xf7},
+ {0x5b, 0xdc, 0xc1, 0x46, 0xbf, 0x60, 0x75, 0x4e, 0x6a, 0x04, 0x24, 0x26, 0x08, 0x95, 0x75, 0xc7, 0x5a, 0x00, 0x3f, 0x08, 0x9d, 0x27, 0x39, 0x83, 0x9d, 0xec, 0x58, 0xb9, 0x64, 0xec, 0x38, 0x43},
+ {0x77, 0x3e, 0xa9, 0x1e, 0x36, 0x80, 0x0e, 0x46, 0x85, 0x4d, 0xb8, 0xeb, 0xd0, 0x91, 0x81, 0xa7, 0x29, 0x59, 0x09, 0x8b, 0x3e, 0xf8, 0xc1, 0x22, 0xd9, 0x63, 0x55, 0x14, 0xce, 0xd5, 0x65, 0xfe},
+ {0x82, 0x55, 0x8a, 0x38, 0x9a, 0x44, 0x3c, 0x0e, 0xa4, 0xcc, 0x81, 0x98, 0x99, 0xf2, 0x08, 0x3a, 0x85, 0xf0, 0xfa, 0xa3, 0xe5, 0x78, 0xf8, 0x07, 0x7a, 0x2e, 0x3f, 0xf4, 0x67, 0x29, 0x66, 0x5b},
+ {0x60, 0xe4, 0x31, 0x59, 0x1e, 0xe0, 0xb6, 0x7f, 0x0d, 0x8a, 0x26, 0xaa, 0xcb, 0xf5, 0xb7, 0x7f, 0x8e, 0x0b, 0xc6, 0x21, 0x37, 0x28, 0xc5, 0x14, 0x05, 0x46, 0x04, 0x0f, 0x0e, 0xe3, 0x7f, 0x54},
+ {0x9b, 0x09, 0xff, 0xa7, 0x1b, 0x94, 0x2f, 0xcb, 0x27, 0x63, 0x5f, 0xbc, 0xd5, 0xb0, 0xe9, 0x44, 0xbf, 0xdc, 0x63, 0x64, 0x4f, 0x07, 0x13, 0x93, 0x8a, 0x7f, 0x51, 0x53, 0x5c, 0x3a, 0x35, 0xe2}
+ };
+ for (int i = 0; i < 6; i++) {
+ secp256k1_hmac_sha256_t hasher;
+ secp256k1_hmac_sha256_initialize(&hasher, (const unsigned char*)(keys[i]), strlen(keys[i]));
+ secp256k1_hmac_sha256_write(&hasher, (const unsigned char*)(inputs[i]), strlen(inputs[i]));
+ unsigned char out[32];
+ secp256k1_hmac_sha256_finalize(&hasher, out);
+ CHECK(memcmp(out, outputs[i], 32) == 0);
+ if (strlen(inputs[i]) > 0) {
+ secp256k1_hmac_sha256_initialize(&hasher, (const unsigned char*)(keys[i]), strlen(keys[i]));
+ int split = secp256k1_rand32() % strlen(inputs[i]);
+ secp256k1_hmac_sha256_write(&hasher, (const unsigned char*)(inputs[i]), split);
+ secp256k1_hmac_sha256_write(&hasher, (const unsigned char*)(inputs[i] + split), strlen(inputs[i]) - split);
+ secp256k1_hmac_sha256_finalize(&hasher, out);
+ CHECK(memcmp(out, outputs[i], 32) == 0);
+ }
+ }
+}
+
+void run_rfc6979_hmac_sha256_tests(void) {
+ static const unsigned char key1[32] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x00};
+ static const unsigned char msg1[32] = {0x4b, 0xf5, 0x12, 0x2f, 0x34, 0x45, 0x54, 0xc5, 0x3b, 0xde, 0x2e, 0xbb, 0x8c, 0xd2, 0xb7, 0xe3, 0xd1, 0x60, 0x0a, 0xd6, 0x31, 0xc3, 0x85, 0xa5, 0xd7, 0xcc, 0xe2, 0x3c, 0x77, 0x85, 0x45, 0x9a};
+ static const unsigned char out1[3][32] = {
+ {0x4f, 0xe2, 0x95, 0x25, 0xb2, 0x08, 0x68, 0x09, 0x15, 0x9a, 0xcd, 0xf0, 0x50, 0x6e, 0xfb, 0x86, 0xb0, 0xec, 0x93, 0x2c, 0x7b, 0xa4, 0x42, 0x56, 0xab, 0x32, 0x1e, 0x42, 0x1e, 0x67, 0xe9, 0xfb},
+ {0x2b, 0xf0, 0xff, 0xf1, 0xd3, 0xc3, 0x78, 0xa2, 0x2d, 0xc5, 0xde, 0x1d, 0x85, 0x65, 0x22, 0x32, 0x5c, 0x65, 0xb5, 0x04, 0x49, 0x1a, 0x0c, 0xbd, 0x01, 0xcb, 0x8f, 0x3a, 0xa6, 0x7f, 0xfd, 0x4a},
+ {0xf5, 0x28, 0xb4, 0x10, 0xcb, 0x54, 0x1f, 0x77, 0x00, 0x0d, 0x7a, 0xfb, 0x6c, 0x5b, 0x53, 0xc5, 0xc4, 0x71, 0xea, 0xb4, 0x3e, 0x46, 0x6d, 0x9a, 0xc5, 0x19, 0x0c, 0x39, 0xc8, 0x2f, 0xd8, 0x2e}
+ };
+
+ static const unsigned char key2[32] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+ static const unsigned char msg2[32] = {0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55};
+ static const unsigned char out2[3][32] = {
+ {0x9c, 0x23, 0x6c, 0x16, 0x5b, 0x82, 0xae, 0x0c, 0xd5, 0x90, 0x65, 0x9e, 0x10, 0x0b, 0x6b, 0xab, 0x30, 0x36, 0xe7, 0xba, 0x8b, 0x06, 0x74, 0x9b, 0xaf, 0x69, 0x81, 0xe1, 0x6f, 0x1a, 0x2b, 0x95},
+ {0xdf, 0x47, 0x10, 0x61, 0x62, 0x5b, 0xc0, 0xea, 0x14, 0xb6, 0x82, 0xfe, 0xee, 0x2c, 0x9c, 0x02, 0xf2, 0x35, 0xda, 0x04, 0x20, 0x4c, 0x1d, 0x62, 0xa1, 0x53, 0x6c, 0x6e, 0x17, 0xae, 0xd7, 0xa9},
+ {0x75, 0x97, 0x88, 0x7c, 0xbd, 0x76, 0x32, 0x1f, 0x32, 0xe3, 0x04, 0x40, 0x67, 0x9a, 0x22, 0xcf, 0x7f, 0x8d, 0x9d, 0x2e, 0xac, 0x39, 0x0e, 0x58, 0x1f, 0xea, 0x09, 0x1c, 0xe2, 0x02, 0xba, 0x94}
+ };
+
+ secp256k1_rfc6979_hmac_sha256_t rng;
+ unsigned char out[32];
+
+ secp256k1_rfc6979_hmac_sha256_initialize(&rng, key1, 32, msg1, 32);
+ for (int i = 0; i < 3; i++) {
+ secp256k1_rfc6979_hmac_sha256_generate(&rng, out, 32);
+ CHECK(memcmp(out, out1[i], 32) == 0);
+ }
+ secp256k1_rfc6979_hmac_sha256_finalize(&rng);
+
+ secp256k1_rfc6979_hmac_sha256_initialize(&rng, key2, 32, msg2, 32);
+ for (int i = 0; i < 3; i++) {
+ secp256k1_rfc6979_hmac_sha256_generate(&rng, out, 32);
+ CHECK(memcmp(out, out2[i], 32) == 0);
+ }
+ secp256k1_rfc6979_hmac_sha256_finalize(&rng);
+}
+
/***** NUM TESTS *****/
#ifndef USE_NUM_NONE
@@ -494,9 +616,9 @@ void random_fe_non_square(secp256k1_fe_t *ns) {
}
int check_fe_equal(const secp256k1_fe_t *a, const secp256k1_fe_t *b) {
- secp256k1_fe_t an = *a; secp256k1_fe_normalize(&an);
+ secp256k1_fe_t an = *a; secp256k1_fe_normalize_weak(&an);
secp256k1_fe_t bn = *b; secp256k1_fe_normalize_var(&bn);
- return secp256k1_fe_equal(&an, &bn);
+ return secp256k1_fe_equal_var(&an, &bn);
}
int check_fe_inverse(const secp256k1_fe_t *a, const secp256k1_fe_t *ai) {
@@ -523,16 +645,16 @@ void run_field_misc(void) {
random_fe_non_zero(&y);
/* Test the fe equality and comparison operations. */
CHECK(secp256k1_fe_cmp_var(&x, &x) == 0);
- CHECK(secp256k1_fe_equal(&x, &x));
+ CHECK(secp256k1_fe_equal_var(&x, &x));
z = x;
secp256k1_fe_add(&z,&y);
secp256k1_fe_normalize(&z);
/* Test the conditional move. */
secp256k1_fe_cmov(&z, &x, 0);
- CHECK(secp256k1_fe_equal(&x, &z) == 0);
+ CHECK(secp256k1_fe_equal_var(&x, &z) == 0);
CHECK(secp256k1_fe_cmp_var(&x, &z) != 0);
secp256k1_fe_cmov(&y, &x, 1);
- CHECK(secp256k1_fe_equal(&x, &y));
+ CHECK(secp256k1_fe_equal_var(&x, &y));
/* Test that mul_int, mul, and add agree. */
secp256k1_fe_add(&y, &x);
secp256k1_fe_add(&y, &x);
@@ -656,108 +778,148 @@ void run_sqrt(void) {
/***** GROUP TESTS *****/
-int ge_equals_ge(const secp256k1_ge_t *a, const secp256k1_ge_t *b) {
- if (a->infinity && b->infinity)
- return 1;
- return check_fe_equal(&a->x, &b->x) && check_fe_equal(&a->y, &b->y);
+void ge_equals_ge(const secp256k1_ge_t *a, const secp256k1_ge_t *b) {
+ CHECK(a->infinity == b->infinity);
+ if (a->infinity)
+ return;
+ CHECK(secp256k1_fe_equal_var(&a->x, &b->x));
+ CHECK(secp256k1_fe_equal_var(&b->y, &b->y));
}
void ge_equals_gej(const secp256k1_ge_t *a, const secp256k1_gej_t *b) {
- secp256k1_ge_t bb;
- secp256k1_gej_t bj = *b;
- secp256k1_ge_set_gej_var(&bb, &bj);
- CHECK(ge_equals_ge(a, &bb));
-}
-
-void gej_equals_gej(const secp256k1_gej_t *a, const secp256k1_gej_t *b) {
- secp256k1_ge_t aa, bb;
- secp256k1_gej_t aj = *a, bj = *b;
- secp256k1_ge_set_gej_var(&aa, &aj);
- secp256k1_ge_set_gej_var(&bb, &bj);
- CHECK(ge_equals_ge(&aa, &bb));
+ CHECK(a->infinity == b->infinity);
+ if (a->infinity)
+ return;
+ /* Check a.x * b.z^2 == b.x && a.y * b.z^3 == b.y, to avoid inverses. */
+ secp256k1_fe_t z2s;
+ secp256k1_fe_sqr(&z2s, &b->z);
+ secp256k1_fe_t u1, u2, s1, s2;
+ secp256k1_fe_mul(&u1, &a->x, &z2s);
+ u2 = b->x; secp256k1_fe_normalize_weak(&u2);
+ secp256k1_fe_mul(&s1, &a->y, &z2s); secp256k1_fe_mul(&s1, &s1, &b->z);
+ s2 = b->y; secp256k1_fe_normalize_weak(&s2);
+ CHECK(secp256k1_fe_equal_var(&u1, &u2));
+ CHECK(secp256k1_fe_equal_var(&s1, &s2));
}
void test_ge(void) {
- char ca[135];
- char cb[68];
- int rlen;
- secp256k1_ge_t a, b, i, n;
- random_group_element_test(&a);
- random_group_element_test(&b);
- rlen = sizeof(ca);
- secp256k1_ge_get_hex(ca,&rlen,&a);
- CHECK(rlen > 4 && rlen <= (int)sizeof(ca));
- rlen = sizeof(cb);
- secp256k1_ge_get_hex(cb,&rlen,&b); /* Intentionally undersized buffer. */
- n = a;
- secp256k1_fe_normalize(&a.y);
- secp256k1_fe_negate(&n.y, &a.y, 1);
- secp256k1_ge_set_infinity(&i);
- random_field_element_magnitude(&a.x);
- random_field_element_magnitude(&a.y);
- random_field_element_magnitude(&b.x);
- random_field_element_magnitude(&b.y);
- random_field_element_magnitude(&n.x);
- random_field_element_magnitude(&n.y);
-
- secp256k1_gej_t aj, bj, ij, nj;
- random_group_element_jacobian_test(&aj, &a);
- random_group_element_jacobian_test(&bj, &b);
- secp256k1_gej_set_infinity(&ij);
- random_group_element_jacobian_test(&nj, &n);
- random_field_element_magnitude(&aj.x);
- random_field_element_magnitude(&aj.y);
- random_field_element_magnitude(&aj.z);
- random_field_element_magnitude(&bj.x);
- random_field_element_magnitude(&bj.y);
- random_field_element_magnitude(&bj.z);
- random_field_element_magnitude(&nj.x);
- random_field_element_magnitude(&nj.y);
- random_field_element_magnitude(&nj.z);
-
- /* gej + gej adds */
- secp256k1_gej_t aaj; secp256k1_gej_add_var(&aaj, &aj, &aj);
- secp256k1_gej_t abj; secp256k1_gej_add_var(&abj, &aj, &bj);
- secp256k1_gej_t aij; secp256k1_gej_add_var(&aij, &aj, &ij);
- secp256k1_gej_t anj; secp256k1_gej_add_var(&anj, &aj, &nj);
- secp256k1_gej_t iaj; secp256k1_gej_add_var(&iaj, &ij, &aj);
- secp256k1_gej_t iij; secp256k1_gej_add_var(&iij, &ij, &ij);
-
- /* gej + ge adds */
- secp256k1_gej_t aa; secp256k1_gej_add_ge_var(&aa, &aj, &a);
- secp256k1_gej_t ab; secp256k1_gej_add_ge_var(&ab, &aj, &b);
- secp256k1_gej_t ai; secp256k1_gej_add_ge_var(&ai, &aj, &i);
- secp256k1_gej_t an; secp256k1_gej_add_ge_var(&an, &aj, &n);
- secp256k1_gej_t ia; secp256k1_gej_add_ge_var(&ia, &ij, &a);
- secp256k1_gej_t ii; secp256k1_gej_add_ge_var(&ii, &ij, &i);
-
- /* const gej + ge adds */
- secp256k1_gej_t aac; secp256k1_gej_add_ge(&aac, &aj, &a);
- secp256k1_gej_t abc; secp256k1_gej_add_ge(&abc, &aj, &b);
- secp256k1_gej_t anc; secp256k1_gej_add_ge(&anc, &aj, &n);
- secp256k1_gej_t iac; secp256k1_gej_add_ge(&iac, &ij, &a);
-
- CHECK(secp256k1_gej_is_infinity(&an));
- CHECK(secp256k1_gej_is_infinity(&anj));
- CHECK(secp256k1_gej_is_infinity(&anc));
- gej_equals_gej(&aa, &aaj);
- gej_equals_gej(&aa, &aac);
- gej_equals_gej(&ab, &abj);
- gej_equals_gej(&ab, &abc);
- gej_equals_gej(&an, &anj);
- gej_equals_gej(&an, &anc);
- gej_equals_gej(&ia, &iaj);
- gej_equals_gej(&ai, &aij);
- gej_equals_gej(&ii, &iij);
- ge_equals_gej(&a, &ai);
- ge_equals_gej(&a, &ai);
- ge_equals_gej(&a, &iaj);
- ge_equals_gej(&a, &iaj);
- ge_equals_gej(&a, &iac);
+ int runs = 4;
+ /* Points: (infinity, p1, p1, -p1, -p1, p2, p2, -p2, -p2, p3, p3, -p3, -p3, p4, p4, -p4, -p4).
+ * The second in each pair of identical points uses a random Z coordinate in the Jacobian form.
+ * All magnitudes are randomized.
+ * All 17*17 combinations of points are added to eachother, using all applicable methods.
+ */
+ secp256k1_ge_t *ge = malloc(sizeof(secp256k1_ge_t) * (1 + 4 * runs));
+ secp256k1_gej_t *gej = malloc(sizeof(secp256k1_gej_t) * (1 + 4 * runs));
+ secp256k1_gej_set_infinity(&gej[0]);
+ secp256k1_ge_clear(&ge[0]);
+ secp256k1_ge_set_gej_var(&ge[0], &gej[0]);
+ for (int i = 0; i < runs; i++) {
+ secp256k1_ge_t g;
+ random_group_element_test(&g);
+ ge[1 + 4 * i] = g;
+ ge[2 + 4 * i] = g;
+ secp256k1_ge_neg(&ge[3 + 4 * i], &g);
+ secp256k1_ge_neg(&ge[4 + 4 * i], &g);
+ secp256k1_gej_set_ge(&gej[1 + 4 * i], &ge[1 + 4 * i]);
+ random_group_element_jacobian_test(&gej[2 + 4 * i], &ge[2 + 4 * i]);
+ secp256k1_gej_set_ge(&gej[3 + 4 * i], &ge[3 + 4 * i]);
+ random_group_element_jacobian_test(&gej[4 + 4 * i], &ge[4 + 4 * i]);
+ for (int j = 0; j < 4; j++) {
+ random_field_element_magnitude(&ge[1 + j + 4 * i].x);
+ random_field_element_magnitude(&ge[1 + j + 4 * i].y);
+ random_field_element_magnitude(&gej[1 + j + 4 * i].x);
+ random_field_element_magnitude(&gej[1 + j + 4 * i].y);
+ random_field_element_magnitude(&gej[1 + j + 4 * i].z);
+ }
+ }
+
+ for (int i1 = 0; i1 < 1 + 4 * runs; i1++) {
+ for (int i2 = 0; i2 < 1 + 4 * runs; i2++) {
+ /* Compute reference result using gej + gej (var). */
+ secp256k1_gej_t refj, resj;
+ secp256k1_ge_t ref;
+ secp256k1_gej_add_var(&refj, &gej[i1], &gej[i2]);
+ secp256k1_ge_set_gej_var(&ref, &refj);
+
+ /* Test gej + ge (var). */
+ secp256k1_gej_add_ge_var(&resj, &gej[i1], &ge[i2]);
+ ge_equals_gej(&ref, &resj);
+
+ /* Test gej + ge (const). */
+ if (i2 != 0) {
+ /* secp256k1_gej_add_ge does not support its second argument being infinity. */
+ secp256k1_gej_add_ge(&resj, &gej[i1], &ge[i2]);
+ ge_equals_gej(&ref, &resj);
+ }
+
+ /* Test doubling (var). */
+ if ((i1 == 0 && i2 == 0) || ((i1 + 3)/4 == (i2 + 3)/4 && ((i1 + 3)%4)/2 == ((i2 + 3)%4)/2)) {
+ /* Normal doubling. */
+ secp256k1_gej_double_var(&resj, &gej[i1]);
+ ge_equals_gej(&ref, &resj);
+ secp256k1_gej_double_var(&resj, &gej[i2]);
+ ge_equals_gej(&ref, &resj);
+ }
+
+ /* Test adding opposites. */
+ if ((i1 == 0 && i2 == 0) || ((i1 + 3)/4 == (i2 + 3)/4 && ((i1 + 3)%4)/2 != ((i2 + 3)%4)/2)) {
+ CHECK(secp256k1_ge_is_infinity(&ref));
+ }
+
+ /* Test adding infinity. */
+ if (i1 == 0) {
+ CHECK(secp256k1_ge_is_infinity(&ge[i1]));
+ CHECK(secp256k1_gej_is_infinity(&gej[i1]));
+ ge_equals_gej(&ref, &gej[i2]);
+ }
+ if (i2 == 0) {
+ CHECK(secp256k1_ge_is_infinity(&ge[i2]));
+ CHECK(secp256k1_gej_is_infinity(&gej[i2]));
+ ge_equals_gej(&ref, &gej[i1]);
+ }
+ }
+ }
+
+ /* Test adding all points together in random order equals infinity. */
+ {
+ secp256k1_gej_t *gej_shuffled = malloc((4 * runs + 1) * sizeof(secp256k1_gej_t));
+ for (int i = 0; i < 4 * runs + 1; i++) {
+ gej_shuffled[i] = gej[i];
+ }
+ for (int i = 0; i < 4 * runs + 1; i++) {
+ int swap = i + secp256k1_rand32() % (4 * runs + 1 - i);
+ if (swap != i) {
+ secp256k1_gej_t t = gej_shuffled[i];
+ gej_shuffled[i] = gej_shuffled[swap];
+ gej_shuffled[swap] = t;
+ }
+ }
+ secp256k1_gej_t sum;
+ secp256k1_gej_set_infinity(&sum);
+ for (int i = 0; i < 4 * runs + 1; i++) {
+ secp256k1_gej_add_var(&sum, &sum, &gej_shuffled[i]);
+ }
+ CHECK(secp256k1_gej_is_infinity(&sum));
+ free(gej_shuffled);
+ }
+
+ /* Test batch gej -> ge conversion. */
+ {
+ secp256k1_ge_t *ge_set_all = malloc((4 * runs + 1) * sizeof(secp256k1_ge_t));
+ secp256k1_ge_set_all_gej_var(4 * runs + 1, ge_set_all, gej);
+ for (int i = 0; i < 4 * runs + 1; i++) {
+ ge_equals_gej(&ge_set_all[i], &gej[i]);
+ }
+ free(ge_set_all);
+ }
+
+ free(ge);
+ free(gej);
}
void run_ge(void) {
- for (int i = 0; i < 2000*count; i++) {
+ for (int i = 0; i < count * 32; i++) {
test_ge();
}
}
@@ -949,6 +1111,44 @@ void run_ecdsa_sign_verify(void) {
}
}
+/** Dummy nonce generation function that just uses a precomputed nonce, and fails if it is not accepted. Use only for testing. */
+static int precomputed_nonce_function(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, unsigned int counter, const void *data) {
+ (void)msg32;
+ (void)key32;
+ memcpy(nonce32, data, 32);
+ return (counter == 0);
+}
+
+static int nonce_function_test_fail(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, unsigned int counter, const void *data) {
+ /* Dummy nonce generator that has a fatal error on the first counter value. */
+ if (counter == 0) return 0;
+ return nonce_function_rfc6979(nonce32, msg32, key32, counter - 1, data);
+}
+
+static int nonce_function_test_retry(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, unsigned int counter, const void *data) {
+ /* Dummy nonce generator that produces unacceptable nonces for the first several counter values. */
+ if (counter < 3) {
+ memset(nonce32, counter==0 ? 0 : 255, 32);
+ if (counter == 2) nonce32[31]--;
+ return 1;
+ }
+ if (counter < 5) {
+ static const unsigned char order[] = {
+ 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
+ };
+ memcpy(nonce32, order, 32);
+ if (counter == 4) nonce32[31]++;
+ return 1;
+ }
+ /* Retry rate of 6979 is negligible esp. as we only call this in determinstic tests. */
+ /* If someone does fine a case where it retries for secp256k1, we'd like to know. */
+ if (counter > 5) return 0;
+ return nonce_function_rfc6979(nonce32, msg32, key32, counter - 5, data);
+}
+
void test_ecdsa_end_to_end(void) {
unsigned char privkey[32];
unsigned char message[32];
@@ -1006,13 +1206,7 @@ void test_ecdsa_end_to_end(void) {
/* Sign. */
unsigned char signature[72]; int signaturelen = 72;
- while(1) {
- unsigned char rnd[32];
- secp256k1_rand256_test(rnd);
- if (secp256k1_ecdsa_sign(message, signature, &signaturelen, privkey, rnd) == 1) {
- break;
- }
- }
+ CHECK(secp256k1_ecdsa_sign(message, signature, &signaturelen, privkey, NULL, NULL) == 1);
/* Verify. */
CHECK(secp256k1_ecdsa_verify(message, signature, signaturelen, pubkey, pubkeylen) == 1);
/* Destroy signature and verify again. */
@@ -1021,13 +1215,7 @@ void test_ecdsa_end_to_end(void) {
/* Compact sign. */
unsigned char csignature[64]; int recid = 0;
- while(1) {
- unsigned char rnd[32];
- secp256k1_rand256_test(rnd);
- if (secp256k1_ecdsa_sign_compact(message, csignature, privkey, rnd, &recid) == 1) {
- break;
- }
- }
+ CHECK(secp256k1_ecdsa_sign_compact(message, csignature, privkey, NULL, NULL, &recid) == 1);
/* Recover. */
unsigned char recpubkey[65]; int recpubkeylen = 0;
CHECK(secp256k1_ecdsa_recover_compact(message, csignature, recpubkey, &recpubkeylen, pubkeylen == 33, recid) == 1);
@@ -1077,7 +1265,7 @@ void test_random_pubkeys(void) {
CHECK(secp256k1_eckey_pubkey_serialize(&elem, in, &size, 0));
CHECK(size == 65);
CHECK(secp256k1_eckey_pubkey_parse(&elem2, in, size));
- CHECK(ge_equals_ge(&elem,&elem2));
+ ge_equals_ge(&elem,&elem2);
/* Check that the X9.62 hybrid type is checked. */
in[0] = (r & 1) ? 6 : 7;
res = secp256k1_eckey_pubkey_parse(&elem2, in, size);
@@ -1086,7 +1274,7 @@ void test_random_pubkeys(void) {
else CHECK(!res);
}
if (res) {
- CHECK(ge_equals_ge(&elem,&elem2));
+ ge_equals_ge(&elem,&elem2);
CHECK(secp256k1_eckey_pubkey_serialize(&elem, out, &size, 0));
CHECK(memcmp(&in[1], &out[1], 64) == 0);
}
@@ -1280,6 +1468,12 @@ void test_ecdsa_edge_cases(void) {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
};
+ static const unsigned char nonce2[32] = {
+ 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
+ };
const unsigned char key[32] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -1294,10 +1488,74 @@ void test_ecdsa_edge_cases(void) {
};
unsigned char sig[72];
int siglen = 72;
- CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, nonce) == 0);
+ CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, precomputed_nonce_function, nonce) == 0);
+ CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, precomputed_nonce_function, nonce2) == 0);
msg[31] = 0xaa;
siglen = 72;
- CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, nonce) == 1);
+ CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, precomputed_nonce_function, nonce) == 1);
+ CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, precomputed_nonce_function, nonce2) == 1);
+ siglen = 10;
+ CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, precomputed_nonce_function, nonce) != 1);
+ }
+
+ /* Nonce function corner cases. */
+ {
+ unsigned char key[32];
+ unsigned char msg[32];
+ unsigned char sig[72];
+ memset(key, 0, 32);
+ memset(msg, 0, 32);
+ key[31] = 1;
+ msg[31] = 1;
+ int siglen = 72;
+ int recid;
+ /* Nonce function failure results in signature failure. */
+ CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, nonce_function_test_fail, NULL) == 0);
+ CHECK(secp256k1_ecdsa_sign_compact(msg, sig, key, nonce_function_test_fail, NULL, &recid) == 0);
+ /* The retry loop successfully makes its way to the first good value. */
+ unsigned char sig2[72];
+ int siglen2 = 72;
+ siglen = 72;
+ CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, nonce_function_test_retry, NULL) == 1);
+ CHECK(secp256k1_ecdsa_sign(msg, sig2, &siglen2, key, nonce_function_rfc6979, NULL) == 1);
+ CHECK((siglen == siglen2) && (memcmp(sig, sig2, siglen) == 0));
+ int recid2;
+ CHECK(secp256k1_ecdsa_sign_compact(msg, sig, key, nonce_function_test_retry, NULL, &recid) == 1);
+ CHECK(secp256k1_ecdsa_sign_compact(msg, sig2, key, nonce_function_rfc6979, NULL, &recid2) == 1);
+ CHECK((recid == recid2) && (memcmp(sig, sig2, 64) == 0));
+ /* The default nonce function is determinstic. */
+ siglen = 72;
+ siglen2 = 72;
+ CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, NULL, NULL) == 1);
+ CHECK(secp256k1_ecdsa_sign(msg, sig2, &siglen2, key, NULL, NULL) == 1);
+ CHECK((siglen == siglen2) && (memcmp(sig, sig2, siglen) == 0));
+ CHECK(secp256k1_ecdsa_sign_compact(msg, sig, key, NULL, NULL, &recid) == 1);
+ CHECK(secp256k1_ecdsa_sign_compact(msg, sig2, key, NULL, NULL, &recid2) == 1);
+ CHECK((recid == recid2) && (memcmp(sig, sig2, 64) == 0));
+ /* The default nonce function changes output with different messages. */
+ secp256k1_ecdsa_sig_t s[512];
+ for(int i=0; i<256; i++) {
+ siglen2 = 72;
+ msg[0] = i;
+ CHECK(secp256k1_ecdsa_sign(msg, sig2, &siglen2, key, NULL, NULL) == 1);
+ CHECK(secp256k1_ecdsa_sig_parse(&s[i], sig2, siglen2));
+ for (int j=0; j<i; j++) {
+ CHECK(!secp256k1_scalar_eq(&s[i].r, &s[j].r));
+ }
+ }
+ msg[0] = 0;
+ msg[31] = 2;
+ /* The default nonce function changes output with different keys. */
+ for(int i=256; i<512; i++) {
+ siglen2 = 72;
+ key[0] = i - 256;
+ CHECK(secp256k1_ecdsa_sign(msg, sig2, &siglen2, key, NULL, NULL) == 1);
+ CHECK(secp256k1_ecdsa_sig_parse(&s[i], sig2, siglen2));
+ for (int j=0; j<i; j++) {
+ CHECK(!secp256k1_scalar_eq(&s[i].r, &s[j].r));
+ }
+ }
+ key[0] = 0;
}
/* Privkey export where pubkey is the point at infinity. */
@@ -1405,6 +1663,10 @@ int main(int argc, char **argv) {
secp256k1_scalar_start();
secp256k1_ecdsa_start();
+ run_sha256_tests();
+ run_hmac_sha256_tests();
+ run_rfc6979_hmac_sha256_tests();
+
#ifndef USE_NUM_NONE
/* num tests */
run_num_smalltests();
diff --git a/src/serialize.h b/src/serialize.h
index e4a4039c71..a62760a793 100644
--- a/src/serialize.h
+++ b/src/serialize.h
@@ -249,7 +249,7 @@ uint64_t ReadCompactSize(Stream& is)
throw std::ios_base::failure("non-canonical ReadCompactSize()");
}
if (nSizeRet > (uint64_t)MAX_SIZE)
- throw std::ios_base::failure("ReadCompactSize() : size too large");
+ throw std::ios_base::failure("ReadCompactSize(): size too large");
return nSizeRet;
}
diff --git a/src/streams.h b/src/streams.h
index 6bd6d2b920..bd8568b1af 100644
--- a/src/streams.h
+++ b/src/streams.h
@@ -224,7 +224,7 @@ public:
{
if (nReadPosNext > vch.size())
{
- throw std::ios_base::failure("CDataStream::read() : end of data");
+ throw std::ios_base::failure("CDataStream::read(): end of data");
}
memcpy(pch, &vch[nReadPos], nSize);
nReadPos = 0;
@@ -244,7 +244,7 @@ public:
if (nReadPosNext >= vch.size())
{
if (nReadPosNext > vch.size())
- throw std::ios_base::failure("CDataStream::ignore() : end of data");
+ throw std::ios_base::failure("CDataStream::ignore(): end of data");
nReadPos = 0;
vch.clear();
return (*this);
@@ -374,18 +374,18 @@ public:
CAutoFile& read(char* pch, size_t nSize)
{
if (!file)
- throw std::ios_base::failure("CAutoFile::read : file handle is NULL");
+ throw std::ios_base::failure("CAutoFile::read: file handle is NULL");
if (fread(pch, 1, nSize, file) != nSize)
- throw std::ios_base::failure(feof(file) ? "CAutoFile::read : end of file" : "CAutoFile::read : fread failed");
+ throw std::ios_base::failure(feof(file) ? "CAutoFile::read: end of file" : "CAutoFile::read: fread failed");
return (*this);
}
CAutoFile& write(const char* pch, size_t nSize)
{
if (!file)
- throw std::ios_base::failure("CAutoFile::write : file handle is NULL");
+ throw std::ios_base::failure("CAutoFile::write: file handle is NULL");
if (fwrite(pch, 1, nSize, file) != nSize)
- throw std::ios_base::failure("CAutoFile::write : write failed");
+ throw std::ios_base::failure("CAutoFile::write: write failed");
return (*this);
}
@@ -401,7 +401,7 @@ public:
{
// Serialize to this stream
if (!file)
- throw std::ios_base::failure("CAutoFile::operator<< : file handle is NULL");
+ throw std::ios_base::failure("CAutoFile::operator<<: file handle is NULL");
::Serialize(*this, obj, nType, nVersion);
return (*this);
}
@@ -411,7 +411,7 @@ public:
{
// Unserialize from this stream
if (!file)
- throw std::ios_base::failure("CAutoFile::operator>> : file handle is NULL");
+ throw std::ios_base::failure("CAutoFile::operator>>: file handle is NULL");
::Unserialize(*this, obj, nType, nVersion);
return (*this);
}
@@ -452,7 +452,7 @@ protected:
return false;
size_t read = fread((void*)&vchBuf[pos], 1, readNow, src);
if (read == 0) {
- throw std::ios_base::failure(feof(src) ? "CBufferedFile::Fill : end of file" : "CBufferedFile::Fill : fread failed");
+ throw std::ios_base::failure(feof(src) ? "CBufferedFile::Fill: end of file" : "CBufferedFile::Fill: fread failed");
} else {
nSrcPos += read;
return true;
diff --git a/src/sync.h b/src/sync.h
index 7891e41560..27e80e813b 100644
--- a/src/sync.h
+++ b/src/sync.h
@@ -142,6 +142,17 @@ public:
Enter(pszName, pszFile, nLine);
}
+ CMutexLock(Mutex* pmutexIn, const char* pszName, const char* pszFile, int nLine, bool fTry = false)
+ {
+ if (!pmutexIn) return;
+
+ lock = boost::unique_lock<Mutex>(*pmutexIn, boost::defer_lock);
+ if (fTry)
+ TryEnter(pszName, pszFile, nLine);
+ else
+ Enter(pszName, pszFile, nLine);
+ }
+
~CMutexLock()
{
if (lock.owns_lock())
diff --git a/src/test/Checkpoints_tests.cpp b/src/test/Checkpoints_tests.cpp
index 4ea6a91d54..a9b6cd44a8 100644
--- a/src/test/Checkpoints_tests.cpp
+++ b/src/test/Checkpoints_tests.cpp
@@ -18,8 +18,8 @@ BOOST_AUTO_TEST_SUITE(Checkpoints_tests)
BOOST_AUTO_TEST_CASE(sanity)
{
- uint256 p11111 = uint256("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d");
- uint256 p134444 = uint256("0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe");
+ uint256 p11111 = uint256S("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d");
+ uint256 p134444 = uint256S("0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe");
BOOST_CHECK(Checkpoints::CheckBlock(11111, p11111));
BOOST_CHECK(Checkpoints::CheckBlock(134444, p134444));
diff --git a/src/test/accounting_tests.cpp b/src/test/accounting_tests.cpp
index bed63991e6..da07b8c7a6 100644
--- a/src/test/accounting_tests.cpp
+++ b/src/test/accounting_tests.cpp
@@ -46,7 +46,7 @@ BOOST_AUTO_TEST_CASE(acc_orderupgrade)
walletdb.WriteAccountingEntry(ae);
wtx.mapValue["comment"] = "z";
- pwalletMain->AddToWallet(wtx);
+ pwalletMain->AddToWallet(wtx, false, &walletdb);
vpwtx.push_back(&pwalletMain->mapWallet[wtx.GetHash()]);
vpwtx[0]->nTimeReceived = (unsigned int)1333333335;
vpwtx[0]->nOrderPos = -1;
@@ -88,7 +88,7 @@ BOOST_AUTO_TEST_CASE(acc_orderupgrade)
--tx.nLockTime; // Just to change the hash :)
*static_cast<CTransaction*>(&wtx) = CTransaction(tx);
}
- pwalletMain->AddToWallet(wtx);
+ pwalletMain->AddToWallet(wtx, false, &walletdb);
vpwtx.push_back(&pwalletMain->mapWallet[wtx.GetHash()]);
vpwtx[1]->nTimeReceived = (unsigned int)1333333336;
@@ -98,7 +98,7 @@ BOOST_AUTO_TEST_CASE(acc_orderupgrade)
--tx.nLockTime; // Just to change the hash :)
*static_cast<CTransaction*>(&wtx) = CTransaction(tx);
}
- pwalletMain->AddToWallet(wtx);
+ pwalletMain->AddToWallet(wtx, false, &walletdb);
vpwtx.push_back(&pwalletMain->mapWallet[wtx.GetHash()]);
vpwtx[2]->nTimeReceived = (unsigned int)1333333329;
vpwtx[2]->nOrderPos = -1;
diff --git a/src/test/arith_uint256_tests.cpp b/src/test/arith_uint256_tests.cpp
new file mode 100644
index 0000000000..565b02ae64
--- /dev/null
+++ b/src/test/arith_uint256_tests.cpp
@@ -0,0 +1,566 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include <boost/test/unit_test.hpp>
+#include <stdint.h>
+#include <sstream>
+#include <iomanip>
+#include <limits>
+#include <cmath>
+#include "uint256.h"
+#include "arith_uint256.h"
+#include <string>
+#include "version.h"
+
+BOOST_AUTO_TEST_SUITE(arith_uint256_tests)
+
+/// Convert vector to arith_uint256, via uint256 blob
+inline arith_uint256 arith_uint256V(const std::vector<unsigned char>& vch)
+{
+ return UintToArith256(uint256(vch));
+}
+
+const unsigned char R1Array[] =
+ "\x9c\x52\x4a\xdb\xcf\x56\x11\x12\x2b\x29\x12\x5e\x5d\x35\xd2\xd2"
+ "\x22\x81\xaa\xb5\x33\xf0\x08\x32\xd5\x56\xb1\xf9\xea\xe5\x1d\x7d";
+const char R1ArrayHex[] = "7D1DE5EAF9B156D53208F033B5AA8122D2d2355d5e12292b121156cfdb4a529c";
+const double R1Ldouble = 0.4887374590559308955; // R1L equals roughly R1Ldouble * 2^256
+const arith_uint256 R1L = arith_uint256V(std::vector<unsigned char>(R1Array,R1Array+32));
+const uint64_t R1LLow64 = 0x121156cfdb4a529cULL;
+
+const unsigned char R2Array[] =
+ "\x70\x32\x1d\x7c\x47\xa5\x6b\x40\x26\x7e\x0a\xc3\xa6\x9c\xb6\xbf"
+ "\x13\x30\x47\xa3\x19\x2d\xda\x71\x49\x13\x72\xf0\xb4\xca\x81\xd7";
+const arith_uint256 R2L = arith_uint256V(std::vector<unsigned char>(R2Array,R2Array+32));
+
+const char R1LplusR2L[] = "549FB09FEA236A1EA3E31D4D58F1B1369288D204211CA751527CFC175767850C";
+
+const unsigned char ZeroArray[] =
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
+const arith_uint256 ZeroL = arith_uint256V(std::vector<unsigned char>(ZeroArray,ZeroArray+32));
+
+const unsigned char OneArray[] =
+ "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
+const arith_uint256 OneL = arith_uint256V(std::vector<unsigned char>(OneArray,OneArray+32));
+
+const unsigned char MaxArray[] =
+ "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
+ "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff";
+const arith_uint256 MaxL = arith_uint256V(std::vector<unsigned char>(MaxArray,MaxArray+32));
+
+const arith_uint256 HalfL = (OneL << 255);
+std::string ArrayToString(const unsigned char A[], unsigned int width)
+{
+ std::stringstream Stream;
+ Stream << std::hex;
+ for (unsigned int i = 0; i < width; ++i)
+ {
+ Stream<<std::setw(2)<<std::setfill('0')<<(unsigned int)A[width-i-1];
+ }
+ return Stream.str();
+}
+
+BOOST_AUTO_TEST_CASE( basics ) // constructors, equality, inequality
+{
+ BOOST_CHECK(1 == 0+1);
+ // constructor arith_uint256(vector<char>):
+ BOOST_CHECK(R1L.ToString() == ArrayToString(R1Array,32));
+ BOOST_CHECK(R2L.ToString() == ArrayToString(R2Array,32));
+ BOOST_CHECK(ZeroL.ToString() == ArrayToString(ZeroArray,32));
+ BOOST_CHECK(OneL.ToString() == ArrayToString(OneArray,32));
+ BOOST_CHECK(MaxL.ToString() == ArrayToString(MaxArray,32));
+ BOOST_CHECK(OneL.ToString() != ArrayToString(ZeroArray,32));
+
+ // == and !=
+ BOOST_CHECK(R1L != R2L);
+ BOOST_CHECK(ZeroL != OneL);
+ BOOST_CHECK(OneL != ZeroL);
+ BOOST_CHECK(MaxL != ZeroL);
+ BOOST_CHECK(~MaxL == ZeroL);
+ BOOST_CHECK( ((R1L ^ R2L) ^ R1L) == R2L);
+
+ uint64_t Tmp64 = 0xc4dab720d9c7acaaULL;
+ for (unsigned int i = 0; i < 256; ++i)
+ {
+ BOOST_CHECK(ZeroL != (OneL << i));
+ BOOST_CHECK((OneL << i) != ZeroL);
+ BOOST_CHECK(R1L != (R1L ^ (OneL << i)));
+ BOOST_CHECK(((arith_uint256(Tmp64) ^ (OneL << i) ) != Tmp64 ));
+ }
+ BOOST_CHECK(ZeroL == (OneL << 256));
+
+ // String Constructor and Copy Constructor
+ BOOST_CHECK(arith_uint256("0x"+R1L.ToString()) == R1L);
+ BOOST_CHECK(arith_uint256("0x"+R2L.ToString()) == R2L);
+ BOOST_CHECK(arith_uint256("0x"+ZeroL.ToString()) == ZeroL);
+ BOOST_CHECK(arith_uint256("0x"+OneL.ToString()) == OneL);
+ BOOST_CHECK(arith_uint256("0x"+MaxL.ToString()) == MaxL);
+ BOOST_CHECK(arith_uint256(R1L.ToString()) == R1L);
+ BOOST_CHECK(arith_uint256(" 0x"+R1L.ToString()+" ") == R1L);
+ BOOST_CHECK(arith_uint256("") == ZeroL);
+ BOOST_CHECK(R1L == arith_uint256(R1ArrayHex));
+ BOOST_CHECK(arith_uint256(R1L) == R1L);
+ BOOST_CHECK((arith_uint256(R1L^R2L)^R2L) == R1L);
+ BOOST_CHECK(arith_uint256(ZeroL) == ZeroL);
+ BOOST_CHECK(arith_uint256(OneL) == OneL);
+
+ // uint64_t constructor
+ BOOST_CHECK( (R1L & arith_uint256("0xffffffffffffffff")) == arith_uint256(R1LLow64));
+ BOOST_CHECK(ZeroL == arith_uint256(0));
+ BOOST_CHECK(OneL == arith_uint256(1));
+ BOOST_CHECK(arith_uint256("0xffffffffffffffff") = arith_uint256(0xffffffffffffffffULL));
+
+ // Assignment (from base_uint)
+ arith_uint256 tmpL = ~ZeroL; BOOST_CHECK(tmpL == ~ZeroL);
+ tmpL = ~OneL; BOOST_CHECK(tmpL == ~OneL);
+ tmpL = ~R1L; BOOST_CHECK(tmpL == ~R1L);
+ tmpL = ~R2L; BOOST_CHECK(tmpL == ~R2L);
+ tmpL = ~MaxL; BOOST_CHECK(tmpL == ~MaxL);
+}
+
+void shiftArrayRight(unsigned char* to, const unsigned char* from, unsigned int arrayLength, unsigned int bitsToShift)
+{
+ for (unsigned int T=0; T < arrayLength; ++T)
+ {
+ unsigned int F = (T+bitsToShift/8);
+ if (F < arrayLength)
+ to[T] = from[F] >> (bitsToShift%8);
+ else
+ to[T] = 0;
+ if (F + 1 < arrayLength)
+ to[T] |= from[(F+1)] << (8-bitsToShift%8);
+ }
+}
+
+void shiftArrayLeft(unsigned char* to, const unsigned char* from, unsigned int arrayLength, unsigned int bitsToShift)
+{
+ for (unsigned int T=0; T < arrayLength; ++T)
+ {
+ if (T >= bitsToShift/8)
+ {
+ unsigned int F = T-bitsToShift/8;
+ to[T] = from[F] << (bitsToShift%8);
+ if (T >= bitsToShift/8+1)
+ to[T] |= from[F-1] >> (8-bitsToShift%8);
+ }
+ else {
+ to[T] = 0;
+ }
+ }
+}
+
+BOOST_AUTO_TEST_CASE( shifts ) { // "<<" ">>" "<<=" ">>="
+ unsigned char TmpArray[32];
+ arith_uint256 TmpL;
+ for (unsigned int i = 0; i < 256; ++i)
+ {
+ shiftArrayLeft(TmpArray, OneArray, 32, i);
+ BOOST_CHECK(arith_uint256V(std::vector<unsigned char>(TmpArray,TmpArray+32)) == (OneL << i));
+ TmpL = OneL; TmpL <<= i;
+ BOOST_CHECK(TmpL == (OneL << i));
+ BOOST_CHECK((HalfL >> (255-i)) == (OneL << i));
+ TmpL = HalfL; TmpL >>= (255-i);
+ BOOST_CHECK(TmpL == (OneL << i));
+
+ shiftArrayLeft(TmpArray, R1Array, 32, i);
+ BOOST_CHECK(arith_uint256V(std::vector<unsigned char>(TmpArray,TmpArray+32)) == (R1L << i));
+ TmpL = R1L; TmpL <<= i;
+ BOOST_CHECK(TmpL == (R1L << i));
+
+ shiftArrayRight(TmpArray, R1Array, 32, i);
+ BOOST_CHECK(arith_uint256V(std::vector<unsigned char>(TmpArray,TmpArray+32)) == (R1L >> i));
+ TmpL = R1L; TmpL >>= i;
+ BOOST_CHECK(TmpL == (R1L >> i));
+
+ shiftArrayLeft(TmpArray, MaxArray, 32, i);
+ BOOST_CHECK(arith_uint256V(std::vector<unsigned char>(TmpArray,TmpArray+32)) == (MaxL << i));
+ TmpL = MaxL; TmpL <<= i;
+ BOOST_CHECK(TmpL == (MaxL << i));
+
+ shiftArrayRight(TmpArray, MaxArray, 32, i);
+ BOOST_CHECK(arith_uint256V(std::vector<unsigned char>(TmpArray,TmpArray+32)) == (MaxL >> i));
+ TmpL = MaxL; TmpL >>= i;
+ BOOST_CHECK(TmpL == (MaxL >> i));
+ }
+ arith_uint256 c1L = arith_uint256(0x0123456789abcdefULL);
+ arith_uint256 c2L = c1L << 128;
+ for (unsigned int i = 0; i < 128; ++i) {
+ BOOST_CHECK((c1L << i) == (c2L >> (128-i)));
+ }
+ for (unsigned int i = 128; i < 256; ++i) {
+ BOOST_CHECK((c1L << i) == (c2L << (i-128)));
+ }
+}
+
+BOOST_AUTO_TEST_CASE( unaryOperators ) // ! ~ -
+{
+ BOOST_CHECK(!ZeroL);
+ BOOST_CHECK(!(!OneL));
+ for (unsigned int i = 0; i < 256; ++i)
+ BOOST_CHECK(!(!(OneL<<i)));
+ BOOST_CHECK(!(!R1L));
+ BOOST_CHECK(!(!MaxL));
+
+ BOOST_CHECK(~ZeroL == MaxL);
+
+ unsigned char TmpArray[32];
+ for (unsigned int i = 0; i < 32; ++i) { TmpArray[i] = ~R1Array[i]; }
+ BOOST_CHECK(arith_uint256V(std::vector<unsigned char>(TmpArray,TmpArray+32)) == (~R1L));
+
+ BOOST_CHECK(-ZeroL == ZeroL);
+ BOOST_CHECK(-R1L == (~R1L)+1);
+ for (unsigned int i = 0; i < 256; ++i)
+ BOOST_CHECK(-(OneL<<i) == (MaxL << i));
+}
+
+
+// Check if doing _A_ _OP_ _B_ results in the same as applying _OP_ onto each
+// element of Aarray and Barray, and then converting the result into a arith_uint256.
+#define CHECKBITWISEOPERATOR(_A_,_B_,_OP_) \
+ for (unsigned int i = 0; i < 32; ++i) { TmpArray[i] = _A_##Array[i] _OP_ _B_##Array[i]; } \
+ BOOST_CHECK(arith_uint256V(std::vector<unsigned char>(TmpArray,TmpArray+32)) == (_A_##L _OP_ _B_##L));
+
+#define CHECKASSIGNMENTOPERATOR(_A_,_B_,_OP_) \
+ TmpL = _A_##L; TmpL _OP_##= _B_##L; BOOST_CHECK(TmpL == (_A_##L _OP_ _B_##L));
+
+BOOST_AUTO_TEST_CASE( bitwiseOperators )
+{
+ unsigned char TmpArray[32];
+
+ CHECKBITWISEOPERATOR(R1,R2,|)
+ CHECKBITWISEOPERATOR(R1,R2,^)
+ CHECKBITWISEOPERATOR(R1,R2,&)
+ CHECKBITWISEOPERATOR(R1,Zero,|)
+ CHECKBITWISEOPERATOR(R1,Zero,^)
+ CHECKBITWISEOPERATOR(R1,Zero,&)
+ CHECKBITWISEOPERATOR(R1,Max,|)
+ CHECKBITWISEOPERATOR(R1,Max,^)
+ CHECKBITWISEOPERATOR(R1,Max,&)
+ CHECKBITWISEOPERATOR(Zero,R1,|)
+ CHECKBITWISEOPERATOR(Zero,R1,^)
+ CHECKBITWISEOPERATOR(Zero,R1,&)
+ CHECKBITWISEOPERATOR(Max,R1,|)
+ CHECKBITWISEOPERATOR(Max,R1,^)
+ CHECKBITWISEOPERATOR(Max,R1,&)
+
+ arith_uint256 TmpL;
+ CHECKASSIGNMENTOPERATOR(R1,R2,|)
+ CHECKASSIGNMENTOPERATOR(R1,R2,^)
+ CHECKASSIGNMENTOPERATOR(R1,R2,&)
+ CHECKASSIGNMENTOPERATOR(R1,Zero,|)
+ CHECKASSIGNMENTOPERATOR(R1,Zero,^)
+ CHECKASSIGNMENTOPERATOR(R1,Zero,&)
+ CHECKASSIGNMENTOPERATOR(R1,Max,|)
+ CHECKASSIGNMENTOPERATOR(R1,Max,^)
+ CHECKASSIGNMENTOPERATOR(R1,Max,&)
+ CHECKASSIGNMENTOPERATOR(Zero,R1,|)
+ CHECKASSIGNMENTOPERATOR(Zero,R1,^)
+ CHECKASSIGNMENTOPERATOR(Zero,R1,&)
+ CHECKASSIGNMENTOPERATOR(Max,R1,|)
+ CHECKASSIGNMENTOPERATOR(Max,R1,^)
+ CHECKASSIGNMENTOPERATOR(Max,R1,&)
+
+ uint64_t Tmp64 = 0xe1db685c9a0b47a2ULL;
+ TmpL = R1L; TmpL |= Tmp64; BOOST_CHECK(TmpL == (R1L | arith_uint256(Tmp64)));
+ TmpL = R1L; TmpL |= 0; BOOST_CHECK(TmpL == R1L);
+ TmpL ^= 0; BOOST_CHECK(TmpL == R1L);
+ TmpL ^= Tmp64; BOOST_CHECK(TmpL == (R1L ^ arith_uint256(Tmp64)));
+}
+
+BOOST_AUTO_TEST_CASE( comparison ) // <= >= < >
+{
+ arith_uint256 TmpL;
+ for (unsigned int i = 0; i < 256; ++i) {
+ TmpL= OneL<< i;
+ BOOST_CHECK( TmpL >= ZeroL && TmpL > ZeroL && ZeroL < TmpL && ZeroL <= TmpL);
+ BOOST_CHECK( TmpL >= 0 && TmpL > 0 && 0 < TmpL && 0 <= TmpL);
+ TmpL |= R1L;
+ BOOST_CHECK( TmpL >= R1L ); BOOST_CHECK( (TmpL == R1L) != (TmpL > R1L)); BOOST_CHECK( (TmpL == R1L) || !( TmpL <= R1L));
+ BOOST_CHECK( R1L <= TmpL ); BOOST_CHECK( (R1L == TmpL) != (R1L < TmpL)); BOOST_CHECK( (TmpL == R1L) || !( R1L >= TmpL));
+ BOOST_CHECK(! (TmpL < R1L)); BOOST_CHECK(! (R1L > TmpL));
+ }
+}
+
+BOOST_AUTO_TEST_CASE( plusMinus )
+{
+ arith_uint256 TmpL = 0;
+ BOOST_CHECK(R1L+R2L == arith_uint256(R1LplusR2L));
+ TmpL += R1L;
+ BOOST_CHECK(TmpL == R1L);
+ TmpL += R2L;
+ BOOST_CHECK(TmpL == R1L + R2L);
+ BOOST_CHECK(OneL+MaxL == ZeroL);
+ BOOST_CHECK(MaxL+OneL == ZeroL);
+ for (unsigned int i = 1; i < 256; ++i) {
+ BOOST_CHECK( (MaxL >> i) + OneL == (HalfL >> (i-1)) );
+ BOOST_CHECK( OneL + (MaxL >> i) == (HalfL >> (i-1)) );
+ TmpL = (MaxL>>i); TmpL += OneL;
+ BOOST_CHECK( TmpL == (HalfL >> (i-1)) );
+ TmpL = (MaxL>>i); TmpL += 1;
+ BOOST_CHECK( TmpL == (HalfL >> (i-1)) );
+ TmpL = (MaxL>>i);
+ BOOST_CHECK( TmpL++ == (MaxL>>i) );
+ BOOST_CHECK( TmpL == (HalfL >> (i-1)));
+ }
+ BOOST_CHECK(arith_uint256(0xbedc77e27940a7ULL) + 0xee8d836fce66fbULL == arith_uint256(0xbedc77e27940a7ULL + 0xee8d836fce66fbULL));
+ TmpL = arith_uint256(0xbedc77e27940a7ULL); TmpL += 0xee8d836fce66fbULL;
+ BOOST_CHECK(TmpL == arith_uint256(0xbedc77e27940a7ULL+0xee8d836fce66fbULL));
+ TmpL -= 0xee8d836fce66fbULL; BOOST_CHECK(TmpL == 0xbedc77e27940a7ULL);
+ TmpL = R1L;
+ BOOST_CHECK(++TmpL == R1L+1);
+
+ BOOST_CHECK(R1L -(-R2L) == R1L+R2L);
+ BOOST_CHECK(R1L -(-OneL) == R1L+OneL);
+ BOOST_CHECK(R1L - OneL == R1L+(-OneL));
+ for (unsigned int i = 1; i < 256; ++i) {
+ BOOST_CHECK((MaxL>>i) - (-OneL) == (HalfL >> (i-1)));
+ BOOST_CHECK((HalfL >> (i-1)) - OneL == (MaxL>>i));
+ TmpL = (HalfL >> (i-1));
+ BOOST_CHECK(TmpL-- == (HalfL >> (i-1)));
+ BOOST_CHECK(TmpL == (MaxL >> i));
+ TmpL = (HalfL >> (i-1));
+ BOOST_CHECK(--TmpL == (MaxL >> i));
+ }
+ TmpL = R1L;
+ BOOST_CHECK(--TmpL == R1L-1);
+}
+
+BOOST_AUTO_TEST_CASE( multiply )
+{
+ BOOST_CHECK((R1L * R1L).ToString() == "62a38c0486f01e45879d7910a7761bf30d5237e9873f9bff3642a732c4d84f10");
+ BOOST_CHECK((R1L * R2L).ToString() == "de37805e9986996cfba76ff6ba51c008df851987d9dd323f0e5de07760529c40");
+ BOOST_CHECK((R1L * ZeroL) == ZeroL);
+ BOOST_CHECK((R1L * OneL) == R1L);
+ BOOST_CHECK((R1L * MaxL) == -R1L);
+ BOOST_CHECK((R2L * R1L) == (R1L * R2L));
+ BOOST_CHECK((R2L * R2L).ToString() == "ac8c010096767d3cae5005dec28bb2b45a1d85ab7996ccd3e102a650f74ff100");
+ BOOST_CHECK((R2L * ZeroL) == ZeroL);
+ BOOST_CHECK((R2L * OneL) == R2L);
+ BOOST_CHECK((R2L * MaxL) == -R2L);
+
+ BOOST_CHECK(MaxL * MaxL == OneL);
+
+ BOOST_CHECK((R1L * 0) == 0);
+ BOOST_CHECK((R1L * 1) == R1L);
+ BOOST_CHECK((R1L * 3).ToString() == "7759b1c0ed14047f961ad09b20ff83687876a0181a367b813634046f91def7d4");
+ BOOST_CHECK((R2L * 0x87654321UL).ToString() == "23f7816e30c4ae2017257b7a0fa64d60402f5234d46e746b61c960d09a26d070");
+}
+
+BOOST_AUTO_TEST_CASE( divide )
+{
+ arith_uint256 D1L("AD7133AC1977FA2B7");
+ arith_uint256 D2L("ECD751716");
+ BOOST_CHECK((R1L / D1L).ToString() == "00000000000000000b8ac01106981635d9ed112290f8895545a7654dde28fb3a");
+ BOOST_CHECK((R1L / D2L).ToString() == "000000000873ce8efec5b67150bad3aa8c5fcb70e947586153bf2cec7c37c57a");
+ BOOST_CHECK(R1L / OneL == R1L);
+ BOOST_CHECK(R1L / MaxL == ZeroL);
+ BOOST_CHECK(MaxL / R1L == 2);
+ BOOST_CHECK_THROW(R1L / ZeroL, uint_error);
+ BOOST_CHECK((R2L / D1L).ToString() == "000000000000000013e1665895a1cc981de6d93670105a6b3ec3b73141b3a3c5");
+ BOOST_CHECK((R2L / D2L).ToString() == "000000000e8f0abe753bb0afe2e9437ee85d280be60882cf0bd1aaf7fa3cc2c4");
+ BOOST_CHECK(R2L / OneL == R2L);
+ BOOST_CHECK(R2L / MaxL == ZeroL);
+ BOOST_CHECK(MaxL / R2L == 1);
+ BOOST_CHECK_THROW(R2L / ZeroL, uint_error);
+}
+
+
+bool almostEqual(double d1, double d2)
+{
+ return fabs(d1-d2) <= 4*fabs(d1)*std::numeric_limits<double>::epsilon();
+}
+
+BOOST_AUTO_TEST_CASE( methods ) // GetHex SetHex size() GetLow64 GetSerializeSize, Serialize, Unserialize
+{
+ BOOST_CHECK(R1L.GetHex() == R1L.ToString());
+ BOOST_CHECK(R2L.GetHex() == R2L.ToString());
+ BOOST_CHECK(OneL.GetHex() == OneL.ToString());
+ BOOST_CHECK(MaxL.GetHex() == MaxL.ToString());
+ arith_uint256 TmpL(R1L);
+ BOOST_CHECK(TmpL == R1L);
+ TmpL.SetHex(R2L.ToString()); BOOST_CHECK(TmpL == R2L);
+ TmpL.SetHex(ZeroL.ToString()); BOOST_CHECK(TmpL == 0);
+ TmpL.SetHex(HalfL.ToString()); BOOST_CHECK(TmpL == HalfL);
+
+ TmpL.SetHex(R1L.ToString());
+ BOOST_CHECK(R1L.size() == 32);
+ BOOST_CHECK(R2L.size() == 32);
+ BOOST_CHECK(ZeroL.size() == 32);
+ BOOST_CHECK(MaxL.size() == 32);
+ BOOST_CHECK(R1L.GetLow64() == R1LLow64);
+ BOOST_CHECK(HalfL.GetLow64() ==0x0000000000000000ULL);
+ BOOST_CHECK(OneL.GetLow64() ==0x0000000000000001ULL);
+
+ for (unsigned int i = 0; i < 255; ++i)
+ {
+ BOOST_CHECK((OneL << i).getdouble() == ldexp(1.0,i));
+ }
+ BOOST_CHECK(ZeroL.getdouble() == 0.0);
+ for (int i = 256; i > 53; --i)
+ BOOST_CHECK(almostEqual((R1L>>(256-i)).getdouble(), ldexp(R1Ldouble,i)));
+ uint64_t R1L64part = (R1L>>192).GetLow64();
+ for (int i = 53; i > 0; --i) // doubles can store all integers in {0,...,2^54-1} exactly
+ {
+ BOOST_CHECK((R1L>>(256-i)).getdouble() == (double)(R1L64part >> (64-i)));
+ }
+}
+
+BOOST_AUTO_TEST_CASE(bignum_SetCompact)
+{
+ arith_uint256 num;
+ bool fNegative;
+ bool fOverflow;
+ num.SetCompact(0, &fNegative, &fOverflow);
+ BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
+ BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
+ BOOST_CHECK_EQUAL(fNegative, false);
+ BOOST_CHECK_EQUAL(fOverflow, false);
+
+ num.SetCompact(0x00123456, &fNegative, &fOverflow);
+ BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
+ BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
+ BOOST_CHECK_EQUAL(fNegative, false);
+ BOOST_CHECK_EQUAL(fOverflow, false);
+
+ num.SetCompact(0x01003456, &fNegative, &fOverflow);
+ BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
+ BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
+ BOOST_CHECK_EQUAL(fNegative, false);
+ BOOST_CHECK_EQUAL(fOverflow, false);
+
+ num.SetCompact(0x02000056, &fNegative, &fOverflow);
+ BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
+ BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
+ BOOST_CHECK_EQUAL(fNegative, false);
+ BOOST_CHECK_EQUAL(fOverflow, false);
+
+ num.SetCompact(0x03000000, &fNegative, &fOverflow);
+ BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
+ BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
+ BOOST_CHECK_EQUAL(fNegative, false);
+ BOOST_CHECK_EQUAL(fOverflow, false);
+
+ num.SetCompact(0x04000000, &fNegative, &fOverflow);
+ BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
+ BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
+ BOOST_CHECK_EQUAL(fNegative, false);
+ BOOST_CHECK_EQUAL(fOverflow, false);
+
+ num.SetCompact(0x00923456, &fNegative, &fOverflow);
+ BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
+ BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
+ BOOST_CHECK_EQUAL(fNegative, false);
+ BOOST_CHECK_EQUAL(fOverflow, false);
+
+ num.SetCompact(0x01803456, &fNegative, &fOverflow);
+ BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
+ BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
+ BOOST_CHECK_EQUAL(fNegative, false);
+ BOOST_CHECK_EQUAL(fOverflow, false);
+
+ num.SetCompact(0x02800056, &fNegative, &fOverflow);
+ BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
+ BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
+ BOOST_CHECK_EQUAL(fNegative, false);
+ BOOST_CHECK_EQUAL(fOverflow, false);
+
+ num.SetCompact(0x03800000, &fNegative, &fOverflow);
+ BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
+ BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
+ BOOST_CHECK_EQUAL(fNegative, false);
+ BOOST_CHECK_EQUAL(fOverflow, false);
+
+ num.SetCompact(0x04800000, &fNegative, &fOverflow);
+ BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
+ BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
+ BOOST_CHECK_EQUAL(fNegative, false);
+ BOOST_CHECK_EQUAL(fOverflow, false);
+
+ num.SetCompact(0x01123456, &fNegative, &fOverflow);
+ BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000012");
+ BOOST_CHECK_EQUAL(num.GetCompact(), 0x01120000U);
+ BOOST_CHECK_EQUAL(fNegative, false);
+ BOOST_CHECK_EQUAL(fOverflow, false);
+
+ // Make sure that we don't generate compacts with the 0x00800000 bit set
+ num = 0x80;
+ BOOST_CHECK_EQUAL(num.GetCompact(), 0x02008000U);
+
+ num.SetCompact(0x01fedcba, &fNegative, &fOverflow);
+ BOOST_CHECK_EQUAL(num.GetHex(), "000000000000000000000000000000000000000000000000000000000000007e");
+ BOOST_CHECK_EQUAL(num.GetCompact(true), 0x01fe0000U);
+ BOOST_CHECK_EQUAL(fNegative, true);
+ BOOST_CHECK_EQUAL(fOverflow, false);
+
+ num.SetCompact(0x02123456, &fNegative, &fOverflow);
+ BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000001234");
+ BOOST_CHECK_EQUAL(num.GetCompact(), 0x02123400U);
+ BOOST_CHECK_EQUAL(fNegative, false);
+ BOOST_CHECK_EQUAL(fOverflow, false);
+
+ num.SetCompact(0x03123456, &fNegative, &fOverflow);
+ BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000123456");
+ BOOST_CHECK_EQUAL(num.GetCompact(), 0x03123456U);
+ BOOST_CHECK_EQUAL(fNegative, false);
+ BOOST_CHECK_EQUAL(fOverflow, false);
+
+ num.SetCompact(0x04123456, &fNegative, &fOverflow);
+ BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000012345600");
+ BOOST_CHECK_EQUAL(num.GetCompact(), 0x04123456U);
+ BOOST_CHECK_EQUAL(fNegative, false);
+ BOOST_CHECK_EQUAL(fOverflow, false);
+
+ num.SetCompact(0x04923456, &fNegative, &fOverflow);
+ BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000012345600");
+ BOOST_CHECK_EQUAL(num.GetCompact(true), 0x04923456U);
+ BOOST_CHECK_EQUAL(fNegative, true);
+ BOOST_CHECK_EQUAL(fOverflow, false);
+
+ num.SetCompact(0x05009234, &fNegative, &fOverflow);
+ BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000092340000");
+ BOOST_CHECK_EQUAL(num.GetCompact(), 0x05009234U);
+ BOOST_CHECK_EQUAL(fNegative, false);
+ BOOST_CHECK_EQUAL(fOverflow, false);
+
+ num.SetCompact(0x20123456, &fNegative, &fOverflow);
+ BOOST_CHECK_EQUAL(num.GetHex(), "1234560000000000000000000000000000000000000000000000000000000000");
+ BOOST_CHECK_EQUAL(num.GetCompact(), 0x20123456U);
+ BOOST_CHECK_EQUAL(fNegative, false);
+ BOOST_CHECK_EQUAL(fOverflow, false);
+
+ num.SetCompact(0xff123456, &fNegative, &fOverflow);
+ BOOST_CHECK_EQUAL(fNegative, false);
+ BOOST_CHECK_EQUAL(fOverflow, true);
+}
+
+
+BOOST_AUTO_TEST_CASE( getmaxcoverage ) // some more tests just to get 100% coverage
+{
+ // ~R1L give a base_uint<256>
+ BOOST_CHECK((~~R1L >> 10) == (R1L >> 10));
+ BOOST_CHECK((~~R1L << 10) == (R1L << 10));
+ BOOST_CHECK(!(~~R1L < R1L));
+ BOOST_CHECK(~~R1L <= R1L);
+ BOOST_CHECK(!(~~R1L > R1L));
+ BOOST_CHECK(~~R1L >= R1L);
+ BOOST_CHECK(!(R1L < ~~R1L));
+ BOOST_CHECK(R1L <= ~~R1L);
+ BOOST_CHECK(!(R1L > ~~R1L));
+ BOOST_CHECK(R1L >= ~~R1L);
+
+ BOOST_CHECK(~~R1L + R2L == R1L + ~~R2L);
+ BOOST_CHECK(~~R1L - R2L == R1L - ~~R2L);
+ BOOST_CHECK(~R1L != R1L); BOOST_CHECK(R1L != ~R1L);
+ unsigned char TmpArray[32];
+ CHECKBITWISEOPERATOR(~R1,R2,|)
+ CHECKBITWISEOPERATOR(~R1,R2,^)
+ CHECKBITWISEOPERATOR(~R1,R2,&)
+ CHECKBITWISEOPERATOR(R1,~R2,|)
+ CHECKBITWISEOPERATOR(R1,~R2,^)
+ CHECKBITWISEOPERATOR(R1,~R2,&)
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/bignum.h b/src/test/bignum.h
index 365b17a1c5..e7aeee9db6 100644
--- a/src/test/bignum.h
+++ b/src/test/bignum.h
@@ -37,14 +37,14 @@ public:
if (!BN_copy(this, &b))
{
BN_clear_free(this);
- throw bignum_error("CBigNum::CBigNum(const CBigNum&) : BN_copy failed");
+ throw bignum_error("CBigNum::CBigNum(const CBigNum&): BN_copy failed");
}
}
CBigNum& operator=(const CBigNum& b)
{
if (!BN_copy(this, &b))
- throw bignum_error("CBigNum::operator= : BN_copy failed");
+ throw bignum_error("CBigNum::operator=: BN_copy failed");
return (*this);
}
@@ -151,7 +151,7 @@ inline const CBigNum operator+(const CBigNum& a, const CBigNum& b)
{
CBigNum r;
if (!BN_add(&r, &a, &b))
- throw bignum_error("CBigNum::operator+ : BN_add failed");
+ throw bignum_error("CBigNum::operator+: BN_add failed");
return r;
}
@@ -159,7 +159,7 @@ inline const CBigNum operator-(const CBigNum& a, const CBigNum& b)
{
CBigNum r;
if (!BN_sub(&r, &a, &b))
- throw bignum_error("CBigNum::operator- : BN_sub failed");
+ throw bignum_error("CBigNum::operator-: BN_sub failed");
return r;
}
diff --git a/src/test/bloom_tests.cpp b/src/test/bloom_tests.cpp
index c32098efa0..64d9909b98 100644
--- a/src/test/bloom_tests.cpp
+++ b/src/test/bloom_tests.cpp
@@ -20,7 +20,6 @@
#include <boost/tuple/tuple.hpp>
using namespace std;
-using namespace boost::tuples;
BOOST_AUTO_TEST_SUITE(bloom_tests)
@@ -125,7 +124,7 @@ BOOST_AUTO_TEST_CASE(bloom_match)
spendStream >> spendingTx;
CBloomFilter filter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
- filter.insert(uint256("0xb4749f017444b051c44dfd2720e88f314ff94f3dd6d56d40ef65854fcd7fff6b"));
+ filter.insert(uint256S("0xb4749f017444b051c44dfd2720e88f314ff94f3dd6d56d40ef65854fcd7fff6b"));
BOOST_CHECK_MESSAGE(filter.IsRelevantAndUpdate(tx), "Simple Bloom filter didn't match tx hash");
filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
@@ -151,11 +150,11 @@ BOOST_AUTO_TEST_CASE(bloom_match)
BOOST_CHECK_MESSAGE(filter.IsRelevantAndUpdate(tx), "Simple Bloom filter didn't match output address");
filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
- filter.insert(COutPoint(uint256("0x90c122d70786e899529d71dbeba91ba216982fb6ba58f3bdaab65e73b7e9260b"), 0));
+ filter.insert(COutPoint(uint256S("0x90c122d70786e899529d71dbeba91ba216982fb6ba58f3bdaab65e73b7e9260b"), 0));
BOOST_CHECK_MESSAGE(filter.IsRelevantAndUpdate(tx), "Simple Bloom filter didn't match COutPoint");
filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
- COutPoint prevOutPoint(uint256("0x90c122d70786e899529d71dbeba91ba216982fb6ba58f3bdaab65e73b7e9260b"), 0);
+ COutPoint prevOutPoint(uint256S("0x90c122d70786e899529d71dbeba91ba216982fb6ba58f3bdaab65e73b7e9260b"), 0);
{
vector<unsigned char> data(32 + sizeof(unsigned int));
memcpy(&data[0], prevOutPoint.hash.begin(), 32);
@@ -165,7 +164,7 @@ BOOST_AUTO_TEST_CASE(bloom_match)
BOOST_CHECK_MESSAGE(filter.IsRelevantAndUpdate(tx), "Simple Bloom filter didn't match manually serialized COutPoint");
filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
- filter.insert(uint256("00000009e784f32f62ef849763d4f45b98e07ba658647343b915ff832b110436"));
+ filter.insert(uint256S("00000009e784f32f62ef849763d4f45b98e07ba658647343b915ff832b110436"));
BOOST_CHECK_MESSAGE(!filter.IsRelevantAndUpdate(tx), "Simple Bloom filter matched random tx hash");
filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
@@ -173,11 +172,11 @@ BOOST_AUTO_TEST_CASE(bloom_match)
BOOST_CHECK_MESSAGE(!filter.IsRelevantAndUpdate(tx), "Simple Bloom filter matched random address");
filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
- filter.insert(COutPoint(uint256("0x90c122d70786e899529d71dbeba91ba216982fb6ba58f3bdaab65e73b7e9260b"), 1));
+ filter.insert(COutPoint(uint256S("0x90c122d70786e899529d71dbeba91ba216982fb6ba58f3bdaab65e73b7e9260b"), 1));
BOOST_CHECK_MESSAGE(!filter.IsRelevantAndUpdate(tx), "Simple Bloom filter matched COutPoint for an output we didn't care about");
filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
- filter.insert(COutPoint(uint256("0x000000d70786e899529d71dbeba91ba216982fb6ba58f3bdaab65e73b7e9260b"), 0));
+ filter.insert(COutPoint(uint256S("0x000000d70786e899529d71dbeba91ba216982fb6ba58f3bdaab65e73b7e9260b"), 0));
BOOST_CHECK_MESSAGE(!filter.IsRelevantAndUpdate(tx), "Simple Bloom filter matched COutPoint for an output we didn't care about");
}
@@ -191,7 +190,7 @@ BOOST_AUTO_TEST_CASE(merkle_block_1)
CBloomFilter filter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
// Match the last transaction
- filter.insert(uint256("0x74d681e0e03bafa802c8aa084379aa98d9fcd632ddc2ed9782b586ec87451f20"));
+ filter.insert(uint256S("0x74d681e0e03bafa802c8aa084379aa98d9fcd632ddc2ed9782b586ec87451f20"));
CMerkleBlock merkleBlock(block, filter);
BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
@@ -199,7 +198,7 @@ BOOST_AUTO_TEST_CASE(merkle_block_1)
BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 1);
pair<unsigned int, uint256> pair = merkleBlock.vMatchedTxn[0];
- BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256("0x74d681e0e03bafa802c8aa084379aa98d9fcd632ddc2ed9782b586ec87451f20"));
+ BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256S("0x74d681e0e03bafa802c8aa084379aa98d9fcd632ddc2ed9782b586ec87451f20"));
BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 8);
vector<uint256> vMatched;
@@ -209,7 +208,7 @@ BOOST_AUTO_TEST_CASE(merkle_block_1)
BOOST_CHECK(vMatched[i] == merkleBlock.vMatchedTxn[i].second);
// Also match the 8th transaction
- filter.insert(uint256("0xdd1fd2a6fc16404faf339881a90adbde7f4f728691ac62e8f168809cdfae1053"));
+ filter.insert(uint256S("0xdd1fd2a6fc16404faf339881a90adbde7f4f728691ac62e8f168809cdfae1053"));
merkleBlock = CMerkleBlock(block, filter);
BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
@@ -217,7 +216,7 @@ BOOST_AUTO_TEST_CASE(merkle_block_1)
BOOST_CHECK(merkleBlock.vMatchedTxn[1] == pair);
- BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256("0xdd1fd2a6fc16404faf339881a90adbde7f4f728691ac62e8f168809cdfae1053"));
+ BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256S("0xdd1fd2a6fc16404faf339881a90adbde7f4f728691ac62e8f168809cdfae1053"));
BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 7);
BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched) == block.hashMerkleRoot);
@@ -236,7 +235,7 @@ BOOST_AUTO_TEST_CASE(merkle_block_2)
CBloomFilter filter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
// Match the first transaction
- filter.insert(uint256("0xe980fe9f792d014e73b95203dc1335c5f9ce19ac537a419e6df5b47aecb93b70"));
+ filter.insert(uint256S("0xe980fe9f792d014e73b95203dc1335c5f9ce19ac537a419e6df5b47aecb93b70"));
CMerkleBlock merkleBlock(block, filter);
BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
@@ -244,7 +243,7 @@ BOOST_AUTO_TEST_CASE(merkle_block_2)
BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 1);
pair<unsigned int, uint256> pair = merkleBlock.vMatchedTxn[0];
- BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256("0xe980fe9f792d014e73b95203dc1335c5f9ce19ac537a419e6df5b47aecb93b70"));
+ BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256S("0xe980fe9f792d014e73b95203dc1335c5f9ce19ac537a419e6df5b47aecb93b70"));
BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 0);
vector<uint256> vMatched;
@@ -265,13 +264,13 @@ BOOST_AUTO_TEST_CASE(merkle_block_2)
BOOST_CHECK(pair == merkleBlock.vMatchedTxn[0]);
- BOOST_CHECK(merkleBlock.vMatchedTxn[1].second == uint256("0x28204cad1d7fc1d199e8ef4fa22f182de6258a3eaafe1bbe56ebdcacd3069a5f"));
+ BOOST_CHECK(merkleBlock.vMatchedTxn[1].second == uint256S("0x28204cad1d7fc1d199e8ef4fa22f182de6258a3eaafe1bbe56ebdcacd3069a5f"));
BOOST_CHECK(merkleBlock.vMatchedTxn[1].first == 1);
- BOOST_CHECK(merkleBlock.vMatchedTxn[2].second == uint256("0x6b0f8a73a56c04b519f1883e8aafda643ba61a30bd1439969df21bea5f4e27e2"));
+ BOOST_CHECK(merkleBlock.vMatchedTxn[2].second == uint256S("0x6b0f8a73a56c04b519f1883e8aafda643ba61a30bd1439969df21bea5f4e27e2"));
BOOST_CHECK(merkleBlock.vMatchedTxn[2].first == 2);
- BOOST_CHECK(merkleBlock.vMatchedTxn[3].second == uint256("0x3c1d7e82342158e4109df2e0b6348b6e84e403d8b4046d7007663ace63cddb23"));
+ BOOST_CHECK(merkleBlock.vMatchedTxn[3].second == uint256S("0x3c1d7e82342158e4109df2e0b6348b6e84e403d8b4046d7007663ace63cddb23"));
BOOST_CHECK(merkleBlock.vMatchedTxn[3].first == 3);
BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched) == block.hashMerkleRoot);
@@ -290,7 +289,7 @@ BOOST_AUTO_TEST_CASE(merkle_block_2_with_update_none)
CBloomFilter filter(10, 0.000001, 0, BLOOM_UPDATE_NONE);
// Match the first transaction
- filter.insert(uint256("0xe980fe9f792d014e73b95203dc1335c5f9ce19ac537a419e6df5b47aecb93b70"));
+ filter.insert(uint256S("0xe980fe9f792d014e73b95203dc1335c5f9ce19ac537a419e6df5b47aecb93b70"));
CMerkleBlock merkleBlock(block, filter);
BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
@@ -298,7 +297,7 @@ BOOST_AUTO_TEST_CASE(merkle_block_2_with_update_none)
BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 1);
pair<unsigned int, uint256> pair = merkleBlock.vMatchedTxn[0];
- BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256("0xe980fe9f792d014e73b95203dc1335c5f9ce19ac537a419e6df5b47aecb93b70"));
+ BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256S("0xe980fe9f792d014e73b95203dc1335c5f9ce19ac537a419e6df5b47aecb93b70"));
BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 0);
vector<uint256> vMatched;
@@ -319,10 +318,10 @@ BOOST_AUTO_TEST_CASE(merkle_block_2_with_update_none)
BOOST_CHECK(pair == merkleBlock.vMatchedTxn[0]);
- BOOST_CHECK(merkleBlock.vMatchedTxn[1].second == uint256("0x28204cad1d7fc1d199e8ef4fa22f182de6258a3eaafe1bbe56ebdcacd3069a5f"));
+ BOOST_CHECK(merkleBlock.vMatchedTxn[1].second == uint256S("0x28204cad1d7fc1d199e8ef4fa22f182de6258a3eaafe1bbe56ebdcacd3069a5f"));
BOOST_CHECK(merkleBlock.vMatchedTxn[1].first == 1);
- BOOST_CHECK(merkleBlock.vMatchedTxn[2].second == uint256("0x3c1d7e82342158e4109df2e0b6348b6e84e403d8b4046d7007663ace63cddb23"));
+ BOOST_CHECK(merkleBlock.vMatchedTxn[2].second == uint256S("0x3c1d7e82342158e4109df2e0b6348b6e84e403d8b4046d7007663ace63cddb23"));
BOOST_CHECK(merkleBlock.vMatchedTxn[2].first == 3);
BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched) == block.hashMerkleRoot);
@@ -341,14 +340,14 @@ BOOST_AUTO_TEST_CASE(merkle_block_3_and_serialize)
CBloomFilter filter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
// Match the only transaction
- filter.insert(uint256("0x63194f18be0af63f2c6bc9dc0f777cbefed3d9415c4af83f3ee3a3d669c00cb5"));
+ filter.insert(uint256S("0x63194f18be0af63f2c6bc9dc0f777cbefed3d9415c4af83f3ee3a3d669c00cb5"));
CMerkleBlock merkleBlock(block, filter);
BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 1);
- BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256("0x63194f18be0af63f2c6bc9dc0f777cbefed3d9415c4af83f3ee3a3d669c00cb5"));
+ BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256S("0x63194f18be0af63f2c6bc9dc0f777cbefed3d9415c4af83f3ee3a3d669c00cb5"));
BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 0);
vector<uint256> vMatched;
@@ -379,7 +378,7 @@ BOOST_AUTO_TEST_CASE(merkle_block_4)
CBloomFilter filter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
// Match the last transaction
- filter.insert(uint256("0x0a2a92f0bda4727d0a13eaddf4dd9ac6b5c61a1429e6b2b818f19b15df0ac154"));
+ filter.insert(uint256S("0x0a2a92f0bda4727d0a13eaddf4dd9ac6b5c61a1429e6b2b818f19b15df0ac154"));
CMerkleBlock merkleBlock(block, filter);
BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
@@ -387,7 +386,7 @@ BOOST_AUTO_TEST_CASE(merkle_block_4)
BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 1);
pair<unsigned int, uint256> pair = merkleBlock.vMatchedTxn[0];
- BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256("0x0a2a92f0bda4727d0a13eaddf4dd9ac6b5c61a1429e6b2b818f19b15df0ac154"));
+ BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256S("0x0a2a92f0bda4727d0a13eaddf4dd9ac6b5c61a1429e6b2b818f19b15df0ac154"));
BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 6);
vector<uint256> vMatched;
@@ -397,13 +396,13 @@ BOOST_AUTO_TEST_CASE(merkle_block_4)
BOOST_CHECK(vMatched[i] == merkleBlock.vMatchedTxn[i].second);
// Also match the 4th transaction
- filter.insert(uint256("0x02981fa052f0481dbc5868f4fc2166035a10f27a03cfd2de67326471df5bc041"));
+ filter.insert(uint256S("0x02981fa052f0481dbc5868f4fc2166035a10f27a03cfd2de67326471df5bc041"));
merkleBlock = CMerkleBlock(block, filter);
BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 2);
- BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256("0x02981fa052f0481dbc5868f4fc2166035a10f27a03cfd2de67326471df5bc041"));
+ BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256S("0x02981fa052f0481dbc5868f4fc2166035a10f27a03cfd2de67326471df5bc041"));
BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 3);
BOOST_CHECK(merkleBlock.vMatchedTxn[1] == pair);
@@ -432,9 +431,9 @@ BOOST_AUTO_TEST_CASE(merkle_block_4_test_p2pubkey_only)
BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
// We should match the generation outpoint
- BOOST_CHECK(filter.contains(COutPoint(uint256("0x147caa76786596590baa4e98f5d9f48b86c7765e489f7a6ff3360fe5c674360b"), 0)));
+ BOOST_CHECK(filter.contains(COutPoint(uint256S("0x147caa76786596590baa4e98f5d9f48b86c7765e489f7a6ff3360fe5c674360b"), 0)));
// ... but not the 4th transaction's output (its not pay-2-pubkey)
- BOOST_CHECK(!filter.contains(COutPoint(uint256("0x02981fa052f0481dbc5868f4fc2166035a10f27a03cfd2de67326471df5bc041"), 0)));
+ BOOST_CHECK(!filter.contains(COutPoint(uint256S("0x02981fa052f0481dbc5868f4fc2166035a10f27a03cfd2de67326471df5bc041"), 0)));
}
BOOST_AUTO_TEST_CASE(merkle_block_4_test_update_none)
@@ -455,8 +454,8 @@ BOOST_AUTO_TEST_CASE(merkle_block_4_test_update_none)
BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
// We shouldn't match any outpoints (UPDATE_NONE)
- BOOST_CHECK(!filter.contains(COutPoint(uint256("0x147caa76786596590baa4e98f5d9f48b86c7765e489f7a6ff3360fe5c674360b"), 0)));
- BOOST_CHECK(!filter.contains(COutPoint(uint256("0x02981fa052f0481dbc5868f4fc2166035a10f27a03cfd2de67326471df5bc041"), 0)));
+ BOOST_CHECK(!filter.contains(COutPoint(uint256S("0x147caa76786596590baa4e98f5d9f48b86c7765e489f7a6ff3360fe5c674360b"), 0)));
+ BOOST_CHECK(!filter.contains(COutPoint(uint256S("0x02981fa052f0481dbc5868f4fc2166035a10f27a03cfd2de67326471df5bc041"), 0)));
}
BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/crypto_tests.cpp b/src/test/crypto_tests.cpp
index 47bfd710cd..d5e595cd8a 100644
--- a/src/test/crypto_tests.cpp
+++ b/src/test/crypto_tests.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 "crypto/rfc6979_hmac_sha256.h"
#include "crypto/ripemd160.h"
#include "crypto/sha1.h"
#include "crypto/sha256.h"
@@ -248,38 +247,4 @@ BOOST_AUTO_TEST_CASE(hmac_sha512_testvectors) {
"b6022cac3c4982b10d5eeb55c3e4de15134676fb6de0446065c97440fa8c6a58");
}
-void TestRFC6979(const std::string& hexkey, const std::string& hexmsg, const std::vector<std::string>& hexout)
-{
- std::vector<unsigned char> key = ParseHex(hexkey);
- std::vector<unsigned char> msg = ParseHex(hexmsg);
- RFC6979_HMAC_SHA256 rng(&key[0], key.size(), &msg[0], msg.size());
-
- for (unsigned int i = 0; i < hexout.size(); i++) {
- std::vector<unsigned char> out = ParseHex(hexout[i]);
- std::vector<unsigned char> gen;
- gen.resize(out.size());
- rng.Generate(&gen[0], gen.size());
- BOOST_CHECK(out == gen);
- }
-}
-
-BOOST_AUTO_TEST_CASE(rfc6979_hmac_sha256)
-{
- TestRFC6979(
- "0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f00",
- "4bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459a",
- boost::assign::list_of
- ("4fe29525b2086809159acdf0506efb86b0ec932c7ba44256ab321e421e67e9fb")
- ("2bf0fff1d3c378a22dc5de1d856522325c65b504491a0cbd01cb8f3aa67ffd4a")
- ("f528b410cb541f77000d7afb6c5b53c5c471eab43e466d9ac5190c39c82fd82e"));
-
- TestRFC6979(
- "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
- "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
- boost::assign::list_of
- ("9c236c165b82ae0cd590659e100b6bab3036e7ba8b06749baf6981e16f1a2b95")
- ("df471061625bc0ea14b682feee2c9c02f235da04204c1d62a1536c6e17aed7a9")
- ("7597887cbd76321f32e30440679a22cf7f8d9d2eac390e581fea091ce202ba94"));
-}
-
BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/data/README.md b/src/test/data/README.md
index 55ac95739c..2463daa42a 100644
--- a/src/test/data/README.md
+++ b/src/test/data/README.md
@@ -6,9 +6,7 @@ This directory contains data-driven tests for various aspects of Bitcoin.
License
--------
-The data files in this directory are
-
- Copyright (c) 2012-2014 The Bitcoin Core developers
- Distributed under the MIT software license, see the accompanying
- file COPYING or http://www.opensource.org/licenses/mit-license.php.
+The data files in this directory are distributed under the MIT software
+license, see the accompanying file COPYING or
+http://www.opensource.org/licenses/mit-license.php.
diff --git a/src/test/data/bitcoin-util-test.json b/src/test/data/bitcoin-util-test.json
index f8424b72a3..6090421cb6 100644
--- a/src/test/data/bitcoin-util-test.json
+++ b/src/test/data/bitcoin-util-test.json
@@ -46,5 +46,15 @@
{ "exec": "./bitcoin-tx",
"args": ["-create", "outscript=0:"],
"output_cmp": "txcreate2.hex"
+ },
+ { "exec": "./bitcoin-tx",
+ "args":
+ ["-create",
+ "in=4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59485:0",
+ "set=privatekeys:[\"5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsreAnchuDf\"]",
+ "set=prevtxs:[{\"txid\":\"4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59485\",\"vout\":0,\"scriptPubKey\":\"4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59485\"}]",
+ "sign=ALL",
+ "outaddr=0.001:193P6LtvS4nCnkDvM9uXn1gsSRqh4aDAz7"],
+ "output_cmp": "txcreatesign.hex"
}
]
diff --git a/src/test/data/script_invalid.json b/src/test/data/script_invalid.json
index 44e0dca8be..a67c157aff 100644
--- a/src/test/data/script_invalid.json
+++ b/src/test/data/script_invalid.json
@@ -504,12 +504,22 @@
"2-of-2 CHECKMULTISIG NOT with the first pubkey invalid, and both signatures validly encoded."
],
[
- "0 0x47 0x3044022044dc17b0887c161bb67ba9635bf758735bdde503e4b0a0987f587f14a4e1143d022009a215772d49a85dae40d8ca03955af26ad3978a0ff965faa12915e9586249a501 0",
+ "0 0x47 0x3044022044dc17b0887c161bb67ba9635bf758735bdde503e4b0a0987f587f14a4e1143d022009a215772d49a85dae40d8ca03955af26ad3978a0ff965faa12915e9586249a501 1",
"2 0x21 0x02865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac0 0x21 0x02865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac0 2 CHECKMULTISIG NOT",
"STRICTENC",
"2-of-2 CHECKMULTISIG NOT with both pubkeys valid, but first signature invalid."
],
+["Increase DERSIG test coverage"],
+["0x4a 0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "0 CHECKSIG NOT", "DERSIG", "Overly long signature is incorrectly encoded for DERSIG"],
+["0x25 0x30220220000000000000000000000000000000000000000000000000000000000000000000", "0 CHECKSIG NOT", "DERSIG", "Missing S is incorrectly encoded for DERSIG"],
+["0x27 0x3024021077777777777777777777777777777777020a7777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "S with invalid S length is incorrectly encoded for DERSIG"],
+["0x27 0x302403107777777777777777777777777777777702107777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "Non-integer R is incorrectly encoded for DERSIG"],
+["0x27 0x302402107777777777777777777777777777777703107777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "Non-integer S is incorrectly encoded for DERSIG"],
+["0x17 0x3014020002107777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "Zero-length R is incorrectly encoded for DERSIG"],
+["0x17 0x3014021077777777777777777777777777777777020001", "0 CHECKSIG NOT", "DERSIG", "Zero-length S is incorrectly encoded for DERSIG"],
+["0x27 0x302402107777777777777777777777777777777702108777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "Negative S is incorrectly encoded for DERSIG"],
+
["Automatically generated test cases"],
[
"0x47 0x3044022053205076a7bb12d2db3162a2d97d8197631f829b065948b7019b15482af819a902204328dcc02c994ca086b1226d0d5f1674d23cfae0d846143df812b81cab3391e801",
@@ -590,6 +600,102 @@
"P2PK NOT with too much R padding"
],
[
+ "0x47 0x30440220d7a0417c3f6d1a15094d1cf2a3378ca0503eb8a57630953a9e2987e21ddd0a6502207a6266d686c99090920249991d3d42065b6d43eb70187b219c0db82e4f94d1a201",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG",
+ "DERSIG",
+ "BIP66 example 1, with DERSIG"
+],
+[
+ "0x47 0x304402208e43c0b91f7c1e5bc58e41c8185f8a6086e111b0090187968a86f2822462d3c902200a58f4076b1133b18ff1dc83ee51676e44c60cc608d9534e0df5ace0424fc0be01",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG NOT",
+ "",
+ "BIP66 example 2, without DERSIG"
+],
+[
+ "0x47 0x304402208e43c0b91f7c1e5bc58e41c8185f8a6086e111b0090187968a86f2822462d3c902200a58f4076b1133b18ff1dc83ee51676e44c60cc608d9534e0df5ace0424fc0be01",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG NOT",
+ "DERSIG",
+ "BIP66 example 2, with DERSIG"
+],
+[
+ "0",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG",
+ "",
+ "BIP66 example 3, without DERSIG"
+],
+[
+ "0",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG",
+ "DERSIG",
+ "BIP66 example 3, with DERSIG"
+],
+[
+ "1",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG",
+ "",
+ "BIP66 example 5, without DERSIG"
+],
+[
+ "1",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG",
+ "DERSIG",
+ "BIP66 example 5, with DERSIG"
+],
+[
+ "1",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG NOT",
+ "DERSIG",
+ "BIP66 example 6, with DERSIG"
+],
+[
+ "0 0x47 0x30440220cae00b1444babfbf6071b0ba8707f6bd373da3df494d6e74119b0430c5db810502205d5231b8c5939c8ff0c82242656d6e06edb073d42af336c99fe8837c36ea39d501 0x47 0x304402200b3d0b0375bb15c14620afa4aa10ae90a0d6a046ce217bc20fe0bc1ced68c1b802204b550acab90ae6d3478057c9ad24f9df743815b799b6449dd7e7f6d3bc6e274c01",
+ "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG",
+ "DERSIG",
+ "BIP66 example 7, with DERSIG"
+],
+[
+ "0 0x47 0x30440220f00a77260d34ec2f0c59621dc710f58169d0ca06df1a88cd4b1f1b97bd46991b02201ee220c7e04f26aed03f94aa97fb09ca5627163bf4ba07e6979972ec737db22601 0x47 0x3044022079ea80afd538d9ada421b5101febeb6bc874e01dde5bca108c1d0479aec339a4022004576db8f66130d1df686ccf00935703689d69cf539438da1edab208b0d63c4801",
+ "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG NOT",
+ "",
+ "BIP66 example 8, without DERSIG"
+],
+[
+ "0 0x47 0x30440220f00a77260d34ec2f0c59621dc710f58169d0ca06df1a88cd4b1f1b97bd46991b02201ee220c7e04f26aed03f94aa97fb09ca5627163bf4ba07e6979972ec737db22601 0x47 0x3044022079ea80afd538d9ada421b5101febeb6bc874e01dde5bca108c1d0479aec339a4022004576db8f66130d1df686ccf00935703689d69cf539438da1edab208b0d63c4801",
+ "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG NOT",
+ "DERSIG",
+ "BIP66 example 8, with DERSIG"
+],
+[
+ "0 0 0x47 0x3044022081aa9d436f2154e8b6d600516db03d78de71df685b585a9807ead4210bd883490220534bb6bdf318a419ac0749660b60e78d17d515558ef369bf872eff405b676b2e01",
+ "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG",
+ "",
+ "BIP66 example 9, without DERSIG"
+],
+[
+ "0 0 0x47 0x3044022081aa9d436f2154e8b6d600516db03d78de71df685b585a9807ead4210bd883490220534bb6bdf318a419ac0749660b60e78d17d515558ef369bf872eff405b676b2e01",
+ "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG",
+ "DERSIG",
+ "BIP66 example 9, with DERSIG"
+],
+[
+ "0 0 0x47 0x30440220afa76a8f60622f813b05711f051c6c3407e32d1b1b70b0576c1f01b54e4c05c702200d58e9df044fd1845cabfbeef6e624ba0401daf7d7e084736f9ff601c3783bf501",
+ "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG NOT",
+ "DERSIG",
+ "BIP66 example 10, with DERSIG"
+],
+[
+ "0 0x47 0x30440220cae00b1444babfbf6071b0ba8707f6bd373da3df494d6e74119b0430c5db810502205d5231b8c5939c8ff0c82242656d6e06edb073d42af336c99fe8837c36ea39d501 0",
+ "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG",
+ "",
+ "BIP66 example 11, without DERSIG"
+],
+[
+ "0 0x47 0x30440220cae00b1444babfbf6071b0ba8707f6bd373da3df494d6e74119b0430c5db810502205d5231b8c5939c8ff0c82242656d6e06edb073d42af336c99fe8837c36ea39d501 0",
+ "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG",
+ "DERSIG",
+ "BIP66 example 11, with DERSIG"
+],
+[
"0x49 0x304502203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022100ab1e3da73d67e32045a20e0b999e049978ea8d6ee5480d485fcf2ce0d03b2ef05101",
"0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG",
"LOW_S",
@@ -667,6 +773,18 @@
"SIGPUSHONLY",
"P2SH(P2PK) with non-push scriptSig"
],
+[
+ "11 0x47 0x3044022053205076a7bb13d2db3162a2d97d8197631f829b065948b7019b15482af819a902204328dcc02c994ca086b1226d0d5f1674d23cfae0d846143df812b81cab3391e801",
+ "0x41 0x0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG",
+ "CLEANSTACK,P2SH",
+ "P2PK with unnecessary input"
+],
+[
+ "11 0x47 0x304402202f7505132be14872581f35d74b759212d9da40482653f1ffa3116c3294a4a51702206adbf347a2240ca41c66522b1a22a41693610b76a8e7770645dc721d1635854f01 0x43 0x410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ac",
+ "HASH160 0x14 0x31edc23bdafda4639e669f89ad6b2318dd79d032 EQUAL",
+ "CLEANSTACK,P2SH",
+ "P2SH with unnecessary input"
+],
["The End"]
]
diff --git a/src/test/data/script_valid.json b/src/test/data/script_valid.json
index a1b7b119ef..fb81fcb1f5 100644
--- a/src/test/data/script_valid.json
+++ b/src/test/data/script_valid.json
@@ -662,6 +662,11 @@
["0 0 0x02 0x0000", "CHECKMULTISIGVERIFY 1", ""],
["0 0x02 0x0000 0", "CHECKMULTISIGVERIFY 1", ""],
+["While not really correctly DER encoded, the empty signature is allowed by"],
+["STRICTENC to provide a compact way to provide a delibrately invalid signature."],
+["0", "0x21 0x02865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac0 CHECKSIG NOT", "STRICTENC"],
+["0 0", "1 0x21 0x02865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac0 1 CHECKMULTISIG NOT", "STRICTENC"],
+
["CHECKMULTISIG evaluation order tests. CHECKMULTISIG evaluates signatures and"],
["pubkeys in a specific order, and will exit early if the number of signatures"],
["left to check is greater than the number of keys left. As STRICTENC fails the"],
@@ -683,6 +688,16 @@
"2-of-2 CHECKMULTISIG NOT with both pubkeys valid, but second signature invalid. Valid pubkey fails, and CHECKMULTISIG exits early, prior to evaluation of second invalid signature."
],
+["Increase test coverage for DERSIG"],
+["0x4a 0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "0 CHECKSIG NOT", "", "Overly long signature is correctly encoded"],
+["0x25 0x30220220000000000000000000000000000000000000000000000000000000000000000000", "0 CHECKSIG NOT", "", "Missing S is correctly encoded"],
+["0x27 0x3024021077777777777777777777777777777777020a7777777777777777777777777777777701", "0 CHECKSIG NOT", "", "S with invalid S length is correctly encoded"],
+["0x27 0x302403107777777777777777777777777777777702107777777777777777777777777777777701", "0 CHECKSIG NOT", "", "Non-integer R is correctly encoded"],
+["0x27 0x302402107777777777777777777777777777777703107777777777777777777777777777777701", "0 CHECKSIG NOT", "", "Non-integer S is correctly encoded"],
+["0x17 0x3014020002107777777777777777777777777777777701", "0 CHECKSIG NOT", "", "Zero-length R is correctly encoded"],
+["0x17 0x3014021077777777777777777777777777777777020001", "0 CHECKSIG NOT", "", "Zero-length S is correctly encoded for DERSIG"],
+["0x27 0x302402107777777777777777777777777777777702108777777777777777777777777777777701", "0 CHECKSIG NOT", "", "Negative S is correctly encoded"],
+
["Automatically generated test cases"],
[
"0x47 0x3044022053205076a7bb13d2db3162a2d97d8197631f829b065948b7019b15482af819a902204328dcc02c994ca086b1226d0d5f1674d23cfae0d846143df812b81cab3391e801",
@@ -751,6 +766,54 @@
"P2PK NOT with bad sig with too much R padding but no DERSIG"
],
[
+ "0x47 0x30440220d7a0417c3f6d1a15094d1cf2a3378ca0503eb8a57630953a9e2987e21ddd0a6502207a6266d686c99090920249991d3d42065b6d43eb70187b219c0db82e4f94d1a201",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG",
+ "",
+ "BIP66 example 1, without DERSIG"
+],
+[
+ "0",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG NOT",
+ "",
+ "BIP66 example 4, without DERSIG"
+],
+[
+ "0",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG NOT",
+ "DERSIG",
+ "BIP66 example 4, with DERSIG"
+],
+[
+ "1",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG NOT",
+ "",
+ "BIP66 example 6, without DERSIG"
+],
+[
+ "0 0x47 0x30440220cae00b1444babfbf6071b0ba8707f6bd373da3df494d6e74119b0430c5db810502205d5231b8c5939c8ff0c82242656d6e06edb073d42af336c99fe8837c36ea39d501 0x47 0x304402200b3d0b0375bb15c14620afa4aa10ae90a0d6a046ce217bc20fe0bc1ced68c1b802204b550acab90ae6d3478057c9ad24f9df743815b799b6449dd7e7f6d3bc6e274c01",
+ "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG",
+ "",
+ "BIP66 example 7, without DERSIG"
+],
+[
+ "0 0 0x47 0x30440220afa76a8f60622f813b05711f051c6c3407e32d1b1b70b0576c1f01b54e4c05c702200d58e9df044fd1845cabfbeef6e624ba0401daf7d7e084736f9ff601c3783bf501",
+ "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG NOT",
+ "",
+ "BIP66 example 10, without DERSIG"
+],
+[
+ "0 0x47 0x30440220f00a77260d34ec2f0c59621dc710f58169d0ca06df1a88cd4b1f1b97bd46991b02201ee220c7e04f26aed03f94aa97fb09ca5627163bf4ba07e6979972ec737db22601 0",
+ "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG NOT",
+ "",
+ "BIP66 example 12, without DERSIG"
+],
+[
+ "0 0x47 0x30440220f00a77260d34ec2f0c59621dc710f58169d0ca06df1a88cd4b1f1b97bd46991b02201ee220c7e04f26aed03f94aa97fb09ca5627163bf4ba07e6979972ec737db22601 0",
+ "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG NOT",
+ "DERSIG",
+ "BIP66 example 12, with DERSIG"
+],
+[
"0x49 0x304502203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022100ab1e3da73d67e32045a20e0b999e049978ea8d6ee5480d485fcf2ce0d03b2ef05101",
"0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG",
"",
@@ -816,6 +879,24 @@
"SIGPUSHONLY",
"2-of-2 with two identical keys and sigs pushed"
],
+[
+ "11 0x47 0x3044022053205076a7bb13d2db3162a2d97d8197631f829b065948b7019b15482af819a902204328dcc02c994ca086b1226d0d5f1674d23cfae0d846143df812b81cab3391e801",
+ "0x41 0x0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG",
+ "P2SH",
+ "P2PK with unnecessary input but no CLEANSTACK"
+],
+[
+ "11 0x47 0x304402202f7505132be14872581f35d74b759212d9da40482653f1ffa3116c3294a4a51702206adbf347a2240ca41c66522b1a22a41693610b76a8e7770645dc721d1635854f01 0x43 0x410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ac",
+ "HASH160 0x14 0x31edc23bdafda4639e669f89ad6b2318dd79d032 EQUAL",
+ "P2SH",
+ "P2SH with unnecessary input but no CLEANSTACK"
+],
+[
+ "0x47 0x304402202f7505132be14872581f35d74b759212d9da40482653f1ffa3116c3294a4a51702206adbf347a2240ca41c66522b1a22a41693610b76a8e7770645dc721d1635854f01 0x43 0x410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ac",
+ "HASH160 0x14 0x31edc23bdafda4639e669f89ad6b2318dd79d032 EQUAL",
+ "CLEANSTACK,P2SH",
+ "P2SH with CLEANSTACK"
+],
["The End"]
]
diff --git a/src/test/data/sig_canonical.json b/src/test/data/sig_canonical.json
deleted file mode 100644
index e43a08629a..0000000000
--- a/src/test/data/sig_canonical.json
+++ /dev/null
@@ -1,7 +0,0 @@
-[
- "300602010002010001",
- "3008020200ff020200ff01",
- "304402203932c892e2e550f3af8ee4ce9c215a87f9bb831dcac87b2838e2c2eaa891df0c022030b61dd36543125d56b9f9f3a1f9353189e5af33cdda8d77a5209aec03978fa001",
- "30450220076045be6f9eca28ff1ec606b833d0b87e70b2a630f5e3a496b110967a40f90a0221008fffd599910eefe00bc803c688c2eca1d2ba7f6b180620eaa03488e6585db6ba01",
- "3046022100876045be6f9eca28ff1ec606b833d0b87e70b2a630f5e3a496b110967a40f90a0221008fffd599910eefe00bc803c688c2eca1d2ba7f6b180620eaa03488e6585db6ba01"
-]
diff --git a/src/test/data/sig_noncanonical.json b/src/test/data/sig_noncanonical.json
deleted file mode 100644
index d9a6c1cdd8..0000000000
--- a/src/test/data/sig_noncanonical.json
+++ /dev/null
@@ -1,22 +0,0 @@
-[
- "non-hex strings are ignored",
-
- "too short:", "30050201FF020001",
- "too long:", "30470221005990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba6105022200002d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed01",
- "hashtype:", "304402205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba610502202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed11",
- "type:", "314402205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba610502202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed01",
- "total length:", "304502205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba610502202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed01",
- "S len oob:", "301F01205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb101",
- "R+S:", "304502205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba610502202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed0001",
-
- "R type:", "304401205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba610502202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed01",
- "R len = 0:", "3024020002202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed01",
- "R<0:", "304402208990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba610502202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed01",
- "R padded:", "30450221005990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba610502202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed01",
-
-
- "S type:", "304402205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba610501202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed01",
- "S len = 0:", "302402205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba6105020001",
- "S<0:", "304402205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba61050220fd5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed01",
- "S padded:", "304502205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba61050221002d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed01"
-]
diff --git a/src/test/data/txcreatesign.hex b/src/test/data/txcreatesign.hex
new file mode 100644
index 0000000000..56ce28a865
--- /dev/null
+++ b/src/test/data/txcreatesign.hex
@@ -0,0 +1 @@
+01000000018594c5bdcaec8f06b78b596f31cd292a294fd031e24eec716f43dac91ea7494d0000000000ffffffff01a0860100000000001976a9145834479edbbe0539b31ffd3a8f8ebadc2165ed0188ac00000000
diff --git a/src/test/multisig_tests.cpp b/src/test/multisig_tests.cpp
index 42a159cda2..2168a5fef1 100644
--- a/src/test/multisig_tests.cpp
+++ b/src/test/multisig_tests.cpp
@@ -15,12 +15,10 @@
#include "wallet_ismine.h"
#endif
-#include <boost/assign/std/vector.hpp>
#include <boost/foreach.hpp>
#include <boost/test/unit_test.hpp>
using namespace std;
-using namespace boost::assign;
typedef vector<unsigned char> valtype;
@@ -81,68 +79,62 @@ BOOST_AUTO_TEST_CASE(multisig_verify)
CScript s;
// Test a AND b:
- keys.clear();
- keys += key[0],key[1]; // magic operator+= from boost.assign
+ keys.assign(1,key[0]);
+ keys.push_back(key[1]);
s = sign_multisig(a_and_b, keys, txTo[0], 0);
- BOOST_CHECK(VerifyScript(s, a_and_b, flags, SignatureChecker(txTo[0], 0), &err));
+ BOOST_CHECK(VerifyScript(s, a_and_b, flags, MutableTransactionSignatureChecker(&txTo[0], 0), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
for (int i = 0; i < 4; i++)
{
- keys.clear();
- keys += key[i];
+ keys.assign(1,key[i]);
s = sign_multisig(a_and_b, keys, txTo[0], 0);
- BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, flags, SignatureChecker(txTo[0], 0), &err), strprintf("a&b 1: %d", i));
+ BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, flags, MutableTransactionSignatureChecker(&txTo[0], 0), &err), strprintf("a&b 1: %d", i));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_INVALID_STACK_OPERATION, ScriptErrorString(err));
- keys.clear();
- keys += key[1],key[i];
+ keys.assign(1,key[1]);
+ keys.push_back(key[i]);
s = sign_multisig(a_and_b, keys, txTo[0], 0);
- BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, flags, SignatureChecker(txTo[0], 0), &err), strprintf("a&b 2: %d", i));
+ BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, flags, MutableTransactionSignatureChecker(&txTo[0], 0), &err), strprintf("a&b 2: %d", i));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
}
// Test a OR b:
for (int i = 0; i < 4; i++)
{
- keys.clear();
- keys += key[i];
+ keys.assign(1,key[i]);
s = sign_multisig(a_or_b, keys, txTo[1], 0);
if (i == 0 || i == 1)
{
- BOOST_CHECK_MESSAGE(VerifyScript(s, a_or_b, flags, SignatureChecker(txTo[1], 0), &err), strprintf("a|b: %d", i));
+ BOOST_CHECK_MESSAGE(VerifyScript(s, a_or_b, flags, MutableTransactionSignatureChecker(&txTo[1], 0), &err), strprintf("a|b: %d", i));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
}
else
{
- BOOST_CHECK_MESSAGE(!VerifyScript(s, a_or_b, flags, SignatureChecker(txTo[1], 0), &err), strprintf("a|b: %d", i));
+ BOOST_CHECK_MESSAGE(!VerifyScript(s, a_or_b, flags, MutableTransactionSignatureChecker(&txTo[1], 0), &err), strprintf("a|b: %d", i));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
}
}
s.clear();
- s << OP_0 << OP_0;
- BOOST_CHECK(!VerifyScript(s, a_or_b, flags, SignatureChecker(txTo[1], 0), &err));
- BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_SIG_DER, ScriptErrorString(err));
- s.clear();
s << OP_0 << OP_1;
- BOOST_CHECK(!VerifyScript(s, a_or_b, flags, SignatureChecker(txTo[1], 0), &err));
+ BOOST_CHECK(!VerifyScript(s, a_or_b, flags, MutableTransactionSignatureChecker(&txTo[1], 0), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_SIG_DER, ScriptErrorString(err));
for (int i = 0; i < 4; i++)
for (int j = 0; j < 4; j++)
{
- keys.clear();
- keys += key[i],key[j];
+ keys.assign(1,key[i]);
+ keys.push_back(key[j]);
s = sign_multisig(escrow, keys, txTo[2], 0);
if (i < j && i < 3 && j < 3)
{
- BOOST_CHECK_MESSAGE(VerifyScript(s, escrow, flags, SignatureChecker(txTo[2], 0), &err), strprintf("escrow 1: %d %d", i, j));
+ BOOST_CHECK_MESSAGE(VerifyScript(s, escrow, flags, MutableTransactionSignatureChecker(&txTo[2], 0), &err), strprintf("escrow 1: %d %d", i, j));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
}
else
{
- BOOST_CHECK_MESSAGE(!VerifyScript(s, escrow, flags, SignatureChecker(txTo[2], 0), &err), strprintf("escrow 2: %d %d", i, j));
+ BOOST_CHECK_MESSAGE(!VerifyScript(s, escrow, flags, MutableTransactionSignatureChecker(&txTo[2], 0), &err), strprintf("escrow 2: %d %d", i, j));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
}
}
diff --git a/src/test/pmt_tests.cpp b/src/test/pmt_tests.cpp
index 807a5d1e5f..4406b08e56 100644
--- a/src/test/pmt_tests.cpp
+++ b/src/test/pmt_tests.cpp
@@ -6,10 +6,13 @@
#include "serialize.h"
#include "streams.h"
#include "uint256.h"
+#include "arith_uint256.h"
#include "version.h"
+#include "random.h"
#include <vector>
+#include <boost/assign/list_of.hpp>
#include <boost/test/unit_test.hpp>
using namespace std;
@@ -19,10 +22,9 @@ class CPartialMerkleTreeTester : public CPartialMerkleTree
public:
// flip one bit in one of the hashes - this should break the authentication
void Damage() {
- unsigned int n = rand() % vHash.size();
- int bit = rand() % 256;
- uint256 &hash = vHash[n];
- hash ^= ((uint256)1 << bit);
+ unsigned int n = insecure_rand() % vHash.size();
+ int bit = insecure_rand() % 256;
+ *(vHash[n].begin() + (bit>>3)) ^= 1<<(bit&7);
}
};
@@ -30,6 +32,7 @@ BOOST_AUTO_TEST_SUITE(pmt_tests)
BOOST_AUTO_TEST_CASE(pmt_test1)
{
+ seed_insecure_rand(false);
static const unsigned int nTxCounts[] = {1, 4, 7, 17, 56, 100, 127, 256, 312, 513, 1000, 4095};
for (int n = 0; n < 12; n++) {
@@ -39,13 +42,13 @@ BOOST_AUTO_TEST_CASE(pmt_test1)
CBlock block;
for (unsigned int j=0; j<nTx; j++) {
CMutableTransaction tx;
- tx.nLockTime = rand(); // actual transaction data doesn't matter; just make the nLockTime's unique
+ tx.nLockTime = j; // actual transaction data doesn't matter; just make the nLockTime's unique
block.vtx.push_back(CTransaction(tx));
}
// calculate actual merkle root and height
uint256 merkleRoot1 = block.BuildMerkleTree();
- std::vector<uint256> vTxid(nTx, 0);
+ std::vector<uint256> vTxid(nTx, uint256());
for (unsigned int j=0; j<nTx; j++)
vTxid[j] = block.vtx[j].GetHash();
int nHeight = 1, nTx_ = nTx;
@@ -60,7 +63,7 @@ BOOST_AUTO_TEST_CASE(pmt_test1)
std::vector<bool> vMatch(nTx, false);
std::vector<uint256> vMatchTxid1;
for (unsigned int j=0; j<nTx; j++) {
- bool fInclude = (rand() & ((1 << (att/2)) - 1)) == 0;
+ bool fInclude = (insecure_rand() & ((1 << (att/2)) - 1)) == 0;
vMatch[j] = fInclude;
if (fInclude)
vMatchTxid1.push_back(vTxid[j]);
@@ -87,7 +90,7 @@ BOOST_AUTO_TEST_CASE(pmt_test1)
// check that it has the same merkle root as the original, and a valid one
BOOST_CHECK(merkleRoot1 == merkleRoot2);
- BOOST_CHECK(merkleRoot2 != 0);
+ BOOST_CHECK(!merkleRoot2.IsNull());
// check that it contains the matched transactions (in the same order!)
BOOST_CHECK(vMatchTxid1 == vMatchTxid2);
@@ -104,4 +107,20 @@ BOOST_AUTO_TEST_CASE(pmt_test1)
}
}
+BOOST_AUTO_TEST_CASE(pmt_malleability)
+{
+ std::vector<uint256> vTxid = boost::assign::list_of
+ (ArithToUint256(1))(ArithToUint256(2))
+ (ArithToUint256(3))(ArithToUint256(4))
+ (ArithToUint256(5))(ArithToUint256(6))
+ (ArithToUint256(7))(ArithToUint256(8))
+ (ArithToUint256(9))(ArithToUint256(10))
+ (ArithToUint256(9))(ArithToUint256(10));
+ std::vector<bool> vMatch = boost::assign::list_of(false)(false)(false)(false)(false)(false)(false)(false)(false)(true)(true)(false);
+
+ CPartialMerkleTree tree(vTxid, vMatch);
+ std::vector<uint256> vTxid2;
+ BOOST_CHECK(tree.ExtractMatches(vTxid).IsNull());
+}
+
BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/rpc_wallet_tests.cpp b/src/test/rpc_wallet_tests.cpp
index a83bd120ca..57c49c2dfc 100644
--- a/src/test/rpc_wallet_tests.cpp
+++ b/src/test/rpc_wallet_tests.cpp
@@ -93,6 +93,13 @@ BOOST_AUTO_TEST_CASE(rpc_wallet)
/* 1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4X (33 chars) is an illegal address (should be 34 chars) */
BOOST_CHECK_THROW(CallRPC("setaccount 1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4X nullaccount"), runtime_error);
+
+ /*********************************
+ * getbalance
+ *********************************/
+ BOOST_CHECK_NO_THROW(CallRPC("getbalance"));
+ BOOST_CHECK_NO_THROW(CallRPC("getbalance " + demoAddress.ToString()));
+
/*********************************
* listunspent
*********************************/
@@ -125,6 +132,35 @@ BOOST_AUTO_TEST_CASE(rpc_wallet)
BOOST_CHECK_THROW(CallRPC("listreceivedbyaccount 0 true extra"), runtime_error);
/*********************************
+ * listsinceblock
+ *********************************/
+ BOOST_CHECK_NO_THROW(CallRPC("listsinceblock"));
+
+ /*********************************
+ * listtransactions
+ *********************************/
+ BOOST_CHECK_NO_THROW(CallRPC("listtransactions"));
+ BOOST_CHECK_NO_THROW(CallRPC("listtransactions " + demoAddress.ToString()));
+ BOOST_CHECK_NO_THROW(CallRPC("listtransactions " + demoAddress.ToString() + " 20"));
+ BOOST_CHECK_NO_THROW(CallRPC("listtransactions " + demoAddress.ToString() + " 20 0"));
+ BOOST_CHECK_THROW(CallRPC("listtransactions " + demoAddress.ToString() + " not_int"), runtime_error);
+
+ /*********************************
+ * listlockunspent
+ *********************************/
+ BOOST_CHECK_NO_THROW(CallRPC("listlockunspent"));
+
+ /*********************************
+ * listaccounts
+ *********************************/
+ BOOST_CHECK_NO_THROW(CallRPC("listaccounts"));
+
+ /*********************************
+ * listaddressgroupings
+ *********************************/
+ BOOST_CHECK_NO_THROW(CallRPC("listaddressgroupings"));
+
+ /*********************************
* getrawchangeaddress
*********************************/
BOOST_CHECK_NO_THROW(CallRPC("getrawchangeaddress"));
@@ -179,5 +215,4 @@ BOOST_AUTO_TEST_CASE(rpc_wallet)
BOOST_CHECK(CBitcoinAddress(arr[0].get_str()).Get() == demoAddress.Get());
}
-
BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/sanity_tests.cpp b/src/test/sanity_tests.cpp
new file mode 100644
index 0000000000..464a8fbb8c
--- /dev/null
+++ b/src/test/sanity_tests.cpp
@@ -0,0 +1,18 @@
+// Copyright (c) 2012-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "compat/sanity.h"
+#include "key.h"
+
+#include <boost/test/unit_test.hpp>
+BOOST_AUTO_TEST_SUITE(sanity_tests)
+
+BOOST_AUTO_TEST_CASE(basic_sanity)
+{
+ BOOST_CHECK_MESSAGE(glibc_sanity_test() == true, "libc sanity test");
+ BOOST_CHECK_MESSAGE(glibcxx_sanity_test() == true, "stdlib sanity test");
+ BOOST_CHECK_MESSAGE(ECC_InitSanityCheck() == true, "openssl ECC test");
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/script_P2SH_tests.cpp b/src/test/script_P2SH_tests.cpp
index 63553556ec..94f2ce1a29 100644
--- a/src/test/script_P2SH_tests.cpp
+++ b/src/test/script_P2SH_tests.cpp
@@ -43,7 +43,7 @@ Verify(const CScript& scriptSig, const CScript& scriptPubKey, bool fStrict, Scri
txTo.vin[0].scriptSig = scriptSig;
txTo.vout[0].nValue = 1;
- return VerifyScript(scriptSig, scriptPubKey, fStrict ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE, SignatureChecker(txTo, 0), &err);
+ return VerifyScript(scriptSig, scriptPubKey, fStrict ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE, MutableTransactionSignatureChecker(&txTo, 0), &err);
}
@@ -210,7 +210,7 @@ BOOST_AUTO_TEST_CASE(set)
BOOST_AUTO_TEST_CASE(is)
{
// Test CScript::IsPayToScriptHash()
- uint160 dummy(0);
+ uint160 dummy;
CScript p2sh;
p2sh << OP_HASH160 << ToByteVector(dummy) << OP_EQUAL;
BOOST_CHECK(p2sh.IsPayToScriptHash());
diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp
index 4d2a9aff45..6092afd782 100644
--- a/src/test/script_tests.cpp
+++ b/src/test/script_tests.cpp
@@ -23,12 +23,6 @@
#include <string>
#include <vector>
-#include <boost/algorithm/string/classification.hpp>
-#include <boost/algorithm/string/predicate.hpp>
-#include <boost/algorithm/string/replace.hpp>
-#include <boost/algorithm/string/split.hpp>
-#include <boost/filesystem/operations.hpp>
-#include <boost/filesystem/path.hpp>
#include <boost/foreach.hpp>
#include <boost/test/unit_test.hpp>
#include "json/json_spirit_reader_template.h"
@@ -37,7 +31,6 @@
using namespace std;
using namespace json_spirit;
-using namespace boost::algorithm;
// Uncomment if you want to output updated JSON tests.
// #define UPDATE_JSON_TESTS
@@ -100,7 +93,7 @@ void DoTest(const CScript& scriptPubKey, const CScript& scriptSig, int flags, bo
ScriptError err;
CMutableTransaction tx = BuildSpendingTransaction(scriptSig, BuildCreditingTransaction(scriptPubKey));
CMutableTransaction tx2 = tx;
- BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, flags, SignatureChecker(tx, 0), &err) == expect, message);
+ BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, flags, MutableTransactionSignatureChecker(&tx, 0), &err) == expect, message);
BOOST_CHECK_MESSAGE(expect == (err == SCRIPT_ERR_OK), std::string(ScriptErrorString(err)) + ": " + message);
#if defined(HAVE_CONSENSUS_LIB)
CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
@@ -413,6 +406,79 @@ BOOST_AUTO_TEST_CASE(script_build)
"P2PK NOT with too much R padding", SCRIPT_VERIFY_DERSIG
).PushSig(keys.key2, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000"));
+ good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
+ "BIP66 example 1, without DERSIG", 0
+ ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220"));
+ bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
+ "BIP66 example 1, with DERSIG", SCRIPT_VERIFY_DERSIG
+ ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220"));
+ bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG << OP_NOT,
+ "BIP66 example 2, without DERSIG", 0
+ ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220"));
+ bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG << OP_NOT,
+ "BIP66 example 2, with DERSIG", SCRIPT_VERIFY_DERSIG
+ ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220"));
+ bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
+ "BIP66 example 3, without DERSIG", 0
+ ).Num(0));
+ bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
+ "BIP66 example 3, with DERSIG", SCRIPT_VERIFY_DERSIG
+ ).Num(0));
+ good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG << OP_NOT,
+ "BIP66 example 4, without DERSIG", 0
+ ).Num(0));
+ good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG << OP_NOT,
+ "BIP66 example 4, with DERSIG", SCRIPT_VERIFY_DERSIG
+ ).Num(0));
+ bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
+ "BIP66 example 5, without DERSIG", 0
+ ).Num(1));
+ bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
+ "BIP66 example 5, with DERSIG", SCRIPT_VERIFY_DERSIG
+ ).Num(1));
+ good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG << OP_NOT,
+ "BIP66 example 6, without DERSIG", 0
+ ).Num(1));
+ bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG << OP_NOT,
+ "BIP66 example 6, with DERSIG", SCRIPT_VERIFY_DERSIG
+ ).Num(1));
+ good.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG,
+ "BIP66 example 7, without DERSIG", 0
+ ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").PushSig(keys.key2));
+ bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG,
+ "BIP66 example 7, with DERSIG", SCRIPT_VERIFY_DERSIG
+ ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").PushSig(keys.key2));
+ bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT,
+ "BIP66 example 8, without DERSIG", 0
+ ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").PushSig(keys.key2));
+ bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT,
+ "BIP66 example 8, with DERSIG", SCRIPT_VERIFY_DERSIG
+ ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").PushSig(keys.key2));
+ bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG,
+ "BIP66 example 9, without DERSIG", 0
+ ).Num(0).Num(0).PushSig(keys.key2, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220"));
+ bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG,
+ "BIP66 example 9, with DERSIG", SCRIPT_VERIFY_DERSIG
+ ).Num(0).Num(0).PushSig(keys.key2, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220"));
+ good.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT,
+ "BIP66 example 10, without DERSIG", 0
+ ).Num(0).Num(0).PushSig(keys.key2, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220"));
+ bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT,
+ "BIP66 example 10, with DERSIG", SCRIPT_VERIFY_DERSIG
+ ).Num(0).Num(0).PushSig(keys.key2, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220"));
+ bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG,
+ "BIP66 example 11, without DERSIG", 0
+ ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").Num(0));
+ bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG,
+ "BIP66 example 11, with DERSIG", SCRIPT_VERIFY_DERSIG
+ ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").Num(0));
+ good.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT,
+ "BIP66 example 12, without DERSIG", 0
+ ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").Num(0));
+ good.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT,
+ "BIP66 example 12, with DERSIG", SCRIPT_VERIFY_DERSIG
+ ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").Num(0));
+
good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG,
"P2PK with high S but no LOW_S", 0
).PushSig(keys.key2, SIGHASH_ALL, 32, 33));
@@ -490,6 +556,22 @@ BOOST_AUTO_TEST_CASE(script_build)
"2-of-2 with two identical keys and sigs pushed", SCRIPT_VERIFY_SIGPUSHONLY
).Num(0).PushSig(keys.key1).PushSig(keys.key1));
+ good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
+ "P2PK with unnecessary input but no CLEANSTACK", SCRIPT_VERIFY_P2SH
+ ).Num(11).PushSig(keys.key0));
+ bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
+ "P2PK with unnecessary input", SCRIPT_VERIFY_CLEANSTACK | SCRIPT_VERIFY_P2SH
+ ).Num(11).PushSig(keys.key0));
+ good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
+ "P2SH with unnecessary input but no CLEANSTACK", SCRIPT_VERIFY_P2SH, true
+ ).Num(11).PushSig(keys.key0).PushRedeem());
+ bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
+ "P2SH with unnecessary input", SCRIPT_VERIFY_CLEANSTACK | SCRIPT_VERIFY_P2SH, true
+ ).Num(11).PushSig(keys.key0).PushRedeem());
+ good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
+ "P2SH with CLEANSTACK", SCRIPT_VERIFY_CLEANSTACK | SCRIPT_VERIFY_P2SH, true
+ ).PushSig(keys.key0).PushRedeem());
+
std::set<std::string> tests_good;
std::set<std::string> tests_bad;
@@ -607,21 +689,21 @@ BOOST_AUTO_TEST_CASE(script_PushData)
ScriptError err;
vector<vector<unsigned char> > directStack;
- BOOST_CHECK(EvalScript(directStack, CScript(&direct[0], &direct[sizeof(direct)]), true, BaseSignatureChecker(), &err));
+ BOOST_CHECK(EvalScript(directStack, CScript(&direct[0], &direct[sizeof(direct)]), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
vector<vector<unsigned char> > pushdata1Stack;
- BOOST_CHECK(EvalScript(pushdata1Stack, CScript(&pushdata1[0], &pushdata1[sizeof(pushdata1)]), true, BaseSignatureChecker(), &err));
+ BOOST_CHECK(EvalScript(pushdata1Stack, CScript(&pushdata1[0], &pushdata1[sizeof(pushdata1)]), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), &err));
BOOST_CHECK(pushdata1Stack == directStack);
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
vector<vector<unsigned char> > pushdata2Stack;
- BOOST_CHECK(EvalScript(pushdata2Stack, CScript(&pushdata2[0], &pushdata2[sizeof(pushdata2)]), true, BaseSignatureChecker(), &err));
+ BOOST_CHECK(EvalScript(pushdata2Stack, CScript(&pushdata2[0], &pushdata2[sizeof(pushdata2)]), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), &err));
BOOST_CHECK(pushdata2Stack == directStack);
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
vector<vector<unsigned char> > pushdata4Stack;
- BOOST_CHECK(EvalScript(pushdata4Stack, CScript(&pushdata4[0], &pushdata4[sizeof(pushdata4)]), true, BaseSignatureChecker(), &err));
+ BOOST_CHECK(EvalScript(pushdata4Stack, CScript(&pushdata4[0], &pushdata4[sizeof(pushdata4)]), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), &err));
BOOST_CHECK(pushdata4Stack == directStack);
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
}
@@ -673,18 +755,18 @@ BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG12)
CMutableTransaction txTo12 = BuildSpendingTransaction(CScript(), txFrom12);
CScript goodsig1 = sign_multisig(scriptPubKey12, key1, txTo12);
- BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey12, flags, SignatureChecker(txTo12, 0), &err));
+ BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey12, flags, MutableTransactionSignatureChecker(&txTo12, 0), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
txTo12.vout[0].nValue = 2;
- BOOST_CHECK(!VerifyScript(goodsig1, scriptPubKey12, flags, SignatureChecker(txTo12, 0), &err));
+ BOOST_CHECK(!VerifyScript(goodsig1, scriptPubKey12, flags, MutableTransactionSignatureChecker(&txTo12, 0), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
CScript goodsig2 = sign_multisig(scriptPubKey12, key2, txTo12);
- BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey12, flags, SignatureChecker(txTo12, 0), &err));
+ BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey12, flags, MutableTransactionSignatureChecker(&txTo12, 0), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
CScript badsig1 = sign_multisig(scriptPubKey12, key3, txTo12);
- BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey12, flags, SignatureChecker(txTo12, 0), &err));
+ BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey12, flags, MutableTransactionSignatureChecker(&txTo12, 0), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
}
@@ -706,54 +788,54 @@ BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG23)
std::vector<CKey> keys;
keys.push_back(key1); keys.push_back(key2);
CScript goodsig1 = sign_multisig(scriptPubKey23, keys, txTo23);
- BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey23, flags, SignatureChecker(txTo23, 0), &err));
+ BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
keys.clear();
keys.push_back(key1); keys.push_back(key3);
CScript goodsig2 = sign_multisig(scriptPubKey23, keys, txTo23);
- BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey23, flags, SignatureChecker(txTo23, 0), &err));
+ BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
keys.clear();
keys.push_back(key2); keys.push_back(key3);
CScript goodsig3 = sign_multisig(scriptPubKey23, keys, txTo23);
- BOOST_CHECK(VerifyScript(goodsig3, scriptPubKey23, flags, SignatureChecker(txTo23, 0), &err));
+ BOOST_CHECK(VerifyScript(goodsig3, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
keys.clear();
keys.push_back(key2); keys.push_back(key2); // Can't re-use sig
CScript badsig1 = sign_multisig(scriptPubKey23, keys, txTo23);
- BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey23, flags, SignatureChecker(txTo23, 0), &err));
+ BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
keys.clear();
keys.push_back(key2); keys.push_back(key1); // sigs must be in correct order
CScript badsig2 = sign_multisig(scriptPubKey23, keys, txTo23);
- BOOST_CHECK(!VerifyScript(badsig2, scriptPubKey23, flags, SignatureChecker(txTo23, 0), &err));
+ BOOST_CHECK(!VerifyScript(badsig2, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
keys.clear();
keys.push_back(key3); keys.push_back(key2); // sigs must be in correct order
CScript badsig3 = sign_multisig(scriptPubKey23, keys, txTo23);
- BOOST_CHECK(!VerifyScript(badsig3, scriptPubKey23, flags, SignatureChecker(txTo23, 0), &err));
+ BOOST_CHECK(!VerifyScript(badsig3, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
keys.clear();
keys.push_back(key4); keys.push_back(key2); // sigs must match pubkeys
CScript badsig4 = sign_multisig(scriptPubKey23, keys, txTo23);
- BOOST_CHECK(!VerifyScript(badsig4, scriptPubKey23, flags, SignatureChecker(txTo23, 0), &err));
+ BOOST_CHECK(!VerifyScript(badsig4, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
keys.clear();
keys.push_back(key1); keys.push_back(key4); // sigs must match pubkeys
CScript badsig5 = sign_multisig(scriptPubKey23, keys, txTo23);
- BOOST_CHECK(!VerifyScript(badsig5, scriptPubKey23, flags, SignatureChecker(txTo23, 0), &err));
+ BOOST_CHECK(!VerifyScript(badsig5, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
keys.clear(); // Must have signatures
CScript badsig6 = sign_multisig(scriptPubKey23, keys, txTo23);
- BOOST_CHECK(!VerifyScript(badsig6, scriptPubKey23, flags, SignatureChecker(txTo23, 0), &err));
+ BOOST_CHECK(!VerifyScript(badsig6, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_INVALID_STACK_OPERATION, ScriptErrorString(err));
}
diff --git a/src/test/sighash_tests.cpp b/src/test/sighash_tests.cpp
index a9d2f9e8ca..ea41dbcde2 100644
--- a/src/test/sighash_tests.cpp
+++ b/src/test/sighash_tests.cpp
@@ -24,10 +24,11 @@ extern Array read_json(const std::string& jsondata);
// Old script.cpp SignatureHash function
uint256 static SignatureHashOld(CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType)
{
+ static const uint256 one(uint256S("0000000000000000000000000000000000000000000000000000000000000001"));
if (nIn >= txTo.vin.size())
{
- printf("ERROR: SignatureHash() : nIn=%d out of range\n", nIn);
- return 1;
+ printf("ERROR: SignatureHash(): nIn=%d out of range\n", nIn);
+ return one;
}
CMutableTransaction txTmp(txTo);
@@ -57,8 +58,8 @@ uint256 static SignatureHashOld(CScript scriptCode, const CTransaction& txTo, un
unsigned int nOut = nIn;
if (nOut >= txTmp.vout.size())
{
- printf("ERROR: SignatureHash() : nOut=%d out of range\n", nOut);
- return 1;
+ printf("ERROR: SignatureHash(): nOut=%d out of range\n", nOut);
+ return one;
}
txTmp.vout.resize(nOut+1);
for (unsigned int i = 0; i < nOut; i++)
diff --git a/src/test/sigopcount_tests.cpp b/src/test/sigopcount_tests.cpp
index 3326601492..3c8264d89d 100644
--- a/src/test/sigopcount_tests.cpp
+++ b/src/test/sigopcount_tests.cpp
@@ -32,7 +32,7 @@ BOOST_AUTO_TEST_CASE(GetSigOpCount)
BOOST_CHECK_EQUAL(s1.GetSigOpCount(false), 0U);
BOOST_CHECK_EQUAL(s1.GetSigOpCount(true), 0U);
- uint160 dummy(0);
+ uint160 dummy;
s1 << OP_1 << ToByteVector(dummy) << ToByteVector(dummy) << OP_2 << OP_CHECKMULTISIG;
BOOST_CHECK_EQUAL(s1.GetSigOpCount(true), 2U);
s1 << OP_IF << OP_CHECKSIG << OP_ENDIF;
diff --git a/src/test/skiplist_tests.cpp b/src/test/skiplist_tests.cpp
index 646c7e6ade..c75e21a2ad 100644
--- a/src/test/skiplist_tests.cpp
+++ b/src/test/skiplist_tests.cpp
@@ -49,12 +49,12 @@ BOOST_AUTO_TEST_CASE(getlocator_test)
std::vector<uint256> vHashMain(100000);
std::vector<CBlockIndex> vBlocksMain(100000);
for (unsigned int i=0; i<vBlocksMain.size(); i++) {
- vHashMain[i] = i; // Set the hash equal to the height, so we can quickly check the distances.
+ vHashMain[i] = ArithToUint256(i); // Set the hash equal to the height, so we can quickly check the distances.
vBlocksMain[i].nHeight = i;
vBlocksMain[i].pprev = i ? &vBlocksMain[i - 1] : NULL;
vBlocksMain[i].phashBlock = &vHashMain[i];
vBlocksMain[i].BuildSkip();
- BOOST_CHECK_EQUAL((int)vBlocksMain[i].GetBlockHash().GetLow64(), vBlocksMain[i].nHeight);
+ BOOST_CHECK_EQUAL((int)UintToArith256(vBlocksMain[i].GetBlockHash()).GetLow64(), vBlocksMain[i].nHeight);
BOOST_CHECK(vBlocksMain[i].pprev == NULL || vBlocksMain[i].nHeight == vBlocksMain[i].pprev->nHeight + 1);
}
@@ -62,12 +62,12 @@ BOOST_AUTO_TEST_CASE(getlocator_test)
std::vector<uint256> vHashSide(50000);
std::vector<CBlockIndex> vBlocksSide(50000);
for (unsigned int i=0; i<vBlocksSide.size(); i++) {
- vHashSide[i] = i + 50000 + (uint256(1) << 128); // Add 1<<128 to the hashes, so GetLow64() still returns the height.
+ vHashSide[i] = ArithToUint256(i + 50000 + (arith_uint256(1) << 128)); // Add 1<<128 to the hashes, so GetLow64() still returns the height.
vBlocksSide[i].nHeight = i + 50000;
vBlocksSide[i].pprev = i ? &vBlocksSide[i - 1] : &vBlocksMain[49999];
vBlocksSide[i].phashBlock = &vHashSide[i];
vBlocksSide[i].BuildSkip();
- BOOST_CHECK_EQUAL((int)vBlocksSide[i].GetBlockHash().GetLow64(), vBlocksSide[i].nHeight);
+ BOOST_CHECK_EQUAL((int)UintToArith256(vBlocksSide[i].GetBlockHash()).GetLow64(), vBlocksSide[i].nHeight);
BOOST_CHECK(vBlocksSide[i].pprev == NULL || vBlocksSide[i].nHeight == vBlocksSide[i].pprev->nHeight + 1);
}
@@ -87,13 +87,13 @@ BOOST_AUTO_TEST_CASE(getlocator_test)
// Entries 1 through 11 (inclusive) go back one step each.
for (unsigned int i = 1; i < 12 && i < locator.vHave.size() - 1; i++) {
- BOOST_CHECK_EQUAL(locator.vHave[i].GetLow64(), tip->nHeight - i);
+ BOOST_CHECK_EQUAL(UintToArith256(locator.vHave[i]).GetLow64(), tip->nHeight - i);
}
// The further ones (excluding the last one) go back with exponential steps.
unsigned int dist = 2;
for (unsigned int i = 12; i < locator.vHave.size() - 1; i++) {
- BOOST_CHECK_EQUAL(locator.vHave[i - 1].GetLow64() - locator.vHave[i].GetLow64(), dist);
+ BOOST_CHECK_EQUAL(UintToArith256(locator.vHave[i - 1]).GetLow64() - UintToArith256(locator.vHave[i]).GetLow64(), dist);
dist *= 2;
}
}
diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp
index 2594f89ac3..52adfea992 100644
--- a/src/test/transaction_tests.cpp
+++ b/src/test/transaction_tests.cpp
@@ -24,7 +24,6 @@
using namespace std;
using namespace json_spirit;
-using namespace boost::algorithm;
// In script_tests.cpp
extern Array read_json(const std::string& jsondata);
@@ -38,7 +37,8 @@ static std::map<string, unsigned int> mapFlagNames = boost::assign::map_list_of
(string("SIGPUSHONLY"), (unsigned int)SCRIPT_VERIFY_SIGPUSHONLY)
(string("MINIMALDATA"), (unsigned int)SCRIPT_VERIFY_MINIMALDATA)
(string("NULLDUMMY"), (unsigned int)SCRIPT_VERIFY_NULLDUMMY)
- (string("DISCOURAGE_UPGRADABLE_NOPS"), (unsigned int)SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS);
+ (string("DISCOURAGE_UPGRADABLE_NOPS"), (unsigned int)SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS)
+ (string("CLEANSTACK"), (unsigned int)SCRIPT_VERIFY_CLEANSTACK);
unsigned int ParseScriptFlags(string strFlags)
{
@@ -47,7 +47,7 @@ unsigned int ParseScriptFlags(string strFlags)
}
unsigned int flags = 0;
vector<string> words;
- split(words, strFlags, is_any_of(","));
+ boost::algorithm::split(words, strFlags, boost::algorithm::is_any_of(","));
BOOST_FOREACH(string word, words)
{
@@ -118,7 +118,7 @@ BOOST_AUTO_TEST_CASE(tx_valid)
break;
}
- mapprevOutScriptPubKeys[COutPoint(uint256(vinput[0].get_str()), vinput[1].get_int())] = ParseScript(vinput[2].get_str());
+ mapprevOutScriptPubKeys[COutPoint(uint256S(vinput[0].get_str()), vinput[1].get_int())] = ParseScript(vinput[2].get_str());
}
if (!fValid)
{
@@ -145,7 +145,7 @@ BOOST_AUTO_TEST_CASE(tx_valid)
unsigned int verify_flags = ParseScriptFlags(test[2].get_str());
BOOST_CHECK_MESSAGE(VerifyScript(tx.vin[i].scriptSig, mapprevOutScriptPubKeys[tx.vin[i].prevout],
- verify_flags, SignatureChecker(tx, i), &err),
+ verify_flags, TransactionSignatureChecker(&tx, i), &err),
strTest);
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
}
@@ -194,7 +194,7 @@ BOOST_AUTO_TEST_CASE(tx_invalid)
break;
}
- mapprevOutScriptPubKeys[COutPoint(uint256(vinput[0].get_str()), vinput[1].get_int())] = ParseScript(vinput[2].get_str());
+ mapprevOutScriptPubKeys[COutPoint(uint256S(vinput[0].get_str()), vinput[1].get_int())] = ParseScript(vinput[2].get_str());
}
if (!fValid)
{
@@ -220,7 +220,7 @@ BOOST_AUTO_TEST_CASE(tx_invalid)
unsigned int verify_flags = ParseScriptFlags(test[2].get_str());
fValid = VerifyScript(tx.vin[i].scriptSig, mapprevOutScriptPubKeys[tx.vin[i].prevout],
- verify_flags, SignatureChecker(tx, i), &err);
+ verify_flags, TransactionSignatureChecker(&tx, i), &err);
}
BOOST_CHECK_MESSAGE(!fValid, strTest);
BOOST_CHECK_MESSAGE(err != SCRIPT_ERR_OK, ScriptErrorString(err));
@@ -347,12 +347,12 @@ BOOST_AUTO_TEST_CASE(test_IsStandard)
t.vout[0].scriptPubKey = CScript() << OP_1;
BOOST_CHECK(!IsStandardTx(t, reason));
- // 40-byte TX_NULL_DATA (standard)
- t.vout[0].scriptPubKey = CScript() << OP_RETURN << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38");
+ // 80-byte TX_NULL_DATA (standard)
+ t.vout[0].scriptPubKey = CScript() << OP_RETURN << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3804678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38");
BOOST_CHECK(IsStandardTx(t, reason));
- // 41-byte TX_NULL_DATA (non-standard)
- t.vout[0].scriptPubKey = CScript() << OP_RETURN << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3800");
+ // 81-byte TX_NULL_DATA (non-standard)
+ t.vout[0].scriptPubKey = CScript() << OP_RETURN << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3804678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3800");
BOOST_CHECK(!IsStandardTx(t, reason));
// TX_NULL_DATA w/o PUSHDATA
diff --git a/src/test/uint256_tests.cpp b/src/test/uint256_tests.cpp
index d05b28956c..5b33846ba9 100644
--- a/src/test/uint256_tests.cpp
+++ b/src/test/uint256_tests.cpp
@@ -1,6 +1,9 @@
// Copyright (c) 2011-2013 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#include "arith_uint256.h"
+#include "uint256.h"
+#include "version.h"
#include <boost/test/unit_test.hpp>
#include <stdint.h>
@@ -8,61 +11,66 @@
#include <iomanip>
#include <limits>
#include <cmath>
-#include "uint256.h"
#include <string>
-#include "version.h"
+#include <stdio.h>
BOOST_AUTO_TEST_SUITE(uint256_tests)
-
-const unsigned char R1Array[] =
+
+const unsigned char R1Array[] =
"\x9c\x52\x4a\xdb\xcf\x56\x11\x12\x2b\x29\x12\x5e\x5d\x35\xd2\xd2"
"\x22\x81\xaa\xb5\x33\xf0\x08\x32\xd5\x56\xb1\xf9\xea\xe5\x1d\x7d";
const char R1ArrayHex[] = "7D1DE5EAF9B156D53208F033B5AA8122D2d2355d5e12292b121156cfdb4a529c";
-const double R1Ldouble = 0.4887374590559308955; // R1L equals roughly R1Ldouble * 2^256
-const double R1Sdouble = 0.7096329412477836074;
const uint256 R1L = uint256(std::vector<unsigned char>(R1Array,R1Array+32));
const uint160 R1S = uint160(std::vector<unsigned char>(R1Array,R1Array+20));
-const uint64_t R1LLow64 = 0x121156cfdb4a529cULL;
-const unsigned char R2Array[] =
+const unsigned char R2Array[] =
"\x70\x32\x1d\x7c\x47\xa5\x6b\x40\x26\x7e\x0a\xc3\xa6\x9c\xb6\xbf"
"\x13\x30\x47\xa3\x19\x2d\xda\x71\x49\x13\x72\xf0\xb4\xca\x81\xd7";
const uint256 R2L = uint256(std::vector<unsigned char>(R2Array,R2Array+32));
const uint160 R2S = uint160(std::vector<unsigned char>(R2Array,R2Array+20));
-const char R1LplusR2L[] = "549FB09FEA236A1EA3E31D4D58F1B1369288D204211CA751527CFC175767850C";
-
-const unsigned char ZeroArray[] =
+const unsigned char ZeroArray[] =
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
const uint256 ZeroL = uint256(std::vector<unsigned char>(ZeroArray,ZeroArray+32));
const uint160 ZeroS = uint160(std::vector<unsigned char>(ZeroArray,ZeroArray+20));
-
-const unsigned char OneArray[] =
+
+const unsigned char OneArray[] =
"\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
const uint256 OneL = uint256(std::vector<unsigned char>(OneArray,OneArray+32));
const uint160 OneS = uint160(std::vector<unsigned char>(OneArray,OneArray+20));
-const unsigned char MaxArray[] =
+const unsigned char MaxArray[] =
"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff";
const uint256 MaxL = uint256(std::vector<unsigned char>(MaxArray,MaxArray+32));
const uint160 MaxS = uint160(std::vector<unsigned char>(MaxArray,MaxArray+20));
-const uint256 HalfL = (OneL << 255);
-const uint160 HalfS = (OneS << 159);
std::string ArrayToString(const unsigned char A[], unsigned int width)
{
std::stringstream Stream;
Stream << std::hex;
- for (unsigned int i = 0; i < width; ++i)
+ for (unsigned int i = 0; i < width; ++i)
{
Stream<<std::setw(2)<<std::setfill('0')<<(unsigned int)A[width-i-1];
- }
+ }
return Stream.str();
}
+inline uint160 uint160S(const char *str)
+{
+ uint160 rv;
+ rv.SetHex(str);
+ return rv;
+}
+inline uint160 uint160S(const std::string& str)
+{
+ uint160 rv;
+ rv.SetHex(str);
+ return rv;
+}
+
BOOST_AUTO_TEST_CASE( basics ) // constructors, equality, inequality
{
BOOST_CHECK(1 == 0+1);
@@ -85,477 +93,66 @@ BOOST_AUTO_TEST_CASE( basics ) // constructors, equality, inequality
BOOST_CHECK(ZeroL != OneL && ZeroS != OneS);
BOOST_CHECK(OneL != ZeroL && OneS != ZeroS);
BOOST_CHECK(MaxL != ZeroL && MaxS != ZeroS);
- BOOST_CHECK(~MaxL == ZeroL && ~MaxS == ZeroS);
- BOOST_CHECK( ((R1L ^ R2L) ^ R1L) == R2L);
- BOOST_CHECK( ((R1S ^ R2S) ^ R1S) == R2S);
-
- uint64_t Tmp64 = 0xc4dab720d9c7acaaULL;
- for (unsigned int i = 0; i < 256; ++i)
- {
- BOOST_CHECK(ZeroL != (OneL << i));
- BOOST_CHECK((OneL << i) != ZeroL);
- BOOST_CHECK(R1L != (R1L ^ (OneL << i)));
- BOOST_CHECK(((uint256(Tmp64) ^ (OneL << i) ) != Tmp64 ));
- }
- BOOST_CHECK(ZeroL == (OneL << 256));
-
- for (unsigned int i = 0; i < 160; ++i)
- {
- BOOST_CHECK(ZeroS != (OneS << i));
- BOOST_CHECK((OneS << i) != ZeroS);
- BOOST_CHECK(R1S != (R1S ^ (OneS << i)));
- BOOST_CHECK(((uint160(Tmp64) ^ (OneS << i) ) != Tmp64 ));
- }
- BOOST_CHECK(ZeroS == (OneS << 256));
// String Constructor and Copy Constructor
- BOOST_CHECK(uint256("0x"+R1L.ToString()) == R1L);
- BOOST_CHECK(uint256("0x"+R2L.ToString()) == R2L);
- BOOST_CHECK(uint256("0x"+ZeroL.ToString()) == ZeroL);
- BOOST_CHECK(uint256("0x"+OneL.ToString()) == OneL);
- BOOST_CHECK(uint256("0x"+MaxL.ToString()) == MaxL);
- BOOST_CHECK(uint256(R1L.ToString()) == R1L);
- BOOST_CHECK(uint256(" 0x"+R1L.ToString()+" ") == R1L);
- BOOST_CHECK(uint256("") == ZeroL);
- BOOST_CHECK(R1L == uint256(R1ArrayHex));
+ BOOST_CHECK(uint256S("0x"+R1L.ToString()) == R1L);
+ BOOST_CHECK(uint256S("0x"+R2L.ToString()) == R2L);
+ BOOST_CHECK(uint256S("0x"+ZeroL.ToString()) == ZeroL);
+ BOOST_CHECK(uint256S("0x"+OneL.ToString()) == OneL);
+ BOOST_CHECK(uint256S("0x"+MaxL.ToString()) == MaxL);
+ BOOST_CHECK(uint256S(R1L.ToString()) == R1L);
+ BOOST_CHECK(uint256S(" 0x"+R1L.ToString()+" ") == R1L);
+ BOOST_CHECK(uint256S("") == ZeroL);
+ BOOST_CHECK(R1L == uint256S(R1ArrayHex));
BOOST_CHECK(uint256(R1L) == R1L);
- BOOST_CHECK((uint256(R1L^R2L)^R2L) == R1L);
BOOST_CHECK(uint256(ZeroL) == ZeroL);
BOOST_CHECK(uint256(OneL) == OneL);
- BOOST_CHECK(uint160("0x"+R1S.ToString()) == R1S);
- BOOST_CHECK(uint160("0x"+R2S.ToString()) == R2S);
- BOOST_CHECK(uint160("0x"+ZeroS.ToString()) == ZeroS);
- BOOST_CHECK(uint160("0x"+OneS.ToString()) == OneS);
- BOOST_CHECK(uint160("0x"+MaxS.ToString()) == MaxS);
- BOOST_CHECK(uint160(R1S.ToString()) == R1S);
- BOOST_CHECK(uint160(" 0x"+R1S.ToString()+" ") == R1S);
- BOOST_CHECK(uint160("") == ZeroS);
- BOOST_CHECK(R1S == uint160(R1ArrayHex));
+ BOOST_CHECK(uint160S("0x"+R1S.ToString()) == R1S);
+ BOOST_CHECK(uint160S("0x"+R2S.ToString()) == R2S);
+ BOOST_CHECK(uint160S("0x"+ZeroS.ToString()) == ZeroS);
+ BOOST_CHECK(uint160S("0x"+OneS.ToString()) == OneS);
+ BOOST_CHECK(uint160S("0x"+MaxS.ToString()) == MaxS);
+ BOOST_CHECK(uint160S(R1S.ToString()) == R1S);
+ BOOST_CHECK(uint160S(" 0x"+R1S.ToString()+" ") == R1S);
+ BOOST_CHECK(uint160S("") == ZeroS);
+ BOOST_CHECK(R1S == uint160S(R1ArrayHex));
BOOST_CHECK(uint160(R1S) == R1S);
- BOOST_CHECK((uint160(R1S^R2S)^R2S) == R1S);
BOOST_CHECK(uint160(ZeroS) == ZeroS);
BOOST_CHECK(uint160(OneS) == OneS);
-
- // uint64_t constructor
- BOOST_CHECK( (R1L & uint256("0xffffffffffffffff")) == uint256(R1LLow64));
- BOOST_CHECK(ZeroL == uint256(0));
- BOOST_CHECK(OneL == uint256(1));
- BOOST_CHECK(uint256("0xffffffffffffffff") = uint256(0xffffffffffffffffULL));
- BOOST_CHECK( (R1S & uint160("0xffffffffffffffff")) == uint160(R1LLow64));
- BOOST_CHECK(ZeroS == uint160(0));
- BOOST_CHECK(OneS == uint160(1));
- BOOST_CHECK(uint160("0xffffffffffffffff") = uint160(0xffffffffffffffffULL));
-
- // Assignment (from base_uint)
- uint256 tmpL = ~ZeroL; BOOST_CHECK(tmpL == ~ZeroL);
- tmpL = ~OneL; BOOST_CHECK(tmpL == ~OneL);
- tmpL = ~R1L; BOOST_CHECK(tmpL == ~R1L);
- tmpL = ~R2L; BOOST_CHECK(tmpL == ~R2L);
- tmpL = ~MaxL; BOOST_CHECK(tmpL == ~MaxL);
- uint160 tmpS = ~ZeroS; BOOST_CHECK(tmpS == ~ZeroS);
- tmpS = ~OneS; BOOST_CHECK(tmpS == ~OneS);
- tmpS = ~R1S; BOOST_CHECK(tmpS == ~R1S);
- tmpS = ~R2S; BOOST_CHECK(tmpS == ~R2S);
- tmpS = ~MaxS; BOOST_CHECK(tmpS == ~MaxS);
-
- // Wrong length must throw exception.
- BOOST_CHECK_THROW(uint256(std::vector<unsigned char>(OneArray,OneArray+31)), uint_error);
- BOOST_CHECK_THROW(uint256(std::vector<unsigned char>(OneArray,OneArray+20)), uint_error);
- BOOST_CHECK_THROW(uint160(std::vector<unsigned char>(OneArray,OneArray+32)), uint_error);
- BOOST_CHECK_THROW(uint160(std::vector<unsigned char>(OneArray,OneArray+19)), uint_error);
-}
-
-void shiftArrayRight(unsigned char* to, const unsigned char* from, unsigned int arrayLength, unsigned int bitsToShift)
-{
- for (unsigned int T=0; T < arrayLength; ++T)
- {
- unsigned int F = (T+bitsToShift/8);
- if (F < arrayLength)
- to[T] = from[F] >> (bitsToShift%8);
- else
- to[T] = 0;
- if (F + 1 < arrayLength)
- to[T] |= from[(F+1)] << (8-bitsToShift%8);
- }
-}
-
-void shiftArrayLeft(unsigned char* to, const unsigned char* from, unsigned int arrayLength, unsigned int bitsToShift)
-{
- for (unsigned int T=0; T < arrayLength; ++T)
- {
- if (T >= bitsToShift/8)
- {
- unsigned int F = T-bitsToShift/8;
- to[T] = from[F] << (bitsToShift%8);
- if (T >= bitsToShift/8+1)
- to[T] |= from[F-1] >> (8-bitsToShift%8);
- }
- else {
- to[T] = 0;
- }
- }
-}
-
-BOOST_AUTO_TEST_CASE( shifts ) { // "<<" ">>" "<<=" ">>="
- unsigned char TmpArray[32];
- uint256 TmpL;
- for (unsigned int i = 0; i < 256; ++i)
- {
- shiftArrayLeft(TmpArray, OneArray, 32, i);
- BOOST_CHECK(uint256(std::vector<unsigned char>(TmpArray,TmpArray+32)) == (OneL << i));
- TmpL = OneL; TmpL <<= i;
- BOOST_CHECK(TmpL == (OneL << i));
- BOOST_CHECK((HalfL >> (255-i)) == (OneL << i));
- TmpL = HalfL; TmpL >>= (255-i);
- BOOST_CHECK(TmpL == (OneL << i));
-
- shiftArrayLeft(TmpArray, R1Array, 32, i);
- BOOST_CHECK(uint256(std::vector<unsigned char>(TmpArray,TmpArray+32)) == (R1L << i));
- TmpL = R1L; TmpL <<= i;
- BOOST_CHECK(TmpL == (R1L << i));
-
- shiftArrayRight(TmpArray, R1Array, 32, i);
- BOOST_CHECK(uint256(std::vector<unsigned char>(TmpArray,TmpArray+32)) == (R1L >> i));
- TmpL = R1L; TmpL >>= i;
- BOOST_CHECK(TmpL == (R1L >> i));
-
- shiftArrayLeft(TmpArray, MaxArray, 32, i);
- BOOST_CHECK(uint256(std::vector<unsigned char>(TmpArray,TmpArray+32)) == (MaxL << i));
- TmpL = MaxL; TmpL <<= i;
- BOOST_CHECK(TmpL == (MaxL << i));
-
- shiftArrayRight(TmpArray, MaxArray, 32, i);
- BOOST_CHECK(uint256(std::vector<unsigned char>(TmpArray,TmpArray+32)) == (MaxL >> i));
- TmpL = MaxL; TmpL >>= i;
- BOOST_CHECK(TmpL == (MaxL >> i));
- }
- uint256 c1L = uint256(0x0123456789abcdefULL);
- uint256 c2L = c1L << 128;
- for (unsigned int i = 0; i < 128; ++i) {
- BOOST_CHECK((c1L << i) == (c2L >> (128-i)));
- }
- for (unsigned int i = 128; i < 256; ++i) {
- BOOST_CHECK((c1L << i) == (c2L << (i-128)));
- }
-
- uint160 TmpS;
- for (unsigned int i = 0; i < 160; ++i)
- {
- shiftArrayLeft(TmpArray, OneArray, 20, i);
- BOOST_CHECK(uint160(std::vector<unsigned char>(TmpArray,TmpArray+20)) == (OneS << i));
- TmpS = OneS; TmpS <<= i;
- BOOST_CHECK(TmpS == (OneS << i));
- BOOST_CHECK((HalfS >> (159-i)) == (OneS << i));
- TmpS = HalfS; TmpS >>= (159-i);
- BOOST_CHECK(TmpS == (OneS << i));
-
- shiftArrayLeft(TmpArray, R1Array, 20, i);
- BOOST_CHECK(uint160(std::vector<unsigned char>(TmpArray,TmpArray+20)) == (R1S << i));
- TmpS = R1S; TmpS <<= i;
- BOOST_CHECK(TmpS == (R1S << i));
-
- shiftArrayRight(TmpArray, R1Array, 20, i);
- BOOST_CHECK(uint160(std::vector<unsigned char>(TmpArray,TmpArray+20)) == (R1S >> i));
- TmpS = R1S; TmpS >>= i;
- BOOST_CHECK(TmpS == (R1S >> i));
-
- shiftArrayLeft(TmpArray, MaxArray, 20, i);
- BOOST_CHECK(uint160(std::vector<unsigned char>(TmpArray,TmpArray+20)) == (MaxS << i));
- TmpS = MaxS; TmpS <<= i;
- BOOST_CHECK(TmpS == (MaxS << i));
-
- shiftArrayRight(TmpArray, MaxArray, 20, i);
- BOOST_CHECK(uint160(std::vector<unsigned char>(TmpArray,TmpArray+20)) == (MaxS >> i));
- TmpS = MaxS; TmpS >>= i;
- BOOST_CHECK(TmpS == (MaxS >> i));
- }
- uint160 c1S = uint160(0x0123456789abcdefULL);
- uint160 c2S = c1S << 80;
- for (unsigned int i = 0; i < 80; ++i) {
- BOOST_CHECK((c1S << i) == (c2S >> (80-i)));
- }
- for (unsigned int i = 80; i < 160; ++i) {
- BOOST_CHECK((c1S << i) == (c2S << (i-80)));
- }
-}
-
-BOOST_AUTO_TEST_CASE( unaryOperators ) // ! ~ -
-{
- BOOST_CHECK(!ZeroL); BOOST_CHECK(!ZeroS);
- BOOST_CHECK(!(!OneL));BOOST_CHECK(!(!OneS));
- for (unsigned int i = 0; i < 256; ++i)
- BOOST_CHECK(!(!(OneL<<i)));
- for (unsigned int i = 0; i < 160; ++i)
- BOOST_CHECK(!(!(OneS<<i)));
- BOOST_CHECK(!(!R1L));BOOST_CHECK(!(!R1S));
- BOOST_CHECK(!(!R2S));BOOST_CHECK(!(!R2S));
- BOOST_CHECK(!(!MaxL));BOOST_CHECK(!(!MaxS));
-
- BOOST_CHECK(~ZeroL == MaxL); BOOST_CHECK(~ZeroS == MaxS);
-
- unsigned char TmpArray[32];
- for (unsigned int i = 0; i < 32; ++i) { TmpArray[i] = ~R1Array[i]; }
- BOOST_CHECK(uint256(std::vector<unsigned char>(TmpArray,TmpArray+32)) == (~R1L));
- BOOST_CHECK(uint160(std::vector<unsigned char>(TmpArray,TmpArray+20)) == (~R1S));
-
- BOOST_CHECK(-ZeroL == ZeroL); BOOST_CHECK(-ZeroS == ZeroS);
- BOOST_CHECK(-R1L == (~R1L)+1);
- BOOST_CHECK(-R1S == (~R1S)+1);
- for (unsigned int i = 0; i < 256; ++i)
- BOOST_CHECK(-(OneL<<i) == (MaxL << i));
- for (unsigned int i = 0; i < 160; ++i)
- BOOST_CHECK(-(OneS<<i) == (MaxS << i));
-}
-
-
-// Check if doing _A_ _OP_ _B_ results in the same as applying _OP_ onto each
-// element of Aarray and Barray, and then converting the result into a uint256.
-#define CHECKBITWISEOPERATOR(_A_,_B_,_OP_) \
- for (unsigned int i = 0; i < 32; ++i) { TmpArray[i] = _A_##Array[i] _OP_ _B_##Array[i]; } \
- BOOST_CHECK(uint256(std::vector<unsigned char>(TmpArray,TmpArray+32)) == (_A_##L _OP_ _B_##L)); \
- for (unsigned int i = 0; i < 20; ++i) { TmpArray[i] = _A_##Array[i] _OP_ _B_##Array[i]; } \
- BOOST_CHECK(uint160(std::vector<unsigned char>(TmpArray,TmpArray+20)) == (_A_##S _OP_ _B_##S));
-
-#define CHECKASSIGNMENTOPERATOR(_A_,_B_,_OP_) \
- TmpL = _A_##L; TmpL _OP_##= _B_##L; BOOST_CHECK(TmpL == (_A_##L _OP_ _B_##L)); \
- TmpS = _A_##S; TmpS _OP_##= _B_##S; BOOST_CHECK(TmpS == (_A_##S _OP_ _B_##S));
-
-BOOST_AUTO_TEST_CASE( bitwiseOperators )
-{
- unsigned char TmpArray[32];
-
- CHECKBITWISEOPERATOR(R1,R2,|)
- CHECKBITWISEOPERATOR(R1,R2,^)
- CHECKBITWISEOPERATOR(R1,R2,&)
- CHECKBITWISEOPERATOR(R1,Zero,|)
- CHECKBITWISEOPERATOR(R1,Zero,^)
- CHECKBITWISEOPERATOR(R1,Zero,&)
- CHECKBITWISEOPERATOR(R1,Max,|)
- CHECKBITWISEOPERATOR(R1,Max,^)
- CHECKBITWISEOPERATOR(R1,Max,&)
- CHECKBITWISEOPERATOR(Zero,R1,|)
- CHECKBITWISEOPERATOR(Zero,R1,^)
- CHECKBITWISEOPERATOR(Zero,R1,&)
- CHECKBITWISEOPERATOR(Max,R1,|)
- CHECKBITWISEOPERATOR(Max,R1,^)
- CHECKBITWISEOPERATOR(Max,R1,&)
-
- uint256 TmpL;
- uint160 TmpS;
- CHECKASSIGNMENTOPERATOR(R1,R2,|)
- CHECKASSIGNMENTOPERATOR(R1,R2,^)
- CHECKASSIGNMENTOPERATOR(R1,R2,&)
- CHECKASSIGNMENTOPERATOR(R1,Zero,|)
- CHECKASSIGNMENTOPERATOR(R1,Zero,^)
- CHECKASSIGNMENTOPERATOR(R1,Zero,&)
- CHECKASSIGNMENTOPERATOR(R1,Max,|)
- CHECKASSIGNMENTOPERATOR(R1,Max,^)
- CHECKASSIGNMENTOPERATOR(R1,Max,&)
- CHECKASSIGNMENTOPERATOR(Zero,R1,|)
- CHECKASSIGNMENTOPERATOR(Zero,R1,^)
- CHECKASSIGNMENTOPERATOR(Zero,R1,&)
- CHECKASSIGNMENTOPERATOR(Max,R1,|)
- CHECKASSIGNMENTOPERATOR(Max,R1,^)
- CHECKASSIGNMENTOPERATOR(Max,R1,&)
-
- uint64_t Tmp64 = 0xe1db685c9a0b47a2ULL;
- TmpL = R1L; TmpL |= Tmp64; BOOST_CHECK(TmpL == (R1L | uint256(Tmp64)));
- TmpS = R1S; TmpS |= Tmp64; BOOST_CHECK(TmpS == (R1S | uint160(Tmp64)));
- TmpL = R1L; TmpL |= 0; BOOST_CHECK(TmpL == R1L);
- TmpS = R1S; TmpS |= 0; BOOST_CHECK(TmpS == R1S);
- TmpL ^= 0; BOOST_CHECK(TmpL == R1L);
- TmpS ^= 0; BOOST_CHECK(TmpS == R1S);
- TmpL ^= Tmp64; BOOST_CHECK(TmpL == (R1L ^ uint256(Tmp64)));
- TmpS ^= Tmp64; BOOST_CHECK(TmpS == (R1S ^ uint160(Tmp64)));
}
BOOST_AUTO_TEST_CASE( comparison ) // <= >= < >
{
- uint256 TmpL;
- for (unsigned int i = 0; i < 256; ++i) {
- TmpL= OneL<< i;
- BOOST_CHECK( TmpL >= ZeroL && TmpL > ZeroL && ZeroL < TmpL && ZeroL <= TmpL);
- BOOST_CHECK( TmpL >= 0 && TmpL > 0 && 0 < TmpL && 0 <= TmpL);
- TmpL |= R1L;
- BOOST_CHECK( TmpL >= R1L ); BOOST_CHECK( (TmpL == R1L) != (TmpL > R1L)); BOOST_CHECK( (TmpL == R1L) || !( TmpL <= R1L));
- BOOST_CHECK( R1L <= TmpL ); BOOST_CHECK( (R1L == TmpL) != (R1L < TmpL)); BOOST_CHECK( (TmpL == R1L) || !( R1L >= TmpL));
- BOOST_CHECK(! (TmpL < R1L)); BOOST_CHECK(! (R1L > TmpL));
- }
- uint160 TmpS;
- for (unsigned int i = 0; i < 160; ++i) {
- TmpS= OneS<< i;
- BOOST_CHECK( TmpS >= ZeroS && TmpS > ZeroS && ZeroS < TmpS && ZeroS <= TmpS);
- BOOST_CHECK( TmpS >= 0 && TmpS > 0 && 0 < TmpS && 0 <= TmpS);
- TmpS |= R1S;
- BOOST_CHECK( TmpS >= R1S ); BOOST_CHECK( (TmpS == R1S) != (TmpS > R1S)); BOOST_CHECK( (TmpS == R1S) || !( TmpS <= R1S));
- BOOST_CHECK( R1S <= TmpS ); BOOST_CHECK( (R1S == TmpS) != (R1S < TmpS)); BOOST_CHECK( (TmpS == R1S) || !( R1S >= TmpS));
- BOOST_CHECK(! (TmpS < R1S)); BOOST_CHECK(! (R1S > TmpS));
+ uint256 LastL;
+ for (int i = 255; i >= 0; --i) {
+ uint256 TmpL;
+ *(TmpL.begin() + (i>>3)) |= 1<<(7-(i&7));
+ BOOST_CHECK( LastL < TmpL );
+ LastL = TmpL;
}
-}
-BOOST_AUTO_TEST_CASE( plusMinus )
-{
- uint256 TmpL = 0;
- BOOST_CHECK(R1L+R2L == uint256(R1LplusR2L));
- TmpL += R1L;
- BOOST_CHECK(TmpL == R1L);
- TmpL += R2L;
- BOOST_CHECK(TmpL == R1L + R2L);
- BOOST_CHECK(OneL+MaxL == ZeroL);
- BOOST_CHECK(MaxL+OneL == ZeroL);
- for (unsigned int i = 1; i < 256; ++i) {
- BOOST_CHECK( (MaxL >> i) + OneL == (HalfL >> (i-1)) );
- BOOST_CHECK( OneL + (MaxL >> i) == (HalfL >> (i-1)) );
- TmpL = (MaxL>>i); TmpL += OneL;
- BOOST_CHECK( TmpL == (HalfL >> (i-1)) );
- TmpL = (MaxL>>i); TmpL += 1;
- BOOST_CHECK( TmpL == (HalfL >> (i-1)) );
- TmpL = (MaxL>>i);
- BOOST_CHECK( TmpL++ == (MaxL>>i) );
- BOOST_CHECK( TmpL == (HalfL >> (i-1)));
+ BOOST_CHECK( ZeroL < R1L );
+ BOOST_CHECK( R2L < R1L );
+ BOOST_CHECK( ZeroL < OneL );
+ BOOST_CHECK( OneL < MaxL );
+ BOOST_CHECK( R1L < MaxL );
+ BOOST_CHECK( R2L < MaxL );
+
+ uint160 LastS;
+ for (int i = 159; i >= 0; --i) {
+ uint160 TmpS;
+ *(TmpS.begin() + (i>>3)) |= 1<<(7-(i&7));
+ BOOST_CHECK( LastS < TmpS );
+ LastS = TmpS;
}
- BOOST_CHECK(uint256(0xbedc77e27940a7ULL) + 0xee8d836fce66fbULL == uint256(0xbedc77e27940a7ULL + 0xee8d836fce66fbULL));
- TmpL = uint256(0xbedc77e27940a7ULL); TmpL += 0xee8d836fce66fbULL;
- BOOST_CHECK(TmpL == uint256(0xbedc77e27940a7ULL+0xee8d836fce66fbULL));
- TmpL -= 0xee8d836fce66fbULL; BOOST_CHECK(TmpL == 0xbedc77e27940a7ULL);
- TmpL = R1L;
- BOOST_CHECK(++TmpL == R1L+1);
-
- BOOST_CHECK(R1L -(-R2L) == R1L+R2L);
- BOOST_CHECK(R1L -(-OneL) == R1L+OneL);
- BOOST_CHECK(R1L - OneL == R1L+(-OneL));
- for (unsigned int i = 1; i < 256; ++i) {
- BOOST_CHECK((MaxL>>i) - (-OneL) == (HalfL >> (i-1)));
- BOOST_CHECK((HalfL >> (i-1)) - OneL == (MaxL>>i));
- TmpL = (HalfL >> (i-1));
- BOOST_CHECK(TmpL-- == (HalfL >> (i-1)));
- BOOST_CHECK(TmpL == (MaxL >> i));
- TmpL = (HalfL >> (i-1));
- BOOST_CHECK(--TmpL == (MaxL >> i));
- }
- TmpL = R1L;
- BOOST_CHECK(--TmpL == R1L-1);
-
- // 160-bit; copy-pasted
- uint160 TmpS = 0;
- BOOST_CHECK(R1S+R2S == uint160(R1LplusR2L));
- TmpS += R1S;
- BOOST_CHECK(TmpS == R1S);
- TmpS += R2S;
- BOOST_CHECK(TmpS == R1S + R2S);
- BOOST_CHECK(OneS+MaxS == ZeroS);
- BOOST_CHECK(MaxS+OneS == ZeroS);
- for (unsigned int i = 1; i < 160; ++i) {
- BOOST_CHECK( (MaxS >> i) + OneS == (HalfS >> (i-1)) );
- BOOST_CHECK( OneS + (MaxS >> i) == (HalfS >> (i-1)) );
- TmpS = (MaxS>>i); TmpS += OneS;
- BOOST_CHECK( TmpS == (HalfS >> (i-1)) );
- TmpS = (MaxS>>i); TmpS += 1;
- BOOST_CHECK( TmpS == (HalfS >> (i-1)) );
- TmpS = (MaxS>>i);
- BOOST_CHECK( TmpS++ == (MaxS>>i) );
- BOOST_CHECK( TmpS == (HalfS >> (i-1)));
- }
- BOOST_CHECK(uint160(0xbedc77e27940a7ULL) + 0xee8d836fce66fbULL == uint160(0xbedc77e27940a7ULL + 0xee8d836fce66fbULL));
- TmpS = uint160(0xbedc77e27940a7ULL); TmpS += 0xee8d836fce66fbULL;
- BOOST_CHECK(TmpS == uint160(0xbedc77e27940a7ULL+0xee8d836fce66fbULL));
- TmpS -= 0xee8d836fce66fbULL; BOOST_CHECK(TmpS == 0xbedc77e27940a7ULL);
- TmpS = R1S;
- BOOST_CHECK(++TmpS == R1S+1);
-
- BOOST_CHECK(R1S -(-R2S) == R1S+R2S);
- BOOST_CHECK(R1S -(-OneS) == R1S+OneS);
- BOOST_CHECK(R1S - OneS == R1S+(-OneS));
- for (unsigned int i = 1; i < 160; ++i) {
- BOOST_CHECK((MaxS>>i) - (-OneS) == (HalfS >> (i-1)));
- BOOST_CHECK((HalfS >> (i-1)) - OneS == (MaxS>>i));
- TmpS = (HalfS >> (i-1));
- BOOST_CHECK(TmpS-- == (HalfS >> (i-1)));
- BOOST_CHECK(TmpS == (MaxS >> i));
- TmpS = (HalfS >> (i-1));
- BOOST_CHECK(--TmpS == (MaxS >> i));
- }
- TmpS = R1S;
- BOOST_CHECK(--TmpS == R1S-1);
-
-}
-
-BOOST_AUTO_TEST_CASE( multiply )
-{
- BOOST_CHECK((R1L * R1L).ToString() == "62a38c0486f01e45879d7910a7761bf30d5237e9873f9bff3642a732c4d84f10");
- BOOST_CHECK((R1L * R2L).ToString() == "de37805e9986996cfba76ff6ba51c008df851987d9dd323f0e5de07760529c40");
- BOOST_CHECK((R1L * ZeroL) == ZeroL);
- BOOST_CHECK((R1L * OneL) == R1L);
- BOOST_CHECK((R1L * MaxL) == -R1L);
- BOOST_CHECK((R2L * R1L) == (R1L * R2L));
- BOOST_CHECK((R2L * R2L).ToString() == "ac8c010096767d3cae5005dec28bb2b45a1d85ab7996ccd3e102a650f74ff100");
- BOOST_CHECK((R2L * ZeroL) == ZeroL);
- BOOST_CHECK((R2L * OneL) == R2L);
- BOOST_CHECK((R2L * MaxL) == -R2L);
-
- BOOST_CHECK((R1S * R1S).ToString() == "a7761bf30d5237e9873f9bff3642a732c4d84f10");
- BOOST_CHECK((R1S * R2S).ToString() == "ba51c008df851987d9dd323f0e5de07760529c40");
- BOOST_CHECK((R1S * ZeroS) == ZeroS);
- BOOST_CHECK((R1S * OneS) == R1S);
- BOOST_CHECK((R1S * MaxS) == -R1S);
- BOOST_CHECK((R2S * R1S) == (R1S * R2S));
- BOOST_CHECK((R2S * R2S).ToString() == "c28bb2b45a1d85ab7996ccd3e102a650f74ff100");
- BOOST_CHECK((R2S * ZeroS) == ZeroS);
- BOOST_CHECK((R2S * OneS) == R2S);
- BOOST_CHECK((R2S * MaxS) == -R2S);
-
- BOOST_CHECK(MaxL * MaxL == OneL);
- BOOST_CHECK(MaxS * MaxS == OneS);
-
- BOOST_CHECK((R1L * 0) == 0);
- BOOST_CHECK((R1L * 1) == R1L);
- BOOST_CHECK((R1L * 3).ToString() == "7759b1c0ed14047f961ad09b20ff83687876a0181a367b813634046f91def7d4");
- BOOST_CHECK((R2L * 0x87654321UL).ToString() == "23f7816e30c4ae2017257b7a0fa64d60402f5234d46e746b61c960d09a26d070");
- BOOST_CHECK((R1S * 0) == 0);
- BOOST_CHECK((R1S * 1) == R1S);
- BOOST_CHECK((R1S * 7).ToString() == "f7a987f3c3bf758d927f202d7e795faeff084244");
- BOOST_CHECK((R2S * 0xFFFFFFFFUL).ToString() == "1c6f6c930353e17f7d6127213bb18d2883e2cd90");
-}
-
-BOOST_AUTO_TEST_CASE( divide )
-{
- uint256 D1L("AD7133AC1977FA2B7");
- uint256 D2L("ECD751716");
- BOOST_CHECK((R1L / D1L).ToString() == "00000000000000000b8ac01106981635d9ed112290f8895545a7654dde28fb3a");
- BOOST_CHECK((R1L / D2L).ToString() == "000000000873ce8efec5b67150bad3aa8c5fcb70e947586153bf2cec7c37c57a");
- BOOST_CHECK(R1L / OneL == R1L);
- BOOST_CHECK(R1L / MaxL == ZeroL);
- BOOST_CHECK(MaxL / R1L == 2);
- BOOST_CHECK_THROW(R1L / ZeroL, uint_error);
- BOOST_CHECK((R2L / D1L).ToString() == "000000000000000013e1665895a1cc981de6d93670105a6b3ec3b73141b3a3c5");
- BOOST_CHECK((R2L / D2L).ToString() == "000000000e8f0abe753bb0afe2e9437ee85d280be60882cf0bd1aaf7fa3cc2c4");
- BOOST_CHECK(R2L / OneL == R2L);
- BOOST_CHECK(R2L / MaxL == ZeroL);
- BOOST_CHECK(MaxL / R2L == 1);
- BOOST_CHECK_THROW(R2L / ZeroL, uint_error);
-
- uint160 D1S("D3C5EDCDEA54EB92679F0A4B4");
- uint160 D2S("13037");
- BOOST_CHECK((R1S / D1S).ToString() == "0000000000000000000000000db9af3beade6c02");
- BOOST_CHECK((R1S / D2S).ToString() == "000098dfb6cc40ca592bf74366794f298ada205c");
- BOOST_CHECK(R1S / OneS == R1S);
- BOOST_CHECK(R1S / MaxS == ZeroS);
- BOOST_CHECK(MaxS / R1S == 1);
- BOOST_CHECK_THROW(R1S / ZeroS, uint_error);
- BOOST_CHECK((R2S / D1S).ToString() == "0000000000000000000000000c5608e781182047");
- BOOST_CHECK((R2S / D2S).ToString() == "00008966751b7187c3c67c1fda5cea7db2c1c069");
- BOOST_CHECK(R2S / OneS == R2S);
- BOOST_CHECK(R2S / MaxS == ZeroS);
- BOOST_CHECK(MaxS / R2S == 1);
- BOOST_CHECK_THROW(R2S / ZeroS, uint_error);
-}
-
-
-bool almostEqual(double d1, double d2)
-{
- return fabs(d1-d2) <= 4*fabs(d1)*std::numeric_limits<double>::epsilon();
+ BOOST_CHECK( ZeroS < R1S );
+ BOOST_CHECK( R2S < R1S );
+ BOOST_CHECK( ZeroS < OneS );
+ BOOST_CHECK( OneS < MaxS );
+ BOOST_CHECK( R1S < MaxS );
+ BOOST_CHECK( R2S < MaxS );
}
BOOST_AUTO_TEST_CASE( methods ) // GetHex SetHex begin() end() size() GetLow64 GetSerializeSize, Serialize, Unserialize
@@ -567,8 +164,7 @@ BOOST_AUTO_TEST_CASE( methods ) // GetHex SetHex begin() end() size() GetLow64 G
uint256 TmpL(R1L);
BOOST_CHECK(TmpL == R1L);
TmpL.SetHex(R2L.ToString()); BOOST_CHECK(TmpL == R2L);
- TmpL.SetHex(ZeroL.ToString()); BOOST_CHECK(TmpL == 0);
- TmpL.SetHex(HalfL.ToString()); BOOST_CHECK(TmpL == HalfL);
+ TmpL.SetHex(ZeroL.ToString()); BOOST_CHECK(TmpL == uint256());
TmpL.SetHex(R1L.ToString());
BOOST_CHECK(memcmp(R1L.begin(), R1Array, 32)==0);
@@ -576,6 +172,8 @@ BOOST_AUTO_TEST_CASE( methods ) // GetHex SetHex begin() end() size() GetLow64 G
BOOST_CHECK(memcmp(R2L.begin(), R2Array, 32)==0);
BOOST_CHECK(memcmp(ZeroL.begin(), ZeroArray, 32)==0);
BOOST_CHECK(memcmp(OneL.begin(), OneArray, 32)==0);
+ BOOST_CHECK(R1L.size() == sizeof(R1L));
+ BOOST_CHECK(sizeof(R1L) == 32);
BOOST_CHECK(R1L.size() == 32);
BOOST_CHECK(R2L.size() == 32);
BOOST_CHECK(ZeroL.size() == 32);
@@ -585,9 +183,6 @@ BOOST_AUTO_TEST_CASE( methods ) // GetHex SetHex begin() end() size() GetLow64 G
BOOST_CHECK(OneL.begin() + 32 == OneL.end());
BOOST_CHECK(MaxL.begin() + 32 == MaxL.end());
BOOST_CHECK(TmpL.begin() + 32 == TmpL.end());
- BOOST_CHECK(R1L.GetLow64() == R1LLow64);
- BOOST_CHECK(HalfL.GetLow64() ==0x0000000000000000ULL);
- BOOST_CHECK(OneL.GetLow64() ==0x0000000000000001ULL);
BOOST_CHECK(R1L.GetSerializeSize(0,PROTOCOL_VERSION) == 32);
BOOST_CHECK(ZeroL.GetSerializeSize(0,PROTOCOL_VERSION) == 32);
@@ -615,8 +210,7 @@ BOOST_AUTO_TEST_CASE( methods ) // GetHex SetHex begin() end() size() GetLow64 G
uint160 TmpS(R1S);
BOOST_CHECK(TmpS == R1S);
TmpS.SetHex(R2S.ToString()); BOOST_CHECK(TmpS == R2S);
- TmpS.SetHex(ZeroS.ToString()); BOOST_CHECK(TmpS == 0);
- TmpS.SetHex(HalfS.ToString()); BOOST_CHECK(TmpS == HalfS);
+ TmpS.SetHex(ZeroS.ToString()); BOOST_CHECK(TmpS == uint160());
TmpS.SetHex(R1S.ToString());
BOOST_CHECK(memcmp(R1S.begin(), R1Array, 20)==0);
@@ -624,6 +218,8 @@ BOOST_AUTO_TEST_CASE( methods ) // GetHex SetHex begin() end() size() GetLow64 G
BOOST_CHECK(memcmp(R2S.begin(), R2Array, 20)==0);
BOOST_CHECK(memcmp(ZeroS.begin(), ZeroArray, 20)==0);
BOOST_CHECK(memcmp(OneS.begin(), OneArray, 20)==0);
+ BOOST_CHECK(R1S.size() == sizeof(R1S));
+ BOOST_CHECK(sizeof(R1S) == 20);
BOOST_CHECK(R1S.size() == 20);
BOOST_CHECK(R2S.size() == 20);
BOOST_CHECK(ZeroS.size() == 20);
@@ -633,9 +229,6 @@ BOOST_AUTO_TEST_CASE( methods ) // GetHex SetHex begin() end() size() GetLow64 G
BOOST_CHECK(OneS.begin() + 20 == OneS.end());
BOOST_CHECK(MaxS.begin() + 20 == MaxS.end());
BOOST_CHECK(TmpS.begin() + 20 == TmpS.end());
- BOOST_CHECK(R1S.GetLow64() == R1LLow64);
- BOOST_CHECK(HalfS.GetLow64() ==0x0000000000000000ULL);
- BOOST_CHECK(OneS.GetLow64() ==0x0000000000000001ULL);
BOOST_CHECK(R1S.GetSerializeSize(0,PROTOCOL_VERSION) == 20);
BOOST_CHECK(ZeroS.GetSerializeSize(0,PROTOCOL_VERSION) == 20);
@@ -654,184 +247,22 @@ BOOST_AUTO_TEST_CASE( methods ) // GetHex SetHex begin() end() size() GetLow64 G
TmpS.Unserialize(ss,0,PROTOCOL_VERSION);
BOOST_CHECK(MaxS == TmpS);
ss.str("");
-
- for (unsigned int i = 0; i < 255; ++i)
- {
- BOOST_CHECK((OneL << i).getdouble() == ldexp(1.0,i));
- if (i < 160) BOOST_CHECK((OneS << i).getdouble() == ldexp(1.0,i));
- }
- BOOST_CHECK(ZeroL.getdouble() == 0.0);
- BOOST_CHECK(ZeroS.getdouble() == 0.0);
- for (int i = 256; i > 53; --i)
- BOOST_CHECK(almostEqual((R1L>>(256-i)).getdouble(), ldexp(R1Ldouble,i)));
- for (int i = 160; i > 53; --i)
- BOOST_CHECK(almostEqual((R1S>>(160-i)).getdouble(), ldexp(R1Sdouble,i)));
- uint64_t R1L64part = (R1L>>192).GetLow64();
- uint64_t R1S64part = (R1S>>96).GetLow64();
- for (int i = 53; i > 0; --i) // doubles can store all integers in {0,...,2^54-1} exactly
- {
- BOOST_CHECK((R1L>>(256-i)).getdouble() == (double)(R1L64part >> (64-i)));
- BOOST_CHECK((R1S>>(160-i)).getdouble() == (double)(R1S64part >> (64-i)));
- }
}
-BOOST_AUTO_TEST_CASE(bignum_SetCompact)
+BOOST_AUTO_TEST_CASE( conversion )
{
- uint256 num;
- bool fNegative;
- bool fOverflow;
- num.SetCompact(0, &fNegative, &fOverflow);
- BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
- BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
- BOOST_CHECK_EQUAL(fNegative, false);
- BOOST_CHECK_EQUAL(fOverflow, false);
-
- num.SetCompact(0x00123456, &fNegative, &fOverflow);
- BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
- BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
- BOOST_CHECK_EQUAL(fNegative, false);
- BOOST_CHECK_EQUAL(fOverflow, false);
-
- num.SetCompact(0x01003456, &fNegative, &fOverflow);
- BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
- BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
- BOOST_CHECK_EQUAL(fNegative, false);
- BOOST_CHECK_EQUAL(fOverflow, false);
-
- num.SetCompact(0x02000056, &fNegative, &fOverflow);
- BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
- BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
- BOOST_CHECK_EQUAL(fNegative, false);
- BOOST_CHECK_EQUAL(fOverflow, false);
-
- num.SetCompact(0x03000000, &fNegative, &fOverflow);
- BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
- BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
- BOOST_CHECK_EQUAL(fNegative, false);
- BOOST_CHECK_EQUAL(fOverflow, false);
-
- num.SetCompact(0x04000000, &fNegative, &fOverflow);
- BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
- BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
- BOOST_CHECK_EQUAL(fNegative, false);
- BOOST_CHECK_EQUAL(fOverflow, false);
-
- num.SetCompact(0x00923456, &fNegative, &fOverflow);
- BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
- BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
- BOOST_CHECK_EQUAL(fNegative, false);
- BOOST_CHECK_EQUAL(fOverflow, false);
-
- num.SetCompact(0x01803456, &fNegative, &fOverflow);
- BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
- BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
- BOOST_CHECK_EQUAL(fNegative, false);
- BOOST_CHECK_EQUAL(fOverflow, false);
-
- num.SetCompact(0x02800056, &fNegative, &fOverflow);
- BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
- BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
- BOOST_CHECK_EQUAL(fNegative, false);
- BOOST_CHECK_EQUAL(fOverflow, false);
-
- num.SetCompact(0x03800000, &fNegative, &fOverflow);
- BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
- BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
- BOOST_CHECK_EQUAL(fNegative, false);
- BOOST_CHECK_EQUAL(fOverflow, false);
-
- num.SetCompact(0x04800000, &fNegative, &fOverflow);
- BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
- BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
- BOOST_CHECK_EQUAL(fNegative, false);
- BOOST_CHECK_EQUAL(fOverflow, false);
-
- num.SetCompact(0x01123456, &fNegative, &fOverflow);
- BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000012");
- BOOST_CHECK_EQUAL(num.GetCompact(), 0x01120000U);
- BOOST_CHECK_EQUAL(fNegative, false);
- BOOST_CHECK_EQUAL(fOverflow, false);
-
- // Make sure that we don't generate compacts with the 0x00800000 bit set
- num = 0x80;
- BOOST_CHECK_EQUAL(num.GetCompact(), 0x02008000U);
-
- num.SetCompact(0x01fedcba, &fNegative, &fOverflow);
- BOOST_CHECK_EQUAL(num.GetHex(), "000000000000000000000000000000000000000000000000000000000000007e");
- BOOST_CHECK_EQUAL(num.GetCompact(true), 0x01fe0000U);
- BOOST_CHECK_EQUAL(fNegative, true);
- BOOST_CHECK_EQUAL(fOverflow, false);
-
- num.SetCompact(0x02123456, &fNegative, &fOverflow);
- BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000001234");
- BOOST_CHECK_EQUAL(num.GetCompact(), 0x02123400U);
- BOOST_CHECK_EQUAL(fNegative, false);
- BOOST_CHECK_EQUAL(fOverflow, false);
-
- num.SetCompact(0x03123456, &fNegative, &fOverflow);
- BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000123456");
- BOOST_CHECK_EQUAL(num.GetCompact(), 0x03123456U);
- BOOST_CHECK_EQUAL(fNegative, false);
- BOOST_CHECK_EQUAL(fOverflow, false);
-
- num.SetCompact(0x04123456, &fNegative, &fOverflow);
- BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000012345600");
- BOOST_CHECK_EQUAL(num.GetCompact(), 0x04123456U);
- BOOST_CHECK_EQUAL(fNegative, false);
- BOOST_CHECK_EQUAL(fOverflow, false);
-
- num.SetCompact(0x04923456, &fNegative, &fOverflow);
- BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000012345600");
- BOOST_CHECK_EQUAL(num.GetCompact(true), 0x04923456U);
- BOOST_CHECK_EQUAL(fNegative, true);
- BOOST_CHECK_EQUAL(fOverflow, false);
-
- num.SetCompact(0x05009234, &fNegative, &fOverflow);
- BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000092340000");
- BOOST_CHECK_EQUAL(num.GetCompact(), 0x05009234U);
- BOOST_CHECK_EQUAL(fNegative, false);
- BOOST_CHECK_EQUAL(fOverflow, false);
-
- num.SetCompact(0x20123456, &fNegative, &fOverflow);
- BOOST_CHECK_EQUAL(num.GetHex(), "1234560000000000000000000000000000000000000000000000000000000000");
- BOOST_CHECK_EQUAL(num.GetCompact(), 0x20123456U);
- BOOST_CHECK_EQUAL(fNegative, false);
- BOOST_CHECK_EQUAL(fOverflow, false);
-
- num.SetCompact(0xff123456, &fNegative, &fOverflow);
- BOOST_CHECK_EQUAL(fNegative, false);
- BOOST_CHECK_EQUAL(fOverflow, true);
-}
-
-
-BOOST_AUTO_TEST_CASE( getmaxcoverage ) // some more tests just to get 100% coverage
-{
- // ~R1L give a base_uint<256>
- BOOST_CHECK((~~R1L >> 10) == (R1L >> 10)); BOOST_CHECK((~~R1S >> 10) == (R1S >> 10));
- BOOST_CHECK((~~R1L << 10) == (R1L << 10)); BOOST_CHECK((~~R1S << 10) == (R1S << 10));
- BOOST_CHECK(!(~~R1L < R1L)); BOOST_CHECK(!(~~R1S < R1S));
- BOOST_CHECK(~~R1L <= R1L); BOOST_CHECK(~~R1S <= R1S);
- BOOST_CHECK(!(~~R1L > R1L)); BOOST_CHECK(!(~~R1S > R1S));
- BOOST_CHECK(~~R1L >= R1L); BOOST_CHECK(~~R1S >= R1S);
- BOOST_CHECK(!(R1L < ~~R1L)); BOOST_CHECK(!(R1S < ~~R1S));
- BOOST_CHECK(R1L <= ~~R1L); BOOST_CHECK(R1S <= ~~R1S);
- BOOST_CHECK(!(R1L > ~~R1L)); BOOST_CHECK(!(R1S > ~~R1S));
- BOOST_CHECK(R1L >= ~~R1L); BOOST_CHECK(R1S >= ~~R1S);
-
- BOOST_CHECK(~~R1L + R2L == R1L + ~~R2L);
- BOOST_CHECK(~~R1S + R2S == R1S + ~~R2S);
- BOOST_CHECK(~~R1L - R2L == R1L - ~~R2L);
- BOOST_CHECK(~~R1S - R2S == R1S - ~~R2S);
- BOOST_CHECK(~R1L != R1L); BOOST_CHECK(R1L != ~R1L);
- BOOST_CHECK(~R1S != R1S); BOOST_CHECK(R1S != ~R1S);
- unsigned char TmpArray[32];
- CHECKBITWISEOPERATOR(~R1,R2,|)
- CHECKBITWISEOPERATOR(~R1,R2,^)
- CHECKBITWISEOPERATOR(~R1,R2,&)
- CHECKBITWISEOPERATOR(R1,~R2,|)
- CHECKBITWISEOPERATOR(R1,~R2,^)
- CHECKBITWISEOPERATOR(R1,~R2,&)
+ BOOST_CHECK(ArithToUint256(UintToArith256(ZeroL)) == ZeroL);
+ BOOST_CHECK(ArithToUint256(UintToArith256(OneL)) == OneL);
+ BOOST_CHECK(ArithToUint256(UintToArith256(R1L)) == R1L);
+ BOOST_CHECK(ArithToUint256(UintToArith256(R2L)) == R2L);
+ BOOST_CHECK(UintToArith256(ZeroL) == 0);
+ BOOST_CHECK(UintToArith256(OneL) == 1);
+ BOOST_CHECK(ArithToUint256(0) == ZeroL);
+ BOOST_CHECK(ArithToUint256(1) == OneL);
+ BOOST_CHECK(arith_uint256(R1L.GetHex()) == UintToArith256(R1L));
+ BOOST_CHECK(arith_uint256(R2L.GetHex()) == UintToArith256(R2L));
+ BOOST_CHECK(R1L.GetHex() == UintToArith256(R1L).GetHex());
+ BOOST_CHECK(R2L.GetHex() == UintToArith256(R2L).GetHex());
}
BOOST_AUTO_TEST_SUITE_END()
-
diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp
index 1c5778abed..d829ec228d 100644
--- a/src/test/util_tests.cpp
+++ b/src/test/util_tests.cpp
@@ -282,21 +282,21 @@ BOOST_AUTO_TEST_CASE(strprintf_numbers)
{
int64_t s64t = -9223372036854775807LL; /* signed 64 bit test value */
uint64_t u64t = 18446744073709551615ULL; /* unsigned 64 bit test value */
- BOOST_CHECK(strprintf("%s %d %s", B, s64t, E) == B" -9223372036854775807 "E);
- BOOST_CHECK(strprintf("%s %u %s", B, u64t, E) == B" 18446744073709551615 "E);
- BOOST_CHECK(strprintf("%s %x %s", B, u64t, E) == B" ffffffffffffffff "E);
+ BOOST_CHECK(strprintf("%s %d %s", B, s64t, E) == B" -9223372036854775807 " E);
+ BOOST_CHECK(strprintf("%s %u %s", B, u64t, E) == B" 18446744073709551615 " E);
+ BOOST_CHECK(strprintf("%s %x %s", B, u64t, E) == B" ffffffffffffffff " E);
size_t st = 12345678; /* unsigned size_t test value */
ssize_t sst = -12345678; /* signed size_t test value */
- BOOST_CHECK(strprintf("%s %d %s", B, sst, E) == B" -12345678 "E);
- BOOST_CHECK(strprintf("%s %u %s", B, st, E) == B" 12345678 "E);
- BOOST_CHECK(strprintf("%s %x %s", B, st, E) == B" bc614e "E);
+ BOOST_CHECK(strprintf("%s %d %s", B, sst, E) == B" -12345678 " E);
+ BOOST_CHECK(strprintf("%s %u %s", B, st, E) == B" 12345678 " E);
+ BOOST_CHECK(strprintf("%s %x %s", B, st, E) == B" bc614e " E);
ptrdiff_t pt = 87654321; /* positive ptrdiff_t test value */
ptrdiff_t spt = -87654321; /* negative ptrdiff_t test value */
- BOOST_CHECK(strprintf("%s %d %s", B, spt, E) == B" -87654321 "E);
- BOOST_CHECK(strprintf("%s %u %s", B, pt, E) == B" 87654321 "E);
- BOOST_CHECK(strprintf("%s %x %s", B, pt, E) == B" 5397fb1 "E);
+ BOOST_CHECK(strprintf("%s %d %s", B, spt, E) == B" -87654321 " E);
+ BOOST_CHECK(strprintf("%s %u %s", B, pt, E) == B" 87654321 " E);
+ BOOST_CHECK(strprintf("%s %x %s", B, pt, E) == B" 5397fb1 " E);
}
#undef B
#undef E
diff --git a/src/timedata.cpp b/src/timedata.cpp
index d04f3d2f78..c3e9c75f6e 100644
--- a/src/timedata.cpp
+++ b/src/timedata.cpp
@@ -40,10 +40,8 @@ static int64_t abs64(int64_t n)
return (n >= 0 ? n : -n);
}
-void AddTimeData(const CNetAddr& ip, int64_t nTime)
+void AddTimeData(const CNetAddr& ip, int64_t nOffsetSample)
{
- int64_t nOffsetSample = nTime - GetTime();
-
LOCK(cs_nTimeOffset);
// Ignore duplicates
static set<CNetAddr> setKnown;
diff --git a/src/txdb.cpp b/src/txdb.cpp
index 5096ab19a5..da271bd5d1 100644
--- a/src/txdb.cpp
+++ b/src/txdb.cpp
@@ -14,32 +14,43 @@
using namespace std;
+static const char DB_COINS = 'c';
+static const char DB_BLOCK_FILES = 'f';
+static const char DB_TXINDEX = 't';
+static const char DB_BLOCK_INDEX = 'b';
+
+static const char DB_BEST_BLOCK = 'B';
+static const char DB_FLAG = 'F';
+static const char DB_REINDEX_FLAG = 'R';
+static const char DB_LAST_BLOCK = 'l';
+
+
void static BatchWriteCoins(CLevelDBBatch &batch, const uint256 &hash, const CCoins &coins) {
if (coins.IsPruned())
- batch.Erase(make_pair('c', hash));
+ batch.Erase(make_pair(DB_COINS, hash));
else
- batch.Write(make_pair('c', hash), coins);
+ batch.Write(make_pair(DB_COINS, hash), coins);
}
void static BatchWriteHashBestChain(CLevelDBBatch &batch, const uint256 &hash) {
- batch.Write('B', hash);
+ batch.Write(DB_BEST_BLOCK, hash);
}
CCoinsViewDB::CCoinsViewDB(size_t nCacheSize, bool fMemory, bool fWipe) : db(GetDataDir() / "chainstate", nCacheSize, fMemory, fWipe) {
}
bool CCoinsViewDB::GetCoins(const uint256 &txid, CCoins &coins) const {
- return db.Read(make_pair('c', txid), coins);
+ return db.Read(make_pair(DB_COINS, txid), coins);
}
bool CCoinsViewDB::HaveCoins(const uint256 &txid) const {
- return db.Exists(make_pair('c', txid));
+ return db.Exists(make_pair(DB_COINS, txid));
}
uint256 CCoinsViewDB::GetBestBlock() const {
uint256 hashBestChain;
- if (!db.Read('B', hashBestChain))
- return uint256(0);
+ if (!db.Read(DB_BEST_BLOCK, hashBestChain))
+ return uint256();
return hashBestChain;
}
@@ -56,7 +67,7 @@ bool CCoinsViewDB::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) {
CCoinsMap::iterator itOld = it++;
mapCoins.erase(itOld);
}
- if (hashBlock != uint256(0))
+ if (!hashBlock.IsNull())
BatchWriteHashBestChain(batch, hashBlock);
LogPrint("coindb", "Committing %u changed transactions (out of %u) to coin database...\n", (unsigned int)changed, (unsigned int)count);
@@ -67,23 +78,23 @@ CBlockTreeDB::CBlockTreeDB(size_t nCacheSize, bool fMemory, bool fWipe) : CLevel
}
bool CBlockTreeDB::ReadBlockFileInfo(int nFile, CBlockFileInfo &info) {
- return Read(make_pair('f', nFile), info);
+ return Read(make_pair(DB_BLOCK_FILES, nFile), info);
}
bool CBlockTreeDB::WriteReindexing(bool fReindexing) {
if (fReindexing)
- return Write('R', '1');
+ return Write(DB_REINDEX_FLAG, '1');
else
- return Erase('R');
+ return Erase(DB_REINDEX_FLAG);
}
bool CBlockTreeDB::ReadReindexing(bool &fReindexing) {
- fReindexing = Exists('R');
+ fReindexing = Exists(DB_REINDEX_FLAG);
return true;
}
bool CBlockTreeDB::ReadLastBlockFile(int &nFile) {
- return Read('l', nFile);
+ return Read(DB_LAST_BLOCK, nFile);
}
bool CCoinsViewDB::GetStats(CCoinsStats &stats) const {
@@ -104,7 +115,7 @@ bool CCoinsViewDB::GetStats(CCoinsStats &stats) const {
CDataStream ssKey(slKey.data(), slKey.data()+slKey.size(), SER_DISK, CLIENT_VERSION);
char chType;
ssKey >> chType;
- if (chType == 'c') {
+ if (chType == DB_COINS) {
leveldb::Slice slValue = pcursor->value();
CDataStream ssValue(slValue.data(), slValue.data()+slValue.size(), SER_DISK, CLIENT_VERSION);
CCoins coins;
@@ -130,7 +141,7 @@ bool CCoinsViewDB::GetStats(CCoinsStats &stats) const {
}
pcursor->Next();
} catch (const std::exception& e) {
- return error("%s : Deserialize or I/O error - %s", __func__, e.what());
+ return error("%s: Deserialize or I/O error - %s", __func__, e.what());
}
}
stats.nHeight = mapBlockIndex.find(GetBestBlock())->second->nHeight;
@@ -142,33 +153,33 @@ bool CCoinsViewDB::GetStats(CCoinsStats &stats) const {
bool CBlockTreeDB::WriteBatchSync(const std::vector<std::pair<int, const CBlockFileInfo*> >& fileInfo, int nLastFile, const std::vector<const CBlockIndex*>& blockinfo) {
CLevelDBBatch batch;
for (std::vector<std::pair<int, const CBlockFileInfo*> >::const_iterator it=fileInfo.begin(); it != fileInfo.end(); it++) {
- batch.Write(make_pair('f', it->first), *it->second);
+ batch.Write(make_pair(DB_BLOCK_FILES, it->first), *it->second);
}
- batch.Write('l', nLastFile);
+ batch.Write(DB_LAST_BLOCK, nLastFile);
for (std::vector<const CBlockIndex*>::const_iterator it=blockinfo.begin(); it != blockinfo.end(); it++) {
- batch.Write(make_pair('b', (*it)->GetBlockHash()), CDiskBlockIndex(*it));
+ batch.Write(make_pair(DB_BLOCK_INDEX, (*it)->GetBlockHash()), CDiskBlockIndex(*it));
}
return WriteBatch(batch, true);
}
bool CBlockTreeDB::ReadTxIndex(const uint256 &txid, CDiskTxPos &pos) {
- return Read(make_pair('t', txid), pos);
+ return Read(make_pair(DB_TXINDEX, txid), pos);
}
bool CBlockTreeDB::WriteTxIndex(const std::vector<std::pair<uint256, CDiskTxPos> >&vect) {
CLevelDBBatch batch;
for (std::vector<std::pair<uint256,CDiskTxPos> >::const_iterator it=vect.begin(); it!=vect.end(); it++)
- batch.Write(make_pair('t', it->first), it->second);
+ batch.Write(make_pair(DB_TXINDEX, it->first), it->second);
return WriteBatch(batch);
}
bool CBlockTreeDB::WriteFlag(const std::string &name, bool fValue) {
- return Write(std::make_pair('F', name), fValue ? '1' : '0');
+ return Write(std::make_pair(DB_FLAG, name), fValue ? '1' : '0');
}
bool CBlockTreeDB::ReadFlag(const std::string &name, bool &fValue) {
char ch;
- if (!Read(std::make_pair('F', name), ch))
+ if (!Read(std::make_pair(DB_FLAG, name), ch))
return false;
fValue = ch == '1';
return true;
@@ -179,7 +190,7 @@ bool CBlockTreeDB::LoadBlockIndexGuts()
boost::scoped_ptr<leveldb::Iterator> pcursor(NewIterator());
CDataStream ssKeySet(SER_DISK, CLIENT_VERSION);
- ssKeySet << make_pair('b', uint256(0));
+ ssKeySet << make_pair(DB_BLOCK_INDEX, uint256());
pcursor->Seek(ssKeySet.str());
// Load mapBlockIndex
@@ -190,7 +201,7 @@ bool CBlockTreeDB::LoadBlockIndexGuts()
CDataStream ssKey(slKey.data(), slKey.data()+slKey.size(), SER_DISK, CLIENT_VERSION);
char chType;
ssKey >> chType;
- if (chType == 'b') {
+ if (chType == DB_BLOCK_INDEX) {
leveldb::Slice slValue = pcursor->value();
CDataStream ssValue(slValue.data(), slValue.data()+slValue.size(), SER_DISK, CLIENT_VERSION);
CDiskBlockIndex diskindex;
@@ -212,14 +223,14 @@ bool CBlockTreeDB::LoadBlockIndexGuts()
pindexNew->nTx = diskindex.nTx;
if (!CheckProofOfWork(pindexNew->GetBlockHash(), pindexNew->nBits))
- return error("LoadBlockIndex() : CheckProofOfWork failed: %s", pindexNew->ToString());
+ return error("LoadBlockIndex(): CheckProofOfWork failed: %s", pindexNew->ToString());
pcursor->Next();
} else {
break; // if shutdown requested or finished loading block index
}
} catch (const std::exception& e) {
- return error("%s : Deserialize or I/O error - %s", __func__, e.what());
+ return error("%s: Deserialize or I/O error - %s", __func__, e.what());
}
}
diff --git a/src/txmempool.cpp b/src/txmempool.cpp
index 3071ab025c..6e0f7e9c5a 100644
--- a/src/txmempool.cpp
+++ b/src/txmempool.cpp
@@ -192,7 +192,7 @@ private:
// Neither or both fee and priority sufficient to get confirmed:
// don't know why they got confirmed.
}
- LogPrint("estimatefee", "Seen TX confirm: %s : %s fee/%g priority, took %d blocks\n",
+ LogPrint("estimatefee", "Seen TX confirm: %s: %s fee/%g priority, took %d blocks\n",
assignedTo, feeRate.ToString(), dPriority, nBlocksAgo);
}
@@ -585,9 +585,9 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const
if (fDependsWait)
waitingOnDependants.push_back(&it->second);
else {
- CValidationState state; CTxUndo undo;
+ CValidationState state;
assert(CheckInputs(tx, state, mempoolDuplicate, false, 0, false, NULL));
- UpdateCoins(tx, state, mempoolDuplicate, undo, 1000000);
+ UpdateCoins(tx, state, mempoolDuplicate, 1000000);
}
}
unsigned int stepsSinceLastRemove = 0;
@@ -601,8 +601,7 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const
assert(stepsSinceLastRemove < waitingOnDependants.size());
} else {
assert(CheckInputs(entry->GetTx(), state, mempoolDuplicate, false, 0, false, NULL));
- CTxUndo undo;
- UpdateCoins(entry->GetTx(), state, mempoolDuplicate, undo, 1000000);
+ UpdateCoins(entry->GetTx(), state, mempoolDuplicate, 1000000);
stepsSinceLastRemove = 0;
}
}
@@ -659,7 +658,7 @@ CTxMemPool::WriteFeeEstimates(CAutoFile& fileout) const
minerPolicyEstimator->Write(fileout);
}
catch (const std::exception&) {
- LogPrintf("CTxMemPool::WriteFeeEstimates() : unable to write policy estimator data (non-fatal)");
+ LogPrintf("CTxMemPool::WriteFeeEstimates(): unable to write policy estimator data (non-fatal)");
return false;
}
return true;
@@ -672,13 +671,13 @@ CTxMemPool::ReadFeeEstimates(CAutoFile& filein)
int nVersionRequired, nVersionThatWrote;
filein >> nVersionRequired >> nVersionThatWrote;
if (nVersionRequired > CLIENT_VERSION)
- return error("CTxMemPool::ReadFeeEstimates() : up-version (%d) fee estimate file", nVersionRequired);
+ return error("CTxMemPool::ReadFeeEstimates(): up-version (%d) fee estimate file", nVersionRequired);
LOCK(cs);
minerPolicyEstimator->Read(filein, minRelayFee);
}
catch (const std::exception&) {
- LogPrintf("CTxMemPool::ReadFeeEstimates() : unable to read policy estimator data (non-fatal)");
+ LogPrintf("CTxMemPool::ReadFeeEstimates(): unable to read policy estimator data (non-fatal)");
return false;
}
return true;
diff --git a/src/uint256.cpp b/src/uint256.cpp
index 918c1a7cd7..3b1334a032 100644
--- a/src/uint256.cpp
+++ b/src/uint256.cpp
@@ -11,158 +11,25 @@
#include <string.h>
template <unsigned int BITS>
-base_uint<BITS>::base_uint(const std::string& str)
+base_blob<BITS>::base_blob(const std::vector<unsigned char>& vch)
{
- SetHex(str);
+ assert(vch.size() == sizeof(data));
+ memcpy(data, &vch[0], sizeof(data));
}
template <unsigned int BITS>
-base_uint<BITS>::base_uint(const std::vector<unsigned char>& vch)
+std::string base_blob<BITS>::GetHex() const
{
- if (vch.size() != sizeof(pn))
- throw uint_error("Converting vector of wrong size to base_uint");
- memcpy(pn, &vch[0], sizeof(pn));
+ char psz[sizeof(data) * 2 + 1];
+ for (unsigned int i = 0; i < sizeof(data); i++)
+ sprintf(psz + i * 2, "%02x", data[sizeof(data) - i - 1]);
+ return std::string(psz, psz + sizeof(data) * 2);
}
template <unsigned int BITS>
-base_uint<BITS>& base_uint<BITS>::operator<<=(unsigned int shift)
+void base_blob<BITS>::SetHex(const char* psz)
{
- base_uint<BITS> a(*this);
- for (int i = 0; i < WIDTH; i++)
- pn[i] = 0;
- int k = shift / 32;
- shift = shift % 32;
- for (int i = 0; i < WIDTH; i++) {
- if (i + k + 1 < WIDTH && shift != 0)
- pn[i + k + 1] |= (a.pn[i] >> (32 - shift));
- if (i + k < WIDTH)
- pn[i + k] |= (a.pn[i] << shift);
- }
- return *this;
-}
-
-template <unsigned int BITS>
-base_uint<BITS>& base_uint<BITS>::operator>>=(unsigned int shift)
-{
- base_uint<BITS> a(*this);
- for (int i = 0; i < WIDTH; i++)
- pn[i] = 0;
- int k = shift / 32;
- shift = shift % 32;
- for (int i = 0; i < WIDTH; i++) {
- if (i - k - 1 >= 0 && shift != 0)
- pn[i - k - 1] |= (a.pn[i] << (32 - shift));
- if (i - k >= 0)
- pn[i - k] |= (a.pn[i] >> shift);
- }
- return *this;
-}
-
-template <unsigned int BITS>
-base_uint<BITS>& base_uint<BITS>::operator*=(uint32_t b32)
-{
- uint64_t carry = 0;
- for (int i = 0; i < WIDTH; i++) {
- uint64_t n = carry + (uint64_t)b32 * pn[i];
- pn[i] = n & 0xffffffff;
- carry = n >> 32;
- }
- return *this;
-}
-
-template <unsigned int BITS>
-base_uint<BITS>& base_uint<BITS>::operator*=(const base_uint& b)
-{
- base_uint<BITS> a = *this;
- *this = 0;
- for (int j = 0; j < WIDTH; j++) {
- uint64_t carry = 0;
- for (int i = 0; i + j < WIDTH; i++) {
- uint64_t n = carry + pn[i + j] + (uint64_t)a.pn[j] * b.pn[i];
- pn[i + j] = n & 0xffffffff;
- carry = n >> 32;
- }
- }
- return *this;
-}
-
-template <unsigned int BITS>
-base_uint<BITS>& base_uint<BITS>::operator/=(const base_uint& b)
-{
- base_uint<BITS> div = b; // make a copy, so we can shift.
- base_uint<BITS> num = *this; // make a copy, so we can subtract.
- *this = 0; // the quotient.
- int num_bits = num.bits();
- int div_bits = div.bits();
- if (div_bits == 0)
- throw uint_error("Division by zero");
- if (div_bits > num_bits) // the result is certainly 0.
- return *this;
- int shift = num_bits - div_bits;
- div <<= shift; // shift so that div and num align.
- while (shift >= 0) {
- if (num >= div) {
- num -= div;
- pn[shift / 32] |= (1 << (shift & 31)); // set a bit of the result.
- }
- div >>= 1; // shift back.
- shift--;
- }
- // num now contains the remainder of the division.
- return *this;
-}
-
-template <unsigned int BITS>
-int base_uint<BITS>::CompareTo(const base_uint<BITS>& b) const
-{
- for (int i = WIDTH - 1; i >= 0; i--) {
- if (pn[i] < b.pn[i])
- return -1;
- if (pn[i] > b.pn[i])
- return 1;
- }
- return 0;
-}
-
-template <unsigned int BITS>
-bool base_uint<BITS>::EqualTo(uint64_t b) const
-{
- for (int i = WIDTH - 1; i >= 2; i--) {
- if (pn[i])
- return false;
- }
- if (pn[1] != (b >> 32))
- return false;
- if (pn[0] != (b & 0xfffffffful))
- return false;
- return true;
-}
-
-template <unsigned int BITS>
-double base_uint<BITS>::getdouble() const
-{
- double ret = 0.0;
- double fact = 1.0;
- for (int i = 0; i < WIDTH; i++) {
- ret += fact * pn[i];
- fact *= 4294967296.0;
- }
- return ret;
-}
-
-template <unsigned int BITS>
-std::string base_uint<BITS>::GetHex() const
-{
- char psz[sizeof(pn) * 2 + 1];
- for (unsigned int i = 0; i < sizeof(pn); i++)
- sprintf(psz + i * 2, "%02x", ((unsigned char*)pn)[sizeof(pn) - i - 1]);
- return std::string(psz, psz + sizeof(pn) * 2);
-}
-
-template <unsigned int BITS>
-void base_uint<BITS>::SetHex(const char* psz)
-{
- memset(pn, 0, sizeof(pn));
+ memset(data, 0, sizeof(data));
// skip leading spaces
while (isspace(*psz))
@@ -177,7 +44,7 @@ void base_uint<BITS>::SetHex(const char* psz)
while (::HexDigit(*psz) != -1)
psz++;
psz--;
- unsigned char* p1 = (unsigned char*)pn;
+ unsigned char* p1 = (unsigned char*)data;
unsigned char* pend = p1 + WIDTH * 4;
while (psz >= pbegin && p1 < pend) {
*p1 = ::HexDigit(*psz--);
@@ -189,110 +56,30 @@ void base_uint<BITS>::SetHex(const char* psz)
}
template <unsigned int BITS>
-void base_uint<BITS>::SetHex(const std::string& str)
+void base_blob<BITS>::SetHex(const std::string& str)
{
SetHex(str.c_str());
}
template <unsigned int BITS>
-std::string base_uint<BITS>::ToString() const
+std::string base_blob<BITS>::ToString() const
{
return (GetHex());
}
-template <unsigned int BITS>
-unsigned int base_uint<BITS>::bits() const
-{
- for (int pos = WIDTH - 1; pos >= 0; pos--) {
- if (pn[pos]) {
- for (int bits = 31; bits > 0; bits--) {
- if (pn[pos] & 1 << bits)
- return 32 * pos + bits + 1;
- }
- return 32 * pos + 1;
- }
- }
- return 0;
-}
-
-// Explicit instantiations for base_uint<160>
-template base_uint<160>::base_uint(const std::string&);
-template base_uint<160>::base_uint(const std::vector<unsigned char>&);
-template base_uint<160>& base_uint<160>::operator<<=(unsigned int);
-template base_uint<160>& base_uint<160>::operator>>=(unsigned int);
-template base_uint<160>& base_uint<160>::operator*=(uint32_t b32);
-template base_uint<160>& base_uint<160>::operator*=(const base_uint<160>& b);
-template base_uint<160>& base_uint<160>::operator/=(const base_uint<160>& b);
-template int base_uint<160>::CompareTo(const base_uint<160>&) const;
-template bool base_uint<160>::EqualTo(uint64_t) const;
-template double base_uint<160>::getdouble() const;
-template std::string base_uint<160>::GetHex() const;
-template std::string base_uint<160>::ToString() const;
-template void base_uint<160>::SetHex(const char*);
-template void base_uint<160>::SetHex(const std::string&);
-template unsigned int base_uint<160>::bits() const;
+// Explicit instantiations for base_blob<160>
+template base_blob<160>::base_blob(const std::vector<unsigned char>&);
+template std::string base_blob<160>::GetHex() const;
+template std::string base_blob<160>::ToString() const;
+template void base_blob<160>::SetHex(const char*);
+template void base_blob<160>::SetHex(const std::string&);
-// Explicit instantiations for base_uint<256>
-template base_uint<256>::base_uint(const std::string&);
-template base_uint<256>::base_uint(const std::vector<unsigned char>&);
-template base_uint<256>& base_uint<256>::operator<<=(unsigned int);
-template base_uint<256>& base_uint<256>::operator>>=(unsigned int);
-template base_uint<256>& base_uint<256>::operator*=(uint32_t b32);
-template base_uint<256>& base_uint<256>::operator*=(const base_uint<256>& b);
-template base_uint<256>& base_uint<256>::operator/=(const base_uint<256>& b);
-template int base_uint<256>::CompareTo(const base_uint<256>&) const;
-template bool base_uint<256>::EqualTo(uint64_t) const;
-template double base_uint<256>::getdouble() const;
-template std::string base_uint<256>::GetHex() const;
-template std::string base_uint<256>::ToString() const;
-template void base_uint<256>::SetHex(const char*);
-template void base_uint<256>::SetHex(const std::string&);
-template unsigned int base_uint<256>::bits() const;
-
-// This implementation directly uses shifts instead of going
-// through an intermediate MPI representation.
-uint256& uint256::SetCompact(uint32_t nCompact, bool* pfNegative, bool* pfOverflow)
-{
- int nSize = nCompact >> 24;
- uint32_t nWord = nCompact & 0x007fffff;
- if (nSize <= 3) {
- nWord >>= 8 * (3 - nSize);
- *this = nWord;
- } else {
- *this = nWord;
- *this <<= 8 * (nSize - 3);
- }
- if (pfNegative)
- *pfNegative = nWord != 0 && (nCompact & 0x00800000) != 0;
- if (pfOverflow)
- *pfOverflow = nWord != 0 && ((nSize > 34) ||
- (nWord > 0xff && nSize > 33) ||
- (nWord > 0xffff && nSize > 32));
- return *this;
-}
-
-uint32_t uint256::GetCompact(bool fNegative) const
-{
- int nSize = (bits() + 7) / 8;
- uint32_t nCompact = 0;
- if (nSize <= 3) {
- nCompact = GetLow64() << 8 * (3 - nSize);
- } else {
- uint256 bn = *this >> 8 * (nSize - 3);
- nCompact = bn.GetLow64();
- }
- // The 0x00800000 bit denotes the sign.
- // Thus, if it is already set, divide the mantissa by 256 and increase the exponent.
- if (nCompact & 0x00800000) {
- nCompact >>= 8;
- nSize++;
- }
- assert((nCompact & ~0x007fffff) == 0);
- assert(nSize < 256);
- nCompact |= nSize << 24;
- nCompact |= (fNegative && (nCompact & 0x007fffff) ? 0x00800000 : 0);
- return nCompact;
-}
+// Explicit instantiations for base_blob<256>
+template base_blob<256>::base_blob(const std::vector<unsigned char>&);
+template std::string base_blob<256>::GetHex() const;
+template std::string base_blob<256>::ToString() const;
+template void base_blob<256>::SetHex(const char*);
+template void base_blob<256>::SetHex(const std::string&);
static void inline HashMix(uint32_t& a, uint32_t& b, uint32_t& c)
{
@@ -339,18 +126,20 @@ static void inline HashFinal(uint32_t& a, uint32_t& b, uint32_t& c)
uint64_t uint256::GetHash(const uint256& salt) const
{
uint32_t a, b, c;
+ const uint32_t *pn = (const uint32_t*)data;
+ const uint32_t *salt_pn = (const uint32_t*)salt.data;
a = b = c = 0xdeadbeef + (WIDTH << 2);
- a += pn[0] ^ salt.pn[0];
- b += pn[1] ^ salt.pn[1];
- c += pn[2] ^ salt.pn[2];
+ a += pn[0] ^ salt_pn[0];
+ b += pn[1] ^ salt_pn[1];
+ c += pn[2] ^ salt_pn[2];
HashMix(a, b, c);
- a += pn[3] ^ salt.pn[3];
- b += pn[4] ^ salt.pn[4];
- c += pn[5] ^ salt.pn[5];
+ a += pn[3] ^ salt_pn[3];
+ b += pn[4] ^ salt_pn[4];
+ c += pn[5] ^ salt_pn[5];
HashMix(a, b, c);
- a += pn[6] ^ salt.pn[6];
- b += pn[7] ^ salt.pn[7];
+ a += pn[6] ^ salt_pn[6];
+ b += pn[7] ^ salt_pn[7];
HashFinal(a, b, c);
return ((((uint64_t)b) << 32) | c);
diff --git a/src/uint256.h b/src/uint256.h
index 139270ac49..6d016ab164 100644
--- a/src/uint256.h
+++ b/src/uint256.h
@@ -13,217 +13,37 @@
#include <string>
#include <vector>
-class uint_error : public std::runtime_error {
-public:
- explicit uint_error(const std::string& str) : std::runtime_error(str) {}
-};
-
-/** Template base class for unsigned big integers. */
+/** Template base class for fixed-sized opaque blobs. */
template<unsigned int BITS>
-class base_uint
+class base_blob
{
protected:
- enum { WIDTH=BITS/32 };
- uint32_t pn[WIDTH];
+ enum { WIDTH=BITS/8 };
+ uint8_t data[WIDTH];
public:
-
- base_uint()
+ base_blob()
{
- for (int i = 0; i < WIDTH; i++)
- pn[i] = 0;
+ memset(data, 0, sizeof(data));
}
- base_uint(const base_uint& b)
- {
- for (int i = 0; i < WIDTH; i++)
- pn[i] = b.pn[i];
- }
+ explicit base_blob(const std::vector<unsigned char>& vch);
- base_uint& operator=(const base_uint& b)
+ bool IsNull() const
{
for (int i = 0; i < WIDTH; i++)
- pn[i] = b.pn[i];
- return *this;
- }
-
- base_uint(uint64_t b)
- {
- pn[0] = (unsigned int)b;
- pn[1] = (unsigned int)(b >> 32);
- for (int i = 2; i < WIDTH; i++)
- pn[i] = 0;
- }
-
- explicit base_uint(const std::string& str);
- explicit base_uint(const std::vector<unsigned char>& vch);
-
- bool operator!() const
- {
- for (int i = 0; i < WIDTH; i++)
- if (pn[i] != 0)
+ if (data[i] != 0)
return false;
return true;
}
- const base_uint operator~() const
- {
- base_uint ret;
- for (int i = 0; i < WIDTH; i++)
- ret.pn[i] = ~pn[i];
- return ret;
- }
-
- const base_uint operator-() const
- {
- base_uint ret;
- for (int i = 0; i < WIDTH; i++)
- ret.pn[i] = ~pn[i];
- ret++;
- return ret;
- }
-
- double getdouble() const;
-
- base_uint& operator=(uint64_t b)
- {
- pn[0] = (unsigned int)b;
- pn[1] = (unsigned int)(b >> 32);
- for (int i = 2; i < WIDTH; i++)
- pn[i] = 0;
- return *this;
- }
-
- base_uint& operator^=(const base_uint& b)
- {
- for (int i = 0; i < WIDTH; i++)
- pn[i] ^= b.pn[i];
- return *this;
- }
-
- base_uint& operator&=(const base_uint& b)
- {
- for (int i = 0; i < WIDTH; i++)
- pn[i] &= b.pn[i];
- return *this;
- }
-
- base_uint& operator|=(const base_uint& b)
- {
- for (int i = 0; i < WIDTH; i++)
- pn[i] |= b.pn[i];
- return *this;
- }
-
- base_uint& operator^=(uint64_t b)
- {
- pn[0] ^= (unsigned int)b;
- pn[1] ^= (unsigned int)(b >> 32);
- return *this;
- }
-
- base_uint& operator|=(uint64_t b)
+ void SetNull()
{
- pn[0] |= (unsigned int)b;
- pn[1] |= (unsigned int)(b >> 32);
- return *this;
+ memset(data, 0, sizeof(data));
}
- base_uint& operator<<=(unsigned int shift);
- base_uint& operator>>=(unsigned int shift);
-
- base_uint& operator+=(const base_uint& b)
- {
- uint64_t carry = 0;
- for (int i = 0; i < WIDTH; i++)
- {
- uint64_t n = carry + pn[i] + b.pn[i];
- pn[i] = n & 0xffffffff;
- carry = n >> 32;
- }
- return *this;
- }
-
- base_uint& operator-=(const base_uint& b)
- {
- *this += -b;
- return *this;
- }
-
- base_uint& operator+=(uint64_t b64)
- {
- base_uint b;
- b = b64;
- *this += b;
- return *this;
- }
-
- base_uint& operator-=(uint64_t b64)
- {
- base_uint b;
- b = b64;
- *this += -b;
- return *this;
- }
-
- base_uint& operator*=(uint32_t b32);
- base_uint& operator*=(const base_uint& b);
- base_uint& operator/=(const base_uint& b);
-
- base_uint& operator++()
- {
- // prefix operator
- int i = 0;
- while (++pn[i] == 0 && i < WIDTH-1)
- i++;
- return *this;
- }
-
- const base_uint operator++(int)
- {
- // postfix operator
- const base_uint ret = *this;
- ++(*this);
- return ret;
- }
-
- base_uint& operator--()
- {
- // prefix operator
- int i = 0;
- while (--pn[i] == (uint32_t)-1 && i < WIDTH-1)
- i++;
- return *this;
- }
-
- const base_uint operator--(int)
- {
- // postfix operator
- const base_uint ret = *this;
- --(*this);
- return ret;
- }
-
- int CompareTo(const base_uint& b) const;
- bool EqualTo(uint64_t b) const;
-
- friend inline const base_uint operator+(const base_uint& a, const base_uint& b) { return base_uint(a) += b; }
- friend inline const base_uint operator-(const base_uint& a, const base_uint& b) { return base_uint(a) -= b; }
- friend inline const base_uint operator*(const base_uint& a, const base_uint& b) { return base_uint(a) *= b; }
- friend inline const base_uint operator/(const base_uint& a, const base_uint& b) { return base_uint(a) /= b; }
- friend inline const base_uint operator|(const base_uint& a, const base_uint& b) { return base_uint(a) |= b; }
- friend inline const base_uint operator&(const base_uint& a, const base_uint& b) { return base_uint(a) &= b; }
- friend inline const base_uint operator^(const base_uint& a, const base_uint& b) { return base_uint(a) ^= b; }
- friend inline const base_uint operator>>(const base_uint& a, int shift) { return base_uint(a) >>= shift; }
- friend inline const base_uint operator<<(const base_uint& a, int shift) { return base_uint(a) <<= shift; }
- friend inline const base_uint operator*(const base_uint& a, uint32_t b) { return base_uint(a) *= b; }
- friend inline bool operator==(const base_uint& a, const base_uint& b) { return memcmp(a.pn, b.pn, sizeof(a.pn)) == 0; }
- friend inline bool operator!=(const base_uint& a, const base_uint& b) { return memcmp(a.pn, b.pn, sizeof(a.pn)) != 0; }
- friend inline bool operator>(const base_uint& a, const base_uint& b) { return a.CompareTo(b) > 0; }
- friend inline bool operator<(const base_uint& a, const base_uint& b) { return a.CompareTo(b) < 0; }
- friend inline bool operator>=(const base_uint& a, const base_uint& b) { return a.CompareTo(b) >= 0; }
- friend inline bool operator<=(const base_uint& a, const base_uint& b) { return a.CompareTo(b) <= 0; }
- friend inline bool operator==(const base_uint& a, uint64_t b) { return a.EqualTo(b); }
- friend inline bool operator!=(const base_uint& a, uint64_t b) { return !a.EqualTo(b); }
+ friend inline bool operator==(const base_blob& a, const base_blob& b) { return memcmp(a.data, b.data, sizeof(a.data)) == 0; }
+ friend inline bool operator!=(const base_blob& a, const base_blob& b) { return memcmp(a.data, b.data, sizeof(a.data)) != 0; }
+ friend inline bool operator<(const base_blob& a, const base_blob& b) { return memcmp(a.data, b.data, sizeof(a.data)) < 0; }
std::string GetHex() const;
void SetHex(const char* psz);
@@ -232,102 +52,107 @@ public:
unsigned char* begin()
{
- return (unsigned char*)&pn[0];
+ return &data[0];
}
unsigned char* end()
{
- return (unsigned char*)&pn[WIDTH];
+ return &data[WIDTH];
}
const unsigned char* begin() const
{
- return (unsigned char*)&pn[0];
+ return &data[0];
}
const unsigned char* end() const
{
- return (unsigned char*)&pn[WIDTH];
+ return &data[WIDTH];
}
unsigned int size() const
{
- return sizeof(pn);
- }
-
- /**
- * Returns the position of the highest bit set plus one, or zero if the
- * value is zero.
- */
- unsigned int bits() const;
-
- uint64_t GetLow64() const
- {
- assert(WIDTH >= 2);
- return pn[0] | (uint64_t)pn[1] << 32;
+ return sizeof(data);
}
unsigned int GetSerializeSize(int nType, int nVersion) const
{
- return sizeof(pn);
+ return sizeof(data);
}
template<typename Stream>
void Serialize(Stream& s, int nType, int nVersion) const
{
- s.write((char*)pn, sizeof(pn));
+ s.write((char*)data, sizeof(data));
}
template<typename Stream>
void Unserialize(Stream& s, int nType, int nVersion)
{
- s.read((char*)pn, sizeof(pn));
+ s.read((char*)data, sizeof(data));
}
};
-/** 160-bit unsigned big integer. */
-class uint160 : public base_uint<160> {
+/** 160-bit opaque blob.
+ * @note This type is called uint160 for historical reasons only. It is an opaque
+ * blob of 160 bits and has no integer operations.
+ */
+class uint160 : public base_blob<160> {
public:
uint160() {}
- uint160(const base_uint<160>& b) : base_uint<160>(b) {}
- uint160(uint64_t b) : base_uint<160>(b) {}
- explicit uint160(const std::string& str) : base_uint<160>(str) {}
- explicit uint160(const std::vector<unsigned char>& vch) : base_uint<160>(vch) {}
+ uint160(const base_blob<160>& b) : base_blob<160>(b) {}
+ explicit uint160(const std::vector<unsigned char>& vch) : base_blob<160>(vch) {}
};
-/** 256-bit unsigned big integer. */
-class uint256 : public base_uint<256> {
+/** 256-bit opaque blob.
+ * @note This type is called uint256 for historical reasons only. It is an
+ * opaque blob of 256 bits and has no integer operations. Use arith_uint256 if
+ * those are required.
+ */
+class uint256 : public base_blob<256> {
public:
uint256() {}
- uint256(const base_uint<256>& b) : base_uint<256>(b) {}
- uint256(uint64_t b) : base_uint<256>(b) {}
- explicit uint256(const std::string& str) : base_uint<256>(str) {}
- explicit uint256(const std::vector<unsigned char>& vch) : base_uint<256>(vch) {}
-
- /**
- * The "compact" format is a representation of a whole
- * number N using an unsigned 32bit number similar to a
- * floating point format.
- * The most significant 8 bits are the unsigned exponent of base 256.
- * This exponent can be thought of as "number of bytes of N".
- * The lower 23 bits are the mantissa.
- * Bit number 24 (0x800000) represents the sign of N.
- * N = (-1^sign) * mantissa * 256^(exponent-3)
- *
- * Satoshi's original implementation used BN_bn2mpi() and BN_mpi2bn().
- * MPI uses the most significant bit of the first byte as sign.
- * Thus 0x1234560000 is compact (0x05123456)
- * and 0xc0de000000 is compact (0x0600c0de)
- *
- * Bitcoin only uses this "compact" format for encoding difficulty
- * targets, which are unsigned 256bit quantities. Thus, all the
- * complexities of the sign bit and using base 256 are probably an
- * implementation accident.
+ uint256(const base_blob<256>& b) : base_blob<256>(b) {}
+ explicit uint256(const std::vector<unsigned char>& vch) : base_blob<256>(vch) {}
+
+ /** A cheap hash function that just returns 64 bits from the result, it can be
+ * used when the contents are considered uniformly random. It is not appropriate
+ * when the value can easily be influenced from outside as e.g. a network adversary could
+ * provide values to trigger worst-case behavior.
+ * @note The result of this function is not stable between little and big endian.
*/
- uint256& SetCompact(uint32_t nCompact, bool *pfNegative = NULL, bool *pfOverflow = NULL);
- uint32_t GetCompact(bool fNegative = false) const;
+ uint64_t GetCheapHash() const
+ {
+ uint64_t result;
+ memcpy((void*)&result, (void*)data, 8);
+ return result;
+ }
+ /** A more secure, salted hash function.
+ * @note This hash is not stable between little and big endian.
+ */
uint64_t GetHash(const uint256& salt) const;
};
+/* uint256 from const char *.
+ * This is a separate function because the constructor uint256(const char*) can result
+ * in dangerously catching uint256(0).
+ */
+inline uint256 uint256S(const char *str)
+{
+ uint256 rv;
+ rv.SetHex(str);
+ return rv;
+}
+/* uint256 from std::string.
+ * This is a separate function because the constructor uint256(const std::string &str) can result
+ * in dangerously catching uint256(0) via std::string(const char*).
+ */
+inline uint256 uint256S(const std::string& str)
+{
+ uint256 rv;
+ rv.SetHex(str);
+ return rv;
+}
+
#endif // BITCOIN_UINT256_H
diff --git a/src/undo.h b/src/undo.h
index e6d8fd5862..1c4ed95bf2 100644
--- a/src/undo.h
+++ b/src/undo.h
@@ -68,4 +68,18 @@ public:
}
};
+/** Undo information for a CBlock */
+class CBlockUndo
+{
+public:
+ std::vector<CTxUndo> vtxundo; // for all but the coinbase
+
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+ READWRITE(vtxundo);
+ }
+};
+
#endif // BITCOIN_UNDO_H
diff --git a/src/wallet.cpp b/src/wallet.cpp
index 8504c0a287..b51c4d4b14 100644
--- a/src/wallet.cpp
+++ b/src/wallet.cpp
@@ -71,7 +71,6 @@ CPubKey CWallet::GenerateNewKey()
AssertLockHeld(cs_wallet); // mapKeyMetadata
bool fCompressed = CanSupportFeature(FEATURE_COMPRPUBKEY); // default to compressed public keys if we want 0.6.0 wallets
- RandAddSeedPerfmon();
CKey secret;
secret.MakeNewKey(fCompressed);
@@ -89,7 +88,7 @@ CPubKey CWallet::GenerateNewKey()
nTimeFirstKey = nCreationTime;
if (!AddKeyPubKey(secret, pubkey))
- throw std::runtime_error("CWallet::GenerateNewKey() : AddKey failed");
+ throw std::runtime_error("CWallet::GenerateNewKey(): AddKey failed");
return pubkey;
}
@@ -556,7 +555,7 @@ void CWallet::MarkDirty()
}
}
-bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet)
+bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet, CWalletDB* pwalletdb)
{
uint256 hash = wtxIn.GetHash();
@@ -577,10 +576,10 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet)
if (fInsertedNew)
{
wtx.nTimeReceived = GetAdjustedTime();
- wtx.nOrderPos = IncOrderPosNext();
+ wtx.nOrderPos = IncOrderPosNext(pwalletdb);
wtx.nTimeSmart = wtx.nTimeReceived;
- if (wtxIn.hashBlock != 0)
+ if (!wtxIn.hashBlock.IsNull())
{
if (mapBlockIndex.count(wtxIn.hashBlock))
{
@@ -620,7 +619,7 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet)
wtx.nTimeSmart = std::max(latestEntry, std::min(blocktime, latestNow));
}
else
- LogPrintf("AddToWallet() : found %s in block %s not in index\n",
+ LogPrintf("AddToWallet(): found %s in block %s not in index\n",
wtxIn.GetHash().ToString(),
wtxIn.hashBlock.ToString());
}
@@ -631,7 +630,7 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet)
if (!fInsertedNew)
{
// Merge
- if (wtxIn.hashBlock != 0 && wtxIn.hashBlock != wtx.hashBlock)
+ if (!wtxIn.hashBlock.IsNull() && wtxIn.hashBlock != wtx.hashBlock)
{
wtx.hashBlock = wtxIn.hashBlock;
fUpdated = true;
@@ -654,7 +653,7 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet)
// Write to disk
if (fInsertedNew || fUpdated)
- if (!wtx.WriteToDisk())
+ if (!wtx.WriteToDisk(pwalletdb))
return false;
// Break debit/credit balance caches:
@@ -690,10 +689,16 @@ bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pbl
if (fExisted || IsMine(tx) || IsFromMe(tx))
{
CWalletTx wtx(this,tx);
+
// Get merkle branch if transaction was found in a block
if (pblock)
wtx.SetMerkleBranch(*pblock);
- return AddToWallet(wtx);
+
+ // Do not flush the wallet here for performance reasons
+ // this is safe, as in case of a crash, we rescan the necessary blocks on startup through our SetBestChain-mechanism
+ CWalletDB walletdb(strWalletFile, "r+", false);
+
+ return AddToWallet(wtx, false, &walletdb);
}
}
return false;
@@ -796,7 +801,7 @@ int CWalletTx::GetRequestCount() const
if (IsCoinBase())
{
// Generated block
- if (hashBlock != 0)
+ if (!hashBlock.IsNull())
{
map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(hashBlock);
if (mi != pwallet->mapRequestCount.end())
@@ -812,7 +817,7 @@ int CWalletTx::GetRequestCount() const
nRequests = (*mi).second;
// How about the block it's in?
- if (nRequests == 0 && hashBlock != 0)
+ if (nRequests == 0 && !hashBlock.IsNull())
{
map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(hashBlock);
if (mi != pwallet->mapRequestCount.end())
@@ -917,9 +922,9 @@ void CWalletTx::GetAccountAmounts(const string& strAccount, CAmount& nReceived,
}
-bool CWalletTx::WriteToDisk()
+bool CWalletTx::WriteToDisk(CWalletDB *pwalletdb)
{
- return CWalletDB(pwallet->strWalletFile).WriteTx(GetHash(), *this);
+ return pwalletdb->WriteTx(GetHash(), *this);
}
/**
@@ -1010,6 +1015,193 @@ set<uint256> CWalletTx::GetConflicts() const
return result;
}
+CAmount CWalletTx::GetDebit(const isminefilter& filter) const
+{
+ if (vin.empty())
+ return 0;
+
+ CAmount debit = 0;
+ if(filter & ISMINE_SPENDABLE)
+ {
+ if (fDebitCached)
+ debit += nDebitCached;
+ else
+ {
+ nDebitCached = pwallet->GetDebit(*this, ISMINE_SPENDABLE);
+ fDebitCached = true;
+ debit += nDebitCached;
+ }
+ }
+ if(filter & ISMINE_WATCH_ONLY)
+ {
+ if(fWatchDebitCached)
+ debit += nWatchDebitCached;
+ else
+ {
+ nWatchDebitCached = pwallet->GetDebit(*this, ISMINE_WATCH_ONLY);
+ fWatchDebitCached = true;
+ debit += nWatchDebitCached;
+ }
+ }
+ return debit;
+}
+
+CAmount CWalletTx::GetCredit(const isminefilter& filter) const
+{
+ // Must wait until coinbase is safely deep enough in the chain before valuing it
+ if (IsCoinBase() && GetBlocksToMaturity() > 0)
+ return 0;
+
+ int64_t credit = 0;
+ if (filter & ISMINE_SPENDABLE)
+ {
+ // GetBalance can assume transactions in mapWallet won't change
+ if (fCreditCached)
+ credit += nCreditCached;
+ else
+ {
+ nCreditCached = pwallet->GetCredit(*this, ISMINE_SPENDABLE);
+ fCreditCached = true;
+ credit += nCreditCached;
+ }
+ }
+ if (filter & ISMINE_WATCH_ONLY)
+ {
+ if (fWatchCreditCached)
+ credit += nWatchCreditCached;
+ else
+ {
+ nWatchCreditCached = pwallet->GetCredit(*this, ISMINE_WATCH_ONLY);
+ fWatchCreditCached = true;
+ credit += nWatchCreditCached;
+ }
+ }
+ return credit;
+}
+
+CAmount CWalletTx::GetImmatureCredit(bool fUseCache) const
+{
+ if (IsCoinBase() && GetBlocksToMaturity() > 0 && IsInMainChain())
+ {
+ if (fUseCache && fImmatureCreditCached)
+ return nImmatureCreditCached;
+ nImmatureCreditCached = pwallet->GetCredit(*this, ISMINE_SPENDABLE);
+ fImmatureCreditCached = true;
+ return nImmatureCreditCached;
+ }
+
+ return 0;
+}
+
+CAmount CWalletTx::GetAvailableCredit(bool fUseCache) const
+{
+ if (pwallet == 0)
+ return 0;
+
+ // Must wait until coinbase is safely deep enough in the chain before valuing it
+ if (IsCoinBase() && GetBlocksToMaturity() > 0)
+ return 0;
+
+ if (fUseCache && fAvailableCreditCached)
+ return nAvailableCreditCached;
+
+ CAmount nCredit = 0;
+ uint256 hashTx = GetHash();
+ for (unsigned int i = 0; i < vout.size(); i++)
+ {
+ if (!pwallet->IsSpent(hashTx, i))
+ {
+ const CTxOut &txout = vout[i];
+ nCredit += pwallet->GetCredit(txout, ISMINE_SPENDABLE);
+ if (!MoneyRange(nCredit))
+ throw std::runtime_error("CWalletTx::GetAvailableCredit() : value out of range");
+ }
+ }
+
+ nAvailableCreditCached = nCredit;
+ fAvailableCreditCached = true;
+ return nCredit;
+}
+
+CAmount CWalletTx::GetImmatureWatchOnlyCredit(const bool& fUseCache) const
+{
+ if (IsCoinBase() && GetBlocksToMaturity() > 0 && IsInMainChain())
+ {
+ if (fUseCache && fImmatureWatchCreditCached)
+ return nImmatureWatchCreditCached;
+ nImmatureWatchCreditCached = pwallet->GetCredit(*this, ISMINE_WATCH_ONLY);
+ fImmatureWatchCreditCached = true;
+ return nImmatureWatchCreditCached;
+ }
+
+ return 0;
+}
+
+CAmount CWalletTx::GetAvailableWatchOnlyCredit(const bool& fUseCache) const
+{
+ if (pwallet == 0)
+ return 0;
+
+ // Must wait until coinbase is safely deep enough in the chain before valuing it
+ if (IsCoinBase() && GetBlocksToMaturity() > 0)
+ return 0;
+
+ if (fUseCache && fAvailableWatchCreditCached)
+ return nAvailableWatchCreditCached;
+
+ CAmount nCredit = 0;
+ for (unsigned int i = 0; i < vout.size(); i++)
+ {
+ if (!pwallet->IsSpent(GetHash(), i))
+ {
+ const CTxOut &txout = vout[i];
+ nCredit += pwallet->GetCredit(txout, ISMINE_WATCH_ONLY);
+ if (!MoneyRange(nCredit))
+ throw std::runtime_error("CWalletTx::GetAvailableCredit() : value out of range");
+ }
+ }
+
+ nAvailableWatchCreditCached = nCredit;
+ fAvailableWatchCreditCached = true;
+ return nCredit;
+}
+
+CAmount CWalletTx::GetChange() const
+{
+ if (fChangeCached)
+ return nChangeCached;
+ nChangeCached = pwallet->GetChange(*this);
+ fChangeCached = true;
+ return nChangeCached;
+}
+
+bool CWalletTx::IsTrusted() const
+{
+ // Quick answer in most cases
+ if (!IsFinalTx(*this))
+ return false;
+ int nDepth = GetDepthInMainChain();
+ if (nDepth >= 1)
+ return true;
+ if (nDepth < 0)
+ return false;
+ if (!bSpendZeroConfChange || !IsFromMe(ISMINE_ALL)) // using wtx's cached debit
+ return false;
+
+ // Trusted if all inputs are from us and are in the mempool:
+ BOOST_FOREACH(const CTxIn& txin, vin)
+ {
+ // Transactions not sent by us: not trusted
+ const CWalletTx* parent = pwallet->GetWalletTx(txin.prevout.hash);
+ if (parent == NULL)
+ return false;
+ const CTxOut& parentOut = parent->vout[txin.prevout.n];
+ if (pwallet->IsMine(parentOut) != ISMINE_SPENDABLE)
+ return false;
+ }
+ return true;
+}
+
void CWallet::ResendWalletTransactions()
{
// Do this infrequently and randomly to avoid giving away
@@ -1440,10 +1632,14 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, CAmount> >& vecSend,
BOOST_FOREACH(PAIRTYPE(const CWalletTx*, unsigned int) pcoin, setCoins)
{
CAmount nCredit = pcoin.first->vout[pcoin.second].nValue;
- //The priority after the next block (depth+1) is used instead of the current,
+ //The coin age after the next block (depth+1) is used instead of the current,
//reflecting an assumption the user would accept a bit more delay for
//a chance at a free transaction.
- dPriority += (double)nCredit * (pcoin.first->GetDepthInMainChain()+1);
+ //But mempool inputs might still be in the mempool, so their age stays 0
+ int age = pcoin.first->GetDepthInMainChain();
+ if (age != 0)
+ age += 1;
+ dPriority += (double)nCredit * age;
}
CAmount nChange = nValueIn - nValue - nFeeRet;
@@ -1582,14 +1778,14 @@ bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey)
// This is only to keep the database open to defeat the auto-flush for the
// duration of this scope. This is the only place where this optimization
// maybe makes sense; please don't do it anywhere else.
- CWalletDB* pwalletdb = fFileBacked ? new CWalletDB(strWalletFile,"r") : NULL;
+ CWalletDB* pwalletdb = fFileBacked ? new CWalletDB(strWalletFile,"r+") : NULL;
// Take key pair from key pool so it won't be used again
reservekey.KeepKey();
// Add tx to wallet, because if it has change it's also ours,
// otherwise just for transaction history.
- AddToWallet(wtxNew);
+ AddToWallet(wtxNew, false, pwalletdb);
// Notify that old coins are spent
set<CWalletTx*> setCoins;
@@ -1611,7 +1807,7 @@ bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey)
if (!wtxNew.AcceptToMemoryPool(false))
{
// This must not fail. The transaction has already been signed and recorded.
- LogPrintf("CommitTransaction() : Error: Transaction not valid");
+ LogPrintf("CommitTransaction(): Error: Transaction not valid");
return false;
}
wtxNew.RelayWalletTransaction();
@@ -1804,7 +2000,7 @@ bool CWallet::TopUpKeyPool(unsigned int kpSize)
if (!setKeyPool.empty())
nEnd = *(--setKeyPool.end()) + 1;
if (!walletdb.WritePool(nEnd, CKeyPool(GenerateNewKey())))
- throw runtime_error("TopUpKeyPool() : writing generated key failed");
+ throw runtime_error("TopUpKeyPool(): writing generated key failed");
setKeyPool.insert(nEnd);
LogPrintf("keypool added key %d, size=%u\n", nEnd, setKeyPool.size());
}
@@ -1831,9 +2027,9 @@ void CWallet::ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& keypool)
nIndex = *(setKeyPool.begin());
setKeyPool.erase(setKeyPool.begin());
if (!walletdb.ReadPool(nIndex, keypool))
- throw runtime_error("ReserveKeyFromKeyPool() : read failed");
+ throw runtime_error("ReserveKeyFromKeyPool(): read failed");
if (!HaveKey(keypool.vchPubKey.GetID()))
- throw runtime_error("ReserveKeyFromKeyPool() : unknown key in key pool");
+ throw runtime_error("ReserveKeyFromKeyPool(): unknown key in key pool");
assert(keypool.vchPubKey.IsValid());
LogPrintf("keypool reserve %d\n", nIndex);
}
@@ -2081,11 +2277,11 @@ void CWallet::GetAllReserveKeys(set<CKeyID>& setAddress) const
{
CKeyPool keypool;
if (!walletdb.ReadPool(id, keypool))
- throw runtime_error("GetAllReserveKeyHashes() : read failed");
+ throw runtime_error("GetAllReserveKeyHashes(): read failed");
assert(keypool.vchPubKey.IsValid());
CKeyID keyID = keypool.vchPubKey.GetID();
if (!HaveKey(keyID))
- throw runtime_error("GetAllReserveKeyHashes() : unknown key in key pool");
+ throw runtime_error("GetAllReserveKeyHashes(): unknown key in key pool");
setAddress.insert(keyID);
}
}
@@ -2298,7 +2494,7 @@ int CMerkleTx::SetMerkleBranch(const CBlock& block)
{
vMerkleBranch.clear();
nIndex = -1;
- LogPrintf("ERROR: SetMerkleBranch() : couldn't find tx in block\n");
+ LogPrintf("ERROR: SetMerkleBranch(): couldn't find tx in block\n");
return 0;
}
@@ -2318,7 +2514,7 @@ int CMerkleTx::SetMerkleBranch(const CBlock& block)
int CMerkleTx::GetDepthInMainChainINTERNAL(const CBlockIndex* &pindexRet) const
{
- if (hashBlock == 0 || nIndex == -1)
+ if (hashBlock.IsNull() || nIndex == -1)
return 0;
AssertLockHeld(cs_main);
@@ -2360,9 +2556,9 @@ int CMerkleTx::GetBlocksToMaturity() const
}
-bool CMerkleTx::AcceptToMemoryPool(bool fLimitFree, bool fRejectInsaneFee)
+bool CMerkleTx::AcceptToMemoryPool(bool fLimitFree, bool fRejectAbsurdFee)
{
CValidationState state;
- return ::AcceptToMemoryPool(mempool, state, *this, fLimitFree, NULL, fRejectInsaneFee);
+ return ::AcceptToMemoryPool(mempool, state, *this, fLimitFree, NULL, fRejectAbsurdFee);
}
diff --git a/src/wallet.h b/src/wallet.h
index 4d95d0ae2e..6ed87d1e68 100644
--- a/src/wallet.h
+++ b/src/wallet.h
@@ -103,6 +103,329 @@ public:
StringMap destdata;
};
+
+typedef std::map<std::string, std::string> mapValue_t;
+
+
+static void ReadOrderPos(int64_t& nOrderPos, mapValue_t& mapValue)
+{
+ if (!mapValue.count("n"))
+ {
+ nOrderPos = -1; // TODO: calculate elsewhere
+ return;
+ }
+ nOrderPos = atoi64(mapValue["n"].c_str());
+}
+
+
+static void WriteOrderPos(const int64_t& nOrderPos, mapValue_t& mapValue)
+{
+ if (nOrderPos == -1)
+ return;
+ mapValue["n"] = i64tostr(nOrderPos);
+}
+
+struct COutputEntry
+{
+ CTxDestination destination;
+ CAmount amount;
+ int vout;
+};
+
+/** A transaction with a merkle branch linking it to the block chain. */
+class CMerkleTx : public CTransaction
+{
+private:
+ int GetDepthInMainChainINTERNAL(const CBlockIndex* &pindexRet) const;
+
+public:
+ uint256 hashBlock;
+ std::vector<uint256> vMerkleBranch;
+ int nIndex;
+
+ // memory only
+ mutable bool fMerkleVerified;
+
+
+ CMerkleTx()
+ {
+ Init();
+ }
+
+ CMerkleTx(const CTransaction& txIn) : CTransaction(txIn)
+ {
+ Init();
+ }
+
+ void Init()
+ {
+ hashBlock = uint256();
+ nIndex = -1;
+ fMerkleVerified = false;
+ }
+
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+ READWRITE(*(CTransaction*)this);
+ nVersion = this->nVersion;
+ READWRITE(hashBlock);
+ READWRITE(vMerkleBranch);
+ READWRITE(nIndex);
+ }
+
+ int SetMerkleBranch(const CBlock& block);
+
+
+ /**
+ * Return depth of transaction in blockchain:
+ * -1 : not in blockchain, and not in memory pool (conflicted transaction)
+ * 0 : in memory pool, waiting to be included in a block
+ * >=1 : this many blocks deep in the main chain
+ */
+ int GetDepthInMainChain(const CBlockIndex* &pindexRet) const;
+ int GetDepthInMainChain() const { const CBlockIndex *pindexRet; return GetDepthInMainChain(pindexRet); }
+ bool IsInMainChain() const { const CBlockIndex *pindexRet; return GetDepthInMainChainINTERNAL(pindexRet) > 0; }
+ int GetBlocksToMaturity() const;
+ bool AcceptToMemoryPool(bool fLimitFree=true, bool fRejectAbsurdFee=true);
+};
+
+/**
+ * A transaction with a bunch of additional info that only the owner cares about.
+ * It includes any unrecorded transactions needed to link it back to the block chain.
+ */
+class CWalletTx : public CMerkleTx
+{
+private:
+ const CWallet* pwallet;
+
+public:
+ mapValue_t mapValue;
+ std::vector<std::pair<std::string, std::string> > vOrderForm;
+ unsigned int fTimeReceivedIsTxTime;
+ unsigned int nTimeReceived; //! time received by this node
+ unsigned int nTimeSmart;
+ char fFromMe;
+ std::string strFromAccount;
+ int64_t nOrderPos; //! position in ordered transaction list
+
+ // memory only
+ mutable bool fDebitCached;
+ mutable bool fCreditCached;
+ mutable bool fImmatureCreditCached;
+ mutable bool fAvailableCreditCached;
+ mutable bool fWatchDebitCached;
+ mutable bool fWatchCreditCached;
+ mutable bool fImmatureWatchCreditCached;
+ mutable bool fAvailableWatchCreditCached;
+ mutable bool fChangeCached;
+ mutable CAmount nDebitCached;
+ mutable CAmount nCreditCached;
+ mutable CAmount nImmatureCreditCached;
+ mutable CAmount nAvailableCreditCached;
+ mutable CAmount nWatchDebitCached;
+ mutable CAmount nWatchCreditCached;
+ mutable CAmount nImmatureWatchCreditCached;
+ mutable CAmount nAvailableWatchCreditCached;
+ mutable CAmount nChangeCached;
+
+ CWalletTx()
+ {
+ Init(NULL);
+ }
+
+ CWalletTx(const CWallet* pwalletIn)
+ {
+ Init(pwalletIn);
+ }
+
+ CWalletTx(const CWallet* pwalletIn, const CMerkleTx& txIn) : CMerkleTx(txIn)
+ {
+ Init(pwalletIn);
+ }
+
+ CWalletTx(const CWallet* pwalletIn, const CTransaction& txIn) : CMerkleTx(txIn)
+ {
+ Init(pwalletIn);
+ }
+
+ void Init(const CWallet* pwalletIn)
+ {
+ pwallet = pwalletIn;
+ mapValue.clear();
+ vOrderForm.clear();
+ fTimeReceivedIsTxTime = false;
+ nTimeReceived = 0;
+ nTimeSmart = 0;
+ fFromMe = false;
+ strFromAccount.clear();
+ fDebitCached = false;
+ fCreditCached = false;
+ fImmatureCreditCached = false;
+ fAvailableCreditCached = false;
+ fWatchDebitCached = false;
+ fWatchCreditCached = false;
+ fImmatureWatchCreditCached = false;
+ fAvailableWatchCreditCached = false;
+ fChangeCached = false;
+ nDebitCached = 0;
+ nCreditCached = 0;
+ nImmatureCreditCached = 0;
+ nAvailableCreditCached = 0;
+ nWatchDebitCached = 0;
+ nWatchCreditCached = 0;
+ nAvailableWatchCreditCached = 0;
+ nImmatureWatchCreditCached = 0;
+ nChangeCached = 0;
+ nOrderPos = -1;
+ }
+
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+ if (ser_action.ForRead())
+ Init(NULL);
+ char fSpent = false;
+
+ if (!ser_action.ForRead())
+ {
+ mapValue["fromaccount"] = strFromAccount;
+
+ WriteOrderPos(nOrderPos, mapValue);
+
+ if (nTimeSmart)
+ mapValue["timesmart"] = strprintf("%u", nTimeSmart);
+ }
+
+ READWRITE(*(CMerkleTx*)this);
+ std::vector<CMerkleTx> vUnused; //! Used to be vtxPrev
+ READWRITE(vUnused);
+ READWRITE(mapValue);
+ READWRITE(vOrderForm);
+ READWRITE(fTimeReceivedIsTxTime);
+ READWRITE(nTimeReceived);
+ READWRITE(fFromMe);
+ READWRITE(fSpent);
+
+ if (ser_action.ForRead())
+ {
+ strFromAccount = mapValue["fromaccount"];
+
+ ReadOrderPos(nOrderPos, mapValue);
+
+ nTimeSmart = mapValue.count("timesmart") ? (unsigned int)atoi64(mapValue["timesmart"]) : 0;
+ }
+
+ mapValue.erase("fromaccount");
+ mapValue.erase("version");
+ mapValue.erase("spent");
+ mapValue.erase("n");
+ mapValue.erase("timesmart");
+ }
+
+ //! make sure balances are recalculated
+ void MarkDirty()
+ {
+ fCreditCached = false;
+ fAvailableCreditCached = false;
+ fWatchDebitCached = false;
+ fWatchCreditCached = false;
+ fAvailableWatchCreditCached = false;
+ fImmatureWatchCreditCached = false;
+ fDebitCached = false;
+ fChangeCached = false;
+ }
+
+ void BindWallet(CWallet *pwalletIn)
+ {
+ pwallet = pwalletIn;
+ MarkDirty();
+ }
+
+ //! filter decides which addresses will count towards the debit
+ CAmount GetDebit(const isminefilter& filter) const;
+ CAmount GetCredit(const isminefilter& filter) const;
+ CAmount GetImmatureCredit(bool fUseCache=true) const;
+ CAmount GetAvailableCredit(bool fUseCache=true) const;
+ CAmount GetImmatureWatchOnlyCredit(const bool& fUseCache=true) const;
+ CAmount GetAvailableWatchOnlyCredit(const bool& fUseCache=true) const;
+ CAmount GetChange() const;
+
+ void GetAmounts(std::list<COutputEntry>& listReceived,
+ std::list<COutputEntry>& listSent, CAmount& nFee, std::string& strSentAccount, const isminefilter& filter) const;
+
+ void GetAccountAmounts(const std::string& strAccount, CAmount& nReceived,
+ CAmount& nSent, CAmount& nFee, const isminefilter& filter) const;
+
+ bool IsFromMe(const isminefilter& filter) const
+ {
+ return (GetDebit(filter) > 0);
+ }
+
+ bool IsTrusted() const;
+
+ bool WriteToDisk(CWalletDB *pwalletdb);
+
+ int64_t GetTxTime() const;
+ int GetRequestCount() const;
+
+ void RelayWalletTransaction();
+
+ std::set<uint256> GetConflicts() const;
+};
+
+
+
+
+class COutput
+{
+public:
+ const CWalletTx *tx;
+ int i;
+ int nDepth;
+ bool fSpendable;
+
+ COutput(const CWalletTx *txIn, int iIn, int nDepthIn, bool fSpendableIn)
+ {
+ tx = txIn; i = iIn; nDepth = nDepthIn; fSpendable = fSpendableIn;
+ }
+
+ std::string ToString() const;
+};
+
+
+
+
+/** Private key that includes an expiration date in case it never gets used. */
+class CWalletKey
+{
+public:
+ CPrivKey vchPrivKey;
+ int64_t nTimeCreated;
+ int64_t nTimeExpires;
+ std::string strComment;
+ //! todo: add something to note what created it (user, getnewaddress, change)
+ //! maybe should have a map<string, string> property map
+
+ CWalletKey(int64_t nExpires=0);
+
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+ if (!(nType & SER_GETHASH))
+ READWRITE(nVersion);
+ READWRITE(vchPrivKey);
+ READWRITE(nTimeCreated);
+ READWRITE(nTimeExpires);
+ READWRITE(LIMITED_STRING(strComment, 65536));
+ }
+};
+
+
+
/**
* A CWallet is an extension of a keystore, which also maintains a set of transactions and balances,
* and provides the ability to create new transactions.
@@ -275,7 +598,7 @@ public:
TxItems OrderedTxItems(std::list<CAccountingEntry>& acentries, std::string strAccount = "");
void MarkDirty();
- bool AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet=false);
+ bool AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet, CWalletDB* pwalletdb);
void SyncTransaction(const CTransaction& tx, const CBlock* pblock);
bool AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate);
void EraseFromWallet(const uint256 &hash);
@@ -320,14 +643,14 @@ public:
CAmount GetCredit(const CTxOut& txout, const isminefilter& filter) const
{
if (!MoneyRange(txout.nValue))
- throw std::runtime_error("CWallet::GetCredit() : value out of range");
+ throw std::runtime_error("CWallet::GetCredit(): value out of range");
return ((IsMine(txout) & filter) ? txout.nValue : 0);
}
bool IsChange(const CTxOut& txout) const;
CAmount GetChange(const CTxOut& txout) const
{
if (!MoneyRange(txout.nValue))
- throw std::runtime_error("CWallet::GetChange() : value out of range");
+ throw std::runtime_error("CWallet::GetChange(): value out of range");
return (IsChange(txout) ? txout.nValue : 0);
}
bool IsMine(const CTransaction& tx) const
@@ -349,7 +672,7 @@ public:
{
nDebit += GetDebit(txin, filter);
if (!MoneyRange(nDebit))
- throw std::runtime_error("CWallet::GetDebit() : value out of range");
+ throw std::runtime_error("CWallet::GetDebit(): value out of range");
}
return nDebit;
}
@@ -360,7 +683,7 @@ public:
{
nCredit += GetCredit(txout, filter);
if (!MoneyRange(nCredit))
- throw std::runtime_error("CWallet::GetCredit() : value out of range");
+ throw std::runtime_error("CWallet::GetCredit(): value out of range");
}
return nCredit;
}
@@ -371,7 +694,7 @@ public:
{
nChange += GetChange(txout);
if (!MoneyRange(nChange))
- throw std::runtime_error("CWallet::GetChange() : value out of range");
+ throw std::runtime_error("CWallet::GetChange(): value out of range");
}
return nChange;
}
@@ -464,508 +787,6 @@ public:
};
-typedef std::map<std::string, std::string> mapValue_t;
-
-
-static void ReadOrderPos(int64_t& nOrderPos, mapValue_t& mapValue)
-{
- if (!mapValue.count("n"))
- {
- nOrderPos = -1; // TODO: calculate elsewhere
- return;
- }
- nOrderPos = atoi64(mapValue["n"].c_str());
-}
-
-
-static void WriteOrderPos(const int64_t& nOrderPos, mapValue_t& mapValue)
-{
- if (nOrderPos == -1)
- return;
- mapValue["n"] = i64tostr(nOrderPos);
-}
-
-struct COutputEntry
-{
- CTxDestination destination;
- CAmount amount;
- int vout;
-};
-
-/** A transaction with a merkle branch linking it to the block chain. */
-class CMerkleTx : public CTransaction
-{
-private:
- int GetDepthInMainChainINTERNAL(const CBlockIndex* &pindexRet) const;
-
-public:
- uint256 hashBlock;
- std::vector<uint256> vMerkleBranch;
- int nIndex;
-
- // memory only
- mutable bool fMerkleVerified;
-
-
- CMerkleTx()
- {
- Init();
- }
-
- CMerkleTx(const CTransaction& txIn) : CTransaction(txIn)
- {
- Init();
- }
-
- void Init()
- {
- hashBlock = 0;
- nIndex = -1;
- fMerkleVerified = false;
- }
-
- ADD_SERIALIZE_METHODS;
-
- template <typename Stream, typename Operation>
- inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
- READWRITE(*(CTransaction*)this);
- nVersion = this->nVersion;
- READWRITE(hashBlock);
- READWRITE(vMerkleBranch);
- READWRITE(nIndex);
- }
-
- int SetMerkleBranch(const CBlock& block);
-
-
- /**
- * Return depth of transaction in blockchain:
- * -1 : not in blockchain, and not in memory pool (conflicted transaction)
- * 0 : in memory pool, waiting to be included in a block
- * >=1 : this many blocks deep in the main chain
- */
- int GetDepthInMainChain(const CBlockIndex* &pindexRet) const;
- int GetDepthInMainChain() const { const CBlockIndex *pindexRet; return GetDepthInMainChain(pindexRet); }
- bool IsInMainChain() const { const CBlockIndex *pindexRet; return GetDepthInMainChainINTERNAL(pindexRet) > 0; }
- int GetBlocksToMaturity() const;
- bool AcceptToMemoryPool(bool fLimitFree=true, bool fRejectInsaneFee=true);
-};
-
-/**
- * A transaction with a bunch of additional info that only the owner cares about.
- * It includes any unrecorded transactions needed to link it back to the block chain.
- */
-class CWalletTx : public CMerkleTx
-{
-private:
- const CWallet* pwallet;
-
-public:
- mapValue_t mapValue;
- std::vector<std::pair<std::string, std::string> > vOrderForm;
- unsigned int fTimeReceivedIsTxTime;
- unsigned int nTimeReceived; //! time received by this node
- unsigned int nTimeSmart;
- char fFromMe;
- std::string strFromAccount;
- int64_t nOrderPos; //! position in ordered transaction list
-
- // memory only
- mutable bool fDebitCached;
- mutable bool fCreditCached;
- mutable bool fImmatureCreditCached;
- mutable bool fAvailableCreditCached;
- mutable bool fWatchDebitCached;
- mutable bool fWatchCreditCached;
- mutable bool fImmatureWatchCreditCached;
- mutable bool fAvailableWatchCreditCached;
- mutable bool fChangeCached;
- mutable CAmount nDebitCached;
- mutable CAmount nCreditCached;
- mutable CAmount nImmatureCreditCached;
- mutable CAmount nAvailableCreditCached;
- mutable CAmount nWatchDebitCached;
- mutable CAmount nWatchCreditCached;
- mutable CAmount nImmatureWatchCreditCached;
- mutable CAmount nAvailableWatchCreditCached;
- mutable CAmount nChangeCached;
-
- CWalletTx()
- {
- Init(NULL);
- }
-
- CWalletTx(const CWallet* pwalletIn)
- {
- Init(pwalletIn);
- }
-
- CWalletTx(const CWallet* pwalletIn, const CMerkleTx& txIn) : CMerkleTx(txIn)
- {
- Init(pwalletIn);
- }
-
- CWalletTx(const CWallet* pwalletIn, const CTransaction& txIn) : CMerkleTx(txIn)
- {
- Init(pwalletIn);
- }
-
- void Init(const CWallet* pwalletIn)
- {
- pwallet = pwalletIn;
- mapValue.clear();
- vOrderForm.clear();
- fTimeReceivedIsTxTime = false;
- nTimeReceived = 0;
- nTimeSmart = 0;
- fFromMe = false;
- strFromAccount.clear();
- fDebitCached = false;
- fCreditCached = false;
- fImmatureCreditCached = false;
- fAvailableCreditCached = false;
- fWatchDebitCached = false;
- fWatchCreditCached = false;
- fImmatureWatchCreditCached = false;
- fAvailableWatchCreditCached = false;
- fChangeCached = false;
- nDebitCached = 0;
- nCreditCached = 0;
- nImmatureCreditCached = 0;
- nAvailableCreditCached = 0;
- nWatchDebitCached = 0;
- nWatchCreditCached = 0;
- nAvailableWatchCreditCached = 0;
- nImmatureWatchCreditCached = 0;
- nChangeCached = 0;
- nOrderPos = -1;
- }
-
- ADD_SERIALIZE_METHODS;
-
- template <typename Stream, typename Operation>
- inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
- if (ser_action.ForRead())
- Init(NULL);
- char fSpent = false;
-
- if (!ser_action.ForRead())
- {
- mapValue["fromaccount"] = strFromAccount;
-
- WriteOrderPos(nOrderPos, mapValue);
-
- if (nTimeSmart)
- mapValue["timesmart"] = strprintf("%u", nTimeSmart);
- }
-
- READWRITE(*(CMerkleTx*)this);
- std::vector<CMerkleTx> vUnused; //! Used to be vtxPrev
- READWRITE(vUnused);
- READWRITE(mapValue);
- READWRITE(vOrderForm);
- READWRITE(fTimeReceivedIsTxTime);
- READWRITE(nTimeReceived);
- READWRITE(fFromMe);
- READWRITE(fSpent);
-
- if (ser_action.ForRead())
- {
- strFromAccount = mapValue["fromaccount"];
-
- ReadOrderPos(nOrderPos, mapValue);
-
- nTimeSmart = mapValue.count("timesmart") ? (unsigned int)atoi64(mapValue["timesmart"]) : 0;
- }
-
- mapValue.erase("fromaccount");
- mapValue.erase("version");
- mapValue.erase("spent");
- mapValue.erase("n");
- mapValue.erase("timesmart");
- }
-
- //! make sure balances are recalculated
- void MarkDirty()
- {
- fCreditCached = false;
- fAvailableCreditCached = false;
- fWatchDebitCached = false;
- fWatchCreditCached = false;
- fAvailableWatchCreditCached = false;
- fImmatureWatchCreditCached = false;
- fDebitCached = false;
- fChangeCached = false;
- }
-
- void BindWallet(CWallet *pwalletIn)
- {
- pwallet = pwalletIn;
- MarkDirty();
- }
-
- //! filter decides which addresses will count towards the debit
- CAmount GetDebit(const isminefilter& filter) const
- {
- if (vin.empty())
- return 0;
-
- CAmount debit = 0;
- if(filter & ISMINE_SPENDABLE)
- {
- if (fDebitCached)
- debit += nDebitCached;
- else
- {
- nDebitCached = pwallet->GetDebit(*this, ISMINE_SPENDABLE);
- fDebitCached = true;
- debit += nDebitCached;
- }
- }
- if(filter & ISMINE_WATCH_ONLY)
- {
- if(fWatchDebitCached)
- debit += nWatchDebitCached;
- else
- {
- nWatchDebitCached = pwallet->GetDebit(*this, ISMINE_WATCH_ONLY);
- fWatchDebitCached = true;
- debit += nWatchDebitCached;
- }
- }
- return debit;
- }
-
- CAmount GetCredit(const isminefilter& filter) const
- {
- // Must wait until coinbase is safely deep enough in the chain before valuing it
- if (IsCoinBase() && GetBlocksToMaturity() > 0)
- return 0;
-
- int64_t credit = 0;
- if (filter & ISMINE_SPENDABLE)
- {
- // GetBalance can assume transactions in mapWallet won't change
- if (fCreditCached)
- credit += nCreditCached;
- else
- {
- nCreditCached = pwallet->GetCredit(*this, ISMINE_SPENDABLE);
- fCreditCached = true;
- credit += nCreditCached;
- }
- }
- if (filter & ISMINE_WATCH_ONLY)
- {
- if (fWatchCreditCached)
- credit += nWatchCreditCached;
- else
- {
- nWatchCreditCached = pwallet->GetCredit(*this, ISMINE_WATCH_ONLY);
- fWatchCreditCached = true;
- credit += nWatchCreditCached;
- }
- }
- return credit;
- }
-
- CAmount GetImmatureCredit(bool fUseCache=true) const
- {
- if (IsCoinBase() && GetBlocksToMaturity() > 0 && IsInMainChain())
- {
- if (fUseCache && fImmatureCreditCached)
- return nImmatureCreditCached;
- nImmatureCreditCached = pwallet->GetCredit(*this, ISMINE_SPENDABLE);
- fImmatureCreditCached = true;
- return nImmatureCreditCached;
- }
-
- return 0;
- }
-
- CAmount GetAvailableCredit(bool fUseCache=true) const
- {
- if (pwallet == 0)
- return 0;
-
- // Must wait until coinbase is safely deep enough in the chain before valuing it
- if (IsCoinBase() && GetBlocksToMaturity() > 0)
- return 0;
-
- if (fUseCache && fAvailableCreditCached)
- return nAvailableCreditCached;
-
- CAmount nCredit = 0;
- uint256 hashTx = GetHash();
- for (unsigned int i = 0; i < vout.size(); i++)
- {
- if (!pwallet->IsSpent(hashTx, i))
- {
- const CTxOut &txout = vout[i];
- nCredit += pwallet->GetCredit(txout, ISMINE_SPENDABLE);
- if (!MoneyRange(nCredit))
- throw std::runtime_error("CWalletTx::GetAvailableCredit() : value out of range");
- }
- }
-
- nAvailableCreditCached = nCredit;
- fAvailableCreditCached = true;
- return nCredit;
- }
-
- CAmount GetImmatureWatchOnlyCredit(const bool& fUseCache=true) const
- {
- if (IsCoinBase() && GetBlocksToMaturity() > 0 && IsInMainChain())
- {
- if (fUseCache && fImmatureWatchCreditCached)
- return nImmatureWatchCreditCached;
- nImmatureWatchCreditCached = pwallet->GetCredit(*this, ISMINE_WATCH_ONLY);
- fImmatureWatchCreditCached = true;
- return nImmatureWatchCreditCached;
- }
-
- return 0;
- }
-
- CAmount GetAvailableWatchOnlyCredit(const bool& fUseCache=true) const
- {
- if (pwallet == 0)
- return 0;
-
- // Must wait until coinbase is safely deep enough in the chain before valuing it
- if (IsCoinBase() && GetBlocksToMaturity() > 0)
- return 0;
-
- if (fUseCache && fAvailableWatchCreditCached)
- return nAvailableWatchCreditCached;
-
- CAmount nCredit = 0;
- for (unsigned int i = 0; i < vout.size(); i++)
- {
- if (!pwallet->IsSpent(GetHash(), i))
- {
- const CTxOut &txout = vout[i];
- nCredit += pwallet->GetCredit(txout, ISMINE_WATCH_ONLY);
- if (!MoneyRange(nCredit))
- throw std::runtime_error("CWalletTx::GetAvailableCredit() : value out of range");
- }
- }
-
- nAvailableWatchCreditCached = nCredit;
- fAvailableWatchCreditCached = true;
- return nCredit;
- }
-
- CAmount GetChange() const
- {
- if (fChangeCached)
- return nChangeCached;
- nChangeCached = pwallet->GetChange(*this);
- fChangeCached = true;
- return nChangeCached;
- }
-
- void GetAmounts(std::list<COutputEntry>& listReceived,
- std::list<COutputEntry>& listSent, CAmount& nFee, std::string& strSentAccount, const isminefilter& filter) const;
-
- void GetAccountAmounts(const std::string& strAccount, CAmount& nReceived,
- CAmount& nSent, CAmount& nFee, const isminefilter& filter) const;
-
- bool IsFromMe(const isminefilter& filter) const
- {
- return (GetDebit(filter) > 0);
- }
-
- bool IsTrusted() const
- {
- // Quick answer in most cases
- if (!IsFinalTx(*this))
- return false;
- int nDepth = GetDepthInMainChain();
- if (nDepth >= 1)
- return true;
- if (nDepth < 0)
- return false;
- if (!bSpendZeroConfChange || !IsFromMe(ISMINE_ALL)) // using wtx's cached debit
- return false;
-
- // Trusted if all inputs are from us and are in the mempool:
- BOOST_FOREACH(const CTxIn& txin, vin)
- {
- // Transactions not sent by us: not trusted
- const CWalletTx* parent = pwallet->GetWalletTx(txin.prevout.hash);
- if (parent == NULL)
- return false;
- const CTxOut& parentOut = parent->vout[txin.prevout.n];
- if (pwallet->IsMine(parentOut) != ISMINE_SPENDABLE)
- return false;
- }
- return true;
- }
-
- bool WriteToDisk();
-
- int64_t GetTxTime() const;
- int GetRequestCount() const;
-
- void RelayWalletTransaction();
-
- std::set<uint256> GetConflicts() const;
-};
-
-
-
-
-class COutput
-{
-public:
- const CWalletTx *tx;
- int i;
- int nDepth;
- bool fSpendable;
-
- COutput(const CWalletTx *txIn, int iIn, int nDepthIn, bool fSpendableIn)
- {
- tx = txIn; i = iIn; nDepth = nDepthIn; fSpendable = fSpendableIn;
- }
-
- std::string ToString() const;
-};
-
-
-
-
-/** Private key that includes an expiration date in case it never gets used. */
-class CWalletKey
-{
-public:
- CPrivKey vchPrivKey;
- int64_t nTimeCreated;
- int64_t nTimeExpires;
- std::string strComment;
- //! todo: add something to note what created it (user, getnewaddress, change)
- //! maybe should have a map<string, string> property map
-
- CWalletKey(int64_t nExpires=0);
-
- ADD_SERIALIZE_METHODS;
-
- template <typename Stream, typename Operation>
- inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
- if (!(nType & SER_GETHASH))
- READWRITE(nVersion);
- READWRITE(vchPrivKey);
- READWRITE(nTimeCreated);
- READWRITE(nTimeExpires);
- READWRITE(LIMITED_STRING(strComment, 65536));
- }
-};
-
-
-
-
-
-
/**
* Account information.
* Stored in wallet with key "acc"+string account name.
diff --git a/src/walletdb.cpp b/src/walletdb.cpp
index 4fd7eb512b..b2daf036ff 100644
--- a/src/walletdb.cpp
+++ b/src/walletdb.cpp
@@ -18,7 +18,6 @@
#include <boost/scoped_ptr.hpp>
#include <boost/thread.hpp>
-using namespace boost;
using namespace std;
static uint64_t nAccountingEntryNumber = 0;
@@ -211,7 +210,7 @@ void CWalletDB::ListAccountCreditDebit(const string& strAccount, list<CAccountin
Dbc* pcursor = GetCursor();
if (!pcursor)
- throw runtime_error("CWalletDB::ListAccountCreditDebit() : cannot create DB cursor");
+ throw runtime_error("CWalletDB::ListAccountCreditDebit(): cannot create DB cursor");
unsigned int fFlags = DB_SET_RANGE;
while (true)
{
@@ -227,7 +226,7 @@ void CWalletDB::ListAccountCreditDebit(const string& strAccount, list<CAccountin
else if (ret != 0)
{
pcursor->close();
- throw runtime_error("CWalletDB::ListAccountCreditDebit() : error scanning DB");
+ throw runtime_error("CWalletDB::ListAccountCreditDebit(): error scanning DB");
}
// Unserialize
@@ -396,7 +395,7 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
if (wtx.nOrderPos == -1)
wss.fAnyUnordered = true;
- pwallet->AddToWallet(wtx, true);
+ pwallet->AddToWallet(wtx, true, NULL);
}
else if (strType == "acentry")
{
@@ -439,7 +438,7 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
}
CKey key;
CPrivKey pkey;
- uint256 hash = 0;
+ uint256 hash;
if (strType == "key")
{
@@ -464,7 +463,7 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
bool fSkipCheck = false;
- if (hash != 0)
+ if (!hash.IsNull())
{
// hash pubkey/privkey to accelerate wallet load
std::vector<unsigned char> vchKey;
@@ -865,20 +864,20 @@ bool BackupWallet(const CWallet& wallet, const string& strDest)
bitdb.mapFileUseCount.erase(wallet.strWalletFile);
// Copy wallet.dat
- filesystem::path pathSrc = GetDataDir() / wallet.strWalletFile;
- filesystem::path pathDest(strDest);
- if (filesystem::is_directory(pathDest))
+ boost::filesystem::path pathSrc = GetDataDir() / wallet.strWalletFile;
+ boost::filesystem::path pathDest(strDest);
+ if (boost::filesystem::is_directory(pathDest))
pathDest /= wallet.strWalletFile;
try {
#if BOOST_VERSION >= 104000
- filesystem::copy_file(pathSrc, pathDest, filesystem::copy_option::overwrite_if_exists);
+ boost::filesystem::copy_file(pathSrc, pathDest, boost::filesystem::copy_option::overwrite_if_exists);
#else
- filesystem::copy_file(pathSrc, pathDest);
+ boost::filesystem::copy_file(pathSrc, pathDest);
#endif
LogPrintf("copied wallet.dat to %s\n", pathDest.string());
return true;
- } catch (const filesystem::filesystem_error& e) {
+ } catch (const boost::filesystem::filesystem_error& e) {
LogPrintf("error copying wallet.dat to %s - %s\n", pathDest.string(), e.what());
return false;
}
diff --git a/src/walletdb.h b/src/walletdb.h
index 45c00328a4..2627ef71a6 100644
--- a/src/walletdb.h
+++ b/src/walletdb.h
@@ -76,7 +76,7 @@ public:
class CWalletDB : public CDB
{
public:
- CWalletDB(const std::string& strFilename, const char* pszMode = "r+") : CDB(strFilename, pszMode)
+ CWalletDB(const std::string& strFilename, const char* pszMode = "r+", bool fFlushOnClose = true) : CDB(strFilename, pszMode, fFlushOnClose)
{
}