diff --git a/.gitignore b/.gitignore index 93a5b03..e409cb1 100644 --- a/.gitignore +++ b/.gitignore @@ -174,3 +174,5 @@ src/ohmcoin-tx src/ohmcoind doc/Doxyfile doc/Doxyfile +src/test/test_ohmcoin +src/qt/test/test_ohmcoin-qt diff --git a/build-aux/m4/bitcoin_qt.m4 b/build-aux/m4/bitcoin_qt.m4 index 25e1cb5..acf64cc 100755 --- a/build-aux/m4/bitcoin_qt.m4 +++ b/build-aux/m4/bitcoin_qt.m4 @@ -410,8 +410,19 @@ dnl Outputs: All necessary QT_* variables are set. dnl Outputs: have_qt_test and have_qt_dbus are set (if applicable) to yes|no. AC_DEFUN([_BITCOIN_QT_FIND_LIBS_WITH_PKGCONFIG],[ m4_ifdef([PKG_CHECK_MODULES],[ - QT_LIB_PREFIX=Qt5 - qt5_modules="Qt5Core Qt5Gui Qt5Network Qt5Widgets Qt5Svg" + auto_priority_version=$1 + if test "x$auto_priority_version" = x; then + auto_priority_version=qt5 + fi + if test "x$bitcoin_qt_want_version" = xqt5 || ( test "x$bitcoin_qt_want_version" = xauto && test "x$auto_priority_version" = xqt5 ); then + QT_LIB_PREFIX=Qt5 + bitcoin_qt_got_major_vers=5 + else + QT_LIB_PREFIX=Qt + bitcoin_qt_got_major_vers=4 + fi + qt5_modules="Qt5Core Qt5Gui Qt5Network Qt5Widgets Qt5Concurrent" + qt4_modules="QtCore QtGui QtNetwork" BITCOIN_QT_CHECK([ PKG_CHECK_MODULES([QT5], [$qt5_modules], [QT_INCLUDES="$QT5_CFLAGS"; QT_LIBS="$QT5_LIBS" have_qt=yes],[have_qt=no]) if test "x$have_qt" != xyes; then diff --git a/compileroutput.txt b/compileroutput.txt new file mode 100644 index 0000000..d2685c4 --- /dev/null +++ b/compileroutput.txt @@ -0,0 +1,6277 @@ +Making all in src + CXX phored-phored.o + CXX libbitcoin_server_a-addrman.o + CXX libbitcoin_server_a-alert.o + CXX libbitcoin_server_a-bloom.o + CXX libbitcoin_server_a-chain.o +In file included from addrman.cpp:5: +In file included from ./addrman.h:11: +In file included from ./sync.h:12: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/condition_variable.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/condition_variable.hpp:12: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/thread_data.hpp:12: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./addrman.h:485:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:125:1: note: expanded from here +criticalblock2 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ + CXX libbitcoin_server_a-checkpoints.o +1 warning generated. + CXX libbitcoin_server_a-httprpc.o +In file included from chain.cpp:6: +In file included from ./chain.h:10: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:121:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +1 warning generated. + CXX libbitcoin_server_a-httpserver.o +In file included from alert.cpp:6: +In file included from ./alert.h:10: +In file included from ./sync.h:12: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/condition_variable.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/condition_variable.hpp:12: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/thread_data.hpp:12: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:121:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +In file included from phored.cpp:11: +In file included from ./main.h:17: +In file included from ./chain.h:10: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:121:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +In file included from checkpoints.cpp:10: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:121:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +In file included from httprpc.cpp:3: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:121:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +1 warning generated. + CXX libbitcoin_server_a-init.o +1 warning generated. + CXX libbitcoin_server_a-leveldbwrapper.o + CXX libbitcoin_server_a-main.o +1 warning generated. + CXX libbitcoin_server_a-merkleblock.o +1 warning generated. + CXX libbitcoin_server_a-miner.o +init.cpp:341:16: warning: unused variable 'showDebug' [-Wunused-variable] + const bool showDebug = GetBoolArg("-help-debug", false); + ^ + CXX libbitcoin_server_a-net.o +In file included from merkleblock.cpp:7: +In file included from ./merkleblock.h:10: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:121:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +In file included from init.cpp:15: +In file included from ./accumulators.h:8: +In file included from ./libzerocoin/Accumulator.h:16: +In file included from ./libzerocoin/Coin.h:21: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:121:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +1 warning generated. + CXX libbitcoin_server_a-noui.o +main.cpp:4275:1: warning: control may reach end of non-void function [-Wreturn-type] +} +^ +main.cpp:6103:17: warning: acquiring mutex 'cs_main' that is already held [-Wthread-safety-analysis] + LOCK(cs_main); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:93:1: note: expanded from here +criticalblock73 +^ +main.cpp:6403:17: warning: acquiring mutex 'cs_main' that is already held [-Wthread-safety-analysis] + LOCK(cs_main); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:188:1: note: expanded from here +criticalblock80 +^ +In file included from miner.cpp:10: +In file included from ./miner.h:9: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:121:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +In file included from main.cpp:10: +In file included from ./main.h:17: +In file included from ./chain.h:10: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:121:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +In file included from net.cpp:15: +In file included from ./net.h:19: +In file included from ./sync.h:12: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/condition_variable.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/condition_variable.hpp:12: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/thread_data.hpp:12: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./net.h:458:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_inventory); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:143:1: note: expanded from here +criticalblock0 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ + CXX libbitcoin_server_a-pow.o +In file included from pow.cpp:11: +In file included from ./chain.h:10: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:121:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +1 warning generated. + CXX libbitcoin_server_a-rest.o +1 warning generated. + CXX libbitcoin_server_a-rpcblockchain.o +In file included from rest.cpp:6: +In file included from ./chain.h:10: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:121:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +In file included from rpcblockchain.cpp:8: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:121:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +1 warning generated. + CXX libbitcoin_server_a-rpcmasternode.o +1 warning generated. + CXX libbitcoin_server_a-rpcmasternode-budget.o +2 warnings generated. + CXX libbitcoin_server_a-rpcmining.o +In file included from rpcmasternode-budget.cpp:4: +In file included from ./activemasternode.h:10: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:121:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +1 warning generated. + CXX libbitcoin_server_a-rpcmisc.o +In file included from rpcmasternode.cpp:6: +In file included from ./activemasternode.h:10: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:121:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +In file included from rpcmining.cpp:9: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:121:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +In file included from rpcmisc.cpp:8: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:121:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +1 warning generated. + CXX libbitcoin_server_a-rpcnet.o +1 warning generated. + CXX libbitcoin_server_a-rpcrawtransaction.o +In file included from rpcnet.cpp:10: +In file included from ./main.h:17: +In file included from ./chain.h:10: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:71:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +1 warning generated. + CXX libbitcoin_server_a-rpcserver.o +1 warning generated. + CXX script/libbitcoin_server_a-sigcache.o +In file included from rpcrawtransaction.cpp:9: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:121:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +1 warning generated. + CXX libbitcoin_server_a-sporkdb.o + CXX libbitcoin_server_a-timedata.o +In file included from rpcserver.cpp:11: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:71:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +rpcserver.cpp:114:23: warning: unused function 'roundint64' [-Wunused-function] +static inline int64_t roundint64(double d) + ^ +In file included from timedata.cpp:8: +In file included from ./sync.h:12: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/condition_variable.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/condition_variable.hpp:12: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/thread_data.hpp:12: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +timedata.cpp:29:5: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_nTimeOffset); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:55:1: note: expanded from here +criticalblock0 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +In file included from sporkdb.cpp:5: +In file included from ./sporkdb.h:10: +In file included from ./spork.h:9: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:15:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +1 warning generated. + CXX libbitcoin_server_a-torcontrol.o +1 warning generated. +1 warning generated. + CXX libbitcoin_server_a-txdb.o + CXX libbitcoin_server_a-txmempool.o +In file included from torcontrol.cpp:6: +In file included from ./torcontrol.h:15: +In file included from /usr/local/opt/boost@1.57/include/boost/thread.hpp:13: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/thread.hpp:12: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/thread_only.hpp:17: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/thread_data.hpp:12: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./net.h:458:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_inventory); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:134:1: note: expanded from here +criticalblock0 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +In file included from txdb.cpp:8: +In file included from ./txdb.h:12: +In file included from ./main.h:17: +In file included from ./chain.h:10: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:121:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +In file included from txmempool.cpp:8: +In file included from ./txmempool.h:16: +In file included from ./sync.h:12: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/condition_variable.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/condition_variable.hpp:12: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/thread_data.hpp:12: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./txmempool.h:151:9: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:8:1: note: expanded from here +criticalblock0 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +2 warnings generated. + CXX libbitcoin_server_a-ui_interface.o +4 warnings generated. + CXX libbitcoin_server_a-validationinterface.o +1 warning generated. + CXX libbitcoin_common_a-accumulators.o +1 warning generated. + CXX libbitcoin_common_a-accumulatorcheckpoints.o +1 warning generated. + CXX libbitcoin_common_a-accumulatormap.o + CXX libbitcoin_common_a-allocators.o + CXX libbitcoin_common_a-amount.o + CXX libbitcoin_common_a-base58.o + CXX libbitcoin_common_a-bech32.o +In file included from accumulators.cpp:5: +In file included from ./accumulators.h:8: +In file included from ./libzerocoin/Accumulator.h:16: +In file included from ./libzerocoin/Coin.h:21: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:121:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +In file included from accumulatormap.cpp:5: +In file included from ./accumulatormap.h:8: +In file included from ./libzerocoin/Accumulator.h:16: +In file included from ./libzerocoin/Coin.h:21: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:121:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ + CXX wallet/libbitcoin_common_a-bip39.o +1 warning generated. + CXX libbitcoin_common_a-bip38.o +In file included from base58.cpp:6: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:121:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ + CXX libbitcoin_common_a-chainparams.o +1 warning generated. + CXX libbitcoin_common_a-coins.o + CXX libbitcoin_common_a-compressor.o +In file included from bip38.cpp:6: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:121:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +1 warning generated. + CXX consensus/libbitcoin_common_a-merkle.o +In file included from chainparams.cpp:10: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:121:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ + CXX primitives/libbitcoin_common_a-block.o +1 warning generated. + CXX primitives/libbitcoin_common_a-deterministicmint.o + CXX primitives/libbitcoin_common_a-transaction.o +In file included from consensus/merkle.cpp:5: +In file included from consensus/merkle.h:12: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:121:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ + CXX primitives/libbitcoin_common_a-zerocoin.o +1 warning generated. + CXX libbitcoin_common_a-core_read.o +In file included from primitives/block.cpp:8: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:121:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +1 warning generated. + CXX libbitcoin_common_a-core_write.o +In file included from primitives/transaction.cpp:7: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:121:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +1 warning generated. + CXX libbitcoin_common_a-eccryptoverify.o + CXX libbitcoin_common_a-ecwrapper.o + CXX libbitcoin_common_a-hash.o + CXX libbitcoin_common_a-key.o +In file included from core_write.cpp:7: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:121:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +In file included from core_read.cpp:8: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:121:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ + CXX libbitcoin_common_a-keystore.o +1 warning generated. + CXX libbitcoin_common_a-netbase.o + CXX libbitcoin_common_a-protocol.o +1 warning generated. + CXX libbitcoin_common_a-pubkey.o +In file included from keystore.cpp:6: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:121:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ + CXX libbitcoin_common_a-scheduler.o +1 warning generated. + CXX script/libbitcoin_common_a-interpreter.o +In file included from netbase.cpp:13: +In file included from ./sync.h:12: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/condition_variable.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/condition_variable.hpp:12: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/thread_data.hpp:12: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +netbase.cpp:484:5: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_proxyInfos); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:94:1: note: expanded from here +criticalblock0 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +In file included from protocol.cpp:8: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:121:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +1 warning generated. +1 warning generated. + CXX script/libbitcoin_common_a-script.o + CXX script/libbitcoin_common_a-sign.o + CXX script/libbitcoin_common_a-standard.o +1 warning generated. + CXX script/libbitcoin_common_a-script_error.o + CXX wallet/libbitcoin_common_a-hdchain.o + CXX libbitcoin_common_a-spork.o + CXX libbitcoin_common_a-sporkdb.o +In file included from script/sign.cpp:6: +In file included from ./script/sign.h:10: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:121:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +In file included from wallet/hdchain.cpp:4: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:121:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +In file included from script/standard.cpp:9: +In file included from ./main.h:17: +In file included from ./chain.h:10: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:115:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +1 warning generated. + CXX lib/libunivalue_la-univalue.lo +spork.cpp:282:58: warning: implicit conversion from 'long' to 'int' changes value from 4070908800 to -224058496 [-Wconstant-conversion] + if (strName == "SPORK_19_SEGWIT_ON_COINBASE") return SPORK_19_SEGWIT_ON_COINBASE_DEFAULT; + ~~~~~~ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +./spork.h:63:45: note: expanded from macro 'SPORK_19_SEGWIT_ON_COINBASE_DEFAULT' +#define SPORK_19_SEGWIT_ON_COINBASE_DEFAULT 4070908800 //OFF + ^~~~~~~~~~ +1 warning generated. + CXX libzerocoin/Accumulator.o +In file included from spork.cpp:6: +In file included from ./spork.h:9: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:121:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +In file included from sporkdb.cpp:5: +In file included from ./sporkdb.h:10: +In file included from ./spork.h:9: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:15:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ + CXX lib/libunivalue_la-univalue_read.lo +1 warning generated. + CXX lib/libunivalue_la-univalue_write.lo + CXX libzerocoin/AccumulatorProofOfKnowledge.o + CXX libzerocoin/Coin.o + CXXLD libunivalue.la +1 warning generated. + CXX libzerocoin/Denominations.o + CXX libzerocoin/CoinSpend.o + CXX libzerocoin/Commitment.o +2 warnings generated. + CXX libzerocoin/ParamGeneration.o + CXX libzerocoin/Params.o + CXX libzerocoin/SerialNumberSignatureOfKnowledge.o + CXX libbitcoin_util_a-allocators.o + CXX compat/libbitcoin_util_a-strnlen.o + CXX compat/libbitcoin_util_a-glibc_sanity.o + CXX compat/libbitcoin_util_a-glibcxx_sanity.o + CXX libbitcoin_util_a-chainparamsbase.o + CXX libbitcoin_util_a-random.o + CXX libbitcoin_util_a-rpcprotocol.o + CXX support/libbitcoin_util_a-cleanse.o + CXX libbitcoin_util_a-sync.o + CXX libbitcoin_util_a-uint256.o + CXX libbitcoin_util_a-util.o + CXX libbitcoin_util_a-utilstrencodings.o + CXX libbitcoin_util_a-utilmoneystr.o + CXX libbitcoin_util_a-utiltime.o + CXX libbitcoin_wallet_a-activemasternode.o + CXX libbitcoin_wallet_a-bip38.o + CXX libbitcoin_wallet_a-denomination_functions.o +In file included from util.cpp:14: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +util.cpp:596:5: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(csPathCached); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:352:1: note: expanded from here +criticalblock0 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +In file included from bip38.cpp:6: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:121:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ + CXX libbitcoin_wallet_a-obfuscation.o +1 warning generated. + CXX libbitcoin_wallet_a-obfuscation-relay.o +1 warning generated. + CXX libbitcoin_wallet_a-swifttx.o +In file included from activemasternode.cpp:6: +In file included from ./activemasternode.h:10: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:121:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ + CXX libbitcoin_wallet_a-masternode.o +In file included from obfuscation-relay.cpp:6: +In file included from ./obfuscation-relay.h:9: +In file included from ./activemasternode.h:10: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:121:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +In file included from obfuscation.cpp:6: +In file included from ./obfuscation.h:9: +In file included from ./main.h:17: +In file included from ./chain.h:10: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:121:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +In file included from swifttx.cpp:6: +In file included from ./swifttx.h:9: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:121:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +1 warning generated. + CXX libbitcoin_wallet_a-masternode-budget.o +In file included from masternode.cpp:6: +In file included from ./masternode.h:9: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:121:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +1 warning generated. + CXX libbitcoin_wallet_a-masternode-payments.o +In file included from masternode-budget.cpp:8: +In file included from ./main.h:17: +In file included from ./chain.h:10: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:121:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +1 warning generated. + CXX libbitcoin_wallet_a-masternode-sync.o +In file included from masternode-payments.cpp:6: +In file included from ./masternode-payments.h:9: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:121:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +1 warning generated. + CXX libbitcoin_wallet_a-masternodeconfig.o +1 warning generated. + CXX libbitcoin_wallet_a-masternodeman.o +In file included from masternode-sync.cpp:7: +In file included from ./main.h:17: +In file included from ./chain.h:10: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:121:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +In file included from masternodeconfig.cpp:7: +In file included from ./net.h:19: +In file included from ./sync.h:12: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/condition_variable.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/condition_variable.hpp:12: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/thread_data.hpp:12: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./net.h:458:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_inventory); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:143:1: note: expanded from here +criticalblock0 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +1 warning generated. + CXX libbitcoin_wallet_a-mintpool.o +1 warning generated. + CXX wallet/libbitcoin_wallet_a-rpcdump.o +In file included from masternodeman.cpp:6: +In file included from ./masternodeman.h:9: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:121:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +1 warning generated. + CXX primitives/libbitcoin_wallet_a-deterministicmint.o + CXX primitives/libbitcoin_wallet_a-zerocoin.o + CXX libbitcoin_wallet_a-kernel.o + CXX libbitcoin_wallet_a-wallet_ismine.o +1 warning generated. + CXX libbitcoin_wallet_a-stakeinput.o +In file included from wallet/rpcdump.cpp:9: +In file included from ./main.h:17: +In file included from ./chain.h:10: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:121:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +In file included from wallet_ismine.cpp:8: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:121:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +kernel.cpp:425:18: warning: unused variable 'txin' [-Wunused-variable] + const CTxIn& txin = tx.vin[0]; + ^ +In file included from kernel.cpp:12: +In file included from ./kernel.h:8: +In file included from ./main.h:17: +In file included from ./chain.h:10: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:91:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +1 warning generated. + CXX libbitcoin_wallet_a-zphrwallet.o +In file included from stakeinput.cpp:5: +In file included from ./chain.h:10: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:121:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +1 warning generated. + CXX libbitcoin_wallet_a-zphrtracker.o +In file included from zphrwallet.cpp:5: +In file included from ./zphrwallet.h:9: +In file included from ./libzerocoin/Coin.h:21: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:121:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +2 warnings generated. + CXX wallet/libbitcoin_wallet_a-crypter.o +1 warning generated. + CXX wallet/libbitcoin_wallet_a-db.o +In file included from zphrtracker.cpp:6: +In file included from ./zphrtracker.h:8: +In file included from ./primitives/zerocoin.h:12: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:15:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +In file included from wallet/db.cpp:6: +In file included from ./wallet/db.h:12: +In file included from ./sync.h:12: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/condition_variable.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/condition_variable.hpp:12: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/thread_data.hpp:12: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./addrman.h:485:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:160:1: note: expanded from here +criticalblock2 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +wallet/crypter.cpp:183:10: warning: extra tokens at end of #else directive [-Wextra-tokens] +#else EVP_CIPHER_CTX_init(&ctx); + ^ + // +1 warning generated. + CXX wallet/libbitcoin_wallet_a-rpcwallet.o +In file included from wallet/crypter.cpp:5: +In file included from ./wallet/crypter.h:8: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:121:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +1 warning generated. + CXX wallet/libbitcoin_wallet_a-wallet.o +1 warning generated. + CXX wallet/libbitcoin_wallet_a-walletdb.o +1 warning generated. + CXX zmq/libbitcoin_zmq_a-zmqabstractnotifier.o +In file included from zmq/zmqabstractnotifier.cpp:5: +In file included from zmq/zmqabstractnotifier.h:8: +In file included from zmq/zmqconfig.h:19: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:121:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +1 warning generated. + CXX zmq/libbitcoin_zmq_a-zmqnotificationinterface.o +wallet/rpcwallet.cpp:2173:27: warning: comparison of integers of different signs: 'int' and 'size_t' (aka 'unsigned long') [-Wsign-compare] + for (int i = 0; i < hdChainCurrent.CountAccounts(); ++i) + ~ ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +In file included from wallet/rpcwallet.cpp:11: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:121:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +2 warnings generated. + CXX zmq/libbitcoin_zmq_a-zmqpublishnotifier.o +In file included from wallet/walletdb.cpp:8: +In file included from ./wallet/walletdb.h:13: +In file included from ./wallet/db.h:12: +In file included from ./sync.h:12: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/condition_variable.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/condition_variable.hpp:12: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/thread_data.hpp:12: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:15:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +In file included from wallet/wallet.cpp:9: +In file included from ./wallet/wallet.h:12: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:121:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +In file included from zmq/zmqnotificationinterface.cpp:6: +In file included from zmq/zmqpublishnotifier.h:8: +In file included from zmq/zmqabstractnotifier.h:8: +In file included from zmq/zmqconfig.h:19: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:12:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +In file included from zmq/zmqpublishnotifier.cpp:5: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:121:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +1 warning generated. + CXX crypto/libbitcoin_crypto_a-sha1.o + CXX crypto/libbitcoin_crypto_a-sha256.o + CXX crypto/libbitcoin_crypto_a-sha512.o + CXX crypto/libbitcoin_crypto_a-hmac_sha256.o +wallet/wallet.cpp:60:16: warning: unused variable 'BIP32_HARDENED_KEY_LIMIT' [-Wunused-const-variable] +const uint32_t BIP32_HARDENED_KEY_LIMIT = 0x80000000; + ^ + CXX crypto/libbitcoin_crypto_a-pkcs5_pbkdf2.o +1 warning generated. + CXX crypto/libbitcoin_crypto_a-rfc6979_hmac_sha256.o + CXX crypto/libbitcoin_crypto_a-hmac_sha512.o + CXX crypto/libbitcoin_crypto_a-scrypt.o + CXX crypto/libbitcoin_crypto_a-ripemd160.o + CC crypto/libbitcoin_crypto_a-aes_helper.o + CC crypto/libbitcoin_crypto_a-blake.o + CC crypto/libbitcoin_crypto_a-bmw.o + CC crypto/libbitcoin_crypto_a-groestl.o + CC crypto/libbitcoin_crypto_a-jh.o + CC crypto/libbitcoin_crypto_a-keccak.o + CC crypto/libbitcoin_crypto_a-skein.o +Building LevelDB ... + CC libsecp256k1_la-secp256k1.lo +g++ -std=c++11 -I. -I./include -std=c++0x -DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -DLEVELDB_ATOMIC_PRESENT -Wstack-protector -fstack-protector-all -fPIC -g -O2 -Wall -Wextra -Wformat -Wvla -Wformat-security -Wthread-safety-analysis -Wno-unused-parameter -Wno-self-assign -Wno-unused-local-typedef -Wno-deprecated-register -Wno-implicit-fallthrough -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -I/usr/local/opt/boost@1.57/include -I/usr/local/opt/qt/include -I/usr/local/opt/openssl/include -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS -isystem /opt/local/include -I/opt/local/include/db48 -I/usr/local/opt/berkeley-db@4/include -DMAC_OSX -DHAVE_QT5 -D__STDC_LIMIT_MACROS -c helpers/memenv/memenv.cc -o helpers/memenv/memenv.o +In file included from helpers/memenv/memenv.cc:9: +In file included from ./port/port.h:14: +In file included from ./port/port_posix.h:47: +./port/atomic_pointer.h:55:3: warning: 'OSMemoryBarrier' is deprecated: first deprecated in macOS 10.12 - Use std::atomic_thread_fence() from instead [-Wdeprecated-declarations] + OSMemoryBarrier(); + ^ +/usr/include/libkern/OSAtomicDeprecated.h:749:9: note: 'OSMemoryBarrier' has been explicitly marked deprecated here +void OSMemoryBarrier( void ); + ^ +1 warning generated. +rm -f libmemenv.a +/usr/bin/ar -rs libmemenv.a helpers/memenv/memenv.o +ar: creating archive libmemenv.a + CXX phore_cli-phore-cli.o + CCLD libsecp256k1.la + CXX libbitcoin_cli_a-rpcclient.o + CXX phore_tx-phore-tx.o +2 warnings generated. + GEN qt/paymentrequest.pb.h +[libprotobuf WARNING google/protobuf/compiler/parser.cc:546] No syntax specified for the proto file: paymentrequest.proto. Please use 'syntax = "proto2";' or 'syntax = "proto3";' to specify a syntax version. (Defaulted to proto2 syntax.) + GEN qt/forms/ui_addressbookpage.h + GEN qt/forms/ui_configuremasternodepage.h + GEN qt/forms/ui_askpassphrasedialog.h + GEN qt/forms/ui_startoptionsdialog.h + GEN qt/forms/ui_startoptions.h + GEN qt/forms/ui_startoptionsrestore.h + GEN qt/forms/ui_startoptionssort.h + GEN qt/forms/ui_startoptionsrevealed.h + GEN qt/forms/ui_startoptionsmain.h +qt/forms/startoptionsmain.ui: Warning: The name 'horizontalLayout' (QHBoxLayout) is already in use, defaulting to 'horizontalLayout1'. + GEN qt/forms/ui_bip38tooldialog.h + GEN qt/forms/ui_coincontroldialog.h + GEN qt/forms/ui_blockexplorer.h + GEN qt/forms/ui_obfuscationconfig.h + GEN qt/forms/ui_editaddressdialog.h + GEN qt/forms/ui_helpmessagedialog.h + GEN qt/forms/ui_intro.h + GEN qt/forms/ui_masternodelist.h + GEN qt/forms/ui_multisenddialog.h + GEN qt/forms/ui_multisigdialog.h + GEN qt/forms/ui_openuridialog.h + GEN qt/forms/ui_optionsdialog.h + GEN qt/forms/ui_overviewpage.h + GEN qt/forms/ui_receivecoinsdialog.h + GEN qt/forms/ui_privacydialog.h + GEN qt/forms/ui_proposaldialog.h + GEN qt/forms/ui_receiverequestdialog.h + GEN qt/forms/ui_rpcconsole.h + GEN qt/forms/ui_sendcoinsdialog.h + GEN qt/forms/ui_sendcoinsentry.h + GEN qt/forms/ui_signverifymessagedialog.h + GEN qt/forms/ui_transactiondescdialog.h + GEN qt/moc_addressbookpage.cpp + GEN qt/forms/ui_zphrcontroldialog.h + GEN qt/moc_configuremasternodepage.cpp + GEN qt/moc_addresstablemodel.cpp + GEN qt/moc_askpassphrasedialog.cpp + GEN qt/moc_startoptionsdialog.cpp + GEN qt/moc_startoptions.cpp + GEN qt/moc_startoptionsrestore.cpp + GEN qt/moc_startoptionssort.cpp + GEN qt/moc_startoptionsrevealed.cpp + GEN qt/moc_startoptionsmain.cpp +1 warning generated. + GEN qt/moc_bantablemodel.cpp + GEN qt/moc_bip38tooldialog.cpp +In file included from phore-tx.cpp:6: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:121:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ + GEN qt/moc_bitcoinaddressvalidator.cpp + GEN qt/moc_bitcoinamountfield.cpp + GEN qt/moc_bitcoingui.cpp + GEN qt/moc_bitcoinunits.cpp + GEN qt/moc_blockexplorer.cpp + GEN qt/moc_clientmodel.cpp + GEN qt/moc_coincontroldialog.cpp + GEN qt/moc_coincontroltreewidget.cpp + GEN qt/moc_csvmodelwriter.cpp + GEN qt/moc_obfuscationconfig.cpp + GEN qt/moc_editaddressdialog.cpp + GEN qt/moc_guiutil.cpp + GEN qt/moc_intro.cpp + GEN qt/moc_macdockiconhandler.cpp + GEN qt/moc_macnotificationhandler.cpp + GEN qt/moc_masternodelist.cpp + GEN qt/moc_multisenddialog.cpp + GEN qt/moc_multisigdialog.cpp + GEN qt/moc_notificator.cpp + GEN qt/moc_openuridialog.cpp + GEN qt/moc_optionsdialog.cpp + GEN qt/moc_optionsmodel.cpp + GEN qt/moc_overviewpage.cpp + GEN qt/moc_peertablemodel.cpp + GEN qt/moc_paymentserver.cpp + GEN qt/moc_columnalignedlayout.cpp + GEN qt/moc_proposaldialog.cpp + GEN qt/moc_proposalfilterproxy.cpp + GEN qt/moc_proposaltablemodel.cpp + GEN qt/moc_proposallist.cpp + GEN qt/moc_qvalidatedlineedit.cpp + GEN qt/moc_qvaluecombobox.cpp + GEN qt/moc_receivecoinsdialog.cpp + GEN qt/moc_privacydialog.cpp + GEN qt/moc_receiverequestdialog.cpp + GEN qt/moc_recentrequeststablemodel.cpp + GEN qt/moc_rpcconsole.cpp + GEN qt/moc_sendcoinsdialog.cpp + GEN qt/moc_sendcoinsentry.cpp + GEN qt/moc_signverifymessagedialog.cpp + GEN qt/moc_splashscreen.cpp + GEN qt/moc_trafficgraphwidget.cpp + GEN qt/moc_transactiondesc.cpp + GEN qt/moc_transactiondescdialog.cpp + GEN qt/moc_transactionfilterproxy.cpp + GEN qt/moc_transactiontablemodel.cpp + GEN qt/moc_transactionview.cpp + GEN qt/moc_utilitydialog.cpp + GEN qt/moc_walletframe.cpp + GEN qt/moc_walletmodel.cpp + GEN qt/moc_walletview.cpp + GEN qt/moc_zphrcontroldialog.cpp + GEN qt/qrc_phore.cpp + GEN qt/locale/phore_bg.qm + GEN qt/locale/phore_ca.qm + GEN qt/locale/phore_cs.qm + GEN qt/locale/phore_da.qm + GEN qt/locale/phore_de.qm + GEN qt/locale/phore_en.qm + GEN qt/locale/phore_en_US.qm +Warning: dropping duplicate messages in 'qt/locale/phore_en.qm' +(try -verbose for more info). + GEN qt/locale/phore_es.qm + GEN qt/locale/phore_fi.qm + GEN qt/locale/phore_fr_FR.qm + GEN qt/locale/phore_hr.qm + GEN qt/locale/phore_it.qm + GEN qt/locale/phore_ja.qm + GEN qt/locale/phore_ko_KR.qm + GEN qt/locale/phore_nl.qm + GEN qt/locale/phore_pl.qm +Warning: dropping duplicate messages in 'qt/locale/phore_nl.qm' +(try -verbose for more info). + GEN qt/locale/phore_pt.qm + GEN qt/locale/phore_pt_BR.qm + GEN qt/locale/phore_ro_RO.qm + GEN qt/locale/phore_ru.qm + GEN qt/locale/phore_sk.qm + GEN qt/locale/phore_sv.qm + GEN qt/locale/phore_tr.qm + GEN qt/locale/phore_uk.qm + GEN qt/locale/phore_zh_CN.qm + GEN qt/locale/phore_zh_TW.qm + AR libbitcoin_server.a + AR libbitcoin_common.a + AR libzerocoin/libbitcoin_zerocoin.a + CXX libbitcoin_util_a-clientversion.o + AR libbitcoin_zmq.a + AR crypto/libbitcoin_crypto.a +/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ranlib: file: crypto/libbitcoin_crypto.a(libbitcoin_crypto_a-aes_helper.o) has no symbols +/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ranlib: file: crypto/libbitcoin_crypto.a(libbitcoin_crypto_a-aes_helper.o) has no symbols +Building LevelDB ... + AR libbitcoin_cli.a +g++ -std=c++11 -I. -I./include -std=c++0x -DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -DLEVELDB_ATOMIC_PRESENT -Wstack-protector -fstack-protector-all -fPIC -g -O2 -Wall -Wextra -Wformat -Wvla -Wformat-security -Wthread-safety-analysis -Wno-unused-parameter -Wno-self-assign -Wno-unused-local-typedef -Wno-deprecated-register -Wno-implicit-fallthrough -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -I/usr/local/opt/boost@1.57/include -I/usr/local/opt/qt/include -I/usr/local/opt/openssl/include -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS -isystem /opt/local/include -I/opt/local/include/db48 -I/usr/local/opt/berkeley-db@4/include -DMAC_OSX -DHAVE_QT5 -D__STDC_LIMIT_MACROS -c db/builder.cc -o db/builder.o +g++ -std=c++11 -I. -I./include -std=c++0x -DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -DLEVELDB_ATOMIC_PRESENT -Wstack-protector -fstack-protector-all -fPIC -g -O2 -Wall -Wextra -Wformat -Wvla -Wformat-security -Wthread-safety-analysis -Wno-unused-parameter -Wno-self-assign -Wno-unused-local-typedef -Wno-deprecated-register -Wno-implicit-fallthrough -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -I/usr/local/opt/boost@1.57/include -I/usr/local/opt/qt/include -I/usr/local/opt/openssl/include -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS -isystem /opt/local/include -I/opt/local/include/db48 -I/usr/local/opt/berkeley-db@4/include -DMAC_OSX -DHAVE_QT5 -D__STDC_LIMIT_MACROS -c db/c.cc -o db/c.o +In file included from db/builder.cc:7: +In file included from ./db/filename.h:14: +In file included from ./port/port.h:14: +In file included from ./port/port_posix.h:47: +./port/atomic_pointer.h:55:3: warning: 'OSMemoryBarrier' is deprecated: first deprecated in macOS 10.12 - Use std::atomic_thread_fence() from instead [-Wdeprecated-declarations] + OSMemoryBarrier(); + ^ +/usr/include/libkern/OSAtomicDeprecated.h:749:9: note: 'OSMemoryBarrier' has been explicitly marked deprecated here +void OSMemoryBarrier( void ); + ^ +1 warning generated. + GEN qt/phore.moc +g++ -std=c++11 -I. -I./include -std=c++0x -DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -DLEVELDB_ATOMIC_PRESENT -Wstack-protector -fstack-protector-all -fPIC -g -O2 -Wall -Wextra -Wformat -Wvla -Wformat-security -Wthread-safety-analysis -Wno-unused-parameter -Wno-self-assign -Wno-unused-local-typedef -Wno-deprecated-register -Wno-implicit-fallthrough -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -I/usr/local/opt/boost@1.57/include -I/usr/local/opt/qt/include -I/usr/local/opt/openssl/include -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS -isystem /opt/local/include -I/opt/local/include/db48 -I/usr/local/opt/berkeley-db@4/include -DMAC_OSX -DHAVE_QT5 -D__STDC_LIMIT_MACROS -c db/db_impl.cc -o db/db_impl.o +g++ -std=c++11 -I. -I./include -std=c++0x -DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -DLEVELDB_ATOMIC_PRESENT -Wstack-protector -fstack-protector-all -fPIC -g -O2 -Wall -Wextra -Wformat -Wvla -Wformat-security -Wthread-safety-analysis -Wno-unused-parameter -Wno-self-assign -Wno-unused-local-typedef -Wno-deprecated-register -Wno-implicit-fallthrough -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -I/usr/local/opt/boost@1.57/include -I/usr/local/opt/qt/include -I/usr/local/opt/openssl/include -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS -isystem /opt/local/include -I/opt/local/include/db48 -I/usr/local/opt/berkeley-db@4/include -DMAC_OSX -DHAVE_QT5 -D__STDC_LIMIT_MACROS -c db/db_iter.cc -o db/db_iter.o +g++ -std=c++11 -I. -I./include -std=c++0x -DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -DLEVELDB_ATOMIC_PRESENT -Wstack-protector -fstack-protector-all -fPIC -g -O2 -Wall -Wextra -Wformat -Wvla -Wformat-security -Wthread-safety-analysis -Wno-unused-parameter -Wno-self-assign -Wno-unused-local-typedef -Wno-deprecated-register -Wno-implicit-fallthrough -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -I/usr/local/opt/boost@1.57/include -I/usr/local/opt/qt/include -I/usr/local/opt/openssl/include -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS -isystem /opt/local/include -I/opt/local/include/db48 -I/usr/local/opt/berkeley-db@4/include -DMAC_OSX -DHAVE_QT5 -D__STDC_LIMIT_MACROS -c db/dbformat.cc -o db/dbformat.o +In file included from db/db_impl.cc:5: +In file included from ./db/db_impl.h:10: +In file included from ./db/dbformat.h:14: +In file included from ./util/coding.h:17: +In file included from ./port/port.h:14: +In file included from ./port/port_posix.h:47: +./port/atomic_pointer.h:55:3: warning: 'OSMemoryBarrier' is deprecated: first deprecated in macOS 10.12 - Use std::atomic_thread_fence() from instead [-Wdeprecated-declarations] + OSMemoryBarrier(); + ^ +/usr/include/libkern/OSAtomicDeprecated.h:749:9: note: 'OSMemoryBarrier' has been explicitly marked deprecated here +void OSMemoryBarrier( void ); + ^ +In file included from db/db_iter.cc:5: +In file included from ./db/db_iter.h:10: +In file included from ./db/dbformat.h:14: +In file included from ./util/coding.h:17: +In file included from ./port/port.h:14: +In file included from ./port/port_posix.h:47: +./port/atomic_pointer.h:55:3: warning: 'OSMemoryBarrier' is deprecated: first deprecated in macOS 10.12 - Use std::atomic_thread_fence() from instead [-Wdeprecated-declarations] + OSMemoryBarrier(); + ^ +/usr/include/libkern/OSAtomicDeprecated.h:749:9: note: 'OSMemoryBarrier' has been explicitly marked deprecated here +void OSMemoryBarrier( void ); + ^ +In file included from db/dbformat.cc:6: +In file included from ./db/dbformat.h:14: +In file included from ./util/coding.h:17: +In file included from ./port/port.h:14: +In file included from ./port/port_posix.h:47: +./port/atomic_pointer.h:55:3: warning: 'OSMemoryBarrier' is deprecated: first deprecated in macOS 10.12 - Use std::atomic_thread_fence() from instead [-Wdeprecated-declarations] + OSMemoryBarrier(); + ^ +/usr/include/libkern/OSAtomicDeprecated.h:749:9: note: 'OSMemoryBarrier' has been explicitly marked deprecated here +void OSMemoryBarrier( void ); + ^ +1 warning generated. + GEN qt/bitcoinamountfield.moc +1 warning generated. + GEN qt/intro.moc + GEN qt/overviewpage.moc + GEN qt/rpcconsole.moc +g++ -std=c++11 -I. -I./include -std=c++0x -DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -DLEVELDB_ATOMIC_PRESENT -Wstack-protector -fstack-protector-all -fPIC -g -O2 -Wall -Wextra -Wformat -Wvla -Wformat-security -Wthread-safety-analysis -Wno-unused-parameter -Wno-self-assign -Wno-unused-local-typedef -Wno-deprecated-register -Wno-implicit-fallthrough -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -I/usr/local/opt/boost@1.57/include -I/usr/local/opt/qt/include -I/usr/local/opt/openssl/include -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS -isystem /opt/local/include -I/opt/local/include/db48 -I/usr/local/opt/berkeley-db@4/include -DMAC_OSX -DHAVE_QT5 -D__STDC_LIMIT_MACROS -c db/dumpfile.cc -o db/dumpfile.o +g++ -std=c++11 -I. -I./include -std=c++0x -DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -DLEVELDB_ATOMIC_PRESENT -Wstack-protector -fstack-protector-all -fPIC -g -O2 -Wall -Wextra -Wformat -Wvla -Wformat-security -Wthread-safety-analysis -Wno-unused-parameter -Wno-self-assign -Wno-unused-local-typedef -Wno-deprecated-register -Wno-implicit-fallthrough -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -I/usr/local/opt/boost@1.57/include -I/usr/local/opt/qt/include -I/usr/local/opt/openssl/include -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS -isystem /opt/local/include -I/opt/local/include/db48 -I/usr/local/opt/berkeley-db@4/include -DMAC_OSX -DHAVE_QT5 -D__STDC_LIMIT_MACROS -c db/filename.cc -o db/filename.o +In file included from db/filename.cc:7: +In file included from ./db/filename.h:14: +In file included from ./port/port.h:14: +In file included from ./port/port_posix.h:47: +./port/atomic_pointer.h:55:3: warning: 'OSMemoryBarrier' is deprecated: first deprecated in macOS 10.12 - Use std::atomic_thread_fence() from instead [-Wdeprecated-declarations] + OSMemoryBarrier(); + ^ +/usr/include/libkern/OSAtomicDeprecated.h:749:9: note: 'OSMemoryBarrier' has been explicitly marked deprecated here +void OSMemoryBarrier( void ); + ^ +In file included from db/dumpfile.cc:6: +In file included from ./db/dbformat.h:14: +In file included from ./util/coding.h:17: +In file included from ./port/port.h:14: +In file included from ./port/port_posix.h:47: +./port/atomic_pointer.h:55:3: warning: 'OSMemoryBarrier' is deprecated: first deprecated in macOS 10.12 - Use std::atomic_thread_fence() from instead [-Wdeprecated-declarations] + OSMemoryBarrier(); + ^ +/usr/include/libkern/OSAtomicDeprecated.h:749:9: note: 'OSMemoryBarrier' has been explicitly marked deprecated here +void OSMemoryBarrier( void ); + ^ +1 warning generated. +g++ -std=c++11 -I. -I./include -std=c++0x -DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -DLEVELDB_ATOMIC_PRESENT -Wstack-protector -fstack-protector-all -fPIC -g -O2 -Wall -Wextra -Wformat -Wvla -Wformat-security -Wthread-safety-analysis -Wno-unused-parameter -Wno-self-assign -Wno-unused-local-typedef -Wno-deprecated-register -Wno-implicit-fallthrough -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -I/usr/local/opt/boost@1.57/include -I/usr/local/opt/qt/include -I/usr/local/opt/openssl/include -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS -isystem /opt/local/include -I/opt/local/include/db48 -I/usr/local/opt/berkeley-db@4/include -DMAC_OSX -DHAVE_QT5 -D__STDC_LIMIT_MACROS -c db/log_reader.cc -o db/log_reader.o +In file included from db/log_reader.cc:9: +In file included from ./util/coding.h:17: +In file included from ./port/port.h:14: +In file included from ./port/port_posix.h:47: +./port/atomic_pointer.h:55:3: warning: 'OSMemoryBarrier' is deprecated: first deprecated in macOS 10.12 - Use std::atomic_thread_fence() from instead [-Wdeprecated-declarations] + OSMemoryBarrier(); + ^ +/usr/include/libkern/OSAtomicDeprecated.h:749:9: note: 'OSMemoryBarrier' has been explicitly marked deprecated here +void OSMemoryBarrier( void ); + ^ +1 warning generated. +g++ -std=c++11 -I. -I./include -std=c++0x -DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -DLEVELDB_ATOMIC_PRESENT -Wstack-protector -fstack-protector-all -fPIC -g -O2 -Wall -Wextra -Wformat -Wvla -Wformat-security -Wthread-safety-analysis -Wno-unused-parameter -Wno-self-assign -Wno-unused-local-typedef -Wno-deprecated-register -Wno-implicit-fallthrough -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -I/usr/local/opt/boost@1.57/include -I/usr/local/opt/qt/include -I/usr/local/opt/openssl/include -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS -isystem /opt/local/include -I/opt/local/include/db48 -I/usr/local/opt/berkeley-db@4/include -DMAC_OSX -DHAVE_QT5 -D__STDC_LIMIT_MACROS -c db/log_writer.cc -o db/log_writer.o +1 warning generated. + GEN qt/qrc_phore_locale.cpp +In file included from db/log_writer.cc:9: +In file included from ./util/coding.h:17: +In file included from ./port/port.h:14: +In file included from ./port/port_posix.h:47: +./port/atomic_pointer.h:55:3: warning: 'OSMemoryBarrier' is deprecated: first deprecated in macOS 10.12 - Use std::atomic_thread_fence() from instead [-Wdeprecated-declarations] + OSMemoryBarrier(); + ^ +/usr/include/libkern/OSAtomicDeprecated.h:749:9: note: 'OSMemoryBarrier' has been explicitly marked deprecated here +void OSMemoryBarrier( void ); + ^ +1 warning generated. +g++ -std=c++11 -I. -I./include -std=c++0x -DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -DLEVELDB_ATOMIC_PRESENT -Wstack-protector -fstack-protector-all -fPIC -g -O2 -Wall -Wextra -Wformat -Wvla -Wformat-security -Wthread-safety-analysis -Wno-unused-parameter -Wno-self-assign -Wno-unused-local-typedef -Wno-deprecated-register -Wno-implicit-fallthrough -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -I/usr/local/opt/boost@1.57/include -I/usr/local/opt/qt/include -I/usr/local/opt/openssl/include -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS -isystem /opt/local/include -I/opt/local/include/db48 -I/usr/local/opt/berkeley-db@4/include -DMAC_OSX -DHAVE_QT5 -D__STDC_LIMIT_MACROS -c db/memtable.cc -o db/memtable.o +g++ -std=c++11 -I. -I./include -std=c++0x -DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -DLEVELDB_ATOMIC_PRESENT -Wstack-protector -fstack-protector-all -fPIC -g -O2 -Wall -Wextra -Wformat -Wvla -Wformat-security -Wthread-safety-analysis -Wno-unused-parameter -Wno-self-assign -Wno-unused-local-typedef -Wno-deprecated-register -Wno-implicit-fallthrough -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -I/usr/local/opt/boost@1.57/include -I/usr/local/opt/qt/include -I/usr/local/opt/openssl/include -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS -isystem /opt/local/include -I/opt/local/include/db48 -I/usr/local/opt/berkeley-db@4/include -DMAC_OSX -DHAVE_QT5 -D__STDC_LIMIT_MACROS -c db/repair.cc -o db/repair.o +1 warning generated. + AR libbitcoin_util.a +In file included from db/memtable.cc:5: +In file included from ./db/memtable.h:10: +In file included from ./db/dbformat.h:14: +In file included from ./util/coding.h:17: +In file included from ./port/port.h:14: +In file included from ./port/port_posix.h:47: +./port/atomic_pointer.h:55:3: warning: 'OSMemoryBarrier' is deprecated: first deprecated in macOS 10.12 - Use std::atomic_thread_fence() from instead [-Wdeprecated-declarations] + OSMemoryBarrier(); + ^ +/usr/include/libkern/OSAtomicDeprecated.h:749:9: note: 'OSMemoryBarrier' has been explicitly marked deprecated here +void OSMemoryBarrier( void ); + ^ +/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ranlib: file: libbitcoin_util.a(libbitcoin_util_a-strnlen.o) has no symbols +In file included from db/repair.cc:28: +In file included from ./db/db_impl.h:10: +In file included from ./db/dbformat.h:14: +In file included from ./util/coding.h:17: +In file included from ./port/port.h:14: +In file included from ./port/port_posix.h:47: +./port/atomic_pointer.h:55:3: warning: 'OSMemoryBarrier' is deprecated: first deprecated in macOS 10.12 - Use std::atomic_thread_fence() from instead [-Wdeprecated-declarations] + OSMemoryBarrier(); + ^ +/usr/include/libkern/OSAtomicDeprecated.h:749:9: note: 'OSMemoryBarrier' has been explicitly marked deprecated here +void OSMemoryBarrier( void ); + ^ +/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ranlib: file: libbitcoin_util.a(libbitcoin_util_a-strnlen.o) has no symbols +g++ -std=c++11 -I. -I./include -std=c++0x -DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -DLEVELDB_ATOMIC_PRESENT -Wstack-protector -fstack-protector-all -fPIC -g -O2 -Wall -Wextra -Wformat -Wvla -Wformat-security -Wthread-safety-analysis -Wno-unused-parameter -Wno-self-assign -Wno-unused-local-typedef -Wno-deprecated-register -Wno-implicit-fallthrough -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -I/usr/local/opt/boost@1.57/include -I/usr/local/opt/qt/include -I/usr/local/opt/openssl/include -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS -isystem /opt/local/include -I/opt/local/include/db48 -I/usr/local/opt/berkeley-db@4/include -DMAC_OSX -DHAVE_QT5 -D__STDC_LIMIT_MACROS -c db/table_cache.cc -o db/table_cache.o +1 warning generated. + CXX qt/phore_qt-phore.o +In file included from db/table_cache.cc:5: +In file included from ./db/table_cache.h:12: +In file included from ./db/dbformat.h:14: +In file included from ./util/coding.h:17: +In file included from ./port/port.h:14: +In file included from ./port/port_posix.h:47: +./port/atomic_pointer.h:55:3: warning: 'OSMemoryBarrier' is deprecated: first deprecated in macOS 10.12 - Use std::atomic_thread_fence() from instead [-Wdeprecated-declarations] + OSMemoryBarrier(); + ^ +/usr/include/libkern/OSAtomicDeprecated.h:749:9: note: 'OSMemoryBarrier' has been explicitly marked deprecated here +void OSMemoryBarrier( void ); + ^ +1 warning generated. + OBJCXX qt/phore_qt-macdockiconhandler.o +1 warning generated. +g++ -std=c++11 -I. -I./include -std=c++0x -DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -DLEVELDB_ATOMIC_PRESENT -Wstack-protector -fstack-protector-all -fPIC -g -O2 -Wall -Wextra -Wformat -Wvla -Wformat-security -Wthread-safety-analysis -Wno-unused-parameter -Wno-self-assign -Wno-unused-local-typedef -Wno-deprecated-register -Wno-implicit-fallthrough -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -I/usr/local/opt/boost@1.57/include -I/usr/local/opt/qt/include -I/usr/local/opt/openssl/include -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS -isystem /opt/local/include -I/opt/local/include/db48 -I/usr/local/opt/berkeley-db@4/include -DMAC_OSX -DHAVE_QT5 -D__STDC_LIMIT_MACROS -c db/version_edit.cc -o db/version_edit.o +In file included from db/version_edit.cc:5: +In file included from ./db/version_edit.h:11: +In file included from ./db/dbformat.h:14: +In file included from ./util/coding.h:17: +In file included from ./port/port.h:14: +In file included from ./port/port_posix.h:47: +./port/atomic_pointer.h:55:3: warning: 'OSMemoryBarrier' is deprecated: first deprecated in macOS 10.12 - Use std::atomic_thread_fence() from instead [-Wdeprecated-declarations] + OSMemoryBarrier(); + ^ +/usr/include/libkern/OSAtomicDeprecated.h:749:9: note: 'OSMemoryBarrier' has been explicitly marked deprecated here +void OSMemoryBarrier( void ); + ^ +1 warning generated. +g++ -std=c++11 -I. -I./include -std=c++0x -DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -DLEVELDB_ATOMIC_PRESENT -Wstack-protector -fstack-protector-all -fPIC -g -O2 -Wall -Wextra -Wformat -Wvla -Wformat-security -Wthread-safety-analysis -Wno-unused-parameter -Wno-self-assign -Wno-unused-local-typedef -Wno-deprecated-register -Wno-implicit-fallthrough -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -I/usr/local/opt/boost@1.57/include -I/usr/local/opt/qt/include -I/usr/local/opt/openssl/include -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS -isystem /opt/local/include -I/opt/local/include/db48 -I/usr/local/opt/berkeley-db@4/include -DMAC_OSX -DHAVE_QT5 -D__STDC_LIMIT_MACROS -c db/version_set.cc -o db/version_set.o +1 warning generated. +g++ -std=c++11 -I. -I./include -std=c++0x -DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -DLEVELDB_ATOMIC_PRESENT -Wstack-protector -fstack-protector-all -fPIC -g -O2 -Wall -Wextra -Wformat -Wvla -Wformat-security -Wthread-safety-analysis -Wno-unused-parameter -Wno-self-assign -Wno-unused-local-typedef -Wno-deprecated-register -Wno-implicit-fallthrough -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -I/usr/local/opt/boost@1.57/include -I/usr/local/opt/qt/include -I/usr/local/opt/openssl/include -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS -isystem /opt/local/include -I/opt/local/include/db48 -I/usr/local/opt/berkeley-db@4/include -DMAC_OSX -DHAVE_QT5 -D__STDC_LIMIT_MACROS -c db/write_batch.cc -o db/write_batch.o +In file included from db/version_set.cc:5: +In file included from ./db/version_set.h:21: +In file included from ./db/dbformat.h:14: +In file included from ./util/coding.h:17: +In file included from ./port/port.h:14: +In file included from ./port/port_posix.h:47: +./port/atomic_pointer.h:55:3: warning: 'OSMemoryBarrier' is deprecated: first deprecated in macOS 10.12 - Use std::atomic_thread_fence() from instead [-Wdeprecated-declarations] + OSMemoryBarrier(); + ^ +/usr/include/libkern/OSAtomicDeprecated.h:749:9: note: 'OSMemoryBarrier' has been explicitly marked deprecated here +void OSMemoryBarrier( void ); + ^ +In file included from db/write_batch.cc:19: +In file included from ./db/dbformat.h:14: +In file included from ./util/coding.h:17: +In file included from ./port/port.h:14: +In file included from ./port/port_posix.h:47: +./port/atomic_pointer.h:55:3: warning: 'OSMemoryBarrier' is deprecated: first deprecated in macOS 10.12 - Use std::atomic_thread_fence() from instead [-Wdeprecated-declarations] + OSMemoryBarrier(); + ^ +/usr/include/libkern/OSAtomicDeprecated.h:749:9: note: 'OSMemoryBarrier' has been explicitly marked deprecated here +void OSMemoryBarrier( void ); + ^ +1 warning generated. +g++ -std=c++11 -I. -I./include -std=c++0x -DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -DLEVELDB_ATOMIC_PRESENT -Wstack-protector -fstack-protector-all -fPIC -g -O2 -Wall -Wextra -Wformat -Wvla -Wformat-security -Wthread-safety-analysis -Wno-unused-parameter -Wno-self-assign -Wno-unused-local-typedef -Wno-deprecated-register -Wno-implicit-fallthrough -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -I/usr/local/opt/boost@1.57/include -I/usr/local/opt/qt/include -I/usr/local/opt/openssl/include -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS -isystem /opt/local/include -I/opt/local/include/db48 -I/usr/local/opt/berkeley-db@4/include -DMAC_OSX -DHAVE_QT5 -D__STDC_LIMIT_MACROS -c table/block.cc -o table/block.o +In file included from table/block.cc:13: +In file included from ./util/coding.h:17: +In file included from ./port/port.h:14: +In file included from ./port/port_posix.h:47: +./port/atomic_pointer.h:55:3: warning: 'OSMemoryBarrier' is deprecated: first deprecated in macOS 10.12 - Use std::atomic_thread_fence() from instead [-Wdeprecated-declarations] + OSMemoryBarrier(); + ^ +/usr/include/libkern/OSAtomicDeprecated.h:749:9: note: 'OSMemoryBarrier' has been explicitly marked deprecated here +void OSMemoryBarrier( void ); + ^ +1 warning generated. +g++ -std=c++11 -I. -I./include -std=c++0x -DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -DLEVELDB_ATOMIC_PRESENT -Wstack-protector -fstack-protector-all -fPIC -g -O2 -Wall -Wextra -Wformat -Wvla -Wformat-security -Wthread-safety-analysis -Wno-unused-parameter -Wno-self-assign -Wno-unused-local-typedef -Wno-deprecated-register -Wno-implicit-fallthrough -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -I/usr/local/opt/boost@1.57/include -I/usr/local/opt/qt/include -I/usr/local/opt/openssl/include -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS -isystem /opt/local/include -I/opt/local/include/db48 -I/usr/local/opt/berkeley-db@4/include -DMAC_OSX -DHAVE_QT5 -D__STDC_LIMIT_MACROS -c table/block_builder.cc -o table/block_builder.o + OBJCXX qt/phore_qt-macnotificationhandler.o +In file included from table/block_builder.cc:35: +In file included from ./util/coding.h:17: +In file included from ./port/port.h:14: +In file included from ./port/port_posix.h:47: +./port/atomic_pointer.h:55:3: warning: 'OSMemoryBarrier' is deprecated: first deprecated in macOS 10.12 - Use std::atomic_thread_fence() from instead [-Wdeprecated-declarations] + OSMemoryBarrier(); + ^ +/usr/include/libkern/OSAtomicDeprecated.h:749:9: note: 'OSMemoryBarrier' has been explicitly marked deprecated here +void OSMemoryBarrier( void ); + ^ +1 warning generated. +g++ -std=c++11 -I. -I./include -std=c++0x -DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -DLEVELDB_ATOMIC_PRESENT -Wstack-protector -fstack-protector-all -fPIC -g -O2 -Wall -Wextra -Wformat -Wvla -Wformat-security -Wthread-safety-analysis -Wno-unused-parameter -Wno-self-assign -Wno-unused-local-typedef -Wno-deprecated-register -Wno-implicit-fallthrough -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -I/usr/local/opt/boost@1.57/include -I/usr/local/opt/qt/include -I/usr/local/opt/openssl/include -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS -isystem /opt/local/include -I/opt/local/include/db48 -I/usr/local/opt/berkeley-db@4/include -DMAC_OSX -DHAVE_QT5 -D__STDC_LIMIT_MACROS -c table/filter_block.cc -o table/filter_block.o +In file included from table/filter_block.cc:8: +In file included from ./util/coding.h:17: +In file included from ./port/port.h:14: +In file included from ./port/port_posix.h:47: +./port/atomic_pointer.h:55:3: warning: 'OSMemoryBarrier' is deprecated: first deprecated in macOS 10.12 - Use std::atomic_thread_fence() from instead [-Wdeprecated-declarations] + OSMemoryBarrier(); + ^ +/usr/include/libkern/OSAtomicDeprecated.h:749:9: note: 'OSMemoryBarrier' has been explicitly marked deprecated here +void OSMemoryBarrier( void ); + ^ +1 warning generated. +g++ -std=c++11 -I. -I./include -std=c++0x -DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -DLEVELDB_ATOMIC_PRESENT -Wstack-protector -fstack-protector-all -fPIC -g -O2 -Wall -Wextra -Wformat -Wvla -Wformat-security -Wthread-safety-analysis -Wno-unused-parameter -Wno-self-assign -Wno-unused-local-typedef -Wno-deprecated-register -Wno-implicit-fallthrough -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -I/usr/local/opt/boost@1.57/include -I/usr/local/opt/qt/include -I/usr/local/opt/openssl/include -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS -isystem /opt/local/include -I/opt/local/include/db48 -I/usr/local/opt/berkeley-db@4/include -DMAC_OSX -DHAVE_QT5 -D__STDC_LIMIT_MACROS -c table/format.cc -o table/format.o +1 warning generated. +g++ -std=c++11 -I. -I./include -std=c++0x -DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -DLEVELDB_ATOMIC_PRESENT -Wstack-protector -fstack-protector-all -fPIC -g -O2 -Wall -Wextra -Wformat -Wvla -Wformat-security -Wthread-safety-analysis -Wno-unused-parameter -Wno-self-assign -Wno-unused-local-typedef -Wno-deprecated-register -Wno-implicit-fallthrough -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -I/usr/local/opt/boost@1.57/include -I/usr/local/opt/qt/include -I/usr/local/opt/openssl/include -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS -isystem /opt/local/include -I/opt/local/include/db48 -I/usr/local/opt/berkeley-db@4/include -DMAC_OSX -DHAVE_QT5 -D__STDC_LIMIT_MACROS -c table/iterator.cc -o table/iterator.o +In file included from table/format.cc:8: +In file included from ./port/port.h:14: +In file included from ./port/port_posix.h:47: +./port/atomic_pointer.h:55:3: warning: 'OSMemoryBarrier' is deprecated: first deprecated in macOS 10.12 - Use std::atomic_thread_fence() from instead [-Wdeprecated-declarations] + OSMemoryBarrier(); + ^ +/usr/include/libkern/OSAtomicDeprecated.h:749:9: note: 'OSMemoryBarrier' has been explicitly marked deprecated here +void OSMemoryBarrier( void ); + ^ +1 warning generated. + CXX qt/libbitcoinqt_a-bantablemodel.o +g++ -std=c++11 -I. -I./include -std=c++0x -DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -DLEVELDB_ATOMIC_PRESENT -Wstack-protector -fstack-protector-all -fPIC -g -O2 -Wall -Wextra -Wformat -Wvla -Wformat-security -Wthread-safety-analysis -Wno-unused-parameter -Wno-self-assign -Wno-unused-local-typedef -Wno-deprecated-register -Wno-implicit-fallthrough -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -I/usr/local/opt/boost@1.57/include -I/usr/local/opt/qt/include -I/usr/local/opt/openssl/include -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS -isystem /opt/local/include -I/opt/local/include/db48 -I/usr/local/opt/berkeley-db@4/include -DMAC_OSX -DHAVE_QT5 -D__STDC_LIMIT_MACROS -c table/merger.cc -o table/merger.o +g++ -std=c++11 -I. -I./include -std=c++0x -DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -DLEVELDB_ATOMIC_PRESENT -Wstack-protector -fstack-protector-all -fPIC -g -O2 -Wall -Wextra -Wformat -Wvla -Wformat-security -Wthread-safety-analysis -Wno-unused-parameter -Wno-self-assign -Wno-unused-local-typedef -Wno-deprecated-register -Wno-implicit-fallthrough -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -I/usr/local/opt/boost@1.57/include -I/usr/local/opt/qt/include -I/usr/local/opt/openssl/include -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS -isystem /opt/local/include -I/opt/local/include/db48 -I/usr/local/opt/berkeley-db@4/include -DMAC_OSX -DHAVE_QT5 -D__STDC_LIMIT_MACROS -c table/table.cc -o table/table.o + CXX qt/libbitcoinqt_a-bitcoinaddressvalidator.o +In file included from table/table.cc:16: +In file included from ./util/coding.h:17: +In file included from ./port/port.h:14: +In file included from ./port/port_posix.h:47: +./port/atomic_pointer.h:55:3: warning: 'OSMemoryBarrier' is deprecated: first deprecated in macOS 10.12 - Use std::atomic_thread_fence() from instead [-Wdeprecated-declarations] + OSMemoryBarrier(); + ^ +/usr/include/libkern/OSAtomicDeprecated.h:749:9: note: 'OSMemoryBarrier' has been explicitly marked deprecated here +void OSMemoryBarrier( void ); + ^ +1 warning generated. +g++ -std=c++11 -I. -I./include -std=c++0x -DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -DLEVELDB_ATOMIC_PRESENT -Wstack-protector -fstack-protector-all -fPIC -g -O2 -Wall -Wextra -Wformat -Wvla -Wformat-security -Wthread-safety-analysis -Wno-unused-parameter -Wno-self-assign -Wno-unused-local-typedef -Wno-deprecated-register -Wno-implicit-fallthrough -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -I/usr/local/opt/boost@1.57/include -I/usr/local/opt/qt/include -I/usr/local/opt/openssl/include -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS -isystem /opt/local/include -I/opt/local/include/db48 -I/usr/local/opt/berkeley-db@4/include -DMAC_OSX -DHAVE_QT5 -D__STDC_LIMIT_MACROS -c table/table_builder.cc -o table/table_builder.o +In file included from table/table_builder.cc:15: +In file included from ./util/coding.h:17: +In file included from ./port/port.h:14: +In file included from ./port/port_posix.h:47: +./port/atomic_pointer.h:55:3: warning: 'OSMemoryBarrier' is deprecated: first deprecated in macOS 10.12 - Use std::atomic_thread_fence() from instead [-Wdeprecated-declarations] + OSMemoryBarrier(); + ^ +/usr/include/libkern/OSAtomicDeprecated.h:749:9: note: 'OSMemoryBarrier' has been explicitly marked deprecated here +void OSMemoryBarrier( void ); + ^ +1 warning generated. +g++ -std=c++11 -I. -I./include -std=c++0x -DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -DLEVELDB_ATOMIC_PRESENT -Wstack-protector -fstack-protector-all -fPIC -g -O2 -Wall -Wextra -Wformat -Wvla -Wformat-security -Wthread-safety-analysis -Wno-unused-parameter -Wno-self-assign -Wno-unused-local-typedef -Wno-deprecated-register -Wno-implicit-fallthrough -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -I/usr/local/opt/boost@1.57/include -I/usr/local/opt/qt/include -I/usr/local/opt/openssl/include -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS -isystem /opt/local/include -I/opt/local/include/db48 -I/usr/local/opt/berkeley-db@4/include -DMAC_OSX -DHAVE_QT5 -D__STDC_LIMIT_MACROS -c table/two_level_iterator.cc -o table/two_level_iterator.o +g++ -std=c++11 -I. -I./include -std=c++0x -DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -DLEVELDB_ATOMIC_PRESENT -Wstack-protector -fstack-protector-all -fPIC -g -O2 -Wall -Wextra -Wformat -Wvla -Wformat-security -Wthread-safety-analysis -Wno-unused-parameter -Wno-self-assign -Wno-unused-local-typedef -Wno-deprecated-register -Wno-implicit-fallthrough -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -I/usr/local/opt/boost@1.57/include -I/usr/local/opt/qt/include -I/usr/local/opt/openssl/include -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS -isystem /opt/local/include -I/opt/local/include/db48 -I/usr/local/opt/berkeley-db@4/include -DMAC_OSX -DHAVE_QT5 -D__STDC_LIMIT_MACROS -c util/arena.cc -o util/arena.o +In file included from qt/phore.cpp:17: +In file included from ./net.h:19: +In file included from ./sync.h:12: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/condition_variable.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/condition_variable.hpp:12: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/thread_data.hpp:12: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./net.h:458:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_inventory); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:127:1: note: expanded from here +criticalblock0 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +g++ -std=c++11 -I. -I./include -std=c++0x -DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -DLEVELDB_ATOMIC_PRESENT -Wstack-protector -fstack-protector-all -fPIC -g -O2 -Wall -Wextra -Wformat -Wvla -Wformat-security -Wthread-safety-analysis -Wno-unused-parameter -Wno-self-assign -Wno-unused-local-typedef -Wno-deprecated-register -Wno-implicit-fallthrough -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -I/usr/local/opt/boost@1.57/include -I/usr/local/opt/qt/include -I/usr/local/opt/openssl/include -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS -isystem /opt/local/include -I/opt/local/include/db48 -I/usr/local/opt/berkeley-db@4/include -DMAC_OSX -DHAVE_QT5 -D__STDC_LIMIT_MACROS -c util/bloom.cc -o util/bloom.o +2 warnings generated. +g++ -std=c++11 -I. -I./include -std=c++0x -DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -DLEVELDB_ATOMIC_PRESENT -Wstack-protector -fstack-protector-all -fPIC -g -O2 -Wall -Wextra -Wformat -Wvla -Wformat-security -Wthread-safety-analysis -Wno-unused-parameter -Wno-self-assign -Wno-unused-local-typedef -Wno-deprecated-register -Wno-implicit-fallthrough -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -I/usr/local/opt/boost@1.57/include -I/usr/local/opt/qt/include -I/usr/local/opt/openssl/include -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS -isystem /opt/local/include -I/opt/local/include/db48 -I/usr/local/opt/berkeley-db@4/include -DMAC_OSX -DHAVE_QT5 -D__STDC_LIMIT_MACROS -c util/cache.cc -o util/cache.o + CXX qt/libbitcoinqt_a-bitcoinamountfield.o +In file included from util/cache.cc:10: +In file included from ./port/port.h:14: +In file included from ./port/port_posix.h:47: +./port/atomic_pointer.h:55:3: warning: 'OSMemoryBarrier' is deprecated: first deprecated in macOS 10.12 - Use std::atomic_thread_fence() from instead [-Wdeprecated-declarations] + OSMemoryBarrier(); + ^ +/usr/include/libkern/OSAtomicDeprecated.h:749:9: note: 'OSMemoryBarrier' has been explicitly marked deprecated here +void OSMemoryBarrier( void ); + ^ +1 warning generated. +g++ -std=c++11 -I. -I./include -std=c++0x -DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -DLEVELDB_ATOMIC_PRESENT -Wstack-protector -fstack-protector-all -fPIC -g -O2 -Wall -Wextra -Wformat -Wvla -Wformat-security -Wthread-safety-analysis -Wno-unused-parameter -Wno-self-assign -Wno-unused-local-typedef -Wno-deprecated-register -Wno-implicit-fallthrough -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -I/usr/local/opt/boost@1.57/include -I/usr/local/opt/qt/include -I/usr/local/opt/openssl/include -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS -isystem /opt/local/include -I/opt/local/include/db48 -I/usr/local/opt/berkeley-db@4/include -DMAC_OSX -DHAVE_QT5 -D__STDC_LIMIT_MACROS -c util/coding.cc -o util/coding.o +In file included from util/coding.cc:5: +In file included from ./util/coding.h:17: +In file included from ./port/port.h:14: +In file included from ./port/port_posix.h:47: +./port/atomic_pointer.h:55:3: warning: 'OSMemoryBarrier' is deprecated: first deprecated in macOS 10.12 - Use std::atomic_thread_fence() from instead [-Wdeprecated-declarations] + OSMemoryBarrier(); + ^ +/usr/include/libkern/OSAtomicDeprecated.h:749:9: note: 'OSMemoryBarrier' has been explicitly marked deprecated here +void OSMemoryBarrier( void ); + ^ +qt/bantablemodel.cpp:67:13: warning: 'qStableSort::iterator, BannedNodeLessThan>' is deprecated: Use std::stable_sort [-Wdeprecated-declarations] + qStableSort(cachedBanlist.begin(), cachedBanlist.end(), BannedNodeLessThan(sortColumn, sortOrder)); + ^ +/usr/local/Cellar/qt/5.13.0/lib/QtCore.framework/Headers/qalgorithms.h:206:1: note: 'qStableSort::iterator, BannedNodeLessThan>' has been explicitly marked deprecated here +QT_DEPRECATED_X("Use std::stable_sort") inline void qStableSort(RandomAccessIterator start, RandomAccessIterator end, LessThan lessThan) +^ +/usr/local/Cellar/qt/5.13.0/lib/QtCore.framework/Headers/qglobal.h:294:33: note: expanded from macro 'QT_DEPRECATED_X' +# define QT_DEPRECATED_X(text) Q_DECL_DEPRECATED_X(text) + ^ +/usr/local/Cellar/qt/5.13.0/lib/QtCore.framework/Headers/qcompilerdetection.h:649:55: note: expanded from macro 'Q_DECL_DEPRECATED_X' +# define Q_DECL_DEPRECATED_X(text) __attribute__ ((__deprecated__(text))) + ^ +1 warning generated. +g++ -std=c++11 -I. -I./include -std=c++0x -DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -DLEVELDB_ATOMIC_PRESENT -Wstack-protector -fstack-protector-all -fPIC -g -O2 -Wall -Wextra -Wformat -Wvla -Wformat-security -Wthread-safety-analysis -Wno-unused-parameter -Wno-self-assign -Wno-unused-local-typedef -Wno-deprecated-register -Wno-implicit-fallthrough -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -I/usr/local/opt/boost@1.57/include -I/usr/local/opt/qt/include -I/usr/local/opt/openssl/include -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS -isystem /opt/local/include -I/opt/local/include/db48 -I/usr/local/opt/berkeley-db@4/include -DMAC_OSX -DHAVE_QT5 -D__STDC_LIMIT_MACROS -c util/comparator.cc -o util/comparator.o +In file included from util/comparator.cc:9: +In file included from ./port/port.h:14: +In file included from ./port/port_posix.h:47: +./port/atomic_pointer.h:55:3: warning: 'OSMemoryBarrier' is deprecated: first deprecated in macOS 10.12 - Use std::atomic_thread_fence() from instead [-Wdeprecated-declarations] + OSMemoryBarrier(); + ^ +/usr/include/libkern/OSAtomicDeprecated.h:749:9: note: 'OSMemoryBarrier' has been explicitly marked deprecated here +void OSMemoryBarrier( void ); + ^ +In file included from qt/bantablemodel.cpp:5: +In file included from ./qt/bantablemodel.h:8: +In file included from ./net.h:19: +In file included from ./sync.h:12: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/condition_variable.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/condition_variable.hpp:12: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/thread_data.hpp:12: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./net.h:458:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_inventory); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:143:1: note: expanded from here +criticalblock0 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +1 warning generated. +g++ -std=c++11 -I. -I./include -std=c++0x -DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -DLEVELDB_ATOMIC_PRESENT -Wstack-protector -fstack-protector-all -fPIC -g -O2 -Wall -Wextra -Wformat -Wvla -Wformat-security -Wthread-safety-analysis -Wno-unused-parameter -Wno-self-assign -Wno-unused-local-typedef -Wno-deprecated-register -Wno-implicit-fallthrough -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -I/usr/local/opt/boost@1.57/include -I/usr/local/opt/qt/include -I/usr/local/opt/openssl/include -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS -isystem /opt/local/include -I/opt/local/include/db48 -I/usr/local/opt/berkeley-db@4/include -DMAC_OSX -DHAVE_QT5 -D__STDC_LIMIT_MACROS -c util/crc32c.cc -o util/crc32c.o +In file included from qt/bitcoinaddressvalidator.cpp:10: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:118:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +In file included from util/crc32c.cc:11: +In file included from ./util/coding.h:17: +In file included from ./port/port.h:14: +In file included from ./port/port_posix.h:47: +./port/atomic_pointer.h:55:3: warning: 'OSMemoryBarrier' is deprecated: first deprecated in macOS 10.12 - Use std::atomic_thread_fence() from instead [-Wdeprecated-declarations] + OSMemoryBarrier(); + ^ +/usr/include/libkern/OSAtomicDeprecated.h:749:9: note: 'OSMemoryBarrier' has been explicitly marked deprecated here +void OSMemoryBarrier( void ); + ^ +1 warning generated. +g++ -std=c++11 -I. -I./include -std=c++0x -DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -DLEVELDB_ATOMIC_PRESENT -Wstack-protector -fstack-protector-all -fPIC -g -O2 -Wall -Wextra -Wformat -Wvla -Wformat-security -Wthread-safety-analysis -Wno-unused-parameter -Wno-self-assign -Wno-unused-local-typedef -Wno-deprecated-register -Wno-implicit-fallthrough -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -I/usr/local/opt/boost@1.57/include -I/usr/local/opt/qt/include -I/usr/local/opt/openssl/include -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS -isystem /opt/local/include -I/opt/local/include/db48 -I/usr/local/opt/berkeley-db@4/include -DMAC_OSX -DHAVE_QT5 -D__STDC_LIMIT_MACROS -c util/env.cc -o util/env.o +1 warning generated. +g++ -std=c++11 -I. -I./include -std=c++0x -DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -DLEVELDB_ATOMIC_PRESENT -Wstack-protector -fstack-protector-all -fPIC -g -O2 -Wall -Wextra -Wformat -Wvla -Wformat-security -Wthread-safety-analysis -Wno-unused-parameter -Wno-self-assign -Wno-unused-local-typedef -Wno-deprecated-register -Wno-implicit-fallthrough -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -I/usr/local/opt/boost@1.57/include -I/usr/local/opt/qt/include -I/usr/local/opt/openssl/include -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS -isystem /opt/local/include -I/opt/local/include/db48 -I/usr/local/opt/berkeley-db@4/include -DMAC_OSX -DHAVE_QT5 -D__STDC_LIMIT_MACROS -c util/env_posix.cc -o util/env_posix.o +qt/bitcoinamountfield.cpp:100:24: warning: 'width' is deprecated: Use QFontMetrics::horizontalAdvance [-Wdeprecated-declarations] + int w = fm.width(BitcoinUnits::format(BitcoinUnits::PHR, BitcoinUnits::maxMoney(), false, BitcoinUnits::separatorAlways)); + ^ +/usr/local/Cellar/qt/5.13.0/lib/QtGui.framework/Headers/qfontmetrics.h:107:5: note: 'width' has been explicitly marked deprecated here + QT_DEPRECATED_X("Use QFontMetrics::horizontalAdvance") + ^ +/usr/local/Cellar/qt/5.13.0/lib/QtCore.framework/Headers/qglobal.h:294:33: note: expanded from macro 'QT_DEPRECATED_X' +# define QT_DEPRECATED_X(text) Q_DECL_DEPRECATED_X(text) + ^ +/usr/local/Cellar/qt/5.13.0/lib/QtCore.framework/Headers/qcompilerdetection.h:649:55: note: expanded from macro 'Q_DECL_DEPRECATED_X' +# define Q_DECL_DEPRECATED_X(text) __attribute__ ((__deprecated__(text))) + ^ +2 warnings generated. + CXX qt/libbitcoinqt_a-bitcoingui.o +g++ -std=c++11 -I. -I./include -std=c++0x -DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -DLEVELDB_ATOMIC_PRESENT -Wstack-protector -fstack-protector-all -fPIC -g -O2 -Wall -Wextra -Wformat -Wvla -Wformat-security -Wthread-safety-analysis -Wno-unused-parameter -Wno-self-assign -Wno-unused-local-typedef -Wno-deprecated-register -Wno-implicit-fallthrough -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -I/usr/local/opt/boost@1.57/include -I/usr/local/opt/qt/include -I/usr/local/opt/openssl/include -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS -isystem /opt/local/include -I/opt/local/include/db48 -I/usr/local/opt/berkeley-db@4/include -DMAC_OSX -DHAVE_QT5 -D__STDC_LIMIT_MACROS -c util/env_win.cc -o util/env_win.o +In file included from util/env_posix.cc:23: +In file included from ./port/port.h:14: +In file included from ./port/port_posix.h:47: +./port/atomic_pointer.h:55:3: warning: 'OSMemoryBarrier' is deprecated: first deprecated in macOS 10.12 - Use std::atomic_thread_fence() from instead [-Wdeprecated-declarations] + OSMemoryBarrier(); + ^ +/usr/include/libkern/OSAtomicDeprecated.h:749:9: note: 'OSMemoryBarrier' has been explicitly marked deprecated here +void OSMemoryBarrier( void ); + ^ + CXX qt/libbitcoinqt_a-bitcoinunits.o +1 warning generated. +g++ -std=c++11 -I. -I./include -std=c++0x -DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -DLEVELDB_ATOMIC_PRESENT -Wstack-protector -fstack-protector-all -fPIC -g -O2 -Wall -Wextra -Wformat -Wvla -Wformat-security -Wthread-safety-analysis -Wno-unused-parameter -Wno-self-assign -Wno-unused-local-typedef -Wno-deprecated-register -Wno-implicit-fallthrough -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -I/usr/local/opt/boost@1.57/include -I/usr/local/opt/qt/include -I/usr/local/opt/openssl/include -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS -isystem /opt/local/include -I/opt/local/include/db48 -I/usr/local/opt/berkeley-db@4/include -DMAC_OSX -DHAVE_QT5 -D__STDC_LIMIT_MACROS -c util/filter_policy.cc -o util/filter_policy.o + CXX qt/libbitcoinqt_a-blockexplorer.o +1 warning generated. +g++ -std=c++11 -I. -I./include -std=c++0x -DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -DLEVELDB_ATOMIC_PRESENT -Wstack-protector -fstack-protector-all -fPIC -g -O2 -Wall -Wextra -Wformat -Wvla -Wformat-security -Wthread-safety-analysis -Wno-unused-parameter -Wno-self-assign -Wno-unused-local-typedef -Wno-deprecated-register -Wno-implicit-fallthrough -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -I/usr/local/opt/boost@1.57/include -I/usr/local/opt/qt/include -I/usr/local/opt/openssl/include -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS -isystem /opt/local/include -I/opt/local/include/db48 -I/usr/local/opt/berkeley-db@4/include -DMAC_OSX -DHAVE_QT5 -D__STDC_LIMIT_MACROS -c util/hash.cc -o util/hash.o +In file included from util/hash.cc:6: +In file included from ./util/coding.h:17: +In file included from ./port/port.h:14: +In file included from ./port/port_posix.h:47: +./port/atomic_pointer.h:55:3: warning: 'OSMemoryBarrier' is deprecated: first deprecated in macOS 10.12 - Use std::atomic_thread_fence() from instead [-Wdeprecated-declarations] + OSMemoryBarrier(); + ^ +/usr/include/libkern/OSAtomicDeprecated.h:749:9: note: 'OSMemoryBarrier' has been explicitly marked deprecated here +void OSMemoryBarrier( void ); + ^ +1 warning generated. +g++ -std=c++11 -I. -I./include -std=c++0x -DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -DLEVELDB_ATOMIC_PRESENT -Wstack-protector -fstack-protector-all -fPIC -g -O2 -Wall -Wextra -Wformat -Wvla -Wformat-security -Wthread-safety-analysis -Wno-unused-parameter -Wno-self-assign -Wno-unused-local-typedef -Wno-deprecated-register -Wno-implicit-fallthrough -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -I/usr/local/opt/boost@1.57/include -I/usr/local/opt/qt/include -I/usr/local/opt/openssl/include -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS -isystem /opt/local/include -I/opt/local/include/db48 -I/usr/local/opt/berkeley-db@4/include -DMAC_OSX -DHAVE_QT5 -D__STDC_LIMIT_MACROS -c util/histogram.cc -o util/histogram.o +In file included from util/histogram.cc:7: +In file included from ./port/port.h:14: +In file included from ./port/port_posix.h:47: +./port/atomic_pointer.h:55:3: warning: 'OSMemoryBarrier' is deprecated: first deprecated in macOS 10.12 - Use std::atomic_thread_fence() from instead [-Wdeprecated-declarations] + OSMemoryBarrier(); + ^ +/usr/include/libkern/OSAtomicDeprecated.h:749:9: note: 'OSMemoryBarrier' has been explicitly marked deprecated here +void OSMemoryBarrier( void ); + ^ +1 warning generated. +g++ -std=c++11 -I. -I./include -std=c++0x -DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -DLEVELDB_ATOMIC_PRESENT -Wstack-protector -fstack-protector-all -fPIC -g -O2 -Wall -Wextra -Wformat -Wvla -Wformat-security -Wthread-safety-analysis -Wno-unused-parameter -Wno-self-assign -Wno-unused-local-typedef -Wno-deprecated-register -Wno-implicit-fallthrough -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -I/usr/local/opt/boost@1.57/include -I/usr/local/opt/qt/include -I/usr/local/opt/openssl/include -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS -isystem /opt/local/include -I/opt/local/include/db48 -I/usr/local/opt/berkeley-db@4/include -DMAC_OSX -DHAVE_QT5 -D__STDC_LIMIT_MACROS -c util/logging.cc -o util/logging.o +In file included from util/logging.cc:5: +In file included from ./util/logging.h:14: +In file included from ./port/port.h:14: +In file included from ./port/port_posix.h:47: +./port/atomic_pointer.h:55:3: warning: 'OSMemoryBarrier' is deprecated: first deprecated in macOS 10.12 - Use std::atomic_thread_fence() from instead [-Wdeprecated-declarations] + OSMemoryBarrier(); + ^ +/usr/include/libkern/OSAtomicDeprecated.h:749:9: note: 'OSMemoryBarrier' has been explicitly marked deprecated here +void OSMemoryBarrier( void ); + ^ +1 warning generated. +g++ -std=c++11 -I. -I./include -std=c++0x -DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -DLEVELDB_ATOMIC_PRESENT -Wstack-protector -fstack-protector-all -fPIC -g -O2 -Wall -Wextra -Wformat -Wvla -Wformat-security -Wthread-safety-analysis -Wno-unused-parameter -Wno-self-assign -Wno-unused-local-typedef -Wno-deprecated-register -Wno-implicit-fallthrough -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -I/usr/local/opt/boost@1.57/include -I/usr/local/opt/qt/include -I/usr/local/opt/openssl/include -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS -isystem /opt/local/include -I/opt/local/include/db48 -I/usr/local/opt/berkeley-db@4/include -DMAC_OSX -DHAVE_QT5 -D__STDC_LIMIT_MACROS -c util/options.cc -o util/options.o +g++ -std=c++11 -I. -I./include -std=c++0x -DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -DLEVELDB_ATOMIC_PRESENT -Wstack-protector -fstack-protector-all -fPIC -g -O2 -Wall -Wextra -Wformat -Wvla -Wformat-security -Wthread-safety-analysis -Wno-unused-parameter -Wno-self-assign -Wno-unused-local-typedef -Wno-deprecated-register -Wno-implicit-fallthrough -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -I/usr/local/opt/boost@1.57/include -I/usr/local/opt/qt/include -I/usr/local/opt/openssl/include -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS -isystem /opt/local/include -I/opt/local/include/db48 -I/usr/local/opt/berkeley-db@4/include -DMAC_OSX -DHAVE_QT5 -D__STDC_LIMIT_MACROS -c util/status.cc -o util/status.o +In file included from util/status.cc:6: +In file included from ./port/port.h:14: +In file included from ./port/port_posix.h:47: +./port/atomic_pointer.h:55:3: warning: 'OSMemoryBarrier' is deprecated: first deprecated in macOS 10.12 - Use std::atomic_thread_fence() from instead [-Wdeprecated-declarations] + OSMemoryBarrier(); + ^ +/usr/include/libkern/OSAtomicDeprecated.h:749:9: note: 'OSMemoryBarrier' has been explicitly marked deprecated here +void OSMemoryBarrier( void ); + ^ +1 warning generated. +g++ -std=c++11 -I. -I./include -std=c++0x -DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -DLEVELDB_ATOMIC_PRESENT -Wstack-protector -fstack-protector-all -fPIC -g -O2 -Wall -Wextra -Wformat -Wvla -Wformat-security -Wthread-safety-analysis -Wno-unused-parameter -Wno-self-assign -Wno-unused-local-typedef -Wno-deprecated-register -Wno-implicit-fallthrough -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -I/usr/local/opt/boost@1.57/include -I/usr/local/opt/qt/include -I/usr/local/opt/openssl/include -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS -isystem /opt/local/include -I/opt/local/include/db48 -I/usr/local/opt/berkeley-db@4/include -DMAC_OSX -DHAVE_QT5 -D__STDC_LIMIT_MACROS -c port/port_posix.cc -o port/port_posix.o +In file included from port/port_posix.cc:5: +In file included from ./port/port_posix.h:47: +./port/atomic_pointer.h:55:3: warning: 'OSMemoryBarrier' is deprecated: first deprecated in macOS 10.12 - Use std::atomic_thread_fence() from instead [-Wdeprecated-declarations] + OSMemoryBarrier(); + ^ +/usr/include/libkern/OSAtomicDeprecated.h:749:9: note: 'OSMemoryBarrier' has been explicitly marked deprecated here +void OSMemoryBarrier( void ); + ^ +1 warning generated. +rm -f libleveldb.a +/usr/bin/ar -rs libleveldb.a db/builder.o db/c.o db/db_impl.o db/db_iter.o db/dbformat.o db/dumpfile.o db/filename.o db/log_reader.o db/log_writer.o db/memtable.o db/repair.o db/table_cache.o db/version_edit.o db/version_set.o db/write_batch.o table/block.o table/block_builder.o table/filter_block.o table/format.o table/iterator.o table/merger.o table/table.o table/table_builder.o table/two_level_iterator.o util/arena.o util/bloom.o util/cache.o util/coding.o util/comparator.o util/crc32c.o util/env.o util/env_posix.o util/env_win.o util/filter_policy.o util/hash.o util/histogram.o util/logging.o util/options.o util/status.o port/port_posix.o +ar: creating archive libleveldb.a +In file included from qt/bitcoinunits.cpp:8: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:71:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ranlib: file: libleveldb.a(env_win.o) has no symbols + CXX qt/libbitcoinqt_a-clientmodel.o +1 warning generated. + CXX qt/libbitcoinqt_a-csvmodelwriter.o +1 warning generated. + CXX qt/libbitcoinqt_a-guiutil.o + CXX qt/libbitcoinqt_a-intro.o +In file included from qt/blockexplorer.cpp:1: +In file included from ./qt/blockexplorer.h:6: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:31:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +In file included from qt/bitcoingui.cpp:13: +In file included from ./miner.h:9: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:96:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +In file included from qt/clientmodel.cpp:9: +In file included from ./qt/bantablemodel.h:8: +In file included from ./net.h:19: +In file included from ./sync.h:12: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/condition_variable.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/condition_variable.hpp:12: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/thread_data.hpp:12: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./net.h:458:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_inventory); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:104:1: note: expanded from here +criticalblock0 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ + CXX qt/libbitcoinqt_a-masternodelist.o +In file included from qt/guiutil.cpp:43: +In file included from /usr/local/opt/boost@1.57/include/boost/filesystem/detail/utf8_codecvt_facet.hpp:18: +/usr/local/opt/boost@1.57/include/boost/detail/utf8_codecvt_facet.hpp:176:17: warning: 'boost::filesystem::detail::utf8_codecvt_facet::do_length' hides overloaded virtual function [-Woverloaded-virtual] + virtual int do_length( + ^ +/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/__locale:1034:17: note: hidden overloaded virtual function 'std::__1::codecvt::do_length' declared here: type mismatch at 1st parameter ('std::__1::codecvt::state_type &' (aka '__mbstate_t &') vs 'const std::mbstate_t &' (aka 'const __mbstate_t &')) + virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const; + ^ +1 warning generated. +qt/guiutil.cpp:874:49: warning: 'screenGeometry' is deprecated: Use QGuiApplication::screens() [-Wdeprecated-declarations] + QRect screen = QApplication::desktop()->screenGeometry(); + ^ +/usr/local/Cellar/qt/5.13.0/lib/QtWidgets.framework/Headers/qdesktopwidget.h:79:5: note: 'screenGeometry' has been explicitly marked deprecated here + QT_DEPRECATED_X("Use QGuiApplication::screens()") const QRect screenGeometry(int screen = -1) const; + ^ +/usr/local/Cellar/qt/5.13.0/lib/QtCore.framework/Headers/qglobal.h:294:33: note: expanded from macro 'QT_DEPRECATED_X' +# define QT_DEPRECATED_X(text) Q_DECL_DEPRECATED_X(text) + ^ +/usr/local/Cellar/qt/5.13.0/lib/QtCore.framework/Headers/qcompilerdetection.h:649:55: note: expanded from macro 'Q_DECL_DEPRECATED_X' +# define Q_DECL_DEPRECATED_X(text) __attribute__ ((__deprecated__(text))) + ^ + CXX qt/libbitcoinqt_a-networkstyle.o +In file included from qt/guiutil.cpp:12: +In file included from ./qt/walletmodel.h:8: +In file included from ./qt/paymentrequestplus.h:13: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:96:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ + CXX qt/libbitcoinqt_a-notificator.o +1 warning generated. + CXX qt/libbitcoinqt_a-optionsdialog.o +1 warning generated. + CXX qt/libbitcoinqt_a-optionsmodel.o +In file included from qt/masternodelist.cpp:9: +./qt/configuremasternodepage.h:66:2: warning: control reaches end of non-void function [-Wreturn-type] + } + ^ +3 warnings generated. + CXX qt/libbitcoinqt_a-peertablemodel.o +In file included from qt/masternodelist.cpp:6: +In file included from ./qt/masternodelist.h:9: +In file included from ./masternode.h:9: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:121:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ + CXX qt/libbitcoinqt_a-platformstyle.o + CXX qt/libbitcoinqt_a-proposaldialog.o +qt/peertablemodel.cpp:86:13: warning: 'qStableSort::iterator, NodeLessThan>' is deprecated: Use std::stable_sort [-Wdeprecated-declarations] + qStableSort(cachedNodeStats.begin(), cachedNodeStats.end(), NodeLessThan(sortColumn, sortOrder)); + ^ +/usr/local/Cellar/qt/5.13.0/lib/QtCore.framework/Headers/qalgorithms.h:206:1: note: 'qStableSort::iterator, NodeLessThan>' has been explicitly marked deprecated here +QT_DEPRECATED_X("Use std::stable_sort") inline void qStableSort(RandomAccessIterator start, RandomAccessIterator end, LessThan lessThan) +^ +/usr/local/Cellar/qt/5.13.0/lib/QtCore.framework/Headers/qglobal.h:294:33: note: expanded from macro 'QT_DEPRECATED_X' +# define QT_DEPRECATED_X(text) Q_DECL_DEPRECATED_X(text) + ^ +/usr/local/Cellar/qt/5.13.0/lib/QtCore.framework/Headers/qcompilerdetection.h:649:55: note: expanded from macro 'Q_DECL_DEPRECATED_X' +# define Q_DECL_DEPRECATED_X(text) __attribute__ ((__deprecated__(text))) + ^ +In file included from qt/optionsdialog.cpp:14: +In file included from ./obfuscation.h:9: +In file included from ./main.h:17: +In file included from ./chain.h:10: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:35:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +In file included from qt/peertablemodel.cpp:5: +In file included from ./qt/peertablemodel.h:8: +In file included from ./main.h:17: +In file included from ./chain.h:10: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:121:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +2 warnings generated. + CXX qt/libbitcoinqt_a-qvalidatedlineedit.o +In file included from qt/optionsmodel.cpp:18: +In file included from ./main.h:17: +In file included from ./chain.h:10: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:41:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +2 warnings generated. + CXX qt/libbitcoinqt_a-qvaluecombobox.o + CXX qt/libbitcoinqt_a-rpcconsole.o + CXX qt/libbitcoinqt_a-splashscreen.o +1 warning generated. + CXX qt/libbitcoinqt_a-trafficgraphwidget.o +In file included from qt/proposaldialog.cpp:14: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:15:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +1 warning generated. + CXX qt/libbitcoinqt_a-startoptionsdialog.o + CXX qt/libbitcoinqt_a-startoptions.o + CXX qt/libbitcoinqt_a-startoptionsrestore.o + CXX qt/libbitcoinqt_a-startoptionssort.o +qt/startoptionsrestore.cpp:18:28: warning: field 'wordList' will be initialized after field 'ui' [-Wreorder] + : QWidget(parent), wordList(_wordList), ui(new Ui::StartOptionsRestore) + ^ +qt/rpcconsole.cpp:443:43: warning: 'QSignalMapper' is deprecated [-Wdeprecated-declarations] + QSignalMapper* signalMapper = new QSignalMapper(this); + ^ +/usr/local/Cellar/qt/5.13.0/lib/QtCore.framework/Headers/qsignalmapper.h:56:5: note: 'QSignalMapper' has been explicitly marked deprecated here + QT_DEPRECATED explicit QSignalMapper(QObject *parent = nullptr); + ^ +/usr/local/Cellar/qt/5.13.0/lib/QtCore.framework/Headers/qglobal.h:292:25: note: expanded from macro 'QT_DEPRECATED' +# define QT_DEPRECATED Q_DECL_DEPRECATED + ^ +/usr/local/Cellar/qt/5.13.0/lib/QtCore.framework/Headers/qcompilerdetection.h:233:45: note: expanded from macro 'Q_DECL_DEPRECATED' +# define Q_DECL_DEPRECATED __attribute__ ((__deprecated__)) + ^ +1 warning generated. + CXX qt/libbitcoinqt_a-startoptionsrevealed.o +In file included from qt/rpcconsole.cpp:7: +In file included from ./qt/rpcconsole.h:9: +In file included from ./qt/peertablemodel.h:8: +In file included from ./main.h:17: +In file included from ./chain.h:10: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:31:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +qt/splashscreen.cpp:59:29: warning: 'width' is deprecated: Use QFontMetrics::horizontalAdvance [-Wdeprecated-declarations] + int titleTextWidth = fm.width(titleText); + ^ +/usr/local/Cellar/qt/5.13.0/lib/QtGui.framework/Headers/qfontmetrics.h:107:5: note: 'width' has been explicitly marked deprecated here + QT_DEPRECATED_X("Use QFontMetrics::horizontalAdvance") + ^ +/usr/local/Cellar/qt/5.13.0/lib/QtCore.framework/Headers/qglobal.h:294:33: note: expanded from macro 'QT_DEPRECATED_X' +# define QT_DEPRECATED_X(text) Q_DECL_DEPRECATED_X(text) + ^ +/usr/local/Cellar/qt/5.13.0/lib/QtCore.framework/Headers/qcompilerdetection.h:649:55: note: expanded from macro 'Q_DECL_DEPRECATED_X' +# define Q_DECL_DEPRECATED_X(text) __attribute__ ((__deprecated__(text))) + ^ +qt/splashscreen.cpp:100:35: warning: 'screenGeometry' is deprecated: Use QGuiApplication::screens() [-Wdeprecated-declarations] + move(QApplication::desktop()->screenGeometry().center() - r.center()); + ^ +/usr/local/Cellar/qt/5.13.0/lib/QtWidgets.framework/Headers/qdesktopwidget.h:79:5: note: 'screenGeometry' has been explicitly marked deprecated here + QT_DEPRECATED_X("Use QGuiApplication::screens()") const QRect screenGeometry(int screen = -1) const; + ^ +/usr/local/Cellar/qt/5.13.0/lib/QtCore.framework/Headers/qglobal.h:294:33: note: expanded from macro 'QT_DEPRECATED_X' +# define QT_DEPRECATED_X(text) Q_DECL_DEPRECATED_X(text) + ^ +/usr/local/Cellar/qt/5.13.0/lib/QtCore.framework/Headers/qcompilerdetection.h:649:55: note: expanded from macro 'Q_DECL_DEPRECATED_X' +# define Q_DECL_DEPRECATED_X(text) __attribute__ ((__deprecated__(text))) + ^ +1 warning generated. + CXX qt/libbitcoinqt_a-startoptionsmain.o +In file included from qt/splashscreen.cpp:17: +In file included from ./wallet/wallet.h:12: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:2:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ + CXX qt/libbitcoinqt_a-utilitydialog.o + CXX qt/libbitcoinqt_a-addressbookpage.o +2 warnings generated. + CXX qt/libbitcoinqt_a-configuremasternodepage.o + CXX qt/libbitcoinqt_a-addresstablemodel.o + CXX qt/libbitcoinqt_a-askpassphrasedialog.o + CXX qt/libbitcoinqt_a-bip38tooldialog.o +3 warnings generated. + CXX qt/libbitcoinqt_a-coincontroldialog.o +In file included from qt/configuremasternodepage.cpp:10: +./qt/configuremasternodepage.h:66:2: warning: control reaches end of non-void function [-Wreturn-type] + } + ^ +In file included from qt/configuremasternodepage.cpp:10: +In file included from ./qt/configuremasternodepage.h:9: +In file included from ./qt/masternodelist.h:9: +In file included from ./masternode.h:9: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:121:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +qt/addresstablemodel.cpp:99:9: warning: 'qSort::iterator, AddressTableEntryLessThan>' is deprecated: Use std::sort [-Wdeprecated-declarations] + qSort(cachedAddressTable.begin(), cachedAddressTable.end(), AddressTableEntryLessThan()); + ^ +/usr/local/Cellar/qt/5.13.0/lib/QtCore.framework/Headers/qalgorithms.h:181:1: note: 'qSort::iterator, AddressTableEntryLessThan>' has been explicitly marked deprecated here +QT_DEPRECATED_X("Use std::sort") inline void qSort(RandomAccessIterator start, RandomAccessIterator end, LessThan lessThan) +^ +/usr/local/Cellar/qt/5.13.0/lib/QtCore.framework/Headers/qglobal.h:294:33: note: expanded from macro 'QT_DEPRECATED_X' +# define QT_DEPRECATED_X(text) Q_DECL_DEPRECATED_X(text) + ^ +/usr/local/Cellar/qt/5.13.0/lib/QtCore.framework/Headers/qcompilerdetection.h:649:55: note: expanded from macro 'Q_DECL_DEPRECATED_X' +# define Q_DECL_DEPRECATED_X(text) __attribute__ ((__deprecated__(text))) + ^ +qt/addresstablemodel.cpp:105:52: warning: 'qLowerBound::iterator, QString, AddressTableEntryLessThan>' is deprecated: Use std::lower_bound [-Wdeprecated-declarations] + QList::iterator lower = qLowerBound( + ^ +/usr/local/Cellar/qt/5.13.0/lib/QtCore.framework/Headers/qalgorithms.h:247:1: note: 'qLowerBound::iterator, QString, AddressTableEntryLessThan>' has been explicitly marked deprecated here +QT_DEPRECATED_X("Use std::lower_bound") Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan) +^ +/usr/local/Cellar/qt/5.13.0/lib/QtCore.framework/Headers/qglobal.h:294:33: note: expanded from macro 'QT_DEPRECATED_X' +# define QT_DEPRECATED_X(text) Q_DECL_DEPRECATED_X(text) + ^ +/usr/local/Cellar/qt/5.13.0/lib/QtCore.framework/Headers/qcompilerdetection.h:649:55: note: expanded from macro 'Q_DECL_DEPRECATED_X' +# define Q_DECL_DEPRECATED_X(text) __attribute__ ((__deprecated__(text))) + ^ +qt/addresstablemodel.cpp:107:52: warning: 'qUpperBound::iterator, QString, AddressTableEntryLessThan>' is deprecated: Use std::upper_bound [-Wdeprecated-declarations] + QList::iterator upper = qUpperBound( + ^ +/usr/local/Cellar/qt/5.13.0/lib/QtCore.framework/Headers/qalgorithms.h:280:1: note: 'qUpperBound::iterator, QString, AddressTableEntryLessThan>' has been explicitly marked deprecated here +QT_DEPRECATED_X("Use std::upper_bound") Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan) +^ +/usr/local/Cellar/qt/5.13.0/lib/QtCore.framework/Headers/qglobal.h:294:33: note: expanded from macro 'QT_DEPRECATED_X' +# define QT_DEPRECATED_X(text) Q_DECL_DEPRECATED_X(text) + ^ +/usr/local/Cellar/qt/5.13.0/lib/QtCore.framework/Headers/qcompilerdetection.h:649:55: note: expanded from macro 'Q_DECL_DEPRECATED_X' +# define Q_DECL_DEPRECATED_X(text) __attribute__ ((__deprecated__(text))) + ^ +qt/addresstablemodel.cpp:148:52: warning: 'qLowerBound::iterator, QString, AddressTableEntryLessThan>' is deprecated: Use std::lower_bound [-Wdeprecated-declarations] + QList::iterator lower = qLowerBound( + ^ +/usr/local/Cellar/qt/5.13.0/lib/QtCore.framework/Headers/qalgorithms.h:247:1: note: 'qLowerBound::iterator, QString, AddressTableEntryLessThan>' has been explicitly marked deprecated here +QT_DEPRECATED_X("Use std::lower_bound") Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan) +^ +/usr/local/Cellar/qt/5.13.0/lib/QtCore.framework/Headers/qglobal.h:294:33: note: expanded from macro 'QT_DEPRECATED_X' +# define QT_DEPRECATED_X(text) Q_DECL_DEPRECATED_X(text) + ^ +/usr/local/Cellar/qt/5.13.0/lib/QtCore.framework/Headers/qcompilerdetection.h:649:55: note: expanded from macro 'Q_DECL_DEPRECATED_X' +# define Q_DECL_DEPRECATED_X(text) __attribute__ ((__deprecated__(text))) + ^ +qt/addresstablemodel.cpp:150:52: warning: 'qUpperBound::iterator, QString, AddressTableEntryLessThan>' is deprecated: Use std::upper_bound [-Wdeprecated-declarations] + QList::iterator upper = qUpperBound( + ^ +/usr/local/Cellar/qt/5.13.0/lib/QtCore.framework/Headers/qalgorithms.h:280:1: note: 'qUpperBound::iterator, QString, AddressTableEntryLessThan>' has been explicitly marked deprecated here +QT_DEPRECATED_X("Use std::upper_bound") Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan) +^ +/usr/local/Cellar/qt/5.13.0/lib/QtCore.framework/Headers/qglobal.h:294:33: note: expanded from macro 'QT_DEPRECATED_X' +# define QT_DEPRECATED_X(text) Q_DECL_DEPRECATED_X(text) + ^ +/usr/local/Cellar/qt/5.13.0/lib/QtCore.framework/Headers/qcompilerdetection.h:649:55: note: expanded from macro 'Q_DECL_DEPRECATED_X' +# define Q_DECL_DEPRECATED_X(text) __attribute__ ((__deprecated__(text))) + ^ +In file included from qt/askpassphrasedialog.cpp:12: +In file included from ./qt/walletmodel.h:8: +In file included from ./qt/paymentrequestplus.h:13: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:94:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +In file included from qt/addresstablemodel.cpp:10: +In file included from ./qt/walletmodel.h:8: +In file included from ./qt/paymentrequestplus.h:13: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:49:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +In file included from qt/bip38tooldialog.cpp:12: +In file included from ./qt/walletmodel.h:8: +In file included from ./qt/paymentrequestplus.h:13: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:94:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +In file included from qt/coincontroldialog.cpp:15: +In file included from ./qt/walletmodel.h:8: +In file included from ./qt/paymentrequestplus.h:13: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:31:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +2 warnings generated. +1 warning generated. + CXX qt/libbitcoinqt_a-coincontroltreewidget.o + CXX qt/libbitcoinqt_a-obfuscationconfig.o +1 warning generated. +6 warnings generated. + CXX qt/libbitcoinqt_a-editaddressdialog.o + CXX qt/libbitcoinqt_a-multisenddialog.o + CXX qt/libbitcoinqt_a-multisigdialog.o + CXX qt/libbitcoinqt_a-openuridialog.o +1 warning generated. + CXX qt/libbitcoinqt_a-overviewpage.o +In file included from qt/obfuscationconfig.cpp:8: +In file included from ./qt/walletmodel.h:8: +In file included from ./qt/paymentrequestplus.h:13: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:49:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +In file included from qt/multisenddialog.cpp:4: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:106:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +1 warning generated. +In file included from qt/multisigdialog.cpp:5: +In file included from ./qt/multisigdialog.h:16: +In file included from ./qt/walletmodel.h:8: +In file included from ./qt/paymentrequestplus.h:13: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:85:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ + CXX qt/libbitcoinqt_a-paymentrequestplus.o +In file included from qt/openuridialog.cpp:12: +In file included from ./qt/walletmodel.h:8: +In file included from ./qt/paymentrequestplus.h:13: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:79:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +In file included from qt/overviewpage.cpp:16: +In file included from ./obfuscation.h:9: +In file included from ./main.h:17: +In file included from ./chain.h:10: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:15:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +1 warning generated. + CXX qt/libbitcoinqt_a-paymentserver.o +1 warning generated. + CXX qt/libbitcoinqt_a-columnalignedlayout.o +In file included from qt/paymentrequestplus.cpp:10: +In file included from ./qt/paymentrequestplus.h:13: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:31:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ + CXX qt/libbitcoinqt_a-proposalfilterproxy.o +1 warning generated. +1 warning generated. + CXX qt/libbitcoinqt_a-proposallist.o + CXX qt/libbitcoinqt_a-proposalrecord.o + CXX qt/libbitcoinqt_a-proposaltablemodel.o +qt/paymentserver.cpp:138:21: warning: 'setDefaultCaCertificates' is deprecated [-Wdeprecated-declarations] + QSslSocket::setDefaultCaCertificates(certList); + ^ +/usr/local/Cellar/qt/5.13.0/lib/QtNetwork.framework/Headers/qsslsocket.h:180:5: note: 'setDefaultCaCertificates' has been explicitly marked deprecated here + QT_DEPRECATED static void setDefaultCaCertificates(const QList &certificates); + ^ +/usr/local/Cellar/qt/5.13.0/lib/QtCore.framework/Headers/qglobal.h:292:25: note: expanded from macro 'QT_DEPRECATED' +# define QT_DEPRECATED Q_DECL_DEPRECATED + ^ +/usr/local/Cellar/qt/5.13.0/lib/QtCore.framework/Headers/qcompilerdetection.h:233:45: note: expanded from macro 'Q_DECL_DEPRECATED' +# define Q_DECL_DEPRECATED __attribute__ ((__deprecated__)) + ^ +qt/paymentserver.cpp:140:32: warning: 'systemCaCertificates' is deprecated: Use QSslConfiguration::systemCaCertificates() [-Wdeprecated-declarations] + certList = QSslSocket::systemCaCertificates(); + ^ +/usr/local/Cellar/qt/5.13.0/lib/QtNetwork.framework/Headers/qsslsocket.h:182:5: note: 'systemCaCertificates' has been explicitly marked deprecated here + QT_DEPRECATED_X("Use QSslConfiguration::systemCaCertificates()") static QList systemCaCertificates(); + ^ +/usr/local/Cellar/qt/5.13.0/lib/QtCore.framework/Headers/qglobal.h:294:33: note: expanded from macro 'QT_DEPRECATED_X' +# define QT_DEPRECATED_X(text) Q_DECL_DEPRECATED_X(text) + ^ +/usr/local/Cellar/qt/5.13.0/lib/QtCore.framework/Headers/qcompilerdetection.h:649:55: note: expanded from macro 'Q_DECL_DEPRECATED_X' +# define Q_DECL_DEPRECATED_X(text) __attribute__ ((__deprecated__(text))) + ^ +1 warning generated. + CXX qt/libbitcoinqt_a-receivecoinsdialog.o +In file included from qt/paymentserver.cpp:8: +In file included from ./qt/paymentserver.h:35: +In file included from ./qt/paymentrequestplus.h:13: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:31:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +qt/proposalfilterproxy.cpp:45:9: warning: unused variable 'votedNeeded' [-Wunused-variable] + int votedNeeded = index.data(ProposalTableModel::VotesNeededRole).toInt(); + ^ +In file included from qt/proposalfilterproxy.cpp:8: +In file included from ./qt/proposaltablemodel.h:22: +In file included from ./masternode-budget.h:9: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:96:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +In file included from qt/proposallist.cpp:7: +In file included from ./activemasternode.h:10: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:121:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +2 warnings generated. + CXX qt/libbitcoinqt_a-privacydialog.o +In file included from qt/proposaltablemodel.cpp:7: +In file included from ./qt/proposaltablemodel.h:22: +In file included from ./masternode-budget.h:9: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:41:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +3 warnings generated. + CXX qt/libbitcoinqt_a-receiverequestdialog.o +qt/receivecoinsdialog.cpp:246:81: warning: 'child' is deprecated: Use QAbstractItemModel::index [-Wdeprecated-declarations] + GUIUtil::setClipboard(model->getRecentRequestsTableModel()->data(firstIndex.child(firstIndex.row(), column), Qt::EditRole).toString()); + ^ +/usr/local/Cellar/qt/5.13.0/lib/QtCore.framework/Headers/qabstractitemmodel.h:71:5: note: 'child' has been explicitly marked deprecated here + QT_DEPRECATED_X("Use QAbstractItemModel::index") inline QModelIndex child(int row, int column) const; + ^ +/usr/local/Cellar/qt/5.13.0/lib/QtCore.framework/Headers/qglobal.h:294:33: note: expanded from macro 'QT_DEPRECATED_X' +# define QT_DEPRECATED_X(text) Q_DECL_DEPRECATED_X(text) + ^ +/usr/local/Cellar/qt/5.13.0/lib/QtCore.framework/Headers/qcompilerdetection.h:649:55: note: expanded from macro 'Q_DECL_DEPRECATED_X' +# define Q_DECL_DEPRECATED_X(text) __attribute__ ((__deprecated__(text))) + ^ +In file included from qt/receivecoinsdialog.cpp:13: +In file included from ./qt/receiverequestdialog.h:8: +In file included from ./qt/walletmodel.h:8: +In file included from ./qt/paymentrequestplus.h:13: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:94:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +1 warning generated. + CXX qt/libbitcoinqt_a-recentrequeststablemodel.o +1 warning generated. + CXX qt/libbitcoinqt_a-sendcoinsdialog.o +2 warnings generated. + CXX qt/libbitcoinqt_a-sendcoinsentry.o +In file included from qt/receiverequestdialog.cpp:5: +In file included from ./qt/receiverequestdialog.h:8: +In file included from ./qt/walletmodel.h:8: +In file included from ./qt/paymentrequestplus.h:13: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:31:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +In file included from qt/privacydialog.cpp:14: +In file included from ./qt/sendcoinsentry.h:8: +In file included from ./qt/walletmodel.h:8: +In file included from ./qt/paymentrequestplus.h:13: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:109:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +qt/recentrequeststablemodel.cpp:199:5: warning: 'qSort::iterator, RecentRequestEntryLessThan>' is deprecated: Use std::sort [-Wdeprecated-declarations] + qSort(list.begin(), list.end(), RecentRequestEntryLessThan(column, order)); + ^ +/usr/local/Cellar/qt/5.13.0/lib/QtCore.framework/Headers/qalgorithms.h:181:1: note: 'qSort::iterator, RecentRequestEntryLessThan>' has been explicitly marked deprecated here +QT_DEPRECATED_X("Use std::sort") inline void qSort(RandomAccessIterator start, RandomAccessIterator end, LessThan lessThan) +^ +/usr/local/Cellar/qt/5.13.0/lib/QtCore.framework/Headers/qglobal.h:294:33: note: expanded from macro 'QT_DEPRECATED_X' +# define QT_DEPRECATED_X(text) Q_DECL_DEPRECATED_X(text) + ^ +/usr/local/Cellar/qt/5.13.0/lib/QtCore.framework/Headers/qcompilerdetection.h:649:55: note: expanded from macro 'Q_DECL_DEPRECATED_X' +# define Q_DECL_DEPRECATED_X(text) __attribute__ ((__deprecated__(text))) + ^ +In file included from qt/recentrequeststablemodel.cpp:5: +In file included from ./qt/recentrequeststablemodel.h:8: +In file included from ./qt/walletmodel.h:8: +In file included from ./qt/paymentrequestplus.h:13: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:31:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +1 warning generated. + CXX qt/libbitcoinqt_a-signverifymessagedialog.o +In file included from qt/sendcoinsdialog.cpp:7: +In file included from ./qt/sendcoinsdialog.h:8: +In file included from ./qt/walletmodel.h:8: +In file included from ./qt/paymentrequestplus.h:13: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:31:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +In file included from qt/sendcoinsentry.cpp:8: +In file included from ./qt/sendcoinsentry.h:8: +In file included from ./qt/walletmodel.h:8: +In file included from ./qt/paymentrequestplus.h:13: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:31:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +2 warnings generated. + CXX qt/libbitcoinqt_a-transactiondesc.o +1 warning generated. + CXX qt/libbitcoinqt_a-transactiondescdialog.o +1 warning generated. + CXX qt/libbitcoinqt_a-transactionfilterproxy.o +1 warning generated. + CXX qt/libbitcoinqt_a-transactionrecord.o +In file included from qt/signverifymessagedialog.cpp:13: +In file included from ./qt/walletmodel.h:8: +In file included from ./qt/paymentrequestplus.h:13: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:15:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ + CXX qt/libbitcoinqt_a-transactiontablemodel.o + CXX qt/libbitcoinqt_a-transactionview.o +In file included from qt/transactiondesc.cpp:11: +In file included from ./qt/paymentserver.h:35: +In file included from ./qt/paymentrequestplus.h:13: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:58:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +1 warning generated. + CXX qt/libbitcoinqt_a-walletframe.o +In file included from qt/transactionrecord.cpp:9: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:31:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +qt/transactiontablemodel.cpp:96:52: warning: 'qLowerBound::iterator, uint256, TxLessThan>' is deprecated: Use std::lower_bound [-Wdeprecated-declarations] + QList::iterator lower = qLowerBound( + ^ +/usr/local/Cellar/qt/5.13.0/lib/QtCore.framework/Headers/qalgorithms.h:247:1: note: 'qLowerBound::iterator, uint256, TxLessThan>' has been explicitly marked deprecated here +QT_DEPRECATED_X("Use std::lower_bound") Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan) +^ +/usr/local/Cellar/qt/5.13.0/lib/QtCore.framework/Headers/qglobal.h:294:33: note: expanded from macro 'QT_DEPRECATED_X' +# define QT_DEPRECATED_X(text) Q_DECL_DEPRECATED_X(text) + ^ +/usr/local/Cellar/qt/5.13.0/lib/QtCore.framework/Headers/qcompilerdetection.h:649:55: note: expanded from macro 'Q_DECL_DEPRECATED_X' +# define Q_DECL_DEPRECATED_X(text) __attribute__ ((__deprecated__(text))) + ^ +qt/transactiontablemodel.cpp:98:52: warning: 'qUpperBound::iterator, uint256, TxLessThan>' is deprecated: Use std::upper_bound [-Wdeprecated-declarations] + QList::iterator upper = qUpperBound( + ^ +/usr/local/Cellar/qt/5.13.0/lib/QtCore.framework/Headers/qalgorithms.h:280:1: note: 'qUpperBound::iterator, uint256, TxLessThan>' has been explicitly marked deprecated here +QT_DEPRECATED_X("Use std::upper_bound") Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan) +^ +/usr/local/Cellar/qt/5.13.0/lib/QtCore.framework/Headers/qglobal.h:294:33: note: expanded from macro 'QT_DEPRECATED_X' +# define QT_DEPRECATED_X(text) Q_DECL_DEPRECATED_X(text) + ^ +/usr/local/Cellar/qt/5.13.0/lib/QtCore.framework/Headers/qcompilerdetection.h:649:55: note: expanded from macro 'Q_DECL_DEPRECATED_X' +# define Q_DECL_DEPRECATED_X(text) __attribute__ ((__deprecated__(text))) + ^ +qt/transactionview.cpp:177:34: warning: 'QSignalMapper' is deprecated [-Wdeprecated-declarations] + mapperThirdPartyTxUrls = new QSignalMapper(this); + ^ +/usr/local/Cellar/qt/5.13.0/lib/QtCore.framework/Headers/qsignalmapper.h:56:5: note: 'QSignalMapper' has been explicitly marked deprecated here + QT_DEPRECATED explicit QSignalMapper(QObject *parent = nullptr); + ^ +/usr/local/Cellar/qt/5.13.0/lib/QtCore.framework/Headers/qglobal.h:292:25: note: expanded from macro 'QT_DEPRECATED' +# define QT_DEPRECATED Q_DECL_DEPRECATED + ^ +/usr/local/Cellar/qt/5.13.0/lib/QtCore.framework/Headers/qcompilerdetection.h:233:45: note: expanded from macro 'Q_DECL_DEPRECATED' +# define Q_DECL_DEPRECATED __attribute__ ((__deprecated__)) + ^ +In file included from qt/transactiontablemodel.cpp:13: +In file included from ./qt/walletmodel.h:8: +In file included from ./qt/paymentrequestplus.h:13: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:31:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +In file included from qt/transactionview.cpp:17: +In file included from ./qt/walletmodel.h:8: +In file included from ./qt/paymentrequestplus.h:13: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:96:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +1 warning generated. + CXX qt/libbitcoinqt_a-walletmodel.o +1 warning generated. + CXX qt/libbitcoinqt_a-walletmodeltransaction.o +2 warnings generated. +In file included from qt/walletframe.cpp:8: +In file included from ./qt/walletview.h:9: +In file included from ./qt/masternodelist.h:9: +In file included from ./masternode.h:9: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + CXX qt/libbitcoinqt_a-walletview.o + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:121:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +3 warnings generated. + CXX qt/libbitcoinqt_a-zphrcontroldialog.o +1 warning generated. + CXX qt/libbitcoinqt_a-moc_addressbookpage.o +In file included from qt/walletmodeltransaction.cpp:5: +In file included from ./qt/walletmodeltransaction.h:8: +In file included from ./qt/walletmodel.h:8: +In file included from ./qt/paymentrequestplus.h:13: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:31:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +In file included from qt/walletmodel.cpp:7: +In file included from ./qt/walletmodel.h:8: +In file included from ./qt/paymentrequestplus.h:13: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:31:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ + CXX qt/libbitcoinqt_a-moc_configuremasternodepage.o +1 warning generated. + CXX qt/libbitcoinqt_a-moc_addresstablemodel.o +In file included from qt/walletview.cpp:5: +In file included from ./qt/walletview.h:9: +In file included from ./qt/masternodelist.h:9: +In file included from ./masternode.h:9: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:121:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ + CXX qt/libbitcoinqt_a-moc_askpassphrasedialog.o + CXX qt/libbitcoinqt_a-moc_startoptionsdialog.o +In file included from qt/zphrcontroldialog.cpp:5: +In file included from ./qt/zphrcontroldialog.h:10: +In file included from ./primitives/zerocoin.h:12: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:106:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +In file included from qt/moc_configuremasternodepage.cpp:9: +./qt/configuremasternodepage.h:66:2: warning: control reaches end of non-void function [-Wreturn-type] + } + ^ + CXX qt/libbitcoinqt_a-moc_startoptions.o +In file included from qt/moc_configuremasternodepage.cpp:9: +In file included from ./qt/configuremasternodepage.h:9: +In file included from ./qt/masternodelist.h:9: +In file included from ./masternode.h:9: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:121:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +1 warning generated. + CXX qt/libbitcoinqt_a-moc_startoptionsrestore.o + CXX qt/libbitcoinqt_a-moc_startoptionssort.o + CXX qt/libbitcoinqt_a-moc_startoptionsrevealed.o +2 warnings generated. + CXX qt/libbitcoinqt_a-moc_startoptionsmain.o +1 warning generated. + CXX qt/libbitcoinqt_a-moc_bantablemodel.o + CXX qt/libbitcoinqt_a-moc_bip38tooldialog.o + CXX qt/libbitcoinqt_a-moc_bitcoinaddressvalidator.o + CXX qt/libbitcoinqt_a-moc_bitcoinamountfield.o + CXX qt/libbitcoinqt_a-moc_bitcoingui.o + CXX qt/libbitcoinqt_a-moc_bitcoinunits.o + CXX qt/libbitcoinqt_a-moc_blockexplorer.o +In file included from qt/moc_bantablemodel.cpp:9: +In file included from ./qt/bantablemodel.h:8: +In file included from ./net.h:19: +In file included from ./sync.h:12: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/condition_variable.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/condition_variable.hpp:12: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/thread_data.hpp:12: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./net.h:458:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_inventory); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:143:1: note: expanded from here +criticalblock0 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +1 warning generated. + CXX qt/libbitcoinqt_a-moc_clientmodel.o + CXX qt/libbitcoinqt_a-moc_coincontroldialog.o + CXX qt/libbitcoinqt_a-moc_coincontroltreewidget.o + CXX qt/libbitcoinqt_a-moc_csvmodelwriter.o +1 warning generated. + CXX qt/libbitcoinqt_a-moc_obfuscationconfig.o + CXX qt/libbitcoinqt_a-moc_editaddressdialog.o + CXX qt/libbitcoinqt_a-moc_guiutil.o + CXX qt/libbitcoinqt_a-moc_intro.o +In file included from qt/moc_blockexplorer.cpp:9: +In file included from ./qt/blockexplorer.h:6: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:31:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ + CXX qt/libbitcoinqt_a-moc_macdockiconhandler.o + CXX qt/libbitcoinqt_a-moc_macnotificationhandler.o +1 warning generated. + CXX qt/libbitcoinqt_a-moc_masternodelist.o + CXX qt/libbitcoinqt_a-moc_multisenddialog.o + CXX qt/libbitcoinqt_a-moc_multisigdialog.o + CXX qt/libbitcoinqt_a-moc_notificator.o + CXX qt/libbitcoinqt_a-moc_openuridialog.o + CXX qt/libbitcoinqt_a-moc_optionsdialog.o + CXX qt/libbitcoinqt_a-moc_optionsmodel.o + CXX qt/libbitcoinqt_a-moc_overviewpage.o + CXX qt/libbitcoinqt_a-moc_peertablemodel.o + CXX qt/libbitcoinqt_a-moc_paymentserver.o + CXX qt/libbitcoinqt_a-moc_columnalignedlayout.o + CXX qt/libbitcoinqt_a-moc_proposaldialog.o +In file included from qt/moc_masternodelist.cpp:9: +In file included from ./qt/masternodelist.h:9: +In file included from ./masternode.h:9: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:121:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +In file included from qt/moc_peertablemodel.cpp:9: +In file included from ./qt/peertablemodel.h:8: +In file included from ./main.h:17: +In file included from ./chain.h:10: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:121:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +In file included from qt/moc_multisigdialog.cpp:9: +In file included from ./qt/multisigdialog.h:16: +In file included from ./qt/walletmodel.h:8: +In file included from ./qt/paymentrequestplus.h:13: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:85:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +1 warning generated. + CXX qt/libbitcoinqt_a-moc_proposalfilterproxy.o +1 warning generated. + CXX qt/libbitcoinqt_a-moc_proposaltablemodel.o + CXX qt/libbitcoinqt_a-moc_proposallist.o +1 warning generated. +In file included from qt/moc_paymentserver.cpp:9: +In file included from ./qt/paymentserver.h:35: +In file included from ./qt/paymentrequestplus.h:13: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:31:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ + CXX qt/libbitcoinqt_a-moc_qvalidatedlineedit.o +In file included from qt/moc_proposaldialog.cpp:9: +In file included from ./qt/proposaldialog.h:9: +In file included from ./qt/proposallist.h:12: +In file included from ./qt/proposaltablemodel.h:22: +In file included from ./masternode-budget.h:9: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:41:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ + CXX qt/libbitcoinqt_a-moc_qvaluecombobox.o +1 warning generated. + CXX qt/libbitcoinqt_a-moc_receivecoinsdialog.o + CXX qt/libbitcoinqt_a-moc_privacydialog.o +1 warning generated. + CXX qt/libbitcoinqt_a-moc_receiverequestdialog.o +In file included from qt/moc_proposaltablemodel.cpp:9: +In file included from ./qt/proposaltablemodel.h:22: +In file included from ./masternode-budget.h:9: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:41:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ + CXX qt/libbitcoinqt_a-moc_recentrequeststablemodel.o +In file included from qt/moc_proposallist.cpp:9: +In file included from ./qt/proposallist.h:12: +In file included from ./qt/proposaltablemodel.h:22: +In file included from ./masternode-budget.h:9: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:41:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ + CXX qt/libbitcoinqt_a-moc_rpcconsole.o +1 warning generated. + CXX qt/libbitcoinqt_a-moc_sendcoinsdialog.o +1 warning generated. + CXX qt/libbitcoinqt_a-moc_sendcoinsentry.o +In file included from qt/moc_receiverequestdialog.cpp:9: +In file included from ./qt/receiverequestdialog.h:8: +In file included from ./qt/walletmodel.h:8: +In file included from ./qt/paymentrequestplus.h:13: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:31:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +In file included from qt/moc_rpcconsole.cpp:9: +In file included from ./qt/rpcconsole.h:9: +In file included from ./qt/peertablemodel.h:8: +In file included from ./main.h:17: +In file included from ./chain.h:10: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:31:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +1 warning generated. + CXX qt/libbitcoinqt_a-moc_signverifymessagedialog.o +In file included from qt/moc_recentrequeststablemodel.cpp:9: +In file included from ./qt/recentrequeststablemodel.h:8: +In file included from ./qt/walletmodel.h:8: +In file included from ./qt/paymentrequestplus.h:13: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:31:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +1 warning generated. + CXX qt/libbitcoinqt_a-moc_splashscreen.o + CXX qt/libbitcoinqt_a-moc_trafficgraphwidget.o +In file included from qt/moc_sendcoinsdialog.cpp:9: +In file included from ./qt/sendcoinsdialog.h:8: +In file included from ./qt/walletmodel.h:8: +In file included from ./qt/paymentrequestplus.h:13: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:31:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +1 warning generated. + CXX qt/libbitcoinqt_a-moc_transactiondesc.o + CXX qt/libbitcoinqt_a-moc_transactiondescdialog.o + CXX qt/libbitcoinqt_a-moc_transactionfilterproxy.o +In file included from qt/moc_sendcoinsentry.cpp:9: +In file included from ./qt/sendcoinsentry.h:8: +In file included from ./qt/walletmodel.h:8: +In file included from ./qt/paymentrequestplus.h:13: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:31:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ + CXX qt/libbitcoinqt_a-moc_transactiontablemodel.o + CXX qt/libbitcoinqt_a-moc_transactionview.o + CXX qt/libbitcoinqt_a-moc_utilitydialog.o +1 warning generated. + CXX qt/libbitcoinqt_a-moc_walletframe.o + CXX qt/libbitcoinqt_a-moc_walletmodel.o +1 warning generated. + CXX qt/libbitcoinqt_a-moc_walletview.o + CXX qt/libbitcoinqt_a-moc_zphrcontroldialog.o + CXX qt/libbitcoinqt_a-paymentrequest.pb.o + CXX qt/libbitcoinqt_a-qrc_phore.o + CXX qt/libbitcoinqt_a-qrc_phore_locale.o + AR libbitcoin_wallet.a + CXXLD phore-cli + CXXLD phore-tx + CXXLD phored +In file included from qt/moc_walletmodel.cpp:9: +In file included from ./qt/walletmodel.h:8: +In file included from ./qt/paymentrequestplus.h:13: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:31:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +In file included from qt/moc_walletview.cpp:9: +In file included from ./qt/walletview.h:9: +In file included from ./qt/masternodelist.h:9: +In file included from ./masternode.h:9: +In file included from ./base58.h:17: +In file included from ./chainparams.h:13: +In file included from ./primitives/block.h:11: +In file included from ./keystore.h:10: +In file included from ./wallet/hdchain.h:6: +In file included from ./key.h:11: +In file included from ./allocators.h:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/mutex.hpp:16: +In file included from /usr/local/opt/boost@1.57/include/boost/thread/pthread/mutex.hpp:15: +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:348:5: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis] + } + ^ +./sync.h:125:18: note: in instantiation of member function 'boost::unique_lock::lock' requested here + lock.lock(); + ^ +./sync.h:146:13: note: in instantiation of member function 'CMutexLock::Enter' requested here + Enter(pszName, pszFile, nLine); + ^ +./keystore.h:85:13: note: in instantiation of member function 'CMutexLock::CMutexLock' requested here + LOCK(cs_KeyStore); + ^ +./sync.h:177:33: note: expanded from macro 'LOCK' +#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__) + ^ +./sync.h:175:22: note: expanded from macro 'PASTE2' +#define PASTE2(x, y) PASTE(x, y) + ^ +./sync.h:174:21: note: expanded from macro 'PASTE' +#define PASTE(x, y) x ## y + ^ +:121:1: note: expanded from here +criticalblock1 +^ +/usr/local/opt/boost@1.57/include/boost/thread/lock_types.hpp:346:10: note: mutex acquired here + m->lock(); + ^ +1 warning generated. +1 warning generated. + AR qt/libbitcoinqt.a + OBJCXXLD qt/phore-qt +ld: warning: text-based stub file /System/Library/Frameworks//Foundation.framework/Foundation.tbd and library file /System/Library/Frameworks//Foundation.framework/Foundation are out of sync. Falling back to library file for linking. +ld: warning: text-based stub file /System/Library/Frameworks//ApplicationServices.framework/ApplicationServices.tbd and library file /System/Library/Frameworks//ApplicationServices.framework/ApplicationServices are out of sync. Falling back to library file for linking. +ld: warning: text-based stub file /System/Library/Frameworks//AppKit.framework/AppKit.tbd and library file /System/Library/Frameworks//AppKit.framework/AppKit are out of sync. Falling back to library file for linking. +ld: warning: text-based stub file /System/Library/Frameworks//CoreFoundation.framework/Versions/A/CoreFoundation.tbd and library file /System/Library/Frameworks//CoreFoundation.framework/Versions/A/CoreFoundation are out of sync. Falling back to library file for linking. +ld: warning: text-based stub file /System/Library/Frameworks//CoreGraphics.framework/Versions/A/CoreGraphics.tbd and library file /System/Library/Frameworks//CoreGraphics.framework/Versions/A/CoreGraphics are out of sync. Falling back to library file for linking. +ld: warning: text-based stub file /System/Library/Frameworks//CoreText.framework/Versions/A/CoreText.tbd and library file /System/Library/Frameworks//CoreText.framework/Versions/A/CoreText are out of sync. Falling back to library file for linking. +ld: warning: text-based stub file /System/Library/Frameworks//ImageIO.framework/Versions/A/ImageIO.tbd and library file /System/Library/Frameworks//ImageIO.framework/Versions/A/ImageIO are out of sync. Falling back to library file for linking. +ld: warning: text-based stub file /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/ATS.framework/Versions/A/ATS.tbd and library file /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/ATS.framework/Versions/A/ATS are out of sync. Falling back to library file for linking. +ld: warning: text-based stub file /System/Library/Frameworks//CoreServices.framework/Versions/A/CoreServices.tbd and library file /System/Library/Frameworks//CoreServices.framework/Versions/A/CoreServices are out of sync. Falling back to library file for linking. +ld: warning: text-based stub file /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/HIServices.framework/Versions/A/HIServices.tbd and library file /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/HIServices.framework/Versions/A/HIServices are out of sync. Falling back to library file for linking. +ld: warning: text-based stub file /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/SpeechSynthesis.framework/Versions/A/SpeechSynthesis.tbd and library file /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/SpeechSynthesis.framework/Versions/A/SpeechSynthesis are out of sync. Falling back to library file for linking. +ld: warning: text-based stub file /System/Library/PrivateFrameworks/UIFoundation.framework/Versions/A/UIFoundation.tbd and library file /System/Library/PrivateFrameworks/UIFoundation.framework/Versions/A/UIFoundation are out of sync. Falling back to library file for linking. +ld: warning: text-based stub file /System/Library/Frameworks//CFNetwork.framework/Versions/A/CFNetwork.tbd and library file /System/Library/Frameworks//CFNetwork.framework/Versions/A/CFNetwork are out of sync. Falling back to library file for linking. +ld: warning: text-based stub file /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/CarbonCore.framework/Versions/A/CarbonCore.tbd and library file /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/CarbonCore.framework/Versions/A/CarbonCore are out of sync. Falling back to library file for linking. +ld: warning: text-based stub file /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/Metadata.framework/Versions/A/Metadata.tbd and library file /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/Metadata.framework/Versions/A/Metadata are out of sync. Falling back to library file for linking. +ld: warning: text-based stub file /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/OSServices.framework/Versions/A/OSServices.tbd and library file /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/OSServices.framework/Versions/A/OSServices are out of sync. Falling back to library file for linking. +ld: warning: text-based stub file /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/AE.framework/Versions/A/AE.tbd and library file /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/AE.framework/Versions/A/AE are out of sync. Falling back to library file for linking. +ld: warning: text-based stub file /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/LaunchServices.tbd and library file /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/LaunchServices are out of sync. Falling back to library file for linking. +ld: warning: text-based stub file /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/SharedFileList.framework/Versions/A/SharedFileList.tbd and library file /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/SharedFileList.framework/Versions/A/SharedFileList are out of sync. Falling back to library file for linking. +make[1]: Nothing to be done for `all-am'. diff --git a/configure.ac b/configure.ac index 1448cb5..f8bd3b6 100755 --- a/configure.ac +++ b/configure.ac @@ -166,6 +166,16 @@ AC_ARG_ENABLE([glibc-back-compat], [use_glibc_compat=$enableval], [use_glibc_compat=no]) +AC_ARG_ENABLE([asm], + [AS_HELP_STRING([--disable-asm], + [disable assembly routines (enabled by default)])], + [use_asm=$enableval], + [use_asm=yes]) + +if test "x$use_asm" = xyes; then + AC_DEFINE(USE_ASM, 1, [Define this symbol to build in assembly routines]) +fi + AC_ARG_ENABLE([zmq], [AS_HELP_STRING([--disable-zmq], [disable ZMQ notifications])], @@ -1100,6 +1110,7 @@ AM_CONDITIONAL([USE_LCOV],[test x$use_lcov = xyes]) AM_CONDITIONAL([GLIBC_BACK_COMPAT],[test x$use_glibc_compat = xyes]) AM_CONDITIONAL([HARDEN],[test x$use_hardening = xyes]) AM_CONDITIONAL([USE_LIBSECP256K1],[test x$use_libsecp256k1 = xyes]) +AM_CONDITIONAL([USE_ASM],[test x$use_asm = xyes]) AC_DEFINE(CLIENT_VERSION_MAJOR, _CLIENT_VERSION_MAJOR, [Major version]) AC_DEFINE(CLIENT_VERSION_MINOR, _CLIENT_VERSION_MINOR, [Minor version]) @@ -1211,6 +1222,7 @@ echo " with zmq = $use_zmq" echo " with test = $use_tests" dnl echo " with bench = $use_bench" echo " with upnp = $use_upnp" +echo " use asm = $use_asm" echo " debug enabled = $enable_debug" echo " werror = $enable_werror" echo diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index 9582f28..8dffae2 100755 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -1,6 +1,6 @@ PACKAGE=qt $(package)_version=5.7.1 -$(package)_download_path=https://download.qt.io/archive/qt/5.7/$($(package)_version)/submodules +$(package)_download_path=http://download.qt.io/new_archive/qt/5.7/$($(package)_version)/submodules $(package)_suffix=opensource-src-$($(package)_version).tar.gz $(package)_file_name=qtbase-$($(package)_suffix) $(package)_sha256_hash=95f83e532d23b3ddbde7973f380ecae1bac13230340557276f75f2e37984e410 diff --git a/qa/pull-tester/rpc-tests.sh b/qa/pull-tester/rpc-tests.sh index 49f7b3d..5ddb420 100755 --- a/qa/pull-tester/rpc-tests.sh +++ b/qa/pull-tester/rpc-tests.sh @@ -16,8 +16,8 @@ fi #Run the tests if [ "x${ENABLE_BITCOIND}${ENABLE_UTILS}${ENABLE_WALLET}" = "x111" ]; then - ${BUILDDIR}/test/wallet.py - ${BUILDDIR}/test/segwit.py + ${BUILDDIR}/test/functional/wallet.py + ${BUILDDIR}/test/functional/segwit.py else echo "No rpc tests to run. Wallet, utils, and bitcoind must all be enabled" fi diff --git a/src/Makefile.am b/src/Makefile.am index 0c59a59..5215a2a 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -110,25 +110,24 @@ BITCOIN_CORE_H = \ checkpoints.h \ checkqueue.h \ clientversion.h \ - coincontrol.h \ coins.h \ compat.h \ + compat/cpuid.h \ compat/sanity.h \ consensus/merkle.h \ consensus/validation.h \ consensus/params.h \ consensus/upgrades.h \ compressor.h \ + cuckoocache.h \ primitives/block.h \ primitives/deterministicmint.h \ primitives/transaction.h \ primitives/zerocoin.h \ core_io.h \ - crypter.h \ denomination_functions.h \ obfuscation.h \ obfuscation-relay.h \ - wallet/db.h \ eccryptoverify.h \ ecwrapper.h \ hash.h \ @@ -176,10 +175,10 @@ BITCOIN_CORE_H = \ script/script_error.h \ serialize.h \ support/allocators/zeroafterfree.h \ - support/cleanse.h \ spork.h \ sporkdb.h \ streams.h \ + support/cleanse.h \ sync.h \ threadsafety.h \ timedata.h \ @@ -195,12 +194,20 @@ BITCOIN_CORE_H = \ utilmoneystr.h \ utiltime.h \ validationinterface.h \ + utilsplitstring.h \ version.h \ - wallet/wallet.h \ wallet/wallet_ismine.h \ - wallet/walletdb.h \ zohmctracker.h \ zohmcwallet.h \ + wallet/coincontrol.h \ + wallet/crypter.h \ + wallet/db.h \ + wallet/wallet.h \ + wallet/walletdb.h \ + wallet/bip39_english.h \ + wallet/bip39.h \ + wallet/arrayslice.h \ + wallet/hdchain.h \ zmq/zmqabstractnotifier.h \ zmq/zmqconfig.h \ zmq/zmqnotificationinterface.h \ @@ -270,8 +277,6 @@ libbitcoin_wallet_a_SOURCES = \ denomination_functions.cpp \ obfuscation.cpp \ obfuscation-relay.cpp \ - wallet/db.cpp \ - crypter.cpp \ swifttx.cpp \ karmanode.cpp \ karmanode-budget.cpp \ @@ -281,15 +286,18 @@ libbitcoin_wallet_a_SOURCES = \ karmanodeman.cpp \ mintpool.cpp \ wallet/rpcdump.cpp \ - wallet/rpcwallet.cpp \ - kernel.cpp \ - wallet/wallet.cpp \ - wallet/wallet_ismine.cpp \ - wallet/walletdb.cpp \ primitives/deterministicmint.cpp \ primitives/zerocoin.cpp \ + kernel.cpp \ + wallet/wallet_ismine.cpp \ zohmcwallet.cpp \ zohmctracker.cpp \ + wallet/crypter.cpp \ + wallet/db.cpp \ + wallet/rpcwallet.cpp \ + wallet/wallet.cpp \ + wallet/walletdb.cpp \ + ui_interface.cpp \ $(BITCOIN_CORE_H) # crypto primitives library @@ -298,8 +306,11 @@ crypto_libbitcoin_crypto_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) crypto_libbitcoin_crypto_a_SOURCES = \ crypto/sha1.cpp \ crypto/sha256.cpp \ + crypto/sha256_sse4.cpp \ crypto/sha512.cpp \ crypto/hmac_sha256.cpp \ + crypto/pkcs5_pbkdf2.h \ + crypto/pkcs5_pbkdf2.cpp \ crypto/rfc6979_hmac_sha256.cpp \ crypto/hmac_sha512.cpp \ crypto/scrypt.cpp \ @@ -365,6 +376,7 @@ libbitcoin_common_a_SOURCES = \ amount.cpp \ base58.cpp \ bech32.cpp \ + wallet/bip39.cpp \ bip38.cpp \ chainparams.cpp \ coins.cpp \ @@ -391,7 +403,7 @@ libbitcoin_common_a_SOURCES = \ script/sign.cpp \ script/standard.cpp \ script/script_error.cpp \ - support/cleanse.cpp \ + wallet/hdchain.cpp \ spork.cpp \ sporkdb.cpp \ $(BITCOIN_CORE_H) @@ -410,6 +422,7 @@ libbitcoin_util_a_SOURCES = \ clientversion.cpp \ random.cpp \ rpc/protocol.cpp \ + support/cleanse.cpp \ sync.cpp \ uint256.cpp \ util.cpp \ @@ -573,3 +586,4 @@ endif if ENABLE_QT_TESTS include Makefile.qttest.include endif + diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index 71c98a1..f1f0e23 100755 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -38,6 +38,12 @@ QT_FORMS_UI = \ qt/forms/addressbookpage.ui \ qt/forms/configurekarmanodepage.ui \ qt/forms/askpassphrasedialog.ui \ + qt/forms/startoptionsdialog.ui \ + qt/forms/startoptions.ui \ + qt/forms/startoptionsrestore.ui \ + qt/forms/startoptionssort.ui \ + qt/forms/startoptionsrevealed.ui \ + qt/forms/startoptionsmain.ui \ qt/forms/bip38tooldialog.ui \ qt/forms/coincontroldialog.ui \ qt/forms/blockexplorer.ui \ @@ -67,6 +73,12 @@ QT_MOC_CPP = \ qt/moc_configurekarmanodepage.cpp \ qt/moc_addresstablemodel.cpp \ qt/moc_askpassphrasedialog.cpp \ + qt/moc_startoptionsdialog.cpp \ + qt/moc_startoptions.cpp \ + qt/moc_startoptionsrestore.cpp \ + qt/moc_startoptionssort.cpp \ + qt/moc_startoptionsrevealed.cpp \ + qt/moc_startoptionsmain.cpp \ qt/moc_bantablemodel.cpp \ qt/moc_bip38tooldialog.cpp \ qt/moc_bitcoinaddressvalidator.cpp \ @@ -146,6 +158,12 @@ BITCOIN_QT_H = \ qt/addressbookpage.h \ qt/addresstablemodel.h \ qt/askpassphrasedialog.h \ + qt/startoptionsdialog.h \ + qt/startoptions.h \ + qt/startoptionsrestore.h \ + qt/startoptionssort.h \ + qt/startoptionsrevealed.h \ + qt/startoptionsmain.h \ qt/bantablemodel.h \ qt/bip38tooldialog.h \ qt/bitcoinaddressvalidator.h \ @@ -245,6 +263,8 @@ RES_ICONS = \ qt/res/icons/history_off.png \ qt/res/icons/karmanodes.png \ qt/res/icons/karmanodes_off.png \ + qt/res/icons/hd_enabled.png \ + qt/res/icons/hd_disabled.png \ qt/res/icons/key.png \ qt/res/icons/lock_closed.png \ qt/res/icons/lock_open.png \ @@ -306,6 +326,12 @@ BITCOIN_QT_CPP = \ qt/rpcconsole.cpp \ qt/splashscreen.cpp \ qt/trafficgraphwidget.cpp \ + qt/startoptionsdialog.cpp \ + qt/startoptions.cpp \ + qt/startoptionsrestore.cpp \ + qt/startoptionssort.cpp \ + qt/startoptionsrevealed.cpp \ + qt/startoptionsmain.cpp \ qt/utilitydialog.cpp if TARGET_WINDOWS diff --git a/src/Makefile.test.include b/src/Makefile.test.include index f5a82e5..81abc9e 100755 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -25,6 +25,7 @@ JSON_TEST_FILES = \ test/data/sig_noncanonical.json \ test/data/base58_encode_decode.json \ test/data/base58_keys_invalid.json \ + test/data/bip39_vectors.json \ test/data/script_invalid.json \ test/data/tx_invalid.json \ test/data/tx_valid.json \ @@ -46,6 +47,7 @@ BITCOIN_TESTS =\ test/base32_tests.cpp \ test/base58_tests.cpp \ test/base64_tests.cpp \ + test/bip39_tests.cpp \ test/budget_tests.cpp \ test/checkblock_tests.cpp \ test/Checkpoints_tests.cpp \ diff --git a/src/accumulators.cpp b/src/accumulators.cpp index 46f9de6..ebae8b8 100644 --- a/src/accumulators.cpp +++ b/src/accumulators.cpp @@ -19,7 +19,7 @@ std::list listAccCheckpointsNoDB; uint32_t ParseChecksum(uint256 nChecksum, CoinDenomination denomination) { //shift to the beginning bit of this denomination and trim any remaining bits by returning 32 bits only - int pos = std::distance(zerocoinDenomList.begin(), find(zerocoinDenomList.begin(), zerocoinDenomList.end(), denomination)); + int pos = distance(zerocoinDenomList.begin(), find(zerocoinDenomList.begin(), zerocoinDenomList.end(), denomination)); nChecksum = nChecksum >> (32*((zerocoinDenomList.size() - 1) - pos)); return nChecksum.Get32(); } @@ -261,7 +261,7 @@ bool CalculateAccumulatorCheckpoint(int nHeight, uint256& nCheckpoint, Accumulat LogPrint("zero", "%s found %d mints\n", __func__, listPubcoins.size()); //add the pubcoins to accumulator - for (const PublicCoin pubcoin : listPubcoins) { + for (const PublicCoin& pubcoin : listPubcoins) { if(!mapAccumulators.Accumulate(pubcoin, true)) return error("%s: failed to add pubcoin to accumulator at height %d", __func__, pindex->nHeight); } @@ -512,7 +512,7 @@ map GetMintMaturityHeight() if (isFinished) break; - pindex = chainActive[pindex->nHeight - 1]; + pindex = pindex->pprev; } //Generate final map diff --git a/src/addrman.h b/src/addrman.h index c92aaac..27bbb1a 100755 --- a/src/addrman.h +++ b/src/addrman.h @@ -582,4 +582,4 @@ class CAddrMan } }; -#endif // BITCOIN_ADDRMAN_H +#endif // BITCOIN_ADDRMAN_H \ No newline at end of file diff --git a/src/allocators.h b/src/allocators.h index 7d1fed0..ae7e063 100755 --- a/src/allocators.h +++ b/src/allocators.h @@ -6,6 +6,8 @@ #ifndef BITCOIN_ALLOCATORS_H #define BITCOIN_ALLOCATORS_H +#include "support/cleanse.h" + #include #include #include @@ -14,8 +16,6 @@ #include #include -#include // for OPENSSL_cleanse() - /** * Thread-safe class to keep track of locked (ie, non-swappable) memory pages. * @@ -173,7 +173,7 @@ void LockObject(const T& t) template void UnlockObject(const T& t) { - OPENSSL_cleanse((void*)(&t), sizeof(T)); + memory_cleanse((void*)(&t), sizeof(T)); LockedPageManager::Instance().UnlockRange((void*)(&t), sizeof(T)); } @@ -216,7 +216,7 @@ struct secure_allocator : public std::allocator { void deallocate(T* p, std::size_t n) { if (p != NULL) { - OPENSSL_cleanse(p, sizeof(T) * n); + memory_cleanse(p, sizeof(T) * n); LockedPageManager::Instance().UnlockRange(p, sizeof(T) * n); } std::allocator::deallocate(p, n); @@ -226,5 +226,5 @@ struct secure_allocator : public std::allocator { // This is exactly like std::string, but with a custom allocator. typedef std::basic_string, secure_allocator > SecureString; - +typedef std::vector > SecureVector; #endif // BITCOIN_ALLOCATORS_H diff --git a/src/chain.h b/src/chain.h index 6349032..8547ae9 100755 --- a/src/chain.h +++ b/src/chain.h @@ -430,7 +430,7 @@ class CDiskBlockIndex : public CBlockIndex hashNext = uint256(); } - explicit CDiskBlockIndex(CBlockIndex* pindex) : CBlockIndex(*pindex) + explicit CDiskBlockIndex(const CBlockIndex* pindex) : CBlockIndex(*pindex) { hashPrev = (pprev ? pprev->GetBlockHash() : uint256()); } diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 3f873a5..eb9661b 100755 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -458,8 +458,7 @@ class CMainParams : public CChainParams base58Prefixes[SECRET_KEY] = std::vector(1, 212); base58Prefixes[EXT_PUBLIC_KEY] = boost::assign::list_of(0x02)(0x2D)(0x25)(0x33).convert_to_container >(); base58Prefixes[EXT_SECRET_KEY] = boost::assign::list_of(0x02)(0x21)(0x31)(0x2B).convert_to_container >(); - // BIP44 coin type is from https://github.com/satoshilabs/slips/blob/master/slip-0044.md - base58Prefixes[EXT_COIN_TYPE] = boost::assign::list_of(0x80)(0x00)(0x00)(0x77).convert_to_container >(); + nExtCoinType = 444; bech32_hrp = "oh"; @@ -581,8 +580,8 @@ class CTestNetParams : public CMainParams base58Prefixes[EXT_PUBLIC_KEY] = boost::assign::list_of(0x3a)(0x80)(0x61)(0xa0).convert_to_container >(); // Testnet ohmcoin BIP32 prvkeys start with 'DRKP' base58Prefixes[EXT_SECRET_KEY] = boost::assign::list_of(0x3a)(0x80)(0x58)(0x37).convert_to_container >(); - // Testnet ohmcoin BIP44 coin type is '1' (All coin's testnet default) - base58Prefixes[EXT_COIN_TYPE] = boost::assign::list_of(0x80)(0x00)(0x00)(0x01).convert_to_container >(); + // Testnet phore BIP44 coin type is '1' (All coin's testnet default) + nExtCoinType = 1; bech32_hrp = "tp"; @@ -717,6 +716,7 @@ class CUnitTestParams : public CMainParams, public CModifiableParams vFixedSeeds.clear(); //! Unit test mode doesn't have any fixed seeds. vSeeds.clear(); //! Unit test mode doesn't have any DNS seeds. + nExtCoinType = 1; fMiningRequiresPeers = false; fDefaultConsistencyChecks = true; fAllowMinDifficultyBlocks = false; diff --git a/src/chainparams.h b/src/chainparams.h index 1ac49a3..86d8262 100755 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -41,7 +41,6 @@ class CChainParams SECRET_KEY, // BIP16 EXT_PUBLIC_KEY, // BIP32 EXT_SECRET_KEY, // BIP32 - EXT_COIN_TYPE, // BIP44 MAX_BASE58_TYPES }; @@ -97,6 +96,7 @@ class CChainParams const std::string& Bech32HRP() const { return bech32_hrp; } const std::vector& DNSSeeds() const { return vSeeds; } const std::vector& Base58Prefix(Base58Type type) const { return base58Prefixes[type]; } + int ExtCoinType() const { return nExtCoinType; } const std::vector& FixedSeeds() const { return vFixedSeeds; } virtual const Checkpoints::CCheckpointData& Checkpoints() const = 0; int PoolMaxTransactions() const { return nPoolMaxTransactions; } @@ -150,6 +150,7 @@ class CChainParams std::vector vSeeds; std::string bech32_hrp; std::vector base58Prefixes[MAX_BASE58_TYPES]; + int nExtCoinType; CBaseChainParams::Network networkID; std::string strNetworkID; CBlock genesis; diff --git a/src/checkqueue.h b/src/checkqueue.h index 485efa0..b5d9ca7 100755 --- a/src/checkqueue.h +++ b/src/checkqueue.h @@ -8,7 +8,7 @@ #include #include -#include + #include #include #include diff --git a/src/compat/cpuid.h b/src/compat/cpuid.h new file mode 100644 index 0000000..0877ad4 --- /dev/null +++ b/src/compat/cpuid.h @@ -0,0 +1,24 @@ +// Copyright (c) 2017-2019 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_COMPAT_CPUID_H +#define BITCOIN_COMPAT_CPUID_H + +#if defined(__x86_64__) || defined(__amd64__) || defined(__i386__) +#define HAVE_GETCPUID + +#include + +// We can't use cpuid.h's __get_cpuid as it does not support subleafs. +void static inline GetCPUID(uint32_t leaf, uint32_t subleaf, uint32_t& a, uint32_t& b, uint32_t& c, uint32_t& d) +{ +#ifdef __GNUC__ + __cpuid_count(leaf, subleaf, a, b, c, d); +#else + __asm__ ("cpuid" : "=a"(a), "=b"(b), "=c"(c), "=d"(d) : "0"(leaf), "2"(subleaf)); +#endif +} + +#endif // defined(__x86_64__) || defined(__amd64__) || defined(__i386__) +#endif // BITCOIN_COMPAT_CPUID_H diff --git a/src/compressor.cpp b/src/compressor.cpp index 842ac65..53cfe11 100755 --- a/src/compressor.cpp +++ b/src/compressor.cpp @@ -83,44 +83,44 @@ unsigned int CScriptCompressor::GetSpecialSize(unsigned int nSize) const bool CScriptCompressor::Decompress(unsigned int nSize, const std::vector& in) { switch (nSize) { - case 0x00: - script.resize(25); - script[0] = OP_DUP; - script[1] = OP_HASH160; - script[2] = 20; - memcpy(&script[3], &in[0], 20); - script[23] = OP_EQUALVERIFY; - script[24] = OP_CHECKSIG; - return true; - case 0x01: - script.resize(23); - script[0] = OP_HASH160; - script[1] = 20; - memcpy(&script[2], &in[0], 20); - script[22] = OP_EQUAL; - return true; - case 0x02: - case 0x03: - script.resize(35); - script[0] = 33; - script[1] = nSize; - memcpy(&script[2], &in[0], 32); - script[34] = OP_CHECKSIG; - return true; - case 0x04: - case 0x05: - unsigned char vch[33] = {}; - vch[0] = nSize - 2; - memcpy(&vch[1], &in[0], 32); - CPubKey pubkey(&vch[0], &vch[33]); - if (!pubkey.Decompress()) - return false; - assert(pubkey.size() == 65); - script.resize(67); - script[0] = 65; - memcpy(&script[1], pubkey.begin(), 65); - script[66] = OP_CHECKSIG; - return true; + case 0x00: + script.resize(25); + script[0] = OP_DUP; + script[1] = OP_HASH160; + script[2] = 20; + memcpy(&script[3], &in[0], 20); + script[23] = OP_EQUALVERIFY; + script[24] = OP_CHECKSIG; + return true; + case 0x01: + script.resize(23); + script[0] = OP_HASH160; + script[1] = 20; + memcpy(&script[2], &in[0], 20); + script[22] = OP_EQUAL; + return true; + case 0x02: + case 0x03: + script.resize(35); + script[0] = 33; + script[1] = nSize; + memcpy(&script[2], &in[0], 32); + script[34] = OP_CHECKSIG; + return true; + case 0x04: + case 0x05: + unsigned char vch[33] = {}; + vch[0] = nSize - 2; + memcpy(&vch[1], &in[0], 32); + CPubKey pubkey(&vch[0], &vch[33]); + if (!pubkey.Decompress()) + return false; + assert(pubkey.size() == 65); + script.resize(67); + script[0] = 65; + memcpy(&script[1], pubkey.begin(), 65); + script[66] = OP_CHECKSIG; + return true; } return false; } @@ -177,4 +177,4 @@ uint64_t CTxOutCompressor::DecompressAmount(uint64_t x) e--; } return n; -} +} \ No newline at end of file diff --git a/src/compressor.h b/src/compressor.h index 887a2c1..97b5ea0 100755 --- a/src/compressor.h +++ b/src/compressor.h @@ -126,4 +126,4 @@ class CTxOutCompressor } }; -#endif // BITCOIN_COMPRESSOR_H +#endif // BITCOIN_COMPRESSOR_H \ No newline at end of file diff --git a/src/crypto/common.h b/src/crypto/common.h index 8d5452d..b640079 100755 --- a/src/crypto/common.h +++ b/src/crypto/common.h @@ -5,6 +5,10 @@ #ifndef BITCOIN_CRYPTO_COMMON_H #define BITCOIN_CRYPTO_COMMON_H +#if defined(HAVE_CONFIG_H) +#include "config/ohmcoin-config.h" +#endif + #include #if defined(HAVE_ENDIAN_H) diff --git a/src/crypto/pkcs5_pbkdf2.cpp b/src/crypto/pkcs5_pbkdf2.cpp new file mode 100644 index 0000000..612298b --- /dev/null +++ b/src/crypto/pkcs5_pbkdf2.cpp @@ -0,0 +1,83 @@ +/* OpenBSD: pkcs5_pbkdf2.c, v 1.9 2015/02/05 12:59:57 millert */ +/** + * Copyright (c) 2008 Damien Bergamini + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#include "pkcs5_pbkdf2.h" + +#include +#include +#include +#include +#include "hmac_sha512.h" +#include "support/cleanse.h" +#include + +int pkcs5_pbkdf2(const uint8_t* passphrase, size_t passphrase_length, + const uint8_t* salt, size_t salt_length, uint8_t* key, size_t key_length, + size_t iterations) +{ + std::unique_ptr asalt; + size_t asalt_size; + size_t count, index, iteration, length; + uint8_t buffer[64]; + uint8_t digest1[64]; + uint8_t digest2[64]; + + /* An iteration count of 0 is equivalent to a count of 1. */ + /* A key_length of 0 is a no-op. */ + /* A salt_length of 0 is perfectly valid. */ + + if (salt_length > SIZE_MAX - 4) + return -1; + asalt_size = salt_length + 4; + asalt.reset(new uint8_t[asalt_size]); + if (asalt == nullptr) + return -1; + + memcpy(asalt.get(), salt, salt_length); + for (count = 1; key_length > 0; count++) + { + asalt[salt_length + 0] = (count >> 24) & 0xff; + asalt[salt_length + 1] = (count >> 16) & 0xff; + asalt[salt_length + 2] = (count >> 8) & 0xff; + asalt[salt_length + 3] = (count >> 0) & 0xff; + CHMAC_SHA512 sh1(passphrase, passphrase_length); + sh1.Write(asalt.get(), asalt_size); + sh1.Finalize(digest1); + memcpy(buffer, digest1, sizeof(buffer)); + + for (iteration = 1; iteration < iterations; iteration++) + { + CHMAC_SHA512 sh2(passphrase, passphrase_length); + sh2.Write(digest1, sizeof(digest1)); + sh2.Finalize(digest2); + memcpy(digest1, digest2, sizeof(digest1)); + for (index = 0; index < sizeof(buffer); index++) + buffer[index] ^= digest1[index]; + } + + length = (key_length < sizeof(buffer) ? key_length : sizeof(buffer)); + memcpy(key, buffer, length); + key += length; + key_length -= length; + }; + + memory_cleanse(digest1, sizeof(digest1)); + memory_cleanse(digest2, sizeof(digest2)); + memory_cleanse(buffer, sizeof(buffer)); + memory_cleanse(asalt.get(), asalt_size); + + return 0; +} diff --git a/src/crypto/pkcs5_pbkdf2.h b/src/crypto/pkcs5_pbkdf2.h new file mode 100644 index 0000000..c31106b --- /dev/null +++ b/src/crypto/pkcs5_pbkdf2.h @@ -0,0 +1,28 @@ +/* OpenBSD: pkcs5_pbkdf2.c, v 1.9 2015/02/05 12:59:57 millert */ +/** + * Copyright (c) 2008 Damien Bergamini + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#pragma once + +#include +#include + +/* Password-Based Key Derivation Function 2 (PKCS #5 v2.0). */ +/* Code based on IEEE Std 802.11-2007, Annex H.4.2. */ +/* returns 0 if successful. */ +int pkcs5_pbkdf2(const uint8_t* passphrase, size_t passphrase_length, + const uint8_t* salt, size_t salt_length, uint8_t* key, size_t key_length, + size_t iterations); + diff --git a/src/crypto/sha256.cpp b/src/crypto/sha256.cpp index 8410e59..51ddc1b 100755 --- a/src/crypto/sha256.cpp +++ b/src/crypto/sha256.cpp @@ -6,8 +6,40 @@ #include "crypto/common.h" +#include "compat/cpuid.h" + +#include #include +#if defined(__x86_64__) || defined(__amd64__) || defined(__i386__) +#if defined(USE_ASM) +namespace sha256_sse4 +{ +void Transform(uint32_t* s, const unsigned char* chunk, size_t blocks); +} +#endif +#endif + +namespace sha256d64_sse41 +{ +void Transform_4way(unsigned char* out, const unsigned char* in); +} + +namespace sha256d64_avx2 +{ +void Transform_8way(unsigned char* out, const unsigned char* in); +} + +namespace sha256d64_shani +{ +void Transform_2way(unsigned char* out, const unsigned char* in); +} + +namespace sha256_shani +{ +void Transform(uint32_t* s, const unsigned char* chunk, size_t blocks); +} + // Internal implementation code. namespace { @@ -22,9 +54,9 @@ uint32_t inline sigma0(uint32_t x) { return (x >> 7 | x << 25) ^ (x >> 18 | x << uint32_t inline sigma1(uint32_t x) { return (x >> 17 | x << 15) ^ (x >> 19 | x << 13) ^ (x >> 10); } /** One round of SHA-256. */ -void inline Round(uint32_t a, uint32_t b, uint32_t c, uint32_t& d, uint32_t e, uint32_t f, uint32_t g, uint32_t& h, uint32_t k, uint32_t w) +void inline Round(uint32_t a, uint32_t b, uint32_t c, uint32_t& d, uint32_t e, uint32_t f, uint32_t g, uint32_t& h, uint32_t k) { - uint32_t t1 = h + Sigma1(e) + Ch(e, f, g) + k + w; + uint32_t t1 = h + Sigma1(e) + Ch(e, f, g) + k; uint32_t t2 = Sigma0(a) + Maj(a, b, c); d += t1; h = t1 + t2; @@ -43,94 +75,559 @@ void inline Initialize(uint32_t* s) s[7] = 0x5be0cd19ul; } -/** Perform one SHA-256 transformation, processing a 64-byte chunk. */ -void Transform(uint32_t* s, const unsigned char* chunk) +/** Perform a number of SHA-256 transformations, processing 64-byte chunks. */ +void Transform(uint32_t* s, const unsigned char* chunk, size_t blocks) +{ + while (blocks--) { + 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; + chunk += 64; + } +} + +void TransformD64(unsigned char* out, const unsigned char* in) { - 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]; + // Transform 1 + uint32_t a = 0x6a09e667ul; + uint32_t b = 0xbb67ae85ul; + uint32_t c = 0x3c6ef372ul; + uint32_t d = 0xa54ff53aul; + uint32_t e = 0x510e527ful; + uint32_t f = 0x9b05688cul; + uint32_t g = 0x1f83d9abul; + uint32_t h = 0x5be0cd19ul; + 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; + Round(a, b, c, d, e, f, g, h, 0x428a2f98ul + (w0 = ReadBE32(in + 0))); + Round(h, a, b, c, d, e, f, g, 0x71374491ul + (w1 = ReadBE32(in + 4))); + Round(g, h, a, b, c, d, e, f, 0xb5c0fbcful + (w2 = ReadBE32(in + 8))); + Round(f, g, h, a, b, c, d, e, 0xe9b5dba5ul + (w3 = ReadBE32(in + 12))); + Round(e, f, g, h, a, b, c, d, 0x3956c25bul + (w4 = ReadBE32(in + 16))); + Round(d, e, f, g, h, a, b, c, 0x59f111f1ul + (w5 = ReadBE32(in + 20))); + Round(c, d, e, f, g, h, a, b, 0x923f82a4ul + (w6 = ReadBE32(in + 24))); + Round(b, c, d, e, f, g, h, a, 0xab1c5ed5ul + (w7 = ReadBE32(in + 28))); + Round(a, b, c, d, e, f, g, h, 0xd807aa98ul + (w8 = ReadBE32(in + 32))); + Round(h, a, b, c, d, e, f, g, 0x12835b01ul + (w9 = ReadBE32(in + 36))); + Round(g, h, a, b, c, d, e, f, 0x243185beul + (w10 = ReadBE32(in + 40))); + Round(f, g, h, a, b, c, d, e, 0x550c7dc3ul + (w11 = ReadBE32(in + 44))); + Round(e, f, g, h, a, b, c, d, 0x72be5d74ul + (w12 = ReadBE32(in + 48))); + Round(d, e, f, g, h, a, b, c, 0x80deb1feul + (w13 = ReadBE32(in + 52))); + Round(c, d, e, f, g, h, a, b, 0x9bdc06a7ul + (w14 = ReadBE32(in + 56))); + Round(b, c, d, e, f, g, h, a, 0xc19bf174ul + (w15 = ReadBE32(in + 60))); + Round(a, b, c, d, e, f, g, h, 0xe49b69c1ul + (w0 += sigma1(w14) + w9 + sigma0(w1))); + Round(h, a, b, c, d, e, f, g, 0xefbe4786ul + (w1 += sigma1(w15) + w10 + sigma0(w2))); + Round(g, h, a, b, c, d, e, f, 0x0fc19dc6ul + (w2 += sigma1(w0) + w11 + sigma0(w3))); + Round(f, g, h, a, b, c, d, e, 0x240ca1ccul + (w3 += sigma1(w1) + w12 + sigma0(w4))); + Round(e, f, g, h, a, b, c, d, 0x2de92c6ful + (w4 += sigma1(w2) + w13 + sigma0(w5))); + Round(d, e, f, g, h, a, b, c, 0x4a7484aaul + (w5 += sigma1(w3) + w14 + sigma0(w6))); + Round(c, d, e, f, g, h, a, b, 0x5cb0a9dcul + (w6 += sigma1(w4) + w15 + sigma0(w7))); + Round(b, c, d, e, f, g, h, a, 0x76f988daul + (w7 += sigma1(w5) + w0 + sigma0(w8))); + Round(a, b, c, d, e, f, g, h, 0x983e5152ul + (w8 += sigma1(w6) + w1 + sigma0(w9))); + Round(h, a, b, c, d, e, f, g, 0xa831c66dul + (w9 += sigma1(w7) + w2 + sigma0(w10))); + Round(g, h, a, b, c, d, e, f, 0xb00327c8ul + (w10 += sigma1(w8) + w3 + sigma0(w11))); + Round(f, g, h, a, b, c, d, e, 0xbf597fc7ul + (w11 += sigma1(w9) + w4 + sigma0(w12))); + Round(e, f, g, h, a, b, c, d, 0xc6e00bf3ul + (w12 += sigma1(w10) + w5 + sigma0(w13))); + Round(d, e, f, g, h, a, b, c, 0xd5a79147ul + (w13 += sigma1(w11) + w6 + sigma0(w14))); + Round(c, d, e, f, g, h, a, b, 0x06ca6351ul + (w14 += sigma1(w12) + w7 + sigma0(w15))); + Round(b, c, d, e, f, g, h, a, 0x14292967ul + (w15 += sigma1(w13) + w8 + sigma0(w0))); + Round(a, b, c, d, e, f, g, h, 0x27b70a85ul + (w0 += sigma1(w14) + w9 + sigma0(w1))); + Round(h, a, b, c, d, e, f, g, 0x2e1b2138ul + (w1 += sigma1(w15) + w10 + sigma0(w2))); + Round(g, h, a, b, c, d, e, f, 0x4d2c6dfcul + (w2 += sigma1(w0) + w11 + sigma0(w3))); + Round(f, g, h, a, b, c, d, e, 0x53380d13ul + (w3 += sigma1(w1) + w12 + sigma0(w4))); + Round(e, f, g, h, a, b, c, d, 0x650a7354ul + (w4 += sigma1(w2) + w13 + sigma0(w5))); + Round(d, e, f, g, h, a, b, c, 0x766a0abbul + (w5 += sigma1(w3) + w14 + sigma0(w6))); + Round(c, d, e, f, g, h, a, b, 0x81c2c92eul + (w6 += sigma1(w4) + w15 + sigma0(w7))); + Round(b, c, d, e, f, g, h, a, 0x92722c85ul + (w7 += sigma1(w5) + w0 + sigma0(w8))); + Round(a, b, c, d, e, f, g, h, 0xa2bfe8a1ul + (w8 += sigma1(w6) + w1 + sigma0(w9))); + Round(h, a, b, c, d, e, f, g, 0xa81a664bul + (w9 += sigma1(w7) + w2 + sigma0(w10))); + Round(g, h, a, b, c, d, e, f, 0xc24b8b70ul + (w10 += sigma1(w8) + w3 + sigma0(w11))); + Round(f, g, h, a, b, c, d, e, 0xc76c51a3ul + (w11 += sigma1(w9) + w4 + sigma0(w12))); + Round(e, f, g, h, a, b, c, d, 0xd192e819ul + (w12 += sigma1(w10) + w5 + sigma0(w13))); + Round(d, e, f, g, h, a, b, c, 0xd6990624ul + (w13 += sigma1(w11) + w6 + sigma0(w14))); + Round(c, d, e, f, g, h, a, b, 0xf40e3585ul + (w14 += sigma1(w12) + w7 + sigma0(w15))); + Round(b, c, d, e, f, g, h, a, 0x106aa070ul + (w15 += sigma1(w13) + w8 + sigma0(w0))); + Round(a, b, c, d, e, f, g, h, 0x19a4c116ul + (w0 += sigma1(w14) + w9 + sigma0(w1))); + Round(h, a, b, c, d, e, f, g, 0x1e376c08ul + (w1 += sigma1(w15) + w10 + sigma0(w2))); + Round(g, h, a, b, c, d, e, f, 0x2748774cul + (w2 += sigma1(w0) + w11 + sigma0(w3))); + Round(f, g, h, a, b, c, d, e, 0x34b0bcb5ul + (w3 += sigma1(w1) + w12 + sigma0(w4))); + Round(e, f, g, h, a, b, c, d, 0x391c0cb3ul + (w4 += sigma1(w2) + w13 + sigma0(w5))); + Round(d, e, f, g, h, a, b, c, 0x4ed8aa4aul + (w5 += sigma1(w3) + w14 + sigma0(w6))); + Round(c, d, e, f, g, h, a, b, 0x5b9cca4ful + (w6 += sigma1(w4) + w15 + sigma0(w7))); + Round(b, c, d, e, f, g, h, a, 0x682e6ff3ul + (w7 += sigma1(w5) + w0 + sigma0(w8))); + Round(a, b, c, d, e, f, g, h, 0x748f82eeul + (w8 += sigma1(w6) + w1 + sigma0(w9))); + Round(h, a, b, c, d, e, f, g, 0x78a5636ful + (w9 += sigma1(w7) + w2 + sigma0(w10))); + Round(g, h, a, b, c, d, e, f, 0x84c87814ul + (w10 += sigma1(w8) + w3 + sigma0(w11))); + Round(f, g, h, a, b, c, d, e, 0x8cc70208ul + (w11 += sigma1(w9) + w4 + sigma0(w12))); + Round(e, f, g, h, a, b, c, d, 0x90befffaul + (w12 += sigma1(w10) + w5 + sigma0(w13))); + Round(d, e, f, g, h, a, b, c, 0xa4506cebul + (w13 += sigma1(w11) + w6 + sigma0(w14))); + Round(c, d, e, f, g, h, a, b, 0xbef9a3f7ul + (w14 + sigma1(w12) + w7 + sigma0(w15))); + Round(b, c, d, e, f, g, h, a, 0xc67178f2ul + (w15 + sigma1(w13) + w8 + sigma0(w0))); + + a += 0x6a09e667ul; + b += 0xbb67ae85ul; + c += 0x3c6ef372ul; + d += 0xa54ff53aul; + e += 0x510e527ful; + f += 0x9b05688cul; + g += 0x1f83d9abul; + h += 0x5be0cd19ul; + + uint32_t t0 = a, t1 = b, t2 = c, t3 = d, t4 = e, t5 = f, t6 = g, t7 = h; + + // Transform 2 + Round(a, b, c, d, e, f, g, h, 0xc28a2f98ul); + Round(h, a, b, c, d, e, f, g, 0x71374491ul); + Round(g, h, a, b, c, d, e, f, 0xb5c0fbcful); + Round(f, g, h, a, b, c, d, e, 0xe9b5dba5ul); + Round(e, f, g, h, a, b, c, d, 0x3956c25bul); + Round(d, e, f, g, h, a, b, c, 0x59f111f1ul); + Round(c, d, e, f, g, h, a, b, 0x923f82a4ul); + Round(b, c, d, e, f, g, h, a, 0xab1c5ed5ul); + Round(a, b, c, d, e, f, g, h, 0xd807aa98ul); + Round(h, a, b, c, d, e, f, g, 0x12835b01ul); + Round(g, h, a, b, c, d, e, f, 0x243185beul); + Round(f, g, h, a, b, c, d, e, 0x550c7dc3ul); + Round(e, f, g, h, a, b, c, d, 0x72be5d74ul); + Round(d, e, f, g, h, a, b, c, 0x80deb1feul); + Round(c, d, e, f, g, h, a, b, 0x9bdc06a7ul); + Round(b, c, d, e, f, g, h, a, 0xc19bf374ul); + Round(a, b, c, d, e, f, g, h, 0x649b69c1ul); + Round(h, a, b, c, d, e, f, g, 0xf0fe4786ul); + Round(g, h, a, b, c, d, e, f, 0x0fe1edc6ul); + Round(f, g, h, a, b, c, d, e, 0x240cf254ul); + Round(e, f, g, h, a, b, c, d, 0x4fe9346ful); + Round(d, e, f, g, h, a, b, c, 0x6cc984beul); + Round(c, d, e, f, g, h, a, b, 0x61b9411eul); + Round(b, c, d, e, f, g, h, a, 0x16f988faul); + Round(a, b, c, d, e, f, g, h, 0xf2c65152ul); + Round(h, a, b, c, d, e, f, g, 0xa88e5a6dul); + Round(g, h, a, b, c, d, e, f, 0xb019fc65ul); + Round(f, g, h, a, b, c, d, e, 0xb9d99ec7ul); + Round(e, f, g, h, a, b, c, d, 0x9a1231c3ul); + Round(d, e, f, g, h, a, b, c, 0xe70eeaa0ul); + Round(c, d, e, f, g, h, a, b, 0xfdb1232bul); + Round(b, c, d, e, f, g, h, a, 0xc7353eb0ul); + Round(a, b, c, d, e, f, g, h, 0x3069bad5ul); + Round(h, a, b, c, d, e, f, g, 0xcb976d5ful); + Round(g, h, a, b, c, d, e, f, 0x5a0f118ful); + Round(f, g, h, a, b, c, d, e, 0xdc1eeefdul); + Round(e, f, g, h, a, b, c, d, 0x0a35b689ul); + Round(d, e, f, g, h, a, b, c, 0xde0b7a04ul); + Round(c, d, e, f, g, h, a, b, 0x58f4ca9dul); + Round(b, c, d, e, f, g, h, a, 0xe15d5b16ul); + Round(a, b, c, d, e, f, g, h, 0x007f3e86ul); + Round(h, a, b, c, d, e, f, g, 0x37088980ul); + Round(g, h, a, b, c, d, e, f, 0xa507ea32ul); + Round(f, g, h, a, b, c, d, e, 0x6fab9537ul); + Round(e, f, g, h, a, b, c, d, 0x17406110ul); + Round(d, e, f, g, h, a, b, c, 0x0d8cd6f1ul); + Round(c, d, e, f, g, h, a, b, 0xcdaa3b6dul); + Round(b, c, d, e, f, g, h, a, 0xc0bbbe37ul); + Round(a, b, c, d, e, f, g, h, 0x83613bdaul); + Round(h, a, b, c, d, e, f, g, 0xdb48a363ul); + Round(g, h, a, b, c, d, e, f, 0x0b02e931ul); + Round(f, g, h, a, b, c, d, e, 0x6fd15ca7ul); + Round(e, f, g, h, a, b, c, d, 0x521afacaul); + Round(d, e, f, g, h, a, b, c, 0x31338431ul); + Round(c, d, e, f, g, h, a, b, 0x6ed41a95ul); + Round(b, c, d, e, f, g, h, a, 0x6d437890ul); + Round(a, b, c, d, e, f, g, h, 0xc39c91f2ul); + Round(h, a, b, c, d, e, f, g, 0x9eccabbdul); + Round(g, h, a, b, c, d, e, f, 0xb5c9a0e6ul); + Round(f, g, h, a, b, c, d, e, 0x532fb63cul); + Round(e, f, g, h, a, b, c, d, 0xd2c741c6ul); + Round(d, e, f, g, h, a, b, c, 0x07237ea3ul); + Round(c, d, e, f, g, h, a, b, 0xa4954b68ul); + Round(b, c, d, e, f, g, h, a, 0x4c191d76ul); + + w0 = t0 + a; + w1 = t1 + b; + w2 = t2 + c; + w3 = t3 + d; + w4 = t4 + e; + w5 = t5 + f; + w6 = t6 + g; + w7 = t7 + h; + + // Transform 3 + a = 0x6a09e667ul; + b = 0xbb67ae85ul; + c = 0x3c6ef372ul; + d = 0xa54ff53aul; + e = 0x510e527ful; + f = 0x9b05688cul; + g = 0x1f83d9abul; + h = 0x5be0cd19ul; + + Round(a, b, c, d, e, f, g, h, 0x428a2f98ul + w0); + Round(h, a, b, c, d, e, f, g, 0x71374491ul + w1); + Round(g, h, a, b, c, d, e, f, 0xb5c0fbcful + w2); + Round(f, g, h, a, b, c, d, e, 0xe9b5dba5ul + w3); + Round(e, f, g, h, a, b, c, d, 0x3956c25bul + w4); + Round(d, e, f, g, h, a, b, c, 0x59f111f1ul + w5); + Round(c, d, e, f, g, h, a, b, 0x923f82a4ul + w6); + Round(b, c, d, e, f, g, h, a, 0xab1c5ed5ul + w7); + Round(a, b, c, d, e, f, g, h, 0x5807aa98ul); + Round(h, a, b, c, d, e, f, g, 0x12835b01ul); + Round(g, h, a, b, c, d, e, f, 0x243185beul); + Round(f, g, h, a, b, c, d, e, 0x550c7dc3ul); + Round(e, f, g, h, a, b, c, d, 0x72be5d74ul); + Round(d, e, f, g, h, a, b, c, 0x80deb1feul); + Round(c, d, e, f, g, h, a, b, 0x9bdc06a7ul); + Round(b, c, d, e, f, g, h, a, 0xc19bf274ul); + Round(a, b, c, d, e, f, g, h, 0xe49b69c1ul + (w0 += sigma0(w1))); + Round(h, a, b, c, d, e, f, g, 0xefbe4786ul + (w1 += 0xa00000ul + sigma0(w2))); + Round(g, h, a, b, c, d, e, f, 0x0fc19dc6ul + (w2 += sigma1(w0) + sigma0(w3))); + Round(f, g, h, a, b, c, d, e, 0x240ca1ccul + (w3 += sigma1(w1) + sigma0(w4))); + Round(e, f, g, h, a, b, c, d, 0x2de92c6ful + (w4 += sigma1(w2) + sigma0(w5))); + Round(d, e, f, g, h, a, b, c, 0x4a7484aaul + (w5 += sigma1(w3) + sigma0(w6))); + Round(c, d, e, f, g, h, a, b, 0x5cb0a9dcul + (w6 += sigma1(w4) + 0x100ul + sigma0(w7))); + Round(b, c, d, e, f, g, h, a, 0x76f988daul + (w7 += sigma1(w5) + w0 + 0x11002000ul)); + Round(a, b, c, d, e, f, g, h, 0x983e5152ul + (w8 = 0x80000000ul + sigma1(w6) + w1)); + Round(h, a, b, c, d, e, f, g, 0xa831c66dul + (w9 = sigma1(w7) + w2)); + Round(g, h, a, b, c, d, e, f, 0xb00327c8ul + (w10 = sigma1(w8) + w3)); + Round(f, g, h, a, b, c, d, e, 0xbf597fc7ul + (w11 = sigma1(w9) + w4)); + Round(e, f, g, h, a, b, c, d, 0xc6e00bf3ul + (w12 = sigma1(w10) + w5)); + Round(d, e, f, g, h, a, b, c, 0xd5a79147ul + (w13 = sigma1(w11) + w6)); + Round(c, d, e, f, g, h, a, b, 0x06ca6351ul + (w14 = sigma1(w12) + w7 + 0x400022ul)); + Round(b, c, d, e, f, g, h, a, 0x14292967ul + (w15 = 0x100ul + sigma1(w13) + w8 + sigma0(w0))); + Round(a, b, c, d, e, f, g, h, 0x27b70a85ul + (w0 += sigma1(w14) + w9 + sigma0(w1))); + Round(h, a, b, c, d, e, f, g, 0x2e1b2138ul + (w1 += sigma1(w15) + w10 + sigma0(w2))); + Round(g, h, a, b, c, d, e, f, 0x4d2c6dfcul + (w2 += sigma1(w0) + w11 + sigma0(w3))); + Round(f, g, h, a, b, c, d, e, 0x53380d13ul + (w3 += sigma1(w1) + w12 + sigma0(w4))); + Round(e, f, g, h, a, b, c, d, 0x650a7354ul + (w4 += sigma1(w2) + w13 + sigma0(w5))); + Round(d, e, f, g, h, a, b, c, 0x766a0abbul + (w5 += sigma1(w3) + w14 + sigma0(w6))); + Round(c, d, e, f, g, h, a, b, 0x81c2c92eul + (w6 += sigma1(w4) + w15 + sigma0(w7))); + Round(b, c, d, e, f, g, h, a, 0x92722c85ul + (w7 += sigma1(w5) + w0 + sigma0(w8))); + Round(a, b, c, d, e, f, g, h, 0xa2bfe8a1ul + (w8 += sigma1(w6) + w1 + sigma0(w9))); + Round(h, a, b, c, d, e, f, g, 0xa81a664bul + (w9 += sigma1(w7) + w2 + sigma0(w10))); + Round(g, h, a, b, c, d, e, f, 0xc24b8b70ul + (w10 += sigma1(w8) + w3 + sigma0(w11))); + Round(f, g, h, a, b, c, d, e, 0xc76c51a3ul + (w11 += sigma1(w9) + w4 + sigma0(w12))); + Round(e, f, g, h, a, b, c, d, 0xd192e819ul + (w12 += sigma1(w10) + w5 + sigma0(w13))); + Round(d, e, f, g, h, a, b, c, 0xd6990624ul + (w13 += sigma1(w11) + w6 + sigma0(w14))); + Round(c, d, e, f, g, h, a, b, 0xf40e3585ul + (w14 += sigma1(w12) + w7 + sigma0(w15))); + Round(b, c, d, e, f, g, h, a, 0x106aa070ul + (w15 += sigma1(w13) + w8 + sigma0(w0))); + Round(a, b, c, d, e, f, g, h, 0x19a4c116ul + (w0 += sigma1(w14) + w9 + sigma0(w1))); + Round(h, a, b, c, d, e, f, g, 0x1e376c08ul + (w1 += sigma1(w15) + w10 + sigma0(w2))); + Round(g, h, a, b, c, d, e, f, 0x2748774cul + (w2 += sigma1(w0) + w11 + sigma0(w3))); + Round(f, g, h, a, b, c, d, e, 0x34b0bcb5ul + (w3 += sigma1(w1) + w12 + sigma0(w4))); + Round(e, f, g, h, a, b, c, d, 0x391c0cb3ul + (w4 += sigma1(w2) + w13 + sigma0(w5))); + Round(d, e, f, g, h, a, b, c, 0x4ed8aa4aul + (w5 += sigma1(w3) + w14 + sigma0(w6))); + Round(c, d, e, f, g, h, a, b, 0x5b9cca4ful + (w6 += sigma1(w4) + w15 + sigma0(w7))); + Round(b, c, d, e, f, g, h, a, 0x682e6ff3ul + (w7 += sigma1(w5) + w0 + sigma0(w8))); + Round(a, b, c, d, e, f, g, h, 0x748f82eeul + (w8 += sigma1(w6) + w1 + sigma0(w9))); + Round(h, a, b, c, d, e, f, g, 0x78a5636ful + (w9 += sigma1(w7) + w2 + sigma0(w10))); + Round(g, h, a, b, c, d, e, f, 0x84c87814ul + (w10 += sigma1(w8) + w3 + sigma0(w11))); + Round(f, g, h, a, b, c, d, e, 0x8cc70208ul + (w11 += sigma1(w9) + w4 + sigma0(w12))); + Round(e, f, g, h, a, b, c, d, 0x90befffaul + (w12 += sigma1(w10) + w5 + sigma0(w13))); + Round(d, e, f, g, h, a, b, c, 0xa4506cebul + (w13 += sigma1(w11) + w6 + sigma0(w14))); + Round(c, d, e, f, g, h, a, b, 0xbef9a3f7ul + (w14 + sigma1(w12) + w7 + sigma0(w15))); + Round(b, c, d, e, f, g, h, a, 0xc67178f2ul + (w15 + sigma1(w13) + w8 + sigma0(w0))); + + // Output + WriteBE32(out + 0, a + 0x6a09e667ul); + WriteBE32(out + 4, b + 0xbb67ae85ul); + WriteBE32(out + 8, c + 0x3c6ef372ul); + WriteBE32(out + 12, d + 0xa54ff53aul); + WriteBE32(out + 16, e + 0x510e527ful); + WriteBE32(out + 20, f + 0x9b05688cul); + WriteBE32(out + 24, g + 0x1f83d9abul); + WriteBE32(out + 28, h + 0x5be0cd19ul); } } // namespace sha256 + +typedef void (*TransformType)(uint32_t*, const unsigned char*, size_t); +typedef void (*TransformD64Type)(unsigned char*, const unsigned char*); + +template +void TransformD64Wrapper(unsigned char* out, const unsigned char* in) +{ + uint32_t s[8]; + static const unsigned char padding1[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, 2, 0 + }; + unsigned char buffer2[64] = { + 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, + 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, 1, 0 + }; + sha256::Initialize(s); + tr(s, in, 1); + tr(s, padding1, 1); + WriteBE32(buffer2 + 0, s[0]); + WriteBE32(buffer2 + 4, s[1]); + WriteBE32(buffer2 + 8, s[2]); + WriteBE32(buffer2 + 12, s[3]); + WriteBE32(buffer2 + 16, s[4]); + WriteBE32(buffer2 + 20, s[5]); + WriteBE32(buffer2 + 24, s[6]); + WriteBE32(buffer2 + 28, s[7]); + sha256::Initialize(s); + tr(s, buffer2, 1); + WriteBE32(out + 0, s[0]); + WriteBE32(out + 4, s[1]); + WriteBE32(out + 8, s[2]); + WriteBE32(out + 12, s[3]); + WriteBE32(out + 16, s[4]); + WriteBE32(out + 20, s[5]); + WriteBE32(out + 24, s[6]); + WriteBE32(out + 28, s[7]); +} + +TransformType Transform = sha256::Transform; +TransformD64Type TransformD64 = sha256::TransformD64; +TransformD64Type TransformD64_2way = nullptr; +TransformD64Type TransformD64_4way = nullptr; +TransformD64Type TransformD64_8way = nullptr; + +bool SelfTest() { + // Input state (equal to the initial SHA256 state) + static const uint32_t init[8] = { + 0x6a09e667ul, 0xbb67ae85ul, 0x3c6ef372ul, 0xa54ff53aul, 0x510e527ful, 0x9b05688cul, 0x1f83d9abul, 0x5be0cd19ul + }; + // Some random input data to test with + static const unsigned char data[641] = "-" // Intentionally not aligned + "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do " + "eiusmod tempor incididunt ut labore et dolore magna aliqua. Et m" + "olestie ac feugiat sed lectus vestibulum mattis ullamcorper. Mor" + "bi blandit cursus risus at ultrices mi tempus imperdiet nulla. N" + "unc congue nisi vita suscipit tellus mauris. Imperdiet proin fer" + "mentum leo vel orci. Massa tempor nec feugiat nisl pretium fusce" + " id velit. Telus in metus vulputate eu scelerisque felis. Mi tem" + "pus imperdiet nulla malesuada pellentesque. Tristique magna sit."; + // Expected output state for hashing the i*64 first input bytes above (excluding SHA256 padding). + static const uint32_t result[9][8] = { + {0x6a09e667ul, 0xbb67ae85ul, 0x3c6ef372ul, 0xa54ff53aul, 0x510e527ful, 0x9b05688cul, 0x1f83d9abul, 0x5be0cd19ul}, + {0x91f8ec6bul, 0x4da10fe3ul, 0x1c9c292cul, 0x45e18185ul, 0x435cc111ul, 0x3ca26f09ul, 0xeb954caeul, 0x402a7069ul}, + {0xcabea5acul, 0x374fb97cul, 0x182ad996ul, 0x7bd69cbful, 0x450ff900ul, 0xc1d2be8aul, 0x6a41d505ul, 0xe6212dc3ul}, + {0xbcff09d6ul, 0x3e76f36eul, 0x3ecb2501ul, 0x78866e97ul, 0xe1c1e2fdul, 0x32f4eafful, 0x8aa6c4e5ul, 0xdfc024bcul}, + {0xa08c5d94ul, 0x0a862f93ul, 0x6b7f2f40ul, 0x8f9fae76ul, 0x6d40439ful, 0x79dcee0cul, 0x3e39ff3aul, 0xdc3bdbb1ul}, + {0x216a0895ul, 0x9f1a3662ul, 0xe99946f9ul, 0x87ba4364ul, 0x0fb5db2cul, 0x12bed3d3ul, 0x6689c0c7ul, 0x292f1b04ul}, + {0xca3067f8ul, 0xbc8c2656ul, 0x37cb7e0dul, 0x9b6b8b0ful, 0x46dc380bul, 0xf1287f57ul, 0xc42e4b23ul, 0x3fefe94dul}, + {0x3e4c4039ul, 0xbb6fca8cul, 0x6f27d2f7ul, 0x301e44a4ul, 0x8352ba14ul, 0x5769ce37ul, 0x48a1155ful, 0xc0e1c4c6ul}, + {0xfe2fa9ddul, 0x69d0862bul, 0x1ae0db23ul, 0x471f9244ul, 0xf55c0145ul, 0xc30f9c3bul, 0x40a84ea0ul, 0x5b8a266cul}, + }; + // Expected output for each of the individual 8 64-byte messages under full double SHA256 (including padding). + static const unsigned char result_d64[256] = { + 0x09, 0x3a, 0xc4, 0xd0, 0x0f, 0xf7, 0x57, 0xe1, 0x72, 0x85, 0x79, 0x42, 0xfe, 0xe7, 0xe0, 0xa0, + 0xfc, 0x52, 0xd7, 0xdb, 0x07, 0x63, 0x45, 0xfb, 0x53, 0x14, 0x7d, 0x17, 0x22, 0x86, 0xf0, 0x52, + 0x48, 0xb6, 0x11, 0x9e, 0x6e, 0x48, 0x81, 0x6d, 0xcc, 0x57, 0x1f, 0xb2, 0x97, 0xa8, 0xd5, 0x25, + 0x9b, 0x82, 0xaa, 0x89, 0xe2, 0xfd, 0x2d, 0x56, 0xe8, 0x28, 0x83, 0x0b, 0xe2, 0xfa, 0x53, 0xb7, + 0xd6, 0x6b, 0x07, 0x85, 0x83, 0xb0, 0x10, 0xa2, 0xf5, 0x51, 0x3c, 0xf9, 0x60, 0x03, 0xab, 0x45, + 0x6c, 0x15, 0x6e, 0xef, 0xb5, 0xac, 0x3e, 0x6c, 0xdf, 0xb4, 0x92, 0x22, 0x2d, 0xce, 0xbf, 0x3e, + 0xe9, 0xe5, 0xf6, 0x29, 0x0e, 0x01, 0x4f, 0xd2, 0xd4, 0x45, 0x65, 0xb3, 0xbb, 0xf2, 0x4c, 0x16, + 0x37, 0x50, 0x3c, 0x6e, 0x49, 0x8c, 0x5a, 0x89, 0x2b, 0x1b, 0xab, 0xc4, 0x37, 0xd1, 0x46, 0xe9, + 0x3d, 0x0e, 0x85, 0xa2, 0x50, 0x73, 0xa1, 0x5e, 0x54, 0x37, 0xd7, 0x94, 0x17, 0x56, 0xc2, 0xd8, + 0xe5, 0x9f, 0xed, 0x4e, 0xae, 0x15, 0x42, 0x06, 0x0d, 0x74, 0x74, 0x5e, 0x24, 0x30, 0xce, 0xd1, + 0x9e, 0x50, 0xa3, 0x9a, 0xb8, 0xf0, 0x4a, 0x57, 0x69, 0x78, 0x67, 0x12, 0x84, 0x58, 0xbe, 0xc7, + 0x36, 0xaa, 0xee, 0x7c, 0x64, 0xa3, 0x76, 0xec, 0xff, 0x55, 0x41, 0x00, 0x2a, 0x44, 0x68, 0x4d, + 0xb6, 0x53, 0x9e, 0x1c, 0x95, 0xb7, 0xca, 0xdc, 0x7f, 0x7d, 0x74, 0x27, 0x5c, 0x8e, 0xa6, 0x84, + 0xb5, 0xac, 0x87, 0xa9, 0xf3, 0xff, 0x75, 0xf2, 0x34, 0xcd, 0x1a, 0x3b, 0x82, 0x2c, 0x2b, 0x4e, + 0x6a, 0x46, 0x30, 0xa6, 0x89, 0x86, 0x23, 0xac, 0xf8, 0xa5, 0x15, 0xe9, 0x0a, 0xaa, 0x1e, 0x9a, + 0xd7, 0x93, 0x6b, 0x28, 0xe4, 0x3b, 0xfd, 0x59, 0xc6, 0xed, 0x7c, 0x5f, 0xa5, 0x41, 0xcb, 0x51 + }; + + + // Test Transform() for 0 through 8 transformations. + for (size_t i = 0; i <= 8; ++i) { + uint32_t state[8]; + std::copy(init, init + 8, state); + Transform(state, data + 1, i); + if (!std::equal(state, state + 8, result[i])) return false; + } + + // Test TransformD64 + unsigned char out[32]; + TransformD64(out, data + 1); + if (!std::equal(out, out + 32, result_d64)) return false; + + // Test TransformD64_2way, if available. + if (TransformD64_2way) { + unsigned char out[64]; + TransformD64_2way(out, data + 1); + if (!std::equal(out, out + 64, result_d64)) return false; + } + + // Test TransformD64_4way, if available. + if (TransformD64_4way) { + unsigned char out[128]; + TransformD64_4way(out, data + 1); + if (!std::equal(out, out + 128, result_d64)) return false; + } + + // Test TransformD64_8way, if available. + if (TransformD64_8way) { + unsigned char out[256]; + TransformD64_8way(out, data + 1); + if (!std::equal(out, out + 256, result_d64)) return false; + } + + return true; +} + +#if defined(USE_ASM) && (defined(__x86_64__) || defined(__amd64__) || defined(__i386__)) +/** Check whether the OS has enabled AVX registers. */ +bool AVXEnabled() +{ + uint32_t a, d; + __asm__("xgetbv" : "=a"(a), "=d"(d) : "c"(0)); + return (a & 6) == 6; +} +#endif } // namespace +std::string SHA256AutoDetect() +{ + std::string ret = "standard"; +#if defined(USE_ASM) && defined(HAVE_GETCPUID) + bool have_sse4 = false; + bool have_xsave = false; + bool have_avx = false; + bool have_avx2 = false; + bool have_shani = false; + bool enabled_avx = false; + + (void)AVXEnabled; + (void)have_sse4; + (void)have_avx; + (void)have_xsave; + (void)have_avx2; + (void)have_shani; + (void)enabled_avx; + + uint32_t eax, ebx, ecx, edx; + GetCPUID(1, 0, eax, ebx, ecx, edx); + have_sse4 = (ecx >> 19) & 1; + have_xsave = (ecx >> 27) & 1; + have_avx = (ecx >> 28) & 1; + if (have_xsave && have_avx) { + enabled_avx = AVXEnabled(); + } + if (have_sse4) { + GetCPUID(7, 0, eax, ebx, ecx, edx); + have_avx2 = (ebx >> 5) & 1; + have_shani = (ebx >> 29) & 1; + } + +#if defined(ENABLE_SHANI) && !defined(BUILD_BITCOIN_INTERNAL) + if (have_shani) { + Transform = sha256_shani::Transform; + TransformD64 = TransformD64Wrapper; + TransformD64_2way = sha256d64_shani::Transform_2way; + ret = "shani(1way,2way)"; + have_sse4 = false; // Disable SSE4/AVX2; + have_avx2 = false; + } +#endif + + if (have_sse4) { +#if defined(__x86_64__) || defined(__amd64__) + Transform = sha256_sse4::Transform; + TransformD64 = TransformD64Wrapper; + ret = "sse4(1way)"; +#endif +#if defined(ENABLE_SSE41) && !defined(BUILD_BITCOIN_INTERNAL) + TransformD64_4way = sha256d64_sse41::Transform_4way; + ret += ",sse41(4way)"; +#endif + } + +#if defined(ENABLE_AVX2) && !defined(BUILD_BITCOIN_INTERNAL) + if (have_avx2 && have_avx && enabled_avx) { + TransformD64_8way = sha256d64_avx2::Transform_8way; + ret += ",avx2(8way)"; + } +#endif +#endif + + assert(SelfTest()); + return ret; +} + ////// SHA-256 CSHA256::CSHA256() : bytes(0) @@ -147,14 +644,14 @@ CSHA256& CSHA256::Write(const unsigned char* data, size_t len) memcpy(buf + bufsize, data, 64 - bufsize); bytes += 64 - bufsize; data += 64 - bufsize; - sha256::Transform(s, buf); + Transform(s, buf, 1); bufsize = 0; } - while (end >= data + 64) { - // Process full chunks directly from the source. - sha256::Transform(s, data); - bytes += 64; - data += 64; + if (end - data >= 64) { + size_t blocks = (end - data) / 64; + Transform(s, data, blocks); + data += 64 * blocks; + bytes += 64 * blocks; } if (end > data) { // Fill the buffer with what remains. @@ -187,3 +684,4 @@ CSHA256& CSHA256::Reset() sha256::Initialize(s); return *this; } + diff --git a/src/crypto/sha256.h b/src/crypto/sha256.h index bde1a59..9a42326 100755 --- a/src/crypto/sha256.h +++ b/src/crypto/sha256.h @@ -7,6 +7,7 @@ #include #include +#include /** A hasher class for SHA-256. */ class CSHA256 @@ -25,4 +26,9 @@ class CSHA256 CSHA256& Reset(); }; +/** Autodetect the best available SHA256 implementation. + * Returns the name of the implementation. + */ +std::string SHA256AutoDetect(); + #endif // BITCOIN_CRYPTO_SHA256_H diff --git a/src/crypto/sha256_sse4.cpp b/src/crypto/sha256_sse4.cpp new file mode 100644 index 0000000..0cb9419 --- /dev/null +++ b/src/crypto/sha256_sse4.cpp @@ -0,0 +1,1507 @@ + +// Copyright (c) 2017 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// +// This is a translation to GCC extended asm syntax from YASM code by Intel +// (available at the bottom of this file). + +#include +#include + +#if defined(__x86_64__) || defined(__amd64__) + +namespace sha256_sse4 +{ +void Transform(uint32_t* s, const unsigned char* chunk, size_t blocks) +{ + static const uint32_t K256 alignas(16) [] = { + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, + 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, + 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, + 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, + 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, + 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, + 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, + 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, + 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2, + }; + static const uint32_t FLIP_MASK alignas(16) [] = {0x00010203, 0x04050607, 0x08090a0b, 0x0c0d0e0f}; + static const uint32_t SHUF_00BA alignas(16) [] = {0x03020100, 0x0b0a0908, 0xffffffff, 0xffffffff}; + static const uint32_t SHUF_DC00 alignas(16) [] = {0xffffffff, 0xffffffff, 0x03020100, 0x0b0a0908}; + uint32_t a, b, c, d, f, g, h, y0, y1, y2; + uint64_t tbl; + uint64_t inp_end, inp; + uint32_t xfer alignas(16) [4]; + + __asm__ __volatile__( + "shl $0x6,%2;" + "je Ldone_hash_%=;" + "add %1,%2;" + "mov %2,%14;" + "mov (%0),%3;" + "mov 0x4(%0),%4;" + "mov 0x8(%0),%5;" + "mov 0xc(%0),%6;" + "mov 0x10(%0),%k2;" + "mov 0x14(%0),%7;" + "mov 0x18(%0),%8;" + "mov 0x1c(%0),%9;" + "movdqa %18,%%xmm12;" + "movdqa %19,%%xmm10;" + "movdqa %20,%%xmm11;" + + "Lloop0_%=:" + "lea %17,%13;" + "movdqu (%1),%%xmm4;" + "pshufb %%xmm12,%%xmm4;" + "movdqu 0x10(%1),%%xmm5;" + "pshufb %%xmm12,%%xmm5;" + "movdqu 0x20(%1),%%xmm6;" + "pshufb %%xmm12,%%xmm6;" + "movdqu 0x30(%1),%%xmm7;" + "pshufb %%xmm12,%%xmm7;" + "mov %1,%15;" + "mov $3,%1;" + + "Lloop1_%=:" + "movdqa 0x0(%13),%%xmm9;" + "paddd %%xmm4,%%xmm9;" + "movdqa %%xmm9,%16;" + "movdqa %%xmm7,%%xmm0;" + "mov %k2,%10;" + "ror $0xe,%10;" + "mov %3,%11;" + "palignr $0x4,%%xmm6,%%xmm0;" + "ror $0x9,%11;" + "xor %k2,%10;" + "mov %7,%12;" + "ror $0x5,%10;" + "movdqa %%xmm5,%%xmm1;" + "xor %3,%11;" + "xor %8,%12;" + "paddd %%xmm4,%%xmm0;" + "xor %k2,%10;" + "and %k2,%12;" + "ror $0xb,%11;" + "palignr $0x4,%%xmm4,%%xmm1;" + "xor %3,%11;" + "ror $0x6,%10;" + "xor %8,%12;" + "movdqa %%xmm1,%%xmm2;" + "ror $0x2,%11;" + "add %10,%12;" + "add %16,%12;" + "movdqa %%xmm1,%%xmm3;" + "mov %3,%10;" + "add %12,%9;" + "mov %3,%12;" + "pslld $0x19,%%xmm1;" + "or %5,%10;" + "add %9,%6;" + "and %5,%12;" + "psrld $0x7,%%xmm2;" + "and %4,%10;" + "add %11,%9;" + "por %%xmm2,%%xmm1;" + "or %12,%10;" + "add %10,%9;" + "movdqa %%xmm3,%%xmm2;" + "mov %6,%10;" + "mov %9,%11;" + "movdqa %%xmm3,%%xmm8;" + "ror $0xe,%10;" + "xor %6,%10;" + "mov %k2,%12;" + "ror $0x9,%11;" + "pslld $0xe,%%xmm3;" + "xor %9,%11;" + "ror $0x5,%10;" + "xor %7,%12;" + "psrld $0x12,%%xmm2;" + "ror $0xb,%11;" + "xor %6,%10;" + "and %6,%12;" + "ror $0x6,%10;" + "pxor %%xmm3,%%xmm1;" + "xor %9,%11;" + "xor %7,%12;" + "psrld $0x3,%%xmm8;" + "add %10,%12;" + "add 4+%16,%12;" + "ror $0x2,%11;" + "pxor %%xmm2,%%xmm1;" + "mov %9,%10;" + "add %12,%8;" + "mov %9,%12;" + "pxor %%xmm8,%%xmm1;" + "or %4,%10;" + "add %8,%5;" + "and %4,%12;" + "pshufd $0xfa,%%xmm7,%%xmm2;" + "and %3,%10;" + "add %11,%8;" + "paddd %%xmm1,%%xmm0;" + "or %12,%10;" + "add %10,%8;" + "movdqa %%xmm2,%%xmm3;" + "mov %5,%10;" + "mov %8,%11;" + "ror $0xe,%10;" + "movdqa %%xmm2,%%xmm8;" + "xor %5,%10;" + "ror $0x9,%11;" + "mov %6,%12;" + "xor %8,%11;" + "ror $0x5,%10;" + "psrlq $0x11,%%xmm2;" + "xor %k2,%12;" + "psrlq $0x13,%%xmm3;" + "xor %5,%10;" + "and %5,%12;" + "psrld $0xa,%%xmm8;" + "ror $0xb,%11;" + "xor %8,%11;" + "xor %k2,%12;" + "ror $0x6,%10;" + "pxor %%xmm3,%%xmm2;" + "add %10,%12;" + "ror $0x2,%11;" + "add 8+%16,%12;" + "pxor %%xmm2,%%xmm8;" + "mov %8,%10;" + "add %12,%7;" + "mov %8,%12;" + "pshufb %%xmm10,%%xmm8;" + "or %3,%10;" + "add %7,%4;" + "and %3,%12;" + "paddd %%xmm8,%%xmm0;" + "and %9,%10;" + "add %11,%7;" + "pshufd $0x50,%%xmm0,%%xmm2;" + "or %12,%10;" + "add %10,%7;" + "movdqa %%xmm2,%%xmm3;" + "mov %4,%10;" + "ror $0xe,%10;" + "mov %7,%11;" + "movdqa %%xmm2,%%xmm4;" + "ror $0x9,%11;" + "xor %4,%10;" + "mov %5,%12;" + "ror $0x5,%10;" + "psrlq $0x11,%%xmm2;" + "xor %7,%11;" + "xor %6,%12;" + "psrlq $0x13,%%xmm3;" + "xor %4,%10;" + "and %4,%12;" + "ror $0xb,%11;" + "psrld $0xa,%%xmm4;" + "xor %7,%11;" + "ror $0x6,%10;" + "xor %6,%12;" + "pxor %%xmm3,%%xmm2;" + "ror $0x2,%11;" + "add %10,%12;" + "add 12+%16,%12;" + "pxor %%xmm2,%%xmm4;" + "mov %7,%10;" + "add %12,%k2;" + "mov %7,%12;" + "pshufb %%xmm11,%%xmm4;" + "or %9,%10;" + "add %k2,%3;" + "and %9,%12;" + "paddd %%xmm0,%%xmm4;" + "and %8,%10;" + "add %11,%k2;" + "or %12,%10;" + "add %10,%k2;" + "movdqa 0x10(%13),%%xmm9;" + "paddd %%xmm5,%%xmm9;" + "movdqa %%xmm9,%16;" + "movdqa %%xmm4,%%xmm0;" + "mov %3,%10;" + "ror $0xe,%10;" + "mov %k2,%11;" + "palignr $0x4,%%xmm7,%%xmm0;" + "ror $0x9,%11;" + "xor %3,%10;" + "mov %4,%12;" + "ror $0x5,%10;" + "movdqa %%xmm6,%%xmm1;" + "xor %k2,%11;" + "xor %5,%12;" + "paddd %%xmm5,%%xmm0;" + "xor %3,%10;" + "and %3,%12;" + "ror $0xb,%11;" + "palignr $0x4,%%xmm5,%%xmm1;" + "xor %k2,%11;" + "ror $0x6,%10;" + "xor %5,%12;" + "movdqa %%xmm1,%%xmm2;" + "ror $0x2,%11;" + "add %10,%12;" + "add %16,%12;" + "movdqa %%xmm1,%%xmm3;" + "mov %k2,%10;" + "add %12,%6;" + "mov %k2,%12;" + "pslld $0x19,%%xmm1;" + "or %8,%10;" + "add %6,%9;" + "and %8,%12;" + "psrld $0x7,%%xmm2;" + "and %7,%10;" + "add %11,%6;" + "por %%xmm2,%%xmm1;" + "or %12,%10;" + "add %10,%6;" + "movdqa %%xmm3,%%xmm2;" + "mov %9,%10;" + "mov %6,%11;" + "movdqa %%xmm3,%%xmm8;" + "ror $0xe,%10;" + "xor %9,%10;" + "mov %3,%12;" + "ror $0x9,%11;" + "pslld $0xe,%%xmm3;" + "xor %6,%11;" + "ror $0x5,%10;" + "xor %4,%12;" + "psrld $0x12,%%xmm2;" + "ror $0xb,%11;" + "xor %9,%10;" + "and %9,%12;" + "ror $0x6,%10;" + "pxor %%xmm3,%%xmm1;" + "xor %6,%11;" + "xor %4,%12;" + "psrld $0x3,%%xmm8;" + "add %10,%12;" + "add 4+%16,%12;" + "ror $0x2,%11;" + "pxor %%xmm2,%%xmm1;" + "mov %6,%10;" + "add %12,%5;" + "mov %6,%12;" + "pxor %%xmm8,%%xmm1;" + "or %7,%10;" + "add %5,%8;" + "and %7,%12;" + "pshufd $0xfa,%%xmm4,%%xmm2;" + "and %k2,%10;" + "add %11,%5;" + "paddd %%xmm1,%%xmm0;" + "or %12,%10;" + "add %10,%5;" + "movdqa %%xmm2,%%xmm3;" + "mov %8,%10;" + "mov %5,%11;" + "ror $0xe,%10;" + "movdqa %%xmm2,%%xmm8;" + "xor %8,%10;" + "ror $0x9,%11;" + "mov %9,%12;" + "xor %5,%11;" + "ror $0x5,%10;" + "psrlq $0x11,%%xmm2;" + "xor %3,%12;" + "psrlq $0x13,%%xmm3;" + "xor %8,%10;" + "and %8,%12;" + "psrld $0xa,%%xmm8;" + "ror $0xb,%11;" + "xor %5,%11;" + "xor %3,%12;" + "ror $0x6,%10;" + "pxor %%xmm3,%%xmm2;" + "add %10,%12;" + "ror $0x2,%11;" + "add 8+%16,%12;" + "pxor %%xmm2,%%xmm8;" + "mov %5,%10;" + "add %12,%4;" + "mov %5,%12;" + "pshufb %%xmm10,%%xmm8;" + "or %k2,%10;" + "add %4,%7;" + "and %k2,%12;" + "paddd %%xmm8,%%xmm0;" + "and %6,%10;" + "add %11,%4;" + "pshufd $0x50,%%xmm0,%%xmm2;" + "or %12,%10;" + "add %10,%4;" + "movdqa %%xmm2,%%xmm3;" + "mov %7,%10;" + "ror $0xe,%10;" + "mov %4,%11;" + "movdqa %%xmm2,%%xmm5;" + "ror $0x9,%11;" + "xor %7,%10;" + "mov %8,%12;" + "ror $0x5,%10;" + "psrlq $0x11,%%xmm2;" + "xor %4,%11;" + "xor %9,%12;" + "psrlq $0x13,%%xmm3;" + "xor %7,%10;" + "and %7,%12;" + "ror $0xb,%11;" + "psrld $0xa,%%xmm5;" + "xor %4,%11;" + "ror $0x6,%10;" + "xor %9,%12;" + "pxor %%xmm3,%%xmm2;" + "ror $0x2,%11;" + "add %10,%12;" + "add 12+%16,%12;" + "pxor %%xmm2,%%xmm5;" + "mov %4,%10;" + "add %12,%3;" + "mov %4,%12;" + "pshufb %%xmm11,%%xmm5;" + "or %6,%10;" + "add %3,%k2;" + "and %6,%12;" + "paddd %%xmm0,%%xmm5;" + "and %5,%10;" + "add %11,%3;" + "or %12,%10;" + "add %10,%3;" + "movdqa 0x20(%13),%%xmm9;" + "paddd %%xmm6,%%xmm9;" + "movdqa %%xmm9,%16;" + "movdqa %%xmm5,%%xmm0;" + "mov %k2,%10;" + "ror $0xe,%10;" + "mov %3,%11;" + "palignr $0x4,%%xmm4,%%xmm0;" + "ror $0x9,%11;" + "xor %k2,%10;" + "mov %7,%12;" + "ror $0x5,%10;" + "movdqa %%xmm7,%%xmm1;" + "xor %3,%11;" + "xor %8,%12;" + "paddd %%xmm6,%%xmm0;" + "xor %k2,%10;" + "and %k2,%12;" + "ror $0xb,%11;" + "palignr $0x4,%%xmm6,%%xmm1;" + "xor %3,%11;" + "ror $0x6,%10;" + "xor %8,%12;" + "movdqa %%xmm1,%%xmm2;" + "ror $0x2,%11;" + "add %10,%12;" + "add %16,%12;" + "movdqa %%xmm1,%%xmm3;" + "mov %3,%10;" + "add %12,%9;" + "mov %3,%12;" + "pslld $0x19,%%xmm1;" + "or %5,%10;" + "add %9,%6;" + "and %5,%12;" + "psrld $0x7,%%xmm2;" + "and %4,%10;" + "add %11,%9;" + "por %%xmm2,%%xmm1;" + "or %12,%10;" + "add %10,%9;" + "movdqa %%xmm3,%%xmm2;" + "mov %6,%10;" + "mov %9,%11;" + "movdqa %%xmm3,%%xmm8;" + "ror $0xe,%10;" + "xor %6,%10;" + "mov %k2,%12;" + "ror $0x9,%11;" + "pslld $0xe,%%xmm3;" + "xor %9,%11;" + "ror $0x5,%10;" + "xor %7,%12;" + "psrld $0x12,%%xmm2;" + "ror $0xb,%11;" + "xor %6,%10;" + "and %6,%12;" + "ror $0x6,%10;" + "pxor %%xmm3,%%xmm1;" + "xor %9,%11;" + "xor %7,%12;" + "psrld $0x3,%%xmm8;" + "add %10,%12;" + "add 4+%16,%12;" + "ror $0x2,%11;" + "pxor %%xmm2,%%xmm1;" + "mov %9,%10;" + "add %12,%8;" + "mov %9,%12;" + "pxor %%xmm8,%%xmm1;" + "or %4,%10;" + "add %8,%5;" + "and %4,%12;" + "pshufd $0xfa,%%xmm5,%%xmm2;" + "and %3,%10;" + "add %11,%8;" + "paddd %%xmm1,%%xmm0;" + "or %12,%10;" + "add %10,%8;" + "movdqa %%xmm2,%%xmm3;" + "mov %5,%10;" + "mov %8,%11;" + "ror $0xe,%10;" + "movdqa %%xmm2,%%xmm8;" + "xor %5,%10;" + "ror $0x9,%11;" + "mov %6,%12;" + "xor %8,%11;" + "ror $0x5,%10;" + "psrlq $0x11,%%xmm2;" + "xor %k2,%12;" + "psrlq $0x13,%%xmm3;" + "xor %5,%10;" + "and %5,%12;" + "psrld $0xa,%%xmm8;" + "ror $0xb,%11;" + "xor %8,%11;" + "xor %k2,%12;" + "ror $0x6,%10;" + "pxor %%xmm3,%%xmm2;" + "add %10,%12;" + "ror $0x2,%11;" + "add 8+%16,%12;" + "pxor %%xmm2,%%xmm8;" + "mov %8,%10;" + "add %12,%7;" + "mov %8,%12;" + "pshufb %%xmm10,%%xmm8;" + "or %3,%10;" + "add %7,%4;" + "and %3,%12;" + "paddd %%xmm8,%%xmm0;" + "and %9,%10;" + "add %11,%7;" + "pshufd $0x50,%%xmm0,%%xmm2;" + "or %12,%10;" + "add %10,%7;" + "movdqa %%xmm2,%%xmm3;" + "mov %4,%10;" + "ror $0xe,%10;" + "mov %7,%11;" + "movdqa %%xmm2,%%xmm6;" + "ror $0x9,%11;" + "xor %4,%10;" + "mov %5,%12;" + "ror $0x5,%10;" + "psrlq $0x11,%%xmm2;" + "xor %7,%11;" + "xor %6,%12;" + "psrlq $0x13,%%xmm3;" + "xor %4,%10;" + "and %4,%12;" + "ror $0xb,%11;" + "psrld $0xa,%%xmm6;" + "xor %7,%11;" + "ror $0x6,%10;" + "xor %6,%12;" + "pxor %%xmm3,%%xmm2;" + "ror $0x2,%11;" + "add %10,%12;" + "add 12+%16,%12;" + "pxor %%xmm2,%%xmm6;" + "mov %7,%10;" + "add %12,%k2;" + "mov %7,%12;" + "pshufb %%xmm11,%%xmm6;" + "or %9,%10;" + "add %k2,%3;" + "and %9,%12;" + "paddd %%xmm0,%%xmm6;" + "and %8,%10;" + "add %11,%k2;" + "or %12,%10;" + "add %10,%k2;" + "movdqa 0x30(%13),%%xmm9;" + "paddd %%xmm7,%%xmm9;" + "movdqa %%xmm9,%16;" + "add $0x40,%13;" + "movdqa %%xmm6,%%xmm0;" + "mov %3,%10;" + "ror $0xe,%10;" + "mov %k2,%11;" + "palignr $0x4,%%xmm5,%%xmm0;" + "ror $0x9,%11;" + "xor %3,%10;" + "mov %4,%12;" + "ror $0x5,%10;" + "movdqa %%xmm4,%%xmm1;" + "xor %k2,%11;" + "xor %5,%12;" + "paddd %%xmm7,%%xmm0;" + "xor %3,%10;" + "and %3,%12;" + "ror $0xb,%11;" + "palignr $0x4,%%xmm7,%%xmm1;" + "xor %k2,%11;" + "ror $0x6,%10;" + "xor %5,%12;" + "movdqa %%xmm1,%%xmm2;" + "ror $0x2,%11;" + "add %10,%12;" + "add %16,%12;" + "movdqa %%xmm1,%%xmm3;" + "mov %k2,%10;" + "add %12,%6;" + "mov %k2,%12;" + "pslld $0x19,%%xmm1;" + "or %8,%10;" + "add %6,%9;" + "and %8,%12;" + "psrld $0x7,%%xmm2;" + "and %7,%10;" + "add %11,%6;" + "por %%xmm2,%%xmm1;" + "or %12,%10;" + "add %10,%6;" + "movdqa %%xmm3,%%xmm2;" + "mov %9,%10;" + "mov %6,%11;" + "movdqa %%xmm3,%%xmm8;" + "ror $0xe,%10;" + "xor %9,%10;" + "mov %3,%12;" + "ror $0x9,%11;" + "pslld $0xe,%%xmm3;" + "xor %6,%11;" + "ror $0x5,%10;" + "xor %4,%12;" + "psrld $0x12,%%xmm2;" + "ror $0xb,%11;" + "xor %9,%10;" + "and %9,%12;" + "ror $0x6,%10;" + "pxor %%xmm3,%%xmm1;" + "xor %6,%11;" + "xor %4,%12;" + "psrld $0x3,%%xmm8;" + "add %10,%12;" + "add 4+%16,%12;" + "ror $0x2,%11;" + "pxor %%xmm2,%%xmm1;" + "mov %6,%10;" + "add %12,%5;" + "mov %6,%12;" + "pxor %%xmm8,%%xmm1;" + "or %7,%10;" + "add %5,%8;" + "and %7,%12;" + "pshufd $0xfa,%%xmm6,%%xmm2;" + "and %k2,%10;" + "add %11,%5;" + "paddd %%xmm1,%%xmm0;" + "or %12,%10;" + "add %10,%5;" + "movdqa %%xmm2,%%xmm3;" + "mov %8,%10;" + "mov %5,%11;" + "ror $0xe,%10;" + "movdqa %%xmm2,%%xmm8;" + "xor %8,%10;" + "ror $0x9,%11;" + "mov %9,%12;" + "xor %5,%11;" + "ror $0x5,%10;" + "psrlq $0x11,%%xmm2;" + "xor %3,%12;" + "psrlq $0x13,%%xmm3;" + "xor %8,%10;" + "and %8,%12;" + "psrld $0xa,%%xmm8;" + "ror $0xb,%11;" + "xor %5,%11;" + "xor %3,%12;" + "ror $0x6,%10;" + "pxor %%xmm3,%%xmm2;" + "add %10,%12;" + "ror $0x2,%11;" + "add 8+%16,%12;" + "pxor %%xmm2,%%xmm8;" + "mov %5,%10;" + "add %12,%4;" + "mov %5,%12;" + "pshufb %%xmm10,%%xmm8;" + "or %k2,%10;" + "add %4,%7;" + "and %k2,%12;" + "paddd %%xmm8,%%xmm0;" + "and %6,%10;" + "add %11,%4;" + "pshufd $0x50,%%xmm0,%%xmm2;" + "or %12,%10;" + "add %10,%4;" + "movdqa %%xmm2,%%xmm3;" + "mov %7,%10;" + "ror $0xe,%10;" + "mov %4,%11;" + "movdqa %%xmm2,%%xmm7;" + "ror $0x9,%11;" + "xor %7,%10;" + "mov %8,%12;" + "ror $0x5,%10;" + "psrlq $0x11,%%xmm2;" + "xor %4,%11;" + "xor %9,%12;" + "psrlq $0x13,%%xmm3;" + "xor %7,%10;" + "and %7,%12;" + "ror $0xb,%11;" + "psrld $0xa,%%xmm7;" + "xor %4,%11;" + "ror $0x6,%10;" + "xor %9,%12;" + "pxor %%xmm3,%%xmm2;" + "ror $0x2,%11;" + "add %10,%12;" + "add 12+%16,%12;" + "pxor %%xmm2,%%xmm7;" + "mov %4,%10;" + "add %12,%3;" + "mov %4,%12;" + "pshufb %%xmm11,%%xmm7;" + "or %6,%10;" + "add %3,%k2;" + "and %6,%12;" + "paddd %%xmm0,%%xmm7;" + "and %5,%10;" + "add %11,%3;" + "or %12,%10;" + "add %10,%3;" + "sub $0x1,%1;" + "jne Lloop1_%=;" + "mov $0x2,%1;" + + "Lloop2_%=:" + "paddd 0x0(%13),%%xmm4;" + "movdqa %%xmm4,%16;" + "mov %k2,%10;" + "ror $0xe,%10;" + "mov %3,%11;" + "xor %k2,%10;" + "ror $0x9,%11;" + "mov %7,%12;" + "xor %3,%11;" + "ror $0x5,%10;" + "xor %8,%12;" + "xor %k2,%10;" + "ror $0xb,%11;" + "and %k2,%12;" + "xor %3,%11;" + "ror $0x6,%10;" + "xor %8,%12;" + "add %10,%12;" + "ror $0x2,%11;" + "add %16,%12;" + "mov %3,%10;" + "add %12,%9;" + "mov %3,%12;" + "or %5,%10;" + "add %9,%6;" + "and %5,%12;" + "and %4,%10;" + "add %11,%9;" + "or %12,%10;" + "add %10,%9;" + "mov %6,%10;" + "ror $0xe,%10;" + "mov %9,%11;" + "xor %6,%10;" + "ror $0x9,%11;" + "mov %k2,%12;" + "xor %9,%11;" + "ror $0x5,%10;" + "xor %7,%12;" + "xor %6,%10;" + "ror $0xb,%11;" + "and %6,%12;" + "xor %9,%11;" + "ror $0x6,%10;" + "xor %7,%12;" + "add %10,%12;" + "ror $0x2,%11;" + "add 4+%16,%12;" + "mov %9,%10;" + "add %12,%8;" + "mov %9,%12;" + "or %4,%10;" + "add %8,%5;" + "and %4,%12;" + "and %3,%10;" + "add %11,%8;" + "or %12,%10;" + "add %10,%8;" + "mov %5,%10;" + "ror $0xe,%10;" + "mov %8,%11;" + "xor %5,%10;" + "ror $0x9,%11;" + "mov %6,%12;" + "xor %8,%11;" + "ror $0x5,%10;" + "xor %k2,%12;" + "xor %5,%10;" + "ror $0xb,%11;" + "and %5,%12;" + "xor %8,%11;" + "ror $0x6,%10;" + "xor %k2,%12;" + "add %10,%12;" + "ror $0x2,%11;" + "add 8+%16,%12;" + "mov %8,%10;" + "add %12,%7;" + "mov %8,%12;" + "or %3,%10;" + "add %7,%4;" + "and %3,%12;" + "and %9,%10;" + "add %11,%7;" + "or %12,%10;" + "add %10,%7;" + "mov %4,%10;" + "ror $0xe,%10;" + "mov %7,%11;" + "xor %4,%10;" + "ror $0x9,%11;" + "mov %5,%12;" + "xor %7,%11;" + "ror $0x5,%10;" + "xor %6,%12;" + "xor %4,%10;" + "ror $0xb,%11;" + "and %4,%12;" + "xor %7,%11;" + "ror $0x6,%10;" + "xor %6,%12;" + "add %10,%12;" + "ror $0x2,%11;" + "add 12+%16,%12;" + "mov %7,%10;" + "add %12,%k2;" + "mov %7,%12;" + "or %9,%10;" + "add %k2,%3;" + "and %9,%12;" + "and %8,%10;" + "add %11,%k2;" + "or %12,%10;" + "add %10,%k2;" + "paddd 0x10(%13),%%xmm5;" + "movdqa %%xmm5,%16;" + "add $0x20,%13;" + "mov %3,%10;" + "ror $0xe,%10;" + "mov %k2,%11;" + "xor %3,%10;" + "ror $0x9,%11;" + "mov %4,%12;" + "xor %k2,%11;" + "ror $0x5,%10;" + "xor %5,%12;" + "xor %3,%10;" + "ror $0xb,%11;" + "and %3,%12;" + "xor %k2,%11;" + "ror $0x6,%10;" + "xor %5,%12;" + "add %10,%12;" + "ror $0x2,%11;" + "add %16,%12;" + "mov %k2,%10;" + "add %12,%6;" + "mov %k2,%12;" + "or %8,%10;" + "add %6,%9;" + "and %8,%12;" + "and %7,%10;" + "add %11,%6;" + "or %12,%10;" + "add %10,%6;" + "mov %9,%10;" + "ror $0xe,%10;" + "mov %6,%11;" + "xor %9,%10;" + "ror $0x9,%11;" + "mov %3,%12;" + "xor %6,%11;" + "ror $0x5,%10;" + "xor %4,%12;" + "xor %9,%10;" + "ror $0xb,%11;" + "and %9,%12;" + "xor %6,%11;" + "ror $0x6,%10;" + "xor %4,%12;" + "add %10,%12;" + "ror $0x2,%11;" + "add 4+%16,%12;" + "mov %6,%10;" + "add %12,%5;" + "mov %6,%12;" + "or %7,%10;" + "add %5,%8;" + "and %7,%12;" + "and %k2,%10;" + "add %11,%5;" + "or %12,%10;" + "add %10,%5;" + "mov %8,%10;" + "ror $0xe,%10;" + "mov %5,%11;" + "xor %8,%10;" + "ror $0x9,%11;" + "mov %9,%12;" + "xor %5,%11;" + "ror $0x5,%10;" + "xor %3,%12;" + "xor %8,%10;" + "ror $0xb,%11;" + "and %8,%12;" + "xor %5,%11;" + "ror $0x6,%10;" + "xor %3,%12;" + "add %10,%12;" + "ror $0x2,%11;" + "add 8+%16,%12;" + "mov %5,%10;" + "add %12,%4;" + "mov %5,%12;" + "or %k2,%10;" + "add %4,%7;" + "and %k2,%12;" + "and %6,%10;" + "add %11,%4;" + "or %12,%10;" + "add %10,%4;" + "mov %7,%10;" + "ror $0xe,%10;" + "mov %4,%11;" + "xor %7,%10;" + "ror $0x9,%11;" + "mov %8,%12;" + "xor %4,%11;" + "ror $0x5,%10;" + "xor %9,%12;" + "xor %7,%10;" + "ror $0xb,%11;" + "and %7,%12;" + "xor %4,%11;" + "ror $0x6,%10;" + "xor %9,%12;" + "add %10,%12;" + "ror $0x2,%11;" + "add 12+%16,%12;" + "mov %4,%10;" + "add %12,%3;" + "mov %4,%12;" + "or %6,%10;" + "add %3,%k2;" + "and %6,%12;" + "and %5,%10;" + "add %11,%3;" + "or %12,%10;" + "add %10,%3;" + "movdqa %%xmm6,%%xmm4;" + "movdqa %%xmm7,%%xmm5;" + "sub $0x1,%1;" + "jne Lloop2_%=;" + "add (%0),%3;" + "mov %3,(%0);" + "add 0x4(%0),%4;" + "mov %4,0x4(%0);" + "add 0x8(%0),%5;" + "mov %5,0x8(%0);" + "add 0xc(%0),%6;" + "mov %6,0xc(%0);" + "add 0x10(%0),%k2;" + "mov %k2,0x10(%0);" + "add 0x14(%0),%7;" + "mov %7,0x14(%0);" + "add 0x18(%0),%8;" + "mov %8,0x18(%0);" + "add 0x1c(%0),%9;" + "mov %9,0x1c(%0);" + "mov %15,%1;" + "add $0x40,%1;" + "cmp %14,%1;" + "jne Lloop0_%=;" + + "Ldone_hash_%=:" + + : "+r"(s), "+r"(chunk), "+r"(blocks), "=r"(a), "=r"(b), "=r"(c), "=r"(d), /* e = chunk */ "=r"(f), "=r"(g), "=r"(h), "=r"(y0), "=r"(y1), "=r"(y2), "=r"(tbl), "+m"(inp_end), "+m"(inp), "+m"(xfer) + : "m"(K256), "m"(FLIP_MASK), "m"(SHUF_00BA), "m"(SHUF_DC00) + : "cc", "memory", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", "xmm8", "xmm9", "xmm10", "xmm11", "xmm12" + ); +} +} + +/* +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Copyright (c) 2012, Intel Corporation +; +; All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are +; met: +; +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the +; distribution. +; +; * Neither the name of the Intel Corporation nor the names of its +; contributors may be used to endorse or promote products derived from +; this software without specific prior written permission. +; +; +; THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY +; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +; PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL CORPORATION OR +; CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +; EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +; PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +; LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; Example YASM command lines: +; Windows: yasm -Xvc -f x64 -rnasm -pnasm -o sha256_sse4.obj -g cv8 sha256_sse4.asm +; Linux: yasm -f x64 -f elf64 -X gnu -g dwarf2 -D LINUX -o sha256_sse4.o sha256_sse4.asm +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; This code is described in an Intel White-Paper: +; "Fast SHA-256 Implementations on Intel Architecture Processors" +; +; To find it, surf to http://www.intel.com/p/en_US/embedded +; and search for that title. +; The paper is expected to be released roughly at the end of April, 2012 +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; This code schedules 1 blocks at a time, with 4 lanes per block +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +%define MOVDQ movdqu ;; assume buffers not aligned + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Define Macros + +; addm [mem], reg +; Add reg to mem using reg-mem add and store +%macro addm 2 + add %2, %1 + mov %1, %2 +%endm + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; COPY_XMM_AND_BSWAP xmm, [mem], byte_flip_mask +; Load xmm with mem and byte swap each dword +%macro COPY_XMM_AND_BSWAP 3 + MOVDQ %1, %2 + pshufb %1, %3 +%endmacro + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +%define X0 xmm4 +%define X1 xmm5 +%define X2 xmm6 +%define X3 xmm7 + +%define XTMP0 xmm0 +%define XTMP1 xmm1 +%define XTMP2 xmm2 +%define XTMP3 xmm3 +%define XTMP4 xmm8 +%define XFER xmm9 + +%define SHUF_00BA xmm10 ; shuffle xBxA -> 00BA +%define SHUF_DC00 xmm11 ; shuffle xDxC -> DC00 +%define BYTE_FLIP_MASK xmm12 + +%ifdef LINUX +%define NUM_BLKS rdx ; 3rd arg +%define CTX rsi ; 2nd arg +%define INP rdi ; 1st arg + +%define SRND rdi ; clobbers INP +%define c ecx +%define d r8d +%define e edx +%else +%define NUM_BLKS r8 ; 3rd arg +%define CTX rdx ; 2nd arg +%define INP rcx ; 1st arg + +%define SRND rcx ; clobbers INP +%define c edi +%define d esi +%define e r8d + +%endif +%define TBL rbp +%define a eax +%define b ebx + +%define f r9d +%define g r10d +%define h r11d + +%define y0 r13d +%define y1 r14d +%define y2 r15d + + + +_INP_END_SIZE equ 8 +_INP_SIZE equ 8 +_XFER_SIZE equ 8 +%ifdef LINUX +_XMM_SAVE_SIZE equ 0 +%else +_XMM_SAVE_SIZE equ 7*16 +%endif +; STACK_SIZE plus pushes must be an odd multiple of 8 +_ALIGN_SIZE equ 8 + +_INP_END equ 0 +_INP equ _INP_END + _INP_END_SIZE +_XFER equ _INP + _INP_SIZE +_XMM_SAVE equ _XFER + _XFER_SIZE + _ALIGN_SIZE +STACK_SIZE equ _XMM_SAVE + _XMM_SAVE_SIZE + +; rotate_Xs +; Rotate values of symbols X0...X3 +%macro rotate_Xs 0 +%xdefine X_ X0 +%xdefine X0 X1 +%xdefine X1 X2 +%xdefine X2 X3 +%xdefine X3 X_ +%endm + +; ROTATE_ARGS +; Rotate values of symbols a...h +%macro ROTATE_ARGS 0 +%xdefine TMP_ h +%xdefine h g +%xdefine g f +%xdefine f e +%xdefine e d +%xdefine d c +%xdefine c b +%xdefine b a +%xdefine a TMP_ +%endm + +%macro FOUR_ROUNDS_AND_SCHED 0 + ;; compute s0 four at a time and s1 two at a time + ;; compute W[-16] + W[-7] 4 at a time + movdqa XTMP0, X3 + mov y0, e ; y0 = e + ror y0, (25-11) ; y0 = e >> (25-11) + mov y1, a ; y1 = a + palignr XTMP0, X2, 4 ; XTMP0 = W[-7] + ror y1, (22-13) ; y1 = a >> (22-13) + xor y0, e ; y0 = e ^ (e >> (25-11)) + mov y2, f ; y2 = f + ror y0, (11-6) ; y0 = (e >> (11-6)) ^ (e >> (25-6)) + movdqa XTMP1, X1 + xor y1, a ; y1 = a ^ (a >> (22-13) + xor y2, g ; y2 = f^g + paddd XTMP0, X0 ; XTMP0 = W[-7] + W[-16] + xor y0, e ; y0 = e ^ (e >> (11-6)) ^ (e >> (25-6)) + and y2, e ; y2 = (f^g)&e + ror y1, (13-2) ; y1 = (a >> (13-2)) ^ (a >> (22-2)) + ;; compute s0 + palignr XTMP1, X0, 4 ; XTMP1 = W[-15] + xor y1, a ; y1 = a ^ (a >> (13-2)) ^ (a >> (22-2)) + ror y0, 6 ; y0 = S1 = (e>>6) & (e>>11) ^ (e>>25) + xor y2, g ; y2 = CH = ((f^g)&e)^g + movdqa XTMP2, XTMP1 ; XTMP2 = W[-15] + ror y1, 2 ; y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22) + add y2, y0 ; y2 = S1 + CH + add y2, [rsp + _XFER + 0*4] ; y2 = k + w + S1 + CH + movdqa XTMP3, XTMP1 ; XTMP3 = W[-15] + mov y0, a ; y0 = a + add h, y2 ; h = h + S1 + CH + k + w + mov y2, a ; y2 = a + pslld XTMP1, (32-7) + or y0, c ; y0 = a|c + add d, h ; d = d + h + S1 + CH + k + w + and y2, c ; y2 = a&c + psrld XTMP2, 7 + and y0, b ; y0 = (a|c)&b + add h, y1 ; h = h + S1 + CH + k + w + S0 + por XTMP1, XTMP2 ; XTMP1 = W[-15] ror 7 + or y0, y2 ; y0 = MAJ = (a|c)&b)|(a&c) + add h, y0 ; h = h + S1 + CH + k + w + S0 + MAJ + +ROTATE_ARGS + movdqa XTMP2, XTMP3 ; XTMP2 = W[-15] + mov y0, e ; y0 = e + mov y1, a ; y1 = a + movdqa XTMP4, XTMP3 ; XTMP4 = W[-15] + ror y0, (25-11) ; y0 = e >> (25-11) + xor y0, e ; y0 = e ^ (e >> (25-11)) + mov y2, f ; y2 = f + ror y1, (22-13) ; y1 = a >> (22-13) + pslld XTMP3, (32-18) + xor y1, a ; y1 = a ^ (a >> (22-13) + ror y0, (11-6) ; y0 = (e >> (11-6)) ^ (e >> (25-6)) + xor y2, g ; y2 = f^g + psrld XTMP2, 18 + ror y1, (13-2) ; y1 = (a >> (13-2)) ^ (a >> (22-2)) + xor y0, e ; y0 = e ^ (e >> (11-6)) ^ (e >> (25-6)) + and y2, e ; y2 = (f^g)&e + ror y0, 6 ; y0 = S1 = (e>>6) & (e>>11) ^ (e>>25) + pxor XTMP1, XTMP3 + xor y1, a ; y1 = a ^ (a >> (13-2)) ^ (a >> (22-2)) + xor y2, g ; y2 = CH = ((f^g)&e)^g + psrld XTMP4, 3 ; XTMP4 = W[-15] >> 3 + add y2, y0 ; y2 = S1 + CH + add y2, [rsp + _XFER + 1*4] ; y2 = k + w + S1 + CH + ror y1, 2 ; y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22) + pxor XTMP1, XTMP2 ; XTMP1 = W[-15] ror 7 ^ W[-15] ror 18 + mov y0, a ; y0 = a + add h, y2 ; h = h + S1 + CH + k + w + mov y2, a ; y2 = a + pxor XTMP1, XTMP4 ; XTMP1 = s0 + or y0, c ; y0 = a|c + add d, h ; d = d + h + S1 + CH + k + w + and y2, c ; y2 = a&c + ;; compute low s1 + pshufd XTMP2, X3, 11111010b ; XTMP2 = W[-2] {BBAA} + and y0, b ; y0 = (a|c)&b + add h, y1 ; h = h + S1 + CH + k + w + S0 + paddd XTMP0, XTMP1 ; XTMP0 = W[-16] + W[-7] + s0 + or y0, y2 ; y0 = MAJ = (a|c)&b)|(a&c) + add h, y0 ; h = h + S1 + CH + k + w + S0 + MAJ + +ROTATE_ARGS + movdqa XTMP3, XTMP2 ; XTMP3 = W[-2] {BBAA} + mov y0, e ; y0 = e + mov y1, a ; y1 = a + ror y0, (25-11) ; y0 = e >> (25-11) + movdqa XTMP4, XTMP2 ; XTMP4 = W[-2] {BBAA} + xor y0, e ; y0 = e ^ (e >> (25-11)) + ror y1, (22-13) ; y1 = a >> (22-13) + mov y2, f ; y2 = f + xor y1, a ; y1 = a ^ (a >> (22-13) + ror y0, (11-6) ; y0 = (e >> (11-6)) ^ (e >> (25-6)) + psrlq XTMP2, 17 ; XTMP2 = W[-2] ror 17 {xBxA} + xor y2, g ; y2 = f^g + psrlq XTMP3, 19 ; XTMP3 = W[-2] ror 19 {xBxA} + xor y0, e ; y0 = e ^ (e >> (11-6)) ^ (e >> (25-6)) + and y2, e ; y2 = (f^g)&e + psrld XTMP4, 10 ; XTMP4 = W[-2] >> 10 {BBAA} + ror y1, (13-2) ; y1 = (a >> (13-2)) ^ (a >> (22-2)) + xor y1, a ; y1 = a ^ (a >> (13-2)) ^ (a >> (22-2)) + xor y2, g ; y2 = CH = ((f^g)&e)^g + ror y0, 6 ; y0 = S1 = (e>>6) & (e>>11) ^ (e>>25) + pxor XTMP2, XTMP3 + add y2, y0 ; y2 = S1 + CH + ror y1, 2 ; y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22) + add y2, [rsp + _XFER + 2*4] ; y2 = k + w + S1 + CH + pxor XTMP4, XTMP2 ; XTMP4 = s1 {xBxA} + mov y0, a ; y0 = a + add h, y2 ; h = h + S1 + CH + k + w + mov y2, a ; y2 = a + pshufb XTMP4, SHUF_00BA ; XTMP4 = s1 {00BA} + or y0, c ; y0 = a|c + add d, h ; d = d + h + S1 + CH + k + w + and y2, c ; y2 = a&c + paddd XTMP0, XTMP4 ; XTMP0 = {..., ..., W[1], W[0]} + and y0, b ; y0 = (a|c)&b + add h, y1 ; h = h + S1 + CH + k + w + S0 + ;; compute high s1 + pshufd XTMP2, XTMP0, 01010000b ; XTMP2 = W[-2] {DDCC} + or y0, y2 ; y0 = MAJ = (a|c)&b)|(a&c) + add h, y0 ; h = h + S1 + CH + k + w + S0 + MAJ + +ROTATE_ARGS + movdqa XTMP3, XTMP2 ; XTMP3 = W[-2] {DDCC} + mov y0, e ; y0 = e + ror y0, (25-11) ; y0 = e >> (25-11) + mov y1, a ; y1 = a + movdqa X0, XTMP2 ; X0 = W[-2] {DDCC} + ror y1, (22-13) ; y1 = a >> (22-13) + xor y0, e ; y0 = e ^ (e >> (25-11)) + mov y2, f ; y2 = f + ror y0, (11-6) ; y0 = (e >> (11-6)) ^ (e >> (25-6)) + psrlq XTMP2, 17 ; XTMP2 = W[-2] ror 17 {xDxC} + xor y1, a ; y1 = a ^ (a >> (22-13) + xor y2, g ; y2 = f^g + psrlq XTMP3, 19 ; XTMP3 = W[-2] ror 19 {xDxC} + xor y0, e ; y0 = e ^ (e >> (11-6)) ^ (e >> (25-6)) + and y2, e ; y2 = (f^g)&e + ror y1, (13-2) ; y1 = (a >> (13-2)) ^ (a >> (22-2)) + psrld X0, 10 ; X0 = W[-2] >> 10 {DDCC} + xor y1, a ; y1 = a ^ (a >> (13-2)) ^ (a >> (22-2)) + ror y0, 6 ; y0 = S1 = (e>>6) & (e>>11) ^ (e>>25) + xor y2, g ; y2 = CH = ((f^g)&e)^g + pxor XTMP2, XTMP3 + ror y1, 2 ; y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22) + add y2, y0 ; y2 = S1 + CH + add y2, [rsp + _XFER + 3*4] ; y2 = k + w + S1 + CH + pxor X0, XTMP2 ; X0 = s1 {xDxC} + mov y0, a ; y0 = a + add h, y2 ; h = h + S1 + CH + k + w + mov y2, a ; y2 = a + pshufb X0, SHUF_DC00 ; X0 = s1 {DC00} + or y0, c ; y0 = a|c + add d, h ; d = d + h + S1 + CH + k + w + and y2, c ; y2 = a&c + paddd X0, XTMP0 ; X0 = {W[3], W[2], W[1], W[0]} + and y0, b ; y0 = (a|c)&b + add h, y1 ; h = h + S1 + CH + k + w + S0 + or y0, y2 ; y0 = MAJ = (a|c)&b)|(a&c) + add h, y0 ; h = h + S1 + CH + k + w + S0 + MAJ + +ROTATE_ARGS +rotate_Xs +%endm + +;; input is [rsp + _XFER + %1 * 4] +%macro DO_ROUND 1 + mov y0, e ; y0 = e + ror y0, (25-11) ; y0 = e >> (25-11) + mov y1, a ; y1 = a + xor y0, e ; y0 = e ^ (e >> (25-11)) + ror y1, (22-13) ; y1 = a >> (22-13) + mov y2, f ; y2 = f + xor y1, a ; y1 = a ^ (a >> (22-13) + ror y0, (11-6) ; y0 = (e >> (11-6)) ^ (e >> (25-6)) + xor y2, g ; y2 = f^g + xor y0, e ; y0 = e ^ (e >> (11-6)) ^ (e >> (25-6)) + ror y1, (13-2) ; y1 = (a >> (13-2)) ^ (a >> (22-2)) + and y2, e ; y2 = (f^g)&e + xor y1, a ; y1 = a ^ (a >> (13-2)) ^ (a >> (22-2)) + ror y0, 6 ; y0 = S1 = (e>>6) & (e>>11) ^ (e>>25) + xor y2, g ; y2 = CH = ((f^g)&e)^g + add y2, y0 ; y2 = S1 + CH + ror y1, 2 ; y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22) + add y2, [rsp + _XFER + %1 * 4] ; y2 = k + w + S1 + CH + mov y0, a ; y0 = a + add h, y2 ; h = h + S1 + CH + k + w + mov y2, a ; y2 = a + or y0, c ; y0 = a|c + add d, h ; d = d + h + S1 + CH + k + w + and y2, c ; y2 = a&c + and y0, b ; y0 = (a|c)&b + add h, y1 ; h = h + S1 + CH + k + w + S0 + or y0, y2 ; y0 = MAJ = (a|c)&b)|(a&c) + add h, y0 ; h = h + S1 + CH + k + w + S0 + MAJ + ROTATE_ARGS +%endm + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; void sha256_sse4(void *input_data, UINT32 digest[8], UINT64 num_blks) +;; arg 1 : pointer to input data +;; arg 2 : pointer to digest +;; arg 3 : Num blocks +section .text +global sha256_sse4 +align 32 +sha256_sse4: + push rbx +%ifndef LINUX + push rsi + push rdi +%endif + push rbp + push r13 + push r14 + push r15 + + sub rsp,STACK_SIZE +%ifndef LINUX + movdqa [rsp + _XMM_SAVE + 0*16],xmm6 + movdqa [rsp + _XMM_SAVE + 1*16],xmm7 + movdqa [rsp + _XMM_SAVE + 2*16],xmm8 + movdqa [rsp + _XMM_SAVE + 3*16],xmm9 + movdqa [rsp + _XMM_SAVE + 4*16],xmm10 + movdqa [rsp + _XMM_SAVE + 5*16],xmm11 + movdqa [rsp + _XMM_SAVE + 6*16],xmm12 +%endif + + shl NUM_BLKS, 6 ; convert to bytes + jz done_hash + add NUM_BLKS, INP ; pointer to end of data + mov [rsp + _INP_END], NUM_BLKS + + ;; load initial digest + mov a,[4*0 + CTX] + mov b,[4*1 + CTX] + mov c,[4*2 + CTX] + mov d,[4*3 + CTX] + mov e,[4*4 + CTX] + mov f,[4*5 + CTX] + mov g,[4*6 + CTX] + mov h,[4*7 + CTX] + + movdqa BYTE_FLIP_MASK, [PSHUFFLE_BYTE_FLIP_MASK wrt rip] + movdqa SHUF_00BA, [_SHUF_00BA wrt rip] + movdqa SHUF_DC00, [_SHUF_DC00 wrt rip] + +loop0: + lea TBL,[K256 wrt rip] + + ;; byte swap first 16 dwords + COPY_XMM_AND_BSWAP X0, [INP + 0*16], BYTE_FLIP_MASK + COPY_XMM_AND_BSWAP X1, [INP + 1*16], BYTE_FLIP_MASK + COPY_XMM_AND_BSWAP X2, [INP + 2*16], BYTE_FLIP_MASK + COPY_XMM_AND_BSWAP X3, [INP + 3*16], BYTE_FLIP_MASK + + mov [rsp + _INP], INP + + ;; schedule 48 input dwords, by doing 3 rounds of 16 each + mov SRND, 3 +align 16 +loop1: + movdqa XFER, [TBL + 0*16] + paddd XFER, X0 + movdqa [rsp + _XFER], XFER + FOUR_ROUNDS_AND_SCHED + + movdqa XFER, [TBL + 1*16] + paddd XFER, X0 + movdqa [rsp + _XFER], XFER + FOUR_ROUNDS_AND_SCHED + + movdqa XFER, [TBL + 2*16] + paddd XFER, X0 + movdqa [rsp + _XFER], XFER + FOUR_ROUNDS_AND_SCHED + + movdqa XFER, [TBL + 3*16] + paddd XFER, X0 + movdqa [rsp + _XFER], XFER + add TBL, 4*16 + FOUR_ROUNDS_AND_SCHED + + sub SRND, 1 + jne loop1 + + mov SRND, 2 +loop2: + paddd X0, [TBL + 0*16] + movdqa [rsp + _XFER], X0 + DO_ROUND 0 + DO_ROUND 1 + DO_ROUND 2 + DO_ROUND 3 + paddd X1, [TBL + 1*16] + movdqa [rsp + _XFER], X1 + add TBL, 2*16 + DO_ROUND 0 + DO_ROUND 1 + DO_ROUND 2 + DO_ROUND 3 + + movdqa X0, X2 + movdqa X1, X3 + + sub SRND, 1 + jne loop2 + + addm [4*0 + CTX],a + addm [4*1 + CTX],b + addm [4*2 + CTX],c + addm [4*3 + CTX],d + addm [4*4 + CTX],e + addm [4*5 + CTX],f + addm [4*6 + CTX],g + addm [4*7 + CTX],h + + mov INP, [rsp + _INP] + add INP, 64 + cmp INP, [rsp + _INP_END] + jne loop0 + +done_hash: +%ifndef LINUX + movdqa xmm6,[rsp + _XMM_SAVE + 0*16] + movdqa xmm7,[rsp + _XMM_SAVE + 1*16] + movdqa xmm8,[rsp + _XMM_SAVE + 2*16] + movdqa xmm9,[rsp + _XMM_SAVE + 3*16] + movdqa xmm10,[rsp + _XMM_SAVE + 4*16] + movdqa xmm11,[rsp + _XMM_SAVE + 5*16] + movdqa xmm12,[rsp + _XMM_SAVE + 6*16] +%endif + + add rsp, STACK_SIZE + + pop r15 + pop r14 + pop r13 + pop rbp +%ifndef LINUX + pop rdi + pop rsi +%endif + pop rbx + + ret + + +section .data +align 64 +K256: + dd 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5 + dd 0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5 + dd 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3 + dd 0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174 + dd 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc + dd 0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da + dd 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7 + dd 0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967 + dd 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13 + dd 0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85 + dd 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3 + dd 0xd192e819,0xd6990624,0xf40e3585,0x106aa070 + dd 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5 + dd 0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3 + dd 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208 + dd 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 + +PSHUFFLE_BYTE_FLIP_MASK: ddq 0x0c0d0e0f08090a0b0405060700010203 + +; shuffle xBxA -> 00BA +_SHUF_00BA: ddq 0xFFFFFFFFFFFFFFFF0b0a090803020100 + +; shuffle xDxC -> DC00 +_SHUF_DC00: ddq 0x0b0a090803020100FFFFFFFFFFFFFFFF +*/ + +#endif diff --git a/src/cuckoocache.h b/src/cuckoocache.h new file mode 100755 index 0000000..9030fe6 --- /dev/null +++ b/src/cuckoocache.h @@ -0,0 +1,457 @@ +// Copyright (c) 2016 Jeremy Rubin +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef _BITCOIN_CUCKOOCACHE_H_ +#define _BITCOIN_CUCKOOCACHE_H_ + +#include +#include +#include +#include +#include +#include +#include + + +/** namespace CuckooCache provides high performance cache primitives + * + * Summary: + * + * 1) bit_packed_atomic_flags is bit-packed atomic flags for garbage collection + * + * 2) cache is a cache which is performant in memory usage and lookup speed. It + * is lockfree for erase operations. Elements are lazily erased on the next + * insert. + */ +namespace CuckooCache +{ +/** bit_packed_atomic_flags implements a container for garbage collection flags + * that is only thread unsafe on calls to setup. This class bit-packs collection + * flags for memory efficiency. + * + * All operations are std::memory_order_relaxed so external mechanisms must + * ensure that writes and reads are properly synchronized. + * + * On setup(n), all bits up to n are marked as collected. + * + * Under the hood, because it is an 8-bit type, it makes sense to use a multiple + * of 8 for setup, but it will be safe if that is not the case as well. + * + */ +class bit_packed_atomic_flags +{ + std::unique_ptr[]> mem; + +public: + /** No default constructor as there must be some size */ + bit_packed_atomic_flags() = delete; + + /** + * bit_packed_atomic_flags constructor creates memory to sufficiently + * keep track of garbage collection information for size entries. + * + * @param size the number of elements to allocate space for + * + * @post bit_set, bit_unset, and bit_is_set function properly forall x. x < + * size + * @post All calls to bit_is_set (without subsequent bit_unset) will return + * true. + */ + bit_packed_atomic_flags(uint32_t size) + { + // pad out the size if needed + size = (size + 7) / 8; + mem.reset(new std::atomic[size]); + for (uint32_t i = 0; i < size; ++i) + mem[i].store(0xFF); + }; + + /** setup marks all entries and ensures that bit_packed_atomic_flags can store + * at least size entries + * + * @param b the number of elements to allocate space for + * @post bit_set, bit_unset, and bit_is_set function properly forall x. x < + * b + * @post All calls to bit_is_set (without subsequent bit_unset) will return + * true. + */ + inline void setup(uint32_t b) + { + bit_packed_atomic_flags d(b); + std::swap(mem, d.mem); + } + + /** bit_set sets an entry as discardable. + * + * @param s the index of the entry to bit_set. + * @post immediately subsequent call (assuming proper external memory + * ordering) to bit_is_set(s) == true. + * + */ + inline void bit_set(uint32_t s) + { + mem[s >> 3].fetch_or(1 << (s & 7), std::memory_order_relaxed); + } + + /** bit_unset marks an entry as something that should not be overwritten + * + * @param s the index of the entry to bit_unset. + * @post immediately subsequent call (assuming proper external memory + * ordering) to bit_is_set(s) == false. + */ + inline void bit_unset(uint32_t s) + { + mem[s >> 3].fetch_and(~(1 << (s & 7)), std::memory_order_relaxed); + } + + /** bit_is_set queries the table for discardability at s + * + * @param s the index of the entry to read. + * @returns if the bit at index s was set. + * */ + inline bool bit_is_set(uint32_t s) const + { + return (1 << (s & 7)) & mem[s >> 3].load(std::memory_order_relaxed); + } +}; + +/** cache implements a cache with properties similar to a cuckoo-set + * + * The cache is able to hold up to (~(uint32_t)0) - 1 elements. + * + * Read Operations: + * - contains(*, false) + * + * Read+Erase Operations: + * - contains(*, true) + * + * Erase Operations: + * - allow_erase() + * + * Write Operations: + * - setup() + * - setup_bytes() + * - insert() + * - please_keep() + * + * Synchronization Free Operations: + * - invalid() + * - compute_hashes() + * + * User Must Guarantee: + * + * 1) Write Requires synchronized access (e.g., a lock) + * 2) Read Requires no concurrent Write, synchronized with the last insert. + * 3) Erase requires no concurrent Write, synchronized with last insert. + * 4) An Erase caller must release all memory before allowing a new Writer. + * + * + * Note on function names: + * - The name "allow_erase" is used because the real discard happens later. + * - The name "please_keep" is used because elements may be erased anyways on insert. + * + * @tparam Element should be a movable and copyable type + * @tparam Hash should be a function/callable which takes a template parameter + * hash_select and an Element and extracts a hash from it. Should return + * high-entropy hashes for `Hash h; h<0>(e) ... h<7>(e)`. + */ +template +class cache +{ +private: + /** table stores all the elements */ + std::vector table; + + /** size stores the total available slots in the hash table */ + uint32_t size; + + /** The bit_packed_atomic_flags array is marked mutable because we want + * garbage collection to be allowed to occur from const methods */ + mutable bit_packed_atomic_flags collection_flags; + + /** epoch_flags tracks how recently an element was inserted into + * the cache. true denotes recent, false denotes not-recent. See insert() + * method for full semantics. + */ + mutable std::vector epoch_flags; + + /** epoch_heuristic_counter is used to determine when a epoch might be aged + * & an expensive scan should be done. epoch_heuristic_counter is + * decremented on insert and reset to the new number of inserts which would + * cause the epoch to reach epoch_size when it reaches zero. + */ + uint32_t epoch_heuristic_counter; + + /** epoch_size is set to be the number of elements supposed to be in a + * epoch. When the number of non-erased elements in a epoch + * exceeds epoch_size, a new epoch should be started and all + * current entries demoted. epoch_size is set to be 45% of size because + * we want to keep load around 90%, and we support 3 epochs at once -- + * one "dead" which has been erased, one "dying" which has been marked to be + * erased next, and one "living" which new inserts add to. + */ + uint32_t epoch_size; + + /** hash_mask should be set to appropriately mask out a hash such that every + * masked hash is [0,size), eg, if floor(log2(size)) == 20, then hash_mask + * should be (1<<20)-1 + */ + uint32_t hash_mask; + + /** depth_limit determines how many elements insert should try to replace. + * Should be set to log2(n)*/ + uint8_t depth_limit; + + /** hash_function is a const instance of the hash function. It cannot be + * static or initialized at call time as it may have internal state (such as + * a nonce). + * */ + const Hash hash_function; + + /** compute_hashes is convenience for not having to write out this + * expression everywhere we use the hash values of an Element. + * + * @param e the element whose hashes will be returned + * @returns std::array of deterministic hashes derived from e + */ + inline std::array compute_hashes(const Element& e) const + { + return {{hash_function.template operator()<0>(e) & hash_mask, + hash_function.template operator()<1>(e) & hash_mask, + hash_function.template operator()<2>(e) & hash_mask, + hash_function.template operator()<3>(e) & hash_mask, + hash_function.template operator()<4>(e) & hash_mask, + hash_function.template operator()<5>(e) & hash_mask, + hash_function.template operator()<6>(e) & hash_mask, + hash_function.template operator()<7>(e) & hash_mask}}; + } + + /* end + * @returns a constexpr index that can never be inserted to */ + constexpr uint32_t invalid() const + { + return ~(uint32_t)0; + } + + /** allow_erase marks the element at index n as discardable. Threadsafe + * without any concurrent insert. + * @param n the index to allow erasure of + */ + inline void allow_erase(uint32_t n) const + { + collection_flags.bit_set(n); + } + + /** please_keep marks the element at index n as an entry that should be kept. + * Threadsafe without any concurrent insert. + * @param n the index to prioritize keeping + */ + inline void please_keep(uint32_t n) const + { + collection_flags.bit_unset(n); + } + + /** epoch_check handles the changing of epochs for elements stored in the + * cache. epoch_check should be run before every insert. + * + * First, epoch_check decrements and checks the cheap heuristic, and then does + * a more expensive scan if the cheap heuristic runs out. If the expensive + * scan succeeds, the epochs are aged and old elements are allow_erased. The + * cheap heuristic is reset to retrigger after the worst case growth of the + * current epoch's elements would exceed the epoch_size. + */ + void epoch_check() + { + if (epoch_heuristic_counter != 0) { + --epoch_heuristic_counter; + return; + } + // count the number of elements from the latest epoch which + // have not been erased. + uint32_t epoch_unused_count = 0; + for (uint32_t i = 0; i < size; ++i) + epoch_unused_count += epoch_flags[i] && + !collection_flags.bit_is_set(i); + // If there are more non-deleted entries in the current epoch than the + // epoch size, then allow_erase on all elements in the old epoch (marked + // false) and move all elements in the current epoch to the old epoch + // but do not call allow_erase on their indices. + if (epoch_unused_count >= epoch_size) { + for (uint32_t i = 0; i < size; ++i) + if (epoch_flags[i]) + epoch_flags[i] = false; + else + allow_erase(i); + epoch_heuristic_counter = epoch_size; + } else + // reset the epoch_heuristic_counter to next do a scan when worst + // case behavior (no intermittent erases) would exceed epoch size, + // with a reasonable minimum scan size. + // Ordinarily, we would have to sanity check std::min(epoch_size, + // epoch_unused_count), but we already know that `epoch_unused_count + // < epoch_size` in this branch + epoch_heuristic_counter = std::max(1u, std::max(epoch_size / 16, + epoch_size - epoch_unused_count)); + } + +public: + /** You must always construct a cache with some elements via a subsequent + * call to setup or setup_bytes, otherwise operations may segfault. + */ + cache() : table(), size(), collection_flags(0), epoch_flags(), + epoch_heuristic_counter(), epoch_size(), depth_limit(0), hash_function() + { + } + + /** setup initializes the container to store no more than new_size + * elements. setup rounds down to a power of two size. + * + * setup should only be called once. + * + * @param new_size the desired number of elements to store + * @returns the maximum number of elements storable + **/ + uint32_t setup(uint32_t new_size) + { + // depth_limit must be at least one otherwise errors can occur. + depth_limit = static_cast(std::log2(static_cast(std::max((uint32_t)2, new_size)))); + size = 1 << depth_limit; + hash_mask = size-1; + table.resize(size); + collection_flags.setup(size); + epoch_flags.resize(size); + // Set to 45% as described above + epoch_size = std::max((uint32_t)1, (45 * size) / 100); + // Initially set to wait for a whole epoch + epoch_heuristic_counter = epoch_size; + return size; + } + + /** setup_bytes is a convenience function which accounts for internal memory + * usage when deciding how many elements to store. It isn't perfect because + * it doesn't account for any overhead (struct size, MallocUsage, collection + * and epoch flags). This was done to simplify selecting a power of two + * size. In the expected use case, an extra two bits per entry should be + * negligible compared to the size of the elements. + * + * @param bytes the approximate number of bytes to use for this data + * structure. + * @returns the maximum number of elements storable (see setup() + * documentation for more detail) + */ + uint32_t setup_bytes(size_t bytes) + { + return setup(bytes/sizeof(Element)); + } + + /** insert loops at most depth_limit times trying to insert a hash + * at various locations in the table via a variant of the Cuckoo Algorithm + * with eight hash locations. + * + * It drops the last tried element if it runs out of depth before + * encountering an open slot. + * + * Thus + * + * insert(x); + * return contains(x, false); + * + * is not guaranteed to return true. + * + * @param e the element to insert + * @post one of the following: All previously inserted elements and e are + * now in the table, one previously inserted element is evicted from the + * table, the entry attempted to be inserted is evicted. + * + */ + inline void insert(Element e) + { + epoch_check(); + uint32_t last_loc = invalid(); + bool last_epoch = true; + std::array locs = compute_hashes(e); + // Make sure we have not already inserted this element + // If we have, make sure that it does not get deleted + for (uint32_t loc : locs) + if (table[loc] == e) { + please_keep(loc); + epoch_flags[loc] = last_epoch; + return; + } + for (uint8_t depth = 0; depth < depth_limit; ++depth) { + // First try to insert to an empty slot, if one exists + for (uint32_t loc : locs) { + if (!collection_flags.bit_is_set(loc)) + continue; + table[loc] = std::move(e); + please_keep(loc); + epoch_flags[loc] = last_epoch; + return; + } + /** Swap with the element at the location that was + * not the last one looked at. Example: + * + * 1) On first iteration, last_loc == invalid(), find returns last, so + * last_loc defaults to locs[0]. + * 2) On further iterations, where last_loc == locs[k], last_loc will + * go to locs[k+1 % 8], i.e., next of the 8 indices wrapping around + * to 0 if needed. + * + * This prevents moving the element we just put in. + * + * The swap is not a move -- we must switch onto the evicted element + * for the next iteration. + */ + last_loc = locs[(1 + (std::find(locs.begin(), locs.end(), last_loc) - locs.begin())) & 7]; + std::swap(table[last_loc], e); + // Can't std::swap a std::vector::reference and a bool&. + bool epoch = last_epoch; + last_epoch = epoch_flags[last_loc]; + epoch_flags[last_loc] = epoch; + + // Recompute the locs -- unfortunately happens one too many times! + locs = compute_hashes(e); + } + } + + /* contains iterates through the hash locations for a given element + * and checks to see if it is present. + * + * contains does not check garbage collected state (in other words, + * garbage is only collected when the space is needed), so: + * + * insert(x); + * if (contains(x, true)) + * return contains(x, false); + * else + * return true; + * + * executed on a single thread will always return true! + * + * This is a great property for re-org performance for example. + * + * contains returns a bool set true if the element was found. + * + * @param e the element to check + * @param erase + * + * @post if erase is true and the element is found, then the garbage collect + * flag is set + * @returns true if the element is found, false otherwise + */ + inline bool contains(const Element& e, const bool erase) const + { + std::array locs = compute_hashes(e); + for (uint32_t loc : locs) + if (table[loc] == e) { + if (erase) + allow_erase(loc); + return true; + } + return false; + } +}; +} // namespace CuckooCache + +#endif diff --git a/src/denomination_functions.cpp b/src/denomination_functions.cpp index 41b117e..5c88b34 100644 --- a/src/denomination_functions.cpp +++ b/src/denomination_functions.cpp @@ -110,7 +110,7 @@ bool getIdealSpends( // Start with the Highest Denomination coin and grab coins as long as the remaining amount is greater than the // current denomination value for (auto& coin : reverse_iterate(zerocoinDenomList)) { - for (const CMintMeta mint : listMints) { + for (const CMintMeta& mint : listMints) { if (mint.isUsed) continue; if (nRemainingValue >= ZerocoinDenominationToAmount(coin) && coin == mint.denom) { mapOfDenomsUsed.at(coin)++; @@ -134,7 +134,7 @@ std::vector getSpends( nCoinsSpentValue = 0; for (auto& coin : reverse_iterate(zerocoinDenomList)) { do { - for (const CMintMeta mint : listMints) { + for (const CMintMeta& mint : listMints) { if (mint.isUsed) continue; if (coin == mint.denom && mapOfDenomsUsed.at(coin)) { vSelectedMints.push_back(mint); @@ -155,7 +155,7 @@ void listSpends(const std::vector& vSelectedMints) for (auto& denom : libzerocoin::zerocoinDenomList) mapZerocoinSupply.insert(std::make_pair(denom, 0)); - for (const CZerocoinMint mint : vSelectedMints) { + for (const CZerocoinMint& mint : vSelectedMints) { libzerocoin::CoinDenomination denom = mint.GetDenomination(); mapZerocoinSupply.at(denom)++; } diff --git a/src/init.cpp b/src/init.cpp index 235ef5e..42e2eb4 100755 --- a/src/init.cpp +++ b/src/init.cpp @@ -68,6 +68,7 @@ #include #include + #if ENABLE_ZMQ #include "zmq/zmqnotificationinterface.h" #endif @@ -106,7 +107,6 @@ enum BindFlags { }; static const char* FEE_ESTIMATES_FILENAME = "fee_estimates.dat"; -CClientUIInterface uiInterface; ////////////////////////////////////////////////////////////////////////////// // @@ -175,13 +175,14 @@ static CCoinsViewErrorCatcher* pcoinscatcher = NULL; static boost::thread_group threadGroup; static CScheduler scheduler; -void Interrupt() +void Interrupt(boost::thread_group& threadGroup) { InterruptHTTPServer(); InterruptHTTPRPC(); InterruptRPC(); InterruptREST(); InterruptTorControl(); + threadGroup.interrupt_all(); } /** Preparing steps before shutting down or restarting the wallet */ @@ -325,18 +326,6 @@ static void registerSignalHandler(int signal, void(*handler)(int)) } #endif -bool static InitError(const std::string& str) -{ - uiInterface.ThreadSafeMessageBox(str, "", CClientUIInterface::MSG_ERROR); - return false; -} - -bool static InitWarning(const std::string& str) -{ - uiInterface.ThreadSafeMessageBox(str, "", CClientUIInterface::MSG_WARNING); - return true; -} - bool static Bind(const CService& addr, unsigned int flags) { if (!(flags & BF_EXPLICIT) && IsLimited(addr)) @@ -372,8 +361,10 @@ void OnRPCPreCommand(const CRPCCommand& cmd) std::string HelpMessage(HelpMessageMode mode) { + const bool showDebug = GetBoolArg("-help-debug", false); // When adding new options to the categories, please keep and ensure alphabetical ordering. + // Do not translate _(...) -help-debug options, Many technical terms, and only a very small audience, so is unnecessary stress to translators. string strUsage = HelpMessageGroup(_("Options:")); strUsage += HelpMessageOpt("-?", _("This help message")); strUsage += HelpMessageOpt("-version", _("Print version and exit")); @@ -456,10 +447,11 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-createwalletbackups=", _("Number of automatic wallet backups (default: 10)")); strUsage += HelpMessageOpt("-custombackupthreshold=", strprintf(_("Number of custom location backups to retain (default: %d)"), DEFAULT_CUSTOMBACKUPTHRESHOLD)); strUsage += HelpMessageOpt("-disablewallet", _("Do not load the wallet and disable wallet RPC calls")); + strUsage += HelpMessageOpt("-skipmnemonicstartupui", _("Skip the Mnemonic startup page, this would be useful in case you were testing something")); strUsage += HelpMessageOpt("-keypool=", strprintf(_("Set key pool size to (default: %u)"), 100)); - if (GetBoolArg("-help-debug", false)) + if (showDebug) strUsage += HelpMessageOpt("-mintxfee=", strprintf(_("Fees (in OHMC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)"), - FormatMoney(CWallet::minTxFee.GetFeePerK()))); + FormatMoney(CWallet::minTxFee.GetFeePerK()))); strUsage += HelpMessageOpt("-paytxfee=", strprintf(_("Fee (in OHMC/kB) to add to transactions you send (default: %s)"), FormatMoney(payTxFee.GetFeePerK()))); strUsage += HelpMessageOpt("-rescan", _("Rescan the block chain for missing wallet transactions") + " " + _("on startup")); strUsage += HelpMessageOpt("-salvagewallet", _("Attempt to recover private keys from a corrupt wallet.dat") + " " + _("on startup")); @@ -467,15 +459,21 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-spendzeroconfchange", strprintf(_("Spend unconfirmed change when sending transactions (default: %u)"), 1)); strUsage += HelpMessageOpt("-disablesystemnotifications", strprintf(_("Disable OS notifications for incoming transactions (default: %u)"), 0)); strUsage += HelpMessageOpt("-txconfirmtarget=", strprintf(_("If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)"), 1)); + strUsage += HelpMessageOpt("-createhdwallet", _("Use hierarchical deterministic key generation (HD) after BIP32. Only has effect during wallet creation/first start") + " " + strprintf(_("(default: %u)"), DEFAULT_USE_HD_WALLET)); strUsage += HelpMessageOpt("-maxtxfee=", strprintf(_("Maximum total fees to use in a single wallet transaction, setting too low may abort large transactions (default: %s)"), - FormatMoney(maxTxFee))); + FormatMoney(maxTxFee))); + strUsage += HelpMessageOpt("-usehd", _("Use hierarchical deterministic key generation (HD) after bip32. Only has effect during wallet creation/first start") + " " + strprintf(_("(default: %u)"), DEFAULT_USE_HD_WALLET)); + strUsage += HelpMessageOpt("-mnemonic", _("User defined mnemonic for HD wallet (bip39). Only has effect during wallet creation/first start (default: randomly generated)")); + strUsage += HelpMessageOpt("-mnemonicpassphrase", _("User defined memonic passphrase for HD wallet (bip39). Only has effect during wallet creation/first start (default: randomly generated)")); + strUsage += HelpMessageOpt("-hdseed", _("User defined seed for HD wallet (should be in hex). Only has effect during wallet creation/first start (default: randomly generated)")); strUsage += HelpMessageOpt("-upgradewallet", _("Upgrade wallet to latest format") + " " + _("on startup")); strUsage += HelpMessageOpt("-wallet=", _("Specify wallet file (within data directory)") + " " + strprintf(_("(default: %s)"), "wallet.dat")); strUsage += HelpMessageOpt("-walletnotify=", _("Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)")); + strUsage += HelpMessageOpt("-zapwallettxes=", _("Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup") + + " " + _("(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)")); + if (mode == HMM_BITCOIN_QT) strUsage += HelpMessageOpt("-windowtitle=", _("Wallet window title")); - strUsage += HelpMessageOpt("-zapwallettxes=", _("Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup") + - " " + _("(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)")); #endif #if ENABLE_ZMQ @@ -489,7 +487,7 @@ std::string HelpMessage(HelpMessageMode mode) #endif strUsage += HelpMessageGroup(_("Debugging/Testing options:")); - if (GetBoolArg("-help-debug", false)) { + if (showDebug) { strUsage += HelpMessageOpt("-checkblockindex", strprintf("Do a full consistency check for mapBlockIndex, setBlockIndexCandidates, chainActive and mapBlocksUnlinked occasionally. Also sets -checkmempool (default: %u)", Params(CBaseChainParams::MAIN).DefaultConsistencyChecks())); strUsage += HelpMessageOpt("-checkmempool=", strprintf("Run checks every transactions (default: %u)", Params(CBaseChainParams::MAIN).DefaultConsistencyChecks())); strUsage += HelpMessageOpt("-checkpoints", strprintf(_("Only accept block chain matching built-in checkpoints (default: %u)"), 1)); @@ -503,12 +501,12 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-stopafterblockimport", strprintf(_("Stop running after importing blocks from disk (default: %u)"), 0)); strUsage += HelpMessageOpt("-sporkkey=", _("Enable spork administration functionality with the appropriate private key.")); } - string debugCategories = "addrman, alert, bench, coindb, db, lock, rand, rpc, selectcoins, tor, mempool, net, proxy, http, libevent, ohmcoin, (obfuscation, swiftx, karmanode, mnpayments, knbudget, zero)"; // Don't translate these and qt below + string debugCategories = "addrman, alert, bench, coindb, db, lock, rand, rpc, selectcoins, tor, mempool, net, proxy, http, libevent, ohmcoin, (obfuscation, swiftx, karmanode, mnpayments, knbudget, zero, staking)"; // Don't translate these and qt below if (mode == HMM_BITCOIN_QT) debugCategories += ", qt"; strUsage += HelpMessageOpt("-debug=", strprintf(_("Output debugging information (default: %u, supplying is optional)"), 0) + ". " + - _("If is not supplied, output all debugging information.") + _(" can be:") + " " + debugCategories + "."); - if (GetBoolArg("-help-debug", false)) + _("If is not supplied, output all debugging information.") + _(" can be:") + " " + debugCategories + "."); + if (showDebug) strUsage += HelpMessageOpt("-nodebug", "Turn off debugging messages, same as -debug=0"); #ifdef ENABLE_WALLET strUsage += HelpMessageOpt("-gen", strprintf(_("Generate coins (default: %u)"), 0)); @@ -517,14 +515,14 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-help-debug", _("Show all debugging options (usage: --help -help-debug)")); strUsage += HelpMessageOpt("-logips", strprintf(_("Include IP addresses in debug output (default: %u)"), 0)); strUsage += HelpMessageOpt("-logtimestamps", strprintf(_("Prepend debug output with timestamp (default: %u)"), 1)); - if (GetBoolArg("-help-debug", false)) { + if (showDebug) { strUsage += HelpMessageOpt("-limitfreerelay=", strprintf(_("Continuously rate-limit free transactions to *1000 bytes per minute (default:%u)"), 15)); strUsage += HelpMessageOpt("-relaypriority", strprintf(_("Require high priority for relaying free or low-fee transactions (default:%u)"), 1)); strUsage += HelpMessageOpt("-maxsigcachesize=", strprintf(_("Limit size of signature cache to entries (default: %u)"), 50000)); } strUsage += HelpMessageOpt("-minrelaytxfee=", strprintf(_("Fees (in OHMC/Kb) smaller than this are considered zero fee for relaying (default: %s)"), FormatMoney(::minRelayTxFee.GetFeePerK()))); strUsage += HelpMessageOpt("-printtoconsole", strprintf(_("Send trace/debug info to console instead of debug.log file (default: %u)"), 0)); - if (GetBoolArg("-help-debug", false)) { + if (showDebug) { strUsage += HelpMessageOpt("-printpriority", strprintf(_("Log transaction priority and fee per kB when mining blocks (default: %u)"), 0)); strUsage += HelpMessageOpt("-privdb", strprintf(_("Sets the DB_PRIVATE flag in the wallet db environment (default: %u)"), 1)); strUsage += HelpMessageOpt("-regtest", _("Enter regression test mode, which uses a special chain in which blocks can be solved instantly.") + " " + @@ -539,7 +537,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageGroup(_("Staking options:")); strUsage += HelpMessageOpt("-staking=", strprintf(_("Enable staking functionality (0-1, default: %u)"), 1)); strUsage += HelpMessageOpt("-reservebalance=", _("Keep the specified amount available for spending at all times (default: 0)")); - if (GetBoolArg("-help-debug", false)) { + if (showDebug) { strUsage += HelpMessageOpt("-printstakemodifier", _("Display the stake modifier calculations in the debug.log file.")); strUsage += HelpMessageOpt("-printcoinstake", _("Display verbose coin stake messages in the debug.log file.")); } @@ -570,7 +568,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageGroup(_("Node relay options:")); strUsage += HelpMessageOpt("-datacarrier", strprintf(_("Relay and mine data carrier transactions (default: %u)"), 1)); strUsage += HelpMessageOpt("-datacarriersize", strprintf(_("Maximum size of data in data carrier transactions we relay and mine (default: %u)"), MAX_OP_RETURN_RELAY)); - if (GetBoolArg("-help-debug", false)) { + if (showDebug) { strUsage += HelpMessageOpt("-blockversion=", "Override block version to test forking scenarios"); } @@ -591,7 +589,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-rpcallowip=", _("Allow JSON-RPC connections from specified source. Valid for are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times")); strUsage += HelpMessageOpt("-rpcserialversion=", strprintf(_("Sets the serialization of raw transaction or block hex returned in non-verbose mode, non-segwit(0) or segwit(1) (default: %d)"), DEFAULT_RPC_SERIALIZE_VERSION)); strUsage += HelpMessageOpt("-rpcthreads=", strprintf(_("Set the number of threads to service RPC calls (default: %d)"), DEFAULT_HTTP_THREADS)); - if (GetBoolArg("-help-debug", false)) { + if (showDebug) { strUsage += HelpMessageOpt("-rpcworkqueue=", strprintf("Set the depth of the work queue to service RPC calls (default: %d)", DEFAULT_HTTP_WORKQUEUE)); strUsage += HelpMessageOpt("-rpcservertimeout=", strprintf("Timeout during HTTP requests (default: %d)", DEFAULT_HTTP_SERVER_TIMEOUT)); } @@ -798,7 +796,6 @@ bool InitNUParams() }; bool AppInitBasicSetup() - { // ********************************************************* Step 1: setup #ifdef _MSC_VER @@ -854,10 +851,10 @@ bool AppInitBasicSetup() return true; } -/** Initialize pivx. +/** Initialize phore. * @pre Parameters should be parsed and config file should be read. */ -bool AppInit2() +bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler, const std::vector& words) { // ********************************************************* Step 1: setup if (!AppInitBasicSetup()) @@ -868,7 +865,11 @@ bool AppInit2() fPrintToConsole = GetBoolArg("-printtoconsole", false); fLogTimestamps = GetBoolArg("-logtimestamps", true); fLogIPs = GetBoolArg("-logips", false); - + if (mapArgs.count("-hdseed") && IsHex(GetArg("-hdseed", "not hex")) && (mapArgs.count("-mnemonic") || mapArgs.count("-mnemonicpassphrase"))) { + mapArgs.erase("-mnemonic"); + mapArgs.erase("-mnemonicpassphrase"); + LogPrintf("%s: parameter interaction: can't use -hdseed and -mnemonic/-mnemonicpassphrase together, will prefer -seed\n", __func__); + } if (mapArgs.count("-bind") || mapArgs.count("-whitebind")) { // when specifying an explicit binding address, you want to listen on it // even when -connect or -proxy is specified @@ -971,6 +972,9 @@ bool AppInit2() if (GetBoolArg("-benchmark", false)) InitWarning(_("Warning: Unsupported argument -benchmark ignored, use -debug=bench.")); + InitSignatureCache(); + InitScriptExecutionCache(); + // Checkmempool and checkblockindex default to true in regtest mode mempool.setSanityCheck(GetBoolArg("-checkmempool", Params().DefaultConsistencyChecks())); fCheckBlockIndex = GetBoolArg("-checkblockindex", Params().DefaultConsistencyChecks()); @@ -1078,6 +1082,9 @@ bool AppInit2() // Sanity check if (!InitSanityCheck()) return InitError(_("Initialization sanity check failed. Ohmcoin Core is shutting down.")); + + std::string sha256_algo = SHA256AutoDetect(); + LogPrintf("Using the '%s' SHA256 implementation\n", sha256_algo); std::string strDataDir = GetDataDir().string(); #ifdef ENABLE_WALLET @@ -1728,7 +1735,8 @@ bool AppInit2() strErrors << _("Error loading wallet.dat") << "\n"; } - if (GetBoolArg("-upgradewallet", fFirstRun)) { + int prev_version = pwalletMain->GetVersion(); + if (GetBoolArg("-upgradewallet", fFirstRun) || (words.size() !=0 && !pwalletMain->IsHDEnabled() && CheckIfWalletDatExists())) { int nMaxVersion = GetArg("-upgradewallet", 0); if (nMaxVersion == 0) // the -upgradewallet without argument case { @@ -1742,18 +1750,39 @@ bool AppInit2() pwalletMain->SetMaxVersion(nMaxVersion); } - if (fFirstRun) { - // Create new keyUser and set as default key - CPubKey newDefaultKey; - if (pwalletMain->GetKeyFromPool(newDefaultKey)) { - pwalletMain->SetDefaultKey(newDefaultKey); - if (!pwalletMain->SetAddressBook(pwalletMain->vchDefaultKey.GetID(), "", "receive")) - strErrors << _("Cannot write default address") << "\n"; - } + if (fFirstRun) + { + if ((GetBoolArg("-usehd", DEFAULT_USE_HD_WALLET) && !pwalletMain->IsHDEnabled()) || (words.size() !=0 && !pwalletMain->IsHDEnabled())) { + if (GetArg("-mnemonicpassphrase", "").size() > 256) + return InitError(_("Mnemonic passphrase is too long, must be at most 256 characters")); + // generate a new master key + pwalletMain->GenerateNewHDChain(words); + // ensure this wallet.dat can only be opened by clients supporting HD + pwalletMain->SetMinVersion(FEATURE_HD); + } - pwalletMain->SetBestChain(chainActive.GetLocator()); + CPubKey newDefaultKey; + if (pwalletMain->GetKeyFromPool(newDefaultKey, false)) { + pwalletMain->SetDefaultKey(newDefaultKey); + if (!pwalletMain->SetAddressBook(pwalletMain->vchDefaultKey.GetID(), "", "receive")) + return InitError(_("Cannot write default address") += "\n"); } + pwalletMain->SetBestChain(chainActive.GetLocator()); + } + else if (mapArgs.count("-usehd")) { + bool useHD = GetBoolArg("-usehd", DEFAULT_USE_HD_WALLET); + if (pwalletMain->IsHDEnabled() && !useHD) + return InitError(strprintf(_("Error loading %s: You can't disable HD on a already existing HD wallet"), strWalletFile)); + if (!pwalletMain->IsHDEnabled() && useHD) + return InitError(strprintf(_("Error loading %s: You can't enable HD on a already existing non-HD wallet"), strWalletFile)); + } + + // Warn user every time he starts non-encrypted HD wallet + if (GetBoolArg("-usehd", DEFAULT_USE_HD_WALLET) && !pwalletMain->IsLocked() && DEFAULT_ENABLE_WARN_ENCRYPTHD) { + InitWarning(_("Make sure to encrypt your wallet and delete all non-encrypted backups after you verified that wallet works!")); + } + LogPrintf("%s", strErrors.str()); LogPrintf("Wallet completed loading in %15dms\n", GetTimeMillis() - nWalletStartTime); @@ -2049,11 +2078,16 @@ bool AppInit2() LogPrintf("mapBlockIndex.size() = %u\n", mapBlockIndex.size()); LogPrintf("chainActive.Height() = %d\n", chainActive.Height()); #ifdef ENABLE_WALLET - LogPrintf("setKeyPool.size() = %u\n", pwalletMain ? pwalletMain->setKeyPool.size() : 0); - LogPrintf("mapWallet.size() = %u\n", pwalletMain ? pwalletMain->mapWallet.size() : 0); - LogPrintf("mapAddressBook.size() = %u\n", pwalletMain ? pwalletMain->mapAddressBook.size() : 0); + if (pwalletMain) { + LOCK(pwalletMain->cs_wallet); + LogPrintf("setExternalKeyPool.size() = %u\n", pwalletMain->KeypoolCountExternalKeys()); + LogPrintf("setInternalKeyPool.size() = %u\n", pwalletMain->KeypoolCountInternalKeys()); + LogPrintf("mapWallet.size() = %u\n", pwalletMain->mapWallet.size()); + LogPrintf("mapAddressBook.size() = %u\n", pwalletMain->mapAddressBook.size()); + } else { + LogPrintf("wallet is NULL\n"); + } #endif - if (GetBoolArg("-listenonion", DEFAULT_LISTEN_ONION)) StartTorControl(threadGroup); diff --git a/src/init.h b/src/init.h index f8ef10e..5537a2a 100755 --- a/src/init.h +++ b/src/init.h @@ -7,6 +7,7 @@ #define BITCOIN_INIT_H #include +#include class CScheduler; class CWallet; @@ -23,16 +24,10 @@ extern CzOHMCWallet* zwalletMain; void StartShutdown(); bool ShutdownRequested(); /** Interrupt threads */ -void Interrupt(); +void Interrupt(boost::thread_group& threadGroup); void Shutdown(); void PrepareShutdown(); -bool AppInit2(); - -/** Initialize Ohmcoin core: Basic context setup. - * @note This can be done before daemonization. Do not call Shutdown() if this function fails. - * @pre Parameters should be parsed and config file should be read. - */ -bool AppInitBasicSetup(); +bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler, const std::vector& words); /** The help message mode determines what help message to show */ enum HelpMessageMode { diff --git a/src/kernel.cpp b/src/kernel.cpp index 0c6040a..f59438d 100755 --- a/src/kernel.cpp +++ b/src/kernel.cpp @@ -7,7 +7,7 @@ #include -#include "db.h" +#include "wallet/db.h" #include "kernel.h" #include "script/interpreter.h" #include "timedata.h" @@ -242,7 +242,7 @@ bool ComputeNextStakeModifier(const CBlockIndex* pindexPrev, uint64_t& nStakeMod // The stake modifier used to hash for a stake kernel is chosen as the stake // modifier about a selection interval later than the coin generating the kernel -bool GetKernelStakeModifier(uint256 hashBlockFrom, uint64_t& nStakeModifier, int& nStakeModifierHeight, int64_t& nStakeModifierTime, bool fPrintProofOfStake) +bool GetKernelStakeModifier(const uint256 & hashBlockFrom, uint64_t& nStakeModifier, int& nStakeModifierHeight, int64_t& nStakeModifierTime, bool fPrintProofOfStake) { nStakeModifier = 0; if (!mapBlockIndex.count(hashBlockFrom)) @@ -363,7 +363,7 @@ bool CheckStakeKernelHash(unsigned int nBits, const CBlock blockFrom, const CTra } // Check kernel hash target and coinstake signature -bool CheckProofOfStake(const CBlock block, uint256& hashProofOfStake) +bool CheckProofOfStake(const CBlock & block, uint256& hashProofOfStake) { const CTransaction tx = block.vtx[1]; if (!tx.IsCoinStake()) diff --git a/src/kernel.h b/src/kernel.h index 32173ff..8eddd92 100755 --- a/src/kernel.h +++ b/src/kernel.h @@ -29,7 +29,7 @@ bool CheckStakeKernelHash(unsigned int nBits, const CBlock blockFrom, const CTra // Check kernel hash target and coinstake signature // Sets hashProofOfStake on success return -bool CheckProofOfStake(const CBlock block, uint256& hashProofOfStake); +bool CheckProofOfStake(const CBlock & block, uint256& hashProofOfStake); // Check whether the coinstake timestamp meets protocol bool CheckCoinStakeTimestamp(int64_t nTimeBlock, int64_t nTimeTx); diff --git a/src/key.cpp b/src/key.cpp index 2d77d54..f085697 100755 --- a/src/key.cpp +++ b/src/key.cpp @@ -16,19 +16,19 @@ //! anonymous namespace namespace { -class CSecp256k1Init -{ -public: - CSecp256k1Init() - { - secp256k1_start(SECP256K1_START_SIGN); - } - ~CSecp256k1Init() + class CSecp256k1Init { - secp256k1_stop(); - } -}; -static CSecp256k1Init instance_of_csecp256k1; + public: + CSecp256k1Init() + { + secp256k1_start(SECP256K1_START_SIGN); + } + ~CSecp256k1Init() + { + secp256k1_stop(); + } + }; + static CSecp256k1Init instance_of_csecp256k1; } // anon namespace @@ -247,4 +247,4 @@ bool ECC_InitSanityCheck() key.MakeNewKey(true); CPubKey pubkey = key.GetPubKey(); return key.VerifyPubKey(pubkey); -} +} \ No newline at end of file diff --git a/src/key.h b/src/key.h index 9750a44..6f6c0ab 100755 --- a/src/key.h +++ b/src/key.h @@ -7,6 +7,7 @@ #ifndef BITCOIN_KEY_H #define BITCOIN_KEY_H +#include "pubkey.h" #include "allocators.h" #include "serialize.h" #include "uint256.h" @@ -18,7 +19,7 @@ class CPubKey; struct CExtPubKey; -/** +/** * secp256k1: * const unsigned int PRIVATE_KEY_SIZE = 279; * const unsigned int PUBLIC_KEY_SIZE = 65; @@ -115,7 +116,7 @@ class CKey /** * Convert the private key to a CPrivKey (serialized OpenSSL private key data). - * This is expensive. + * This is expensive. */ CPrivKey GetPrivKey() const; @@ -175,9 +176,26 @@ struct CExtKey { bool Derive(CExtKey& out, unsigned int nChild) const; CExtPubKey Neuter() const; void SetMaster(const unsigned char* seed, unsigned int nSeedLen); + template + void Serialize(Stream& s, int nType, int nVersion) const + { + unsigned int len = BIP32_EXTKEY_SIZE; + ::WriteCompactSize(s, len); + unsigned char code[BIP32_EXTKEY_SIZE]; + Encode(code); + s.write((const char *)&code[0], len); + } + template + void Unserialize(Stream& s, int nType, int nVersion) + { + unsigned int len = ::ReadCompactSize(s); + unsigned char code[BIP32_EXTKEY_SIZE]; + s.read((char *)&code[0], len); + Decode(code); + } }; /** Check that required EC support is available at runtime */ bool ECC_InitSanityCheck(void); -#endif // BITCOIN_KEY_H +#endif // BITCOIN_KEY_H \ No newline at end of file diff --git a/src/keystore.cpp b/src/keystore.cpp index 265236a..fafbb14 100755 --- a/src/keystore.cpp +++ b/src/keystore.cpp @@ -5,7 +5,7 @@ #include "keystore.h" -#include "crypter.h" +#include "wallet/crypter.h" #include "key.h" #include "script/script.h" #include "script/standard.h" @@ -145,6 +145,12 @@ bool CBasicKeyStore::HaveWatchOnly() const return (!setWatchOnly.empty()); } +bool CBasicKeyStore::GetHDChain(CHDChain& hdChainRet) const +{ + hdChainRet = hdChain; + return !hdChain.IsNull(); +} + bool CBasicKeyStore::AddMultiSig(const CScript& dest) { LOCK(cs_KeyStore); @@ -192,3 +198,10 @@ CKeyID GetKeyForDestination(const CKeyStore& store, const CTxDestination& dest) } return CKeyID(); } + +bool HaveKey(const CKeyStore& store, const CKey& key) +{ + CKey key2; + key2.Set(key.begin(), key.end(), !key.IsCompressed()); + return store.HaveKey(key.GetPubKey().GetID()) || store.HaveKey(key2.GetPubKey().GetID()); +} diff --git a/src/keystore.h b/src/keystore.h index 128694b..5c03cd1 100755 --- a/src/keystore.h +++ b/src/keystore.h @@ -6,6 +6,8 @@ #ifndef BITCOIN_KEYSTORE_H #define BITCOIN_KEYSTORE_H + +#include "wallet/hdchain.h" #include "key.h" #include "pubkey.h" #include "sync.h" @@ -68,6 +70,7 @@ class CBasicKeyStore : public CKeyStore WatchKeyMap mapWatchKeys; ScriptMap mapScripts; WatchOnlySet setWatchOnly; + CHDChain hdChain; /* the HD chain data model*/ MultiSigScriptSet setMultiSig; void ImplicitlyLearnRelatedKeyScripts(const CPubKey& pubkey); @@ -116,6 +119,7 @@ class CBasicKeyStore : public CKeyStore virtual bool RemoveWatchOnly(const CScript& dest) override; virtual bool HaveWatchOnly(const CScript& dest) const override; virtual bool HaveWatchOnly() const override; + bool GetHDChain(CHDChain& hdChainRet) const; virtual bool AddMultiSig(const CScript& dest) override; virtual bool RemoveMultiSig(const CScript& dest) override; @@ -129,4 +133,7 @@ typedef std::map > > Crypt /** Return the CKeyID of the key involved in a script (if there is a unique one). */ CKeyID GetKeyForDestination(const CKeyStore& store, const CTxDestination& dest); +/** Checks if a CKey is in the given CKeyStore compressed or otherwise*/ +bool HaveKey(const CKeyStore& store, const CKey& key); + #endif // BITCOIN_KEYSTORE_H diff --git a/src/main.cpp b/src/main.cpp old mode 100755 new mode 100644 index 9414e17..b9d15e1 --- a/src/main.cpp +++ b/src/main.cpp @@ -3,7 +3,7 @@ // Copyright (c) 2012-2013 The PPCoin developers // Copyright (c) 2014-2015 The Dash developers // Copyright (c) 2015-2017 The PIVX developers -// Copyright (c) 2017-2019 The Ohmcoin Developers +// Copyright (c) 2017-2019 The Phore Developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -16,9 +16,9 @@ #include "chainparams.h" #include "checkpoints.h" #include "checkqueue.h" -#include "consensus/params.h" #include "consensus/merkle.h" #include "consensus/validation.h" +#include "cuckoocache.h" #include "init.h" #include "kernel.h" #include "karmanode-budget.h" @@ -29,7 +29,6 @@ #include "obfuscation.h" #include "protocol.h" #include "pow.h" -#include "reverse_iterator.h" #include "spork.h" #include "sporkdb.h" #include "swifttx.h" @@ -38,18 +37,22 @@ #include "ui_interface.h" #include "util.h" #include "utilmoneystr.h" -#include "versionbits.h" #include "validationinterface.h" #include "primitives/zerocoin.h" #include "libzerocoin/Denominations.h" #include "accumulatormap.h" +#ifdef ENABLE_WALLET +#include "wallet/wallet.h" +#endif + #include #include #include #include +#include #include using namespace boost; @@ -99,10 +102,10 @@ unsigned int nCoinCacheSize = 5000; unsigned int nBytesPerSigOp = DEFAULT_BYTES_PER_SIGOP; bool fAlerts = DEFAULT_ALERTS; -unsigned int nStakeMinAge = 60 * 60; +unsigned int nStakeMinAge = 3 * 60 * 60; int64_t nReserveBalance = 0; -/** Fees smaller than this (in uohmc) are considered zero fee (for relaying and mining) +/** Fees smaller than this (in uphr) are considered zero fee (for relaying and mining) * We are ~100 times smaller then bitcoin now (2015-06-23), set minRelayTxFee only 10 times higher * so it's still 10 times lower comparing to bitcoin. */ @@ -132,78 +135,78 @@ const string strMessageMagic = "DarkNet Signed Message:\n"; // Internal stuff namespace { - struct CBlockIndexWorkComparator { - bool operator()(CBlockIndex* pa, CBlockIndex* pb) const - { - // First sort by most total work, ... - if (pa->nChainWork > pb->nChainWork) return false; - if (pa->nChainWork < pb->nChainWork) return true; +struct CBlockIndexWorkComparator { + bool operator()(CBlockIndex* pa, CBlockIndex* pb) const + { + // First sort by most total work, ... + if (pa->nChainWork > pb->nChainWork) return false; + if (pa->nChainWork < pb->nChainWork) return true; - // ... then by earliest time received, ... - if (pa->nSequenceId < pb->nSequenceId) return false; - if (pa->nSequenceId > pb->nSequenceId) return true; + // ... then by earliest time received, ... + if (pa->nSequenceId < pb->nSequenceId) return false; + if (pa->nSequenceId > pb->nSequenceId) return true; - // Use pointer address as tie breaker (should only happen with blocks - // loaded from disk, as those all have id 0). - if (pa < pb) return false; - if (pa > pb) return true; + // Use pointer address as tie breaker (should only happen with blocks + // loaded from disk, as those all have id 0). + if (pa < pb) return false; + if (pa > pb) return true; - // Identical blocks. - return false; - } - }; + // Identical blocks. + return false; + } +}; - CBlockIndex* pindexBestInvalid; +CBlockIndex* pindexBestInvalid; /** * The set of all CBlockIndex entries with BLOCK_VALID_TRANSACTIONS (for itself and all ancestors) and * as good as our current tip or better. Entries may be failed, though. */ - set setBlockIndexCandidates; +set setBlockIndexCandidates; /** Number of nodes with fSyncStarted. */ - int nSyncStarted = 0; +int nSyncStarted = 0; /** All pairs A->B, where A (or one if its ancestors) misses transactions, but B has transactions. */ - multimap mapBlocksUnlinked; +multimap mapBlocksUnlinked; - CCriticalSection cs_LastBlockFile; - std::vector vinfoBlockFile; - int nLastBlockFile = 0; +CCriticalSection cs_LastBlockFile; +std::vector vinfoBlockFile; +int nLastBlockFile = 0; /** * Every received block is assigned a unique and increasing identifier, so we * know which one to give priority in case of a fork. */ - CCriticalSection cs_nBlockSequenceId; +CCriticalSection cs_nBlockSequenceId; /** Blocks loaded from disk are assigned id 0, so start the counter at 1. */ - uint32_t nBlockSequenceId = 1; +uint32_t nBlockSequenceId = 1; /** * Sources of received blocks, to be able to send them reject messages or ban * them, if processing happens afterwards. Protected by cs_main. */ - map mapBlockSource; +map mapBlockSource; /** Blocks that are in flight, and that are in the queue to be downloaded. Protected by cs_main. */ - struct QueuedBlock { - 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::iterator> > mapBlocksInFlight; +struct QueuedBlock { + 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::iterator> > mapBlocksInFlight; /** Number of blocks in flight with validated headers. */ - int nQueuedValidatedHeaders = 0; +int nQueuedValidatedHeaders = 0; /** Number of preferable block download peers. */ - int nPreferredDownload = 0; +int nPreferredDownload = 0; /** Dirty block index entries. */ - set setDirtyBlockIndex; +set setDirtyBlockIndex; /** Dirty block file entries. */ - set setDirtyFileInfo; +set setDirtyFileInfo; } // anon namespace ////////////////////////////////////////////////////////////////////////////// @@ -213,11 +216,11 @@ namespace namespace { - struct CBlockReject { - unsigned int chRejectCode; - string strRejectReason; - uint256 hashBlock; - }; +struct CBlockReject { + unsigned int chRejectCode; + string strRejectReason; + uint256 hashBlock; +}; /** * Maintain validation-specific state about nodes, protected by cs_main, instead @@ -225,285 +228,297 @@ namespace * processing of incoming data is done after the ProcessMessage call returns, * and we're no longer holding the node's locks. */ - struct CNodeState { - //! The peer's address - CService address; - //! Whether we have a fully established connection. - bool fCurrentlyConnected; - //! Accumulated misbehaviour score for this peer. - int nMisbehavior; - //! Whether this peer should be disconnected and banned (unless whitelisted). - bool fShouldBan; - //! String name of this peer (debugging/logging purposes). - std::string name; - //! List of asynchronously-determined block rejections to notify this peer about. - std::vector rejects; - //! The best known block we know this peer has announced. - CBlockIndex* pindexBestKnownBlock; - //! The hash of the last unknown block this peer has announced. - uint256 hashLastUnknownBlock; - //! The last full block we both have. - CBlockIndex* pindexLastCommonBlock; - //! Whether we've started headers synchronization with this peer. - bool fSyncStarted; - //! Since when we're stalling block download progress (in microseconds), or 0. - int64_t nStallingSince; - list vBlocksInFlight; - int nBlocksInFlight; - //! Whether we consider this a preferred download peer. - bool fPreferredDownload; - //! Whether this peer can give us witnesses - bool fHaveWitness; - - CNodeState() - { - fCurrentlyConnected = false; - nMisbehavior = 0; - fShouldBan = false; - pindexBestKnownBlock = NULL; - hashLastUnknownBlock = uint256(0); - pindexLastCommonBlock = NULL; - fSyncStarted = false; - nStallingSince = 0; - nBlocksInFlight = 0; - fPreferredDownload = false; - fHaveWitness = false; - } - }; +struct CNodeState { + //! The peer's address + CService address; + //! Whether we have a fully established connection. + bool fCurrentlyConnected; + //! Accumulated misbehaviour score for this peer. + int nMisbehavior; + //! Whether this peer should be disconnected and banned (unless whitelisted). + bool fShouldBan; + //! String name of this peer (debugging/logging purposes). + std::string name; + //! List of asynchronously-determined block rejections to notify this peer about. + std::vector rejects; + //! The best known block we know this peer has announced. + CBlockIndex* pindexBestKnownBlock; + //! The hash of the last unknown block this peer has announced. + uint256 hashLastUnknownBlock; + //! The last full block we both have. + CBlockIndex* pindexLastCommonBlock; + //! Whether we've started headers synchronization with this peer. + bool fSyncStarted; + //! Since when we're stalling block download progress (in microseconds), or 0. + int64_t nStallingSince; + list vBlocksInFlight; + int nBlocksInFlight; + //! Whether we consider this a preferred download peer. + bool fPreferredDownload; + //! Whether this peer can give us witnesses + bool fHaveWitness; + + CNodeState() + { + fCurrentlyConnected = false; + nMisbehavior = 0; + fShouldBan = false; + pindexBestKnownBlock = NULL; + hashLastUnknownBlock = uint256(0); + pindexLastCommonBlock = NULL; + fSyncStarted = false; + nStallingSince = 0; + nBlocksInFlight = 0; + fPreferredDownload = false; + fHaveWitness = false; + } +}; /** Map maintaining per-node state. Requires cs_main. */ - map mapNodeState; +map mapNodeState; // Requires cs_main. - CNodeState* State(NodeId pnode) - { - map::iterator it = mapNodeState.find(pnode); - if (it == mapNodeState.end()) - return NULL; - return &it->second; - } +CNodeState* State(NodeId pnode) +{ + map::iterator it = mapNodeState.find(pnode); + if (it == mapNodeState.end()) + return NULL; + return &it->second; +} - int GetHeight() - { - while (true) { - TRY_LOCK(cs_main, lockMain); - if (!lockMain) { - MilliSleep(50); - continue; - } - return chainActive.Height(); +int GetHeight() +{ + while (true) { + TRY_LOCK(cs_main, lockMain); + if (!lockMain) { + MilliSleep(50); + continue; } + return chainActive.Height(); } +} - void UpdatePreferredDownload(CNode* node, CNodeState* state) - { - nPreferredDownload -= state->fPreferredDownload; +void UpdatePreferredDownload(CNode* node, CNodeState* state) +{ + nPreferredDownload -= state->fPreferredDownload; - // Whether this node should be marked as a preferred download node. - state->fPreferredDownload = (!node->fInbound || node->fWhitelisted) && !node->fOneShot && !node->fClient; + // Whether this node should be marked as a preferred download node. + state->fPreferredDownload = (!node->fInbound || node->fWhitelisted) && !node->fOneShot && !node->fClient; - nPreferredDownload += state->fPreferredDownload; - } + nPreferredDownload += state->fPreferredDownload; +} - void InitializeNode(NodeId nodeid, const CNode* pnode) - { - LOCK(cs_main); - CNodeState& state = mapNodeState.insert(std::make_pair(nodeid, CNodeState())).first->second; - state.name = pnode->addrName; - state.address = pnode->addr; - } +void InitializeNode(NodeId nodeid, const CNode* pnode) +{ + LOCK(cs_main); + CNodeState& state = mapNodeState.insert(std::make_pair(nodeid, CNodeState())).first->second; + state.name = pnode->addrName; + state.address = pnode->addr; +} - void FinalizeNode(NodeId nodeid) - { - LOCK(cs_main); - CNodeState* state = State(nodeid); +void FinalizeNode(NodeId nodeid) +{ + LOCK(cs_main); + CNodeState* state = State(nodeid); - if (state->fSyncStarted) - nSyncStarted--; + if (state->fSyncStarted) + nSyncStarted--; - if (state->nMisbehavior == 0 && state->fCurrentlyConnected) { - AddressCurrentlyConnected(state->address); - } + if (state->nMisbehavior == 0 && state->fCurrentlyConnected) { + AddressCurrentlyConnected(state->address); + } - for (const QueuedBlock& entry : state->vBlocksInFlight) + for (const QueuedBlock& entry : state->vBlocksInFlight) mapBlocksInFlight.erase(entry.hash); - EraseOrphansFor(nodeid); - nPreferredDownload -= state->fPreferredDownload; + EraseOrphansFor(nodeid); + nPreferredDownload -= state->fPreferredDownload; - mapNodeState.erase(nodeid); - } + mapNodeState.erase(nodeid); +} // Requires cs_main. - void MarkBlockAsReceived(const uint256& hash) - { - map::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; - mapBlocksInFlight.erase(itInFlight); - } +void MarkBlockAsReceived(const uint256& hash) +{ + map::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; + mapBlocksInFlight.erase(itInFlight); } +} // Requires cs_main. - void MarkBlockAsInFlight(NodeId nodeid, const uint256& hash, CBlockIndex* pindex = NULL) - { - CNodeState* state = State(nodeid); - assert(state != NULL); +void MarkBlockAsInFlight(NodeId nodeid, const uint256& hash, CBlockIndex* pindex = NULL) +{ + CNodeState* state = State(nodeid); + assert(state != NULL); - // Make sure it's not listed somewhere already. - MarkBlockAsReceived(hash); + // Make sure it's not listed somewhere already. + MarkBlockAsReceived(hash); - QueuedBlock newentry = {hash, pindex, GetTimeMicros(), nQueuedValidatedHeaders, pindex != NULL}; - nQueuedValidatedHeaders += newentry.fValidatedHeaders; - list::iterator it = state->vBlocksInFlight.insert(state->vBlocksInFlight.end(), newentry); - state->nBlocksInFlight++; - mapBlocksInFlight[hash] = std::make_pair(nodeid, it); - } + QueuedBlock newentry = {hash, pindex, GetTimeMicros(), nQueuedValidatedHeaders, pindex != NULL}; + nQueuedValidatedHeaders += newentry.fValidatedHeaders; + list::iterator it = state->vBlocksInFlight.insert(state->vBlocksInFlight.end(), newentry); + state->nBlocksInFlight++; + mapBlocksInFlight[hash] = std::make_pair(nodeid, it); +} /** Check whether the last unknown block a peer advertized is not yet known. */ - void ProcessBlockAvailability(NodeId nodeid) - { - CNodeState* state = State(nodeid); - assert(state != NULL); - - if (state->hashLastUnknownBlock != 0) { - 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); - } +void ProcessBlockAvailability(NodeId nodeid) +{ + CNodeState* state = State(nodeid); + assert(state != NULL); + + if (state->hashLastUnknownBlock != 0) { + 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); } } +} /** Update tracking information about which blocks a peer is assumed to have. */ - void UpdateBlockAvailability(NodeId nodeid, const uint256& hash) - { - CNodeState* state = State(nodeid); - assert(state != NULL); +void UpdateBlockAvailability(NodeId nodeid, const uint256& hash) +{ + CNodeState* state = State(nodeid); + assert(state != NULL); - ProcessBlockAvailability(nodeid); + ProcessBlockAvailability(nodeid); - BlockMap::iterator it = mapBlockIndex.find(hash); - if (it != mapBlockIndex.end() && it->second->nChainWork > 0) { - // An actually better block was announced. - if (state->pindexBestKnownBlock == NULL || it->second->nChainWork >= state->pindexBestKnownBlock->nChainWork) - state->pindexBestKnownBlock = it->second; - } else { - // An unknown block was announced; just assume that the latest one is the best one. - state->hashLastUnknownBlock = hash; - } + BlockMap::iterator it = mapBlockIndex.find(hash); + if (it != mapBlockIndex.end() && it->second->nChainWork > 0) { + // An actually better block was announced. + if (state->pindexBestKnownBlock == NULL || it->second->nChainWork >= state->pindexBestKnownBlock->nChainWork) + state->pindexBestKnownBlock = it->second; + } else { + // An unknown block was announced; just assume that the latest one is the best one. + state->hashLastUnknownBlock = hash; } +} /** Find the last common ancestor two blocks have. * Both pa and pb must be non-NULL. */ - CBlockIndex* LastCommonAncestor(CBlockIndex* pa, CBlockIndex* pb) - { - if (pa->nHeight > pb->nHeight) { - pa = pa->GetAncestor(pb->nHeight); - } else if (pb->nHeight > pa->nHeight) { - pb = pb->GetAncestor(pa->nHeight); - } - - while (pa != pb && pa && pb) { - pa = pa->pprev; - pb = pb->pprev; - } +CBlockIndex* LastCommonAncestor(CBlockIndex* pa, CBlockIndex* pb) +{ + if (pa->nHeight > pb->nHeight) { + pa = pa->GetAncestor(pb->nHeight); + } else if (pb->nHeight > pa->nHeight) { + pb = pb->GetAncestor(pa->nHeight); + } - // Eventually all chain branches meet at the genesis block. - assert(pa == pb); - return pa; + while (pa != pb && pa && pb) { + pa = pa->pprev; + pb = pb->pprev; } + // Eventually all chain branches meet at the genesis block. + assert(pa == pb); + return pa; +} + /** Update pindexLastCommonBlock and add not-in-flight missing successors to vBlocks, until it has * at most count entries. */ - void FindNextBlocksToDownload(NodeId nodeid, unsigned int count, std::vector& vBlocks, NodeId& nodeStaller) - { - if (count == 0) - return; - - vBlocks.reserve(vBlocks.size() + count); - CNodeState* state = State(nodeid); - assert(state != NULL); - - // Make sure pindexBestKnownBlock is up to date, we'll need it. - ProcessBlockAvailability(nodeid); - - if (state->pindexBestKnownBlock == NULL || state->pindexBestKnownBlock->nChainWork < chainActive.Tip()->nChainWork) { - // This peer has nothing interesting. - return; - } - - if (state->pindexLastCommonBlock == NULL) { - // Bootstrap quickly by guessing a parent of our best tip is the forking point. - // Guessing wrong in either direction is not a problem. - state->pindexLastCommonBlock = chainActive[std::min(state->pindexBestKnownBlock->nHeight, chainActive.Height())]; - } - - // If the peer reorganized, our previous pindexLastCommonBlock may not be an ancestor - // of their current tip anymore. Go back enough to fix that. - state->pindexLastCommonBlock = LastCommonAncestor(state->pindexLastCommonBlock, state->pindexBestKnownBlock); - if (state->pindexLastCommonBlock == state->pindexBestKnownBlock) - return; - - std::vector vToFetch; - CBlockIndex* pindexWalk = state->pindexLastCommonBlock; - // Never fetch further than the best block we know the peer has, or more than BLOCK_DOWNLOAD_WINDOW + 1 beyond the last - // linked block we have in common with this peer. The +1 is so we can detect stalling, namely if we would be able to - // download that next block if the window were 1 larger. - int nWindowEnd = state->pindexLastCommonBlock->nHeight + BLOCK_DOWNLOAD_WINDOW; - int nMaxHeight = std::min(state->pindexBestKnownBlock->nHeight, nWindowEnd + 1); - NodeId waitingfor = -1; - while (pindexWalk->nHeight < nMaxHeight) { - // Read up to 128 (or more, if more blocks than that are needed) successors of pindexWalk (towards - // pindexBestKnownBlock) into vToFetch. We fetch 128, because CBlockIndex::GetAncestor may be as expensive - // as iterating over ~100 CBlockIndex* entries anyway. - int nToFetch = std::min(nMaxHeight - pindexWalk->nHeight, std::max(count - vBlocks.size(), 128)); - vToFetch.resize(nToFetch); - pindexWalk = state->pindexBestKnownBlock->GetAncestor(pindexWalk->nHeight + nToFetch); - vToFetch[nToFetch - 1] = pindexWalk; - for (unsigned int i = nToFetch - 1; i > 0; i--) { - vToFetch[i - 1] = vToFetch[i]->pprev; - } +void FindNextBlocksToDownload(NodeId nodeid, unsigned int count, std::vector& vBlocks, NodeId& nodeStaller) +{ + if (count == 0) + return; - // Iterate over those blocks in vToFetch (in forward direction), adding the ones that - // are not yet downloaded and not in flight to vBlocks. In the mean time, update - // pindexLastCommonBlock as long as all ancestors are already downloaded. - for (CBlockIndex* pindex : vToFetch) { - if (!pindex->IsValid(BLOCK_VALID_TREE)) { - // We consider the chain that this peer is on invalid. + vBlocks.reserve(vBlocks.size() + count); + CNodeState* state = State(nodeid); + assert(state != NULL); + + // Make sure pindexBestKnownBlock is up to date, we'll need it. + ProcessBlockAvailability(nodeid); + + if (state->pindexBestKnownBlock == NULL || state->pindexBestKnownBlock->nChainWork < chainActive.Tip()->nChainWork) { + // This peer has nothing interesting. + return; + } + + if (state->pindexLastCommonBlock == NULL) { + // Bootstrap quickly by guessing a parent of our best tip is the forking point. + // Guessing wrong in either direction is not a problem. + state->pindexLastCommonBlock = chainActive[std::min(state->pindexBestKnownBlock->nHeight, chainActive.Height())]; + } + + // If the peer reorganized, our previous pindexLastCommonBlock may not be an ancestor + // of their current tip anymore. Go back enough to fix that. + state->pindexLastCommonBlock = LastCommonAncestor(state->pindexLastCommonBlock, state->pindexBestKnownBlock); + if (state->pindexLastCommonBlock == state->pindexBestKnownBlock) + return; + + std::vector vToFetch; + CBlockIndex* pindexWalk = state->pindexLastCommonBlock; + // Never fetch further than the best block we know the peer has, or more than BLOCK_DOWNLOAD_WINDOW + 1 beyond the last + // linked block we have in common with this peer. The +1 is so we can detect stalling, namely if we would be able to + // download that next block if the window were 1 larger. + int nWindowEnd = state->pindexLastCommonBlock->nHeight + BLOCK_DOWNLOAD_WINDOW; + int nMaxHeight = std::min(state->pindexBestKnownBlock->nHeight, nWindowEnd + 1); + NodeId waitingfor = -1; + while (pindexWalk->nHeight < nMaxHeight) { + // Read up to 128 (or more, if more blocks than that are needed) successors of pindexWalk (towards + // pindexBestKnownBlock) into vToFetch. We fetch 128, because CBlockIndex::GetAncestor may be as expensive + // as iterating over ~100 CBlockIndex* entries anyway. + int nToFetch = std::min(nMaxHeight - pindexWalk->nHeight, std::max(count - vBlocks.size(), 128)); + vToFetch.resize(nToFetch); + pindexWalk = state->pindexBestKnownBlock->GetAncestor(pindexWalk->nHeight + nToFetch); + vToFetch[nToFetch - 1] = pindexWalk; + for (unsigned int i = nToFetch - 1; i > 0; i--) { + vToFetch[i - 1] = vToFetch[i]->pprev; + } + + // Iterate over those blocks in vToFetch (in forward direction), adding the ones that + // are not yet downloaded and not in flight to vBlocks. In the mean time, update + // pindexLastCommonBlock as long as all ancestors are already downloaded. + for (CBlockIndex* pindex : vToFetch) { + if (!pindex->IsValid(BLOCK_VALID_TREE)) { + // We consider the chain that this peer is on invalid. + return; + } + if (pindex->nStatus & BLOCK_HAVE_DATA) { + if (pindex->nChainTx) + state->pindexLastCommonBlock = pindex; + } else if (mapBlocksInFlight.count(pindex->GetBlockHash()) == 0) { + // The block is not already downloaded, and not yet in flight. + if (pindex->nHeight > nWindowEnd) { + // We reached the end of the window. + if (vBlocks.size() == 0 && waitingfor != nodeid) { + // We aren't able to fetch anything, but we would be if the download window was one larger. + nodeStaller = waitingfor; + } return; } - if (pindex->nStatus & BLOCK_HAVE_DATA) { - if (pindex->nChainTx) - state->pindexLastCommonBlock = pindex; - } else if (mapBlocksInFlight.count(pindex->GetBlockHash()) == 0) { - // The block is not already downloaded, and not yet in flight. - if (pindex->nHeight > nWindowEnd) { - // We reached the end of the window. - if (vBlocks.size() == 0 && waitingfor != nodeid) { - // We aren't able to fetch anything, but we would be if the download window was one larger. - nodeStaller = waitingfor; - } - return; - } - vBlocks.push_back(pindex); - if (vBlocks.size() == count) { - return; - } - } else if (waitingfor == -1) { - // This is the first already-in-flight block. - waitingfor = mapBlocksInFlight[pindex->GetBlockHash()].first; + vBlocks.push_back(pindex); + if (vBlocks.size() == count) { + return; } + } else if (waitingfor == -1) { + // This is the first already-in-flight block. + waitingfor = mapBlocksInFlight[pindex->GetBlockHash()].first; } } } +} } // anon namespace +static CuckooCache::cache scriptExecutionCache; +static uint256 scriptExecutionCacheNonce(GetRandHash()); + +void InitScriptExecutionCache() { + // nMaxCacheSize is unsigned. If -maxsigcachesize is set to zero, + // setup_bytes creates the minimum possible cache (2 elements). + size_t nMaxCacheSize = std::min(std::max((int64_t)0, GetArg("-maxsigcachesize", DEFAULT_MAX_SIG_CACHE_SIZE) / 2), MAX_MAX_SIG_CACHE_SIZE) * ((size_t) 1 << 20); + size_t nElems = scriptExecutionCache.setup_bytes(nMaxCacheSize); + LogPrintf("Using %zu MiB out of %zu/2 requested for script execution cache, able to store %zu elements\n", + (nElems*sizeof(uint256)) >>20, (nMaxCacheSize*2)>>20, nElems); +} + bool GetNodeStateStats(NodeId nodeid, CNodeStateStats& stats) { LOCK(cs_main); @@ -587,10 +602,10 @@ bool AddOrphanTx(const CTransaction& tx, NodeId peer) mapOrphanTransactions[hash].tx = tx; mapOrphanTransactions[hash].fromPeer = peer; for (const CTxIn& txin : tx.vin) - mapOrphanTransactionsByPrev[txin.prevout.hash].insert(hash); + mapOrphanTransactionsByPrev[txin.prevout.hash].insert(hash); LogPrint("mempool", "stored orphan tx %s (mapsz %u prevsz %u)\n", hash.ToString(), - mapOrphanTransactions.size(), mapOrphanTransactionsByPrev.size()); + mapOrphanTransactions.size(), mapOrphanTransactionsByPrev.size()); return true; } @@ -741,8 +756,8 @@ bool IsFinalTx(const CTransaction& tx, int nBlockHeight, int64_t nBlockTime) if ((int64_t)tx.nLockTime < ((int64_t)tx.nLockTime < LOCKTIME_THRESHOLD ? (int64_t)nBlockHeight : nBlockTime)) return true; for (const CTxIn& txin : tx.vin) - if (!txin.IsFinal()) - return false; + if (!txin.IsFinal()) + return false; return true; } @@ -1114,7 +1129,7 @@ bool TxOutToPublicCoin(const CTxOut txout, PublicCoin& pubCoin, CValidationState CBigNum publicZerocoin; vector vchZeroMint; vchZeroMint.insert(vchZeroMint.end(), txout.scriptPubKey.begin() + SCRIPT_OFFSET, - txout.scriptPubKey.begin() + txout.scriptPubKey.size()); + txout.scriptPubKey.begin() + txout.scriptPubKey.size()); publicZerocoin.setvch(vchZeroMint); CoinDenomination denomination = AmountToZerocoinDenomination(txout.nValue); @@ -1130,7 +1145,7 @@ bool TxOutToPublicCoin(const CTxOut txout, PublicCoin& pubCoin, CValidationState bool BlockToPubcoinList(const CBlock& block, list& listPubcoins) { - for (const CTransaction tx : block.vtx) { + for (const CTransaction& tx : block.vtx) { if(!tx.IsZerocoinMint()) continue; @@ -1155,7 +1170,7 @@ bool BlockToPubcoinList(const CBlock& block, list& listPubcoins) //return a list of zerocoin mints contained in a specific block bool BlockToZerocoinMintList(const CBlock& block, std::list& vMints) { - for (const CTransaction tx : block.vtx) { + for (const CTransaction& tx : block.vtx) { if(!tx.IsZerocoinMint()) continue; @@ -1180,11 +1195,11 @@ bool BlockToZerocoinMintList(const CBlock& block, std::list& vMin bool BlockToMintValueVector(const CBlock& block, const CoinDenomination denom, vector& vValues) { - for (const CTransaction tx : block.vtx) { + for (const CTransaction& tx : block.vtx) { if(!tx.IsZerocoinMint()) continue; - for (const CTxOut txOut : tx.vout) { + for (const CTxOut& txOut : tx.vout) { if(!txOut.scriptPubKey.IsZerocoinMint()) continue; @@ -1207,7 +1222,7 @@ bool BlockToMintValueVector(const CBlock& block, const CoinDenomination denom, v std::list ZerocoinSpendListFromBlock(const CBlock& block) { std::list vSpends; - for (const CTransaction tx : block.vtx) { + for (const CTransaction& tx : block.vtx) { if (!tx.IsZerocoinSpend()) continue; @@ -1245,7 +1260,7 @@ CoinSpend TxInToZerocoinSpend(const CTxIn& txin) } bool ContextualCheckZerocoinMint(const CTransaction& tx, const PublicCoin& coin, const CBlockIndex* pindex) { - if (pindex->nHeight > Params().Zerocoin_LastOldParams() && Params().NetworkID() != CBaseChainParams::TESTNET) { + if (pindex->nHeight > Params().Zerocoin_LastOldParams() && Params().NetworkID() != CBaseChainParams::TESTNET) { //See if this coin has already been added to the blockchain uint256 txid; if(zerocoinDB->ReadCoinMint(coin.getValue(), txid)) @@ -1291,7 +1306,7 @@ bool CheckZerocoinSpend(const CTransaction tx, bool fVerifySignature, CValidatio //max needed non-mint outputs should be 2 - one for redemption address and a possible 2nd for change if (tx.vout.size() > 2) { int outs = 0; - for (const CTxOut out : tx.vout) { + for (const CTxOut& out : tx.vout) { if (out.IsZerocoinMint()) continue; outs++; @@ -1302,7 +1317,7 @@ bool CheckZerocoinSpend(const CTransaction tx, bool fVerifySignature, CValidatio //compute the txout hash that is used for the zerocoinspend signatures CMutableTransaction txTemp; - for (const CTxOut out : tx.vout) { + for (const CTxOut& out : tx.vout) { txTemp.vout.push_back(out); } uint256 hashTxOut = txTemp.GetHash(); @@ -1370,10 +1385,10 @@ bool CheckTransaction(const CTransaction& tx, bool fZerocoinActive, bool fReject // Basic checks that don't depend on any context if (tx.vin.empty()) return state.DoS(10, error("CheckTransaction() : vin empty"), - REJECT_INVALID, "bad-txns-vin-empty"); + REJECT_INVALID, "bad-txns-vin-empty"); if (tx.vout.empty()) return state.DoS(10, error("CheckTransaction() : vout empty"), - REJECT_INVALID, "bad-txns-vout-empty"); + REJECT_INVALID, "bad-txns-vout-empty"); // Size limits (this doesn't take the witness into account, as that hasn't been checked for malleability) if (::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) > MAX_BLOCK_BASE_SIZE) @@ -1385,14 +1400,14 @@ bool CheckTransaction(const CTransaction& tx, bool fZerocoinActive, bool fReject for (const CTxOut& txout : tx.vout) { if (txout.nValue < 0) return state.DoS(100, error("CheckTransaction() : txout.nValue negative"), - REJECT_INVALID, "bad-txns-vout-negative"); + REJECT_INVALID, "bad-txns-vout-negative"); if (txout.nValue > Params().MaxMoneyOut()) return state.DoS(100, error("CheckTransaction() : txout.nValue too high"), - REJECT_INVALID, "bad-txns-vout-toolarge"); + REJECT_INVALID, "bad-txns-vout-toolarge"); nValueOut += txout.nValue; if (!MoneyRange(nValueOut)) return state.DoS(100, error("CheckTransaction() : txout total out of range"), - REJECT_INVALID, "bad-txns-txouttotal-toolarge"); + REJECT_INVALID, "bad-txns-txouttotal-toolarge"); if (fZerocoinActive && txout.IsZerocoinMint()) { if(!CheckZerocoinMint(tx.GetHash(), txout, state, true)) return state.DoS(100, error("CheckTransaction() : invalid zerocoin mint")); @@ -1426,7 +1441,7 @@ bool CheckTransaction(const CTransaction& tx, bool fZerocoinActive, bool fReject for (const CTxIn& txin : tx.vin) { if (vInOutPoints.count(txin.prevout)) return state.DoS(100, error("CheckTransaction() : duplicate inputs"), - REJECT_INVALID, "bad-txns-inputs-duplicate"); + REJECT_INVALID, "bad-txns-inputs-duplicate"); //duplicate zcspend serials are checked in CheckZerocoinSpend() if (!txin.scriptSig.IsZerocoinSpend()) @@ -1435,16 +1450,16 @@ bool CheckTransaction(const CTransaction& tx, bool fZerocoinActive, bool fReject if (tx.IsCoinBase()) { if (tx.vin[0].scriptSig.size() < 2 || tx.vin[0].scriptSig.size() > 150) - return state.DoS(100, error("CheckTransaction(), coinbase script size=%d", tx.vin[0].scriptSig.size()), - REJECT_INVALID, "bad-cb-length"); + return state.DoS(100, error("CheckTransaction() : coinbase script size=%d", tx.vin[0].scriptSig.size()), + REJECT_INVALID, "bad-cb-length"); } else if (fZerocoinActive && tx.IsZerocoinSpend()) { if(tx.vin.size() < 1 || static_cast(tx.vin.size()) > Params().Zerocoin_MaxSpendsPerTransaction()) return state.DoS(10, error("CheckTransaction() : Zerocoin Spend has more than allowed txin's"), REJECT_INVALID, "bad-zerocoinspend"); } else { for (const CTxIn& txin : tx.vin) - if (txin.prevout.IsNull() && (fZerocoinActive && !txin.scriptSig.IsZerocoinSpend())) - return state.DoS(10, error("CheckTransaction() : prevout is null"), - REJECT_INVALID, "bad-txns-prevout-null"); + if (txin.prevout.IsNull() && (fZerocoinActive && !txin.scriptSig.IsZerocoinSpend())) + return state.DoS(10, error("CheckTransaction() : prevout is null"), + REJECT_INVALID, "bad-txns-prevout-null"); } return true; @@ -1526,12 +1541,12 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState& state, const CTransa // 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"), - REJECT_INVALID, "coinbase"); + REJECT_INVALID, "coinbase"); //Coinstake is also only valid in a block, not as a loose transaction if (tx.IsCoinStake()) return state.DoS(100, error("AcceptToMemoryPool: coinstake as individual tx. txid=%s", tx.GetHash().GetHex()), - REJECT_INVALID, "coinstake"); + REJECT_INVALID, "coinstake"); // is it already in the memory pool? uint256 hash = tx.GetHash(); @@ -1546,8 +1561,8 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState& state, const CTransa if (mapLockedInputs.count(in.prevout)) { if (mapLockedInputs[in.prevout] != tx.GetHash()) { return state.DoS(0, - error("AcceptToMemoryPool : conflicts with existing transaction lock: %s", reason), - REJECT_INVALID, "tx-lock-conflict"); + error("AcceptToMemoryPool : conflicts with existing transaction lock: %s", reason), + REJECT_INVALID, "tx-lock-conflict"); } } } @@ -1572,8 +1587,8 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState& state, const CTransa // Rather not work on nonstandard transactions (unless -testnet/-regtest) if (Params().RequireStandard() && !IsStandardTx(tx, reason)) return state.DoS(0, - error("AcceptToMemoryPool : nonstandard transaction: %s", reason), - REJECT_NONSTANDARD, reason); + error("AcceptToMemoryPool : nonstandard transaction: %s", reason), + REJECT_NONSTANDARD, reason); { CCoinsView dummy; @@ -1637,7 +1652,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"), - REJECT_DUPLICATE, "bad-txns-inputs-spent"); + REJECT_DUPLICATE, "bad-txns-inputs-spent"); // Bring the best block into scope view.GetBestBlock(); @@ -1646,13 +1661,6 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState& state, const CTransa // we have all inputs cached now, so switch back to dummy, so we don't need to keep lock on mempool view.SetBackend(dummy); - // Only accept BIP68 sequence locked 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. - // Must keep pool.cs for this unless we change CheckSequenceLocks to take a - // CoinsViewCache instead of create its own - //if (!CheckSequenceLocks(tx, STANDARD_LOCKTIME_VERIFY_FLAGS, &lp)) - // return state.DoS(0, false, REJECT_NONSTANDARD, "non-BIP68-final"); } // Check for non-standard pay-to-script-hash in inputs @@ -1689,8 +1697,8 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState& state, const CTransa CAmount txMinFee = GetMinRelayFee(tx, nSize, true); if (fLimitFree && nFees < txMinFee && !tx.IsZerocoinSpend()) return state.DoS(0, error("AcceptToMemoryPool : not enough fees %s, %d < %d", - hash.ToString(), nFees, txMinFee), - REJECT_INSUFFICIENTFEE, "insufficient fee"); + hash.ToString(), nFees, txMinFee), + REJECT_INSUFFICIENTFEE, "insufficient fee"); // Require that free transactions have sufficient priority to be mined in the next block. if (tx.IsZerocoinMint()) { @@ -1720,7 +1728,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState& state, const CTransa // At default rate it would take over a month to fill 1GB if (dFreeCount >= GetArg("-limitfreerelay", 30) * 10 * 1000) return state.DoS(0, error("AcceptToMemoryPool : free transaction rejected by rate limiter"), - REJECT_INSUFFICIENTFEE, "rate limited free transaction"); + REJECT_INSUFFICIENTFEE, "rate limited free transaction"); LogPrint("mempool", "Rate limit dFreeCount: %g => %g\n", dFreeCount, dFreeCount + nSize); dFreeCount += nSize; } @@ -1728,8 +1736,8 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState& state, const CTransa if (fRejectInsaneFee && nFees > ::minRelayTxFee.GetFee(nSize) * 10000) return error("AcceptToMemoryPool: : insane fees %s, %d > %d", - hash.ToString(), - nFees, ::minRelayTxFee.GetFee(nSize) * 10000); + hash.ToString(), + nFees, ::minRelayTxFee.GetFee(nSize) * 10000); unsigned int scriptVerifyFlags = STANDARD_SCRIPT_VERIFY_FLAGS; @@ -1739,12 +1747,12 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState& state, const CTransa // Check against previous transactions // This is done last to help prevent CPU exhaustion denial-of-service attacks. - if (!CheckInputs(tx, state, view, true, scriptVerifyFlags, true)) { + if (!CheckInputs(tx, state, view, true, scriptVerifyFlags, true, false)) { // SCRIPT_VERIFY_CLEANSTACK requires SCRIPT_VERIFY_WITNESS, so we // need to turn both off, and compare against just turning off CLEANSTACK // to see if the failure is specifically due to witness validation. - if (CheckInputs(tx, state, view, true, scriptVerifyFlags & ~(SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_CLEANSTACK), true) && - !CheckInputs(tx, state, view, true, scriptVerifyFlags & ~SCRIPT_VERIFY_CLEANSTACK, true)) { + if (CheckInputs(tx, state, view, true, scriptVerifyFlags & ~(SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_CLEANSTACK), true, false) && + !CheckInputs(tx, state, view, true, scriptVerifyFlags & ~SCRIPT_VERIFY_CLEANSTACK, true, false)) { // Only the witness is wrong, so the transaction itself may be fine. state.SetCorruptionPossible(); } @@ -1760,7 +1768,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState& state, const CTransa // There is a similar check in CreateNewBlock() to prevent creating // invalid blocks, however allowing such transactions into the mempool // can be exploited as a DoS attack. - if (!CheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true)) { + if (!CheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true, false)) { return error("AcceptToMemoryPool: : BUG! PLEASE REPORT THIS! ConnectInputs failed against MANDATORY but not STANDARD flags %s", hash.ToString()); } @@ -1827,7 +1835,7 @@ bool AcceptableInputs(CTxMemPool& pool, CValidationState& state, const CTransact // Coinbase is only valid in a block, not as a loose transaction if (tx.IsCoinBase()) return state.DoS(100, error("AcceptableInputs: : coinbase as individual tx"), - REJECT_INVALID, "coinbase"); + REJECT_INVALID, "coinbase"); // Rather not work on nonstandard transactions (unless -testnet/-regtest) string reason; @@ -1848,8 +1856,8 @@ bool AcceptableInputs(CTxMemPool& pool, CValidationState& state, const CTransact if (mapLockedInputs.count(in.prevout)) { if (mapLockedInputs[in.prevout] != tx.GetHash()) { return state.DoS(0, - error("AcceptableInputs : conflicts with existing transaction lock: %s", reason), - REJECT_INVALID, "tx-lock-conflict"); + error("AcceptableInputs : conflicts with existing transaction lock: %s", reason), + REJECT_INVALID, "tx-lock-conflict"); } } } @@ -1910,7 +1918,7 @@ bool AcceptableInputs(CTxMemPool& pool, CValidationState& state, const CTransact // are the actual inputs available? if (!view.HaveInputs(tx)) return state.Invalid(error("AcceptableInputs : inputs already spent"), - REJECT_DUPLICATE, "bad-txns-inputs-spent"); + REJECT_DUPLICATE, "bad-txns-inputs-spent"); // Bring the best block into scope view.GetBestBlock(); @@ -1952,8 +1960,8 @@ bool AcceptableInputs(CTxMemPool& pool, CValidationState& state, const CTransact CAmount txMinFee = GetMinRelayFee(tx, nSize, true); if (fLimitFree && nFees < txMinFee && !tx.IsZerocoinSpend()) return state.DoS(0, error("AcceptableInputs : not enough fees %s, %d < %d", - hash.ToString(), nFees, txMinFee), - REJECT_INSUFFICIENTFEE, "insufficient fee"); + 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))) { @@ -1980,7 +1988,7 @@ bool AcceptableInputs(CTxMemPool& pool, CValidationState& state, const CTransact // At default rate it would take over a month to fill 1GB if (dFreeCount >= GetArg("-limitfreerelay", 30) * 10 * 1000) return state.DoS(0, error("AcceptableInputs : free transaction rejected by rate limiter"), - REJECT_INSUFFICIENTFEE, "rate limited free transaction"); + REJECT_INSUFFICIENTFEE, "rate limited free transaction"); LogPrint("mempool", "Rate limit dFreeCount: %g => %g\n", dFreeCount, dFreeCount + nSize); dFreeCount += nSize; } @@ -1988,12 +1996,12 @@ bool AcceptableInputs(CTxMemPool& pool, CValidationState& state, const CTransact if (fRejectInsaneFee && nFees > ::minRelayTxFee.GetFee(nSize) * 10000) return error("AcceptableInputs: : insane fees %s, %d > %d", - hash.ToString(), - nFees, ::minRelayTxFee.GetFee(nSize) * 10000); + hash.ToString(), + nFees, ::minRelayTxFee.GetFee(nSize) * 10000); // Check against previous transactions // This is done last to help prevent CPU exhaustion denial-of-service attacks. - if (!CheckInputs(tx, state, view, false, STANDARD_SCRIPT_VERIFY_FLAGS, true)) { + if (!CheckInputs(tx, state, view, false, STANDARD_SCRIPT_VERIFY_FLAGS, true, false)) { return error("AcceptableInputs: : ConnectInputs failed %s", hash.ToString()); } @@ -2155,7 +2163,7 @@ double ConvertBitsToDouble(unsigned int nBits) int nShift = (nBits >> 24) & 0xff; double dDiff = - (double)0x0000ffff / (double)(nBits & 0x00ffffff); + (double)0x0000ffff / (double)(nBits & 0x00ffffff); while (nShift < 29) { dDiff *= 256.0; @@ -2171,305 +2179,24 @@ double ConvertBitsToDouble(unsigned int nBits) int64_t GetBlockValue(int nHeight) { - if (nHeight < 1001 && nHeight > 0) { - return 30000 * COIN; - } - - const Consensus::Params& consensus = Params().GetConsensus(); - bool fUpgradeActiveV3 = consensus.NetworkUpgradeActive(nHeight, Consensus::UPGRADE_V3_0_BLOCKREWARD); - - if (Params().NetworkID() == CBaseChainParams::TESTNET) { - if (nHeight <= 3000 && nHeight >= 1001) { - return 1 * COIN; - } else if (nHeight <= 33001 && nHeight >= 3001) { - return 3.14159 * COIN; - } else if (nHeight >= 33002) { - if (fUpgradeActiveV3) { - return 6 * COIN; - } - return 3 * COIN; - } else { - return 1 * COIN; - } - } - if (nHeight == 0) { - return 1 * COIN; - } else if (nHeight <= 904320 && nHeight >= 1000) { - return 1 * COIN; - } else if (nHeight <= 1336320 && nHeight >= 904321) { - return 0.5 * COIN; - } else if (nHeight <= 1941121 && nHeight >= 1336321) { - return 0.25 * COIN; - } else if (nHeight <= 2373122 && nHeight >= 1941122) { - return 0.125 * COIN; - } else if (nHeight <= 2977923 && nHeight >= 2373123) { - return 0.0625 * COIN; - } else if (nHeight >= 2977924) { - if (fUpgradeActiveV3) { - return 6 * COIN; - } - return 3 * COIN; + return 17500000 * COIN; + } else if (nHeight > 0 && nHeight <= 200) { + return 2500 * COIN; + } else if (nHeight > 200 && nHeight <= 775600) { + return 7 * COIN; + } else if (nHeight > 775600 && nHeight <= 1043999) { + return 4.5 * COIN; + } else if (nHeight > 1043999 && nHeight <= 1562398) { + return 3.6 * COIN; } else { - return 1 * COIN; + return 2.7 * COIN; } } int64_t GetKarmanodePayment(int nHeight, int64_t blockValue, int nKarmanodeCount) { - int64_t ret = 0; - - if (Params().NetworkID() == CBaseChainParams::TESTNET) { - if (nHeight < 200) - return 0; - } - - if (nHeight <= 20160) { - ret = blockValue / 5; - } else if (nHeight < 40320 && nHeight > 20161) { - ret = blockValue / (100 / 25); - } else if (nHeight < 60480 && nHeight > 40321) { - ret = blockValue / (100 / 26); - } else if (nHeight < 80640 && nHeight > 60481) { - ret = blockValue / (100 / 28); - } else if (nHeight < 161280 && nHeight > 80641) { - ret = blockValue / (100 / 30); - } else if (nHeight < 247680 && nHeight > 161281) { - ret = blockValue / (100 / 35); - } else if (nHeight < 518400 && nHeight > 247681) { - ret = blockValue / (100 / 40); - } else if (nHeight < (Params().NetworkID() == CBaseChainParams::TESTNET ? 145000 : 151200) && nHeight >= 518401) { - ret = blockValue / (100 / 50); - } else if (nHeight <= Params().LAST_POW_BLOCK() && nHeight >= 998) { - ret = blockValue / 2; - } else if (nHeight > Params().LAST_POW_BLOCK()) { - int64_t nMoneySupply = chainActive.Tip()->nMoneySupply; - int64_t mNodeCoins = mnodeman.size() * 3000 * COIN; - - //if a mn count is inserted into the function we are looking for a specific result for a karmanode count - if(nKarmanodeCount) - mNodeCoins = nKarmanodeCount * 3000 * COIN; - - // Use this log to compare the karmanode count for different clients - LogPrintf("Adjusting seesaw at height %d with %d karmanodes (without drift: %d) at %ld\n", nHeight, nKarmanodeCount, nKarmanodeCount - Params().KarmanodeCountDrift(), GetTime()); - - if (fDebug) - LogPrintf("GetKarmanodePayment(): moneysupply=%s, nodecoins=%s \n", FormatMoney(nMoneySupply).c_str(), - FormatMoney(mNodeCoins).c_str()); - - if (mNodeCoins == 0) { - ret = 0; - } else if (nHeight < 325000) { - if (mNodeCoins <= (nMoneySupply * .05) && mNodeCoins > 0) { - ret = blockValue * .85; - } else if (mNodeCoins <= (nMoneySupply * .1) && mNodeCoins > (nMoneySupply * .05)) { - ret = blockValue * .8; - } else if (mNodeCoins <= (nMoneySupply * .15) && mNodeCoins > (nMoneySupply * .1)) { - ret = blockValue * .75; - } else if (mNodeCoins <= (nMoneySupply * .2) && mNodeCoins > (nMoneySupply * .15)) { - ret = blockValue * .7; - } else if (mNodeCoins <= (nMoneySupply * .25) && mNodeCoins > (nMoneySupply * .2)) { - ret = blockValue * .65; - } else if (mNodeCoins <= (nMoneySupply * .3) && mNodeCoins > (nMoneySupply * .25)) { - ret = blockValue * .6; - } else if (mNodeCoins <= (nMoneySupply * .35) && mNodeCoins > (nMoneySupply * .3)) { - ret = blockValue * .55; - } else if (mNodeCoins <= (nMoneySupply * .4) && mNodeCoins > (nMoneySupply * .35)) { - ret = blockValue * .5; - } else if (mNodeCoins <= (nMoneySupply * .45) && mNodeCoins > (nMoneySupply * .4)) { - ret = blockValue * .45; - } else if (mNodeCoins <= (nMoneySupply * .5) && mNodeCoins > (nMoneySupply * .45)) { - ret = blockValue * .4; - } else if (mNodeCoins <= (nMoneySupply * .55) && mNodeCoins > (nMoneySupply * .5)) { - ret = blockValue * .35; - } else if (mNodeCoins <= (nMoneySupply * .6) && mNodeCoins > (nMoneySupply * .55)) { - ret = blockValue * .3; - } else if (mNodeCoins <= (nMoneySupply * .65) && mNodeCoins > (nMoneySupply * .6)) { - ret = blockValue * .25; - } else if (mNodeCoins <= (nMoneySupply * .7) && mNodeCoins > (nMoneySupply * .65)) { - ret = blockValue * .2; - } else if (mNodeCoins <= (nMoneySupply * .75) && mNodeCoins > (nMoneySupply * .7)) { - ret = blockValue * .15; - } else { - ret = blockValue * .1; - } - } else if (nHeight > 325000) { - if (mNodeCoins <= (nMoneySupply * .01) && mNodeCoins > 0) { - ret = blockValue * .90; - } else if (mNodeCoins <= (nMoneySupply * .02) && mNodeCoins > (nMoneySupply * .01)) { - ret = blockValue * .88; - } else if (mNodeCoins <= (nMoneySupply * .03) && mNodeCoins > (nMoneySupply * .02)) { - ret = blockValue * .87; - } else if (mNodeCoins <= (nMoneySupply * .04) && mNodeCoins > (nMoneySupply * .03)) { - ret = blockValue * .86; - } else if (mNodeCoins <= (nMoneySupply * .05) && mNodeCoins > (nMoneySupply * .04)) { - ret = blockValue * .85; - } else if (mNodeCoins <= (nMoneySupply * .06) && mNodeCoins > (nMoneySupply * .05)) { - ret = blockValue * .84; - } else if (mNodeCoins <= (nMoneySupply * .07) && mNodeCoins > (nMoneySupply * .06)) { - ret = blockValue * .83; - } else if (mNodeCoins <= (nMoneySupply * .08) && mNodeCoins > (nMoneySupply * .07)) { - ret = blockValue * .82; - } else if (mNodeCoins <= (nMoneySupply * .09) && mNodeCoins > (nMoneySupply * .08)) { - ret = blockValue * .81; - } else if (mNodeCoins <= (nMoneySupply * .10) && mNodeCoins > (nMoneySupply * .09)) { - ret = blockValue * .80; - } else if (mNodeCoins <= (nMoneySupply * .11) && mNodeCoins > (nMoneySupply * .10)) { - ret = blockValue * .79; - } else if (mNodeCoins <= (nMoneySupply * .12) && mNodeCoins > (nMoneySupply * .11)) { - ret = blockValue * .78; - } else if (mNodeCoins <= (nMoneySupply * .13) && mNodeCoins > (nMoneySupply * .12)) { - ret = blockValue * .77; - } else if (mNodeCoins <= (nMoneySupply * .14) && mNodeCoins > (nMoneySupply * .13)) { - ret = blockValue * .76; - } else if (mNodeCoins <= (nMoneySupply * .15) && mNodeCoins > (nMoneySupply * .14)) { - ret = blockValue * .75; - } else if (mNodeCoins <= (nMoneySupply * .16) && mNodeCoins > (nMoneySupply * .15)) { - ret = blockValue * .74; - } else if (mNodeCoins <= (nMoneySupply * .17) && mNodeCoins > (nMoneySupply * .16)) { - ret = blockValue * .73; - } else if (mNodeCoins <= (nMoneySupply * .18) && mNodeCoins > (nMoneySupply * .17)) { - ret = blockValue * .72; - } else if (mNodeCoins <= (nMoneySupply * .19) && mNodeCoins > (nMoneySupply * .18)) { - ret = blockValue * .71; - } else if (mNodeCoins <= (nMoneySupply * .20) && mNodeCoins > (nMoneySupply * .19)) { - ret = blockValue * .70; - } else if (mNodeCoins <= (nMoneySupply * .21) && mNodeCoins > (nMoneySupply * .20)) { - ret = blockValue * .69; - } else if (mNodeCoins <= (nMoneySupply * .22) && mNodeCoins > (nMoneySupply * .21)) { - ret = blockValue * .68; - } else if (mNodeCoins <= (nMoneySupply * .23) && mNodeCoins > (nMoneySupply * .22)) { - ret = blockValue * .67; - } else if (mNodeCoins <= (nMoneySupply * .24) && mNodeCoins > (nMoneySupply * .23)) { - ret = blockValue * .66; - } else if (mNodeCoins <= (nMoneySupply * .25) && mNodeCoins > (nMoneySupply * .24)) { - ret = blockValue * .65; - } else if (mNodeCoins <= (nMoneySupply * .26) && mNodeCoins > (nMoneySupply * .25)) { - ret = blockValue * .64; - } else if (mNodeCoins <= (nMoneySupply * .27) && mNodeCoins > (nMoneySupply * .26)) { - ret = blockValue * .63; - } else if (mNodeCoins <= (nMoneySupply * .28) && mNodeCoins > (nMoneySupply * .27)) { - ret = blockValue * .62; - } else if (mNodeCoins <= (nMoneySupply * .29) && mNodeCoins > (nMoneySupply * .28)) { - ret = blockValue * .61; - } else if (mNodeCoins <= (nMoneySupply * .30) && mNodeCoins > (nMoneySupply * .29)) { - ret = blockValue * .60; - } else if (mNodeCoins <= (nMoneySupply * .31) && mNodeCoins > (nMoneySupply * .30)) { - ret = blockValue * .59; - } else if (mNodeCoins <= (nMoneySupply * .32) && mNodeCoins > (nMoneySupply * .31)) { - ret = blockValue * .58; - } else if (mNodeCoins <= (nMoneySupply * .33) && mNodeCoins > (nMoneySupply * .32)) { - ret = blockValue * .57; - } else if (mNodeCoins <= (nMoneySupply * .34) && mNodeCoins > (nMoneySupply * .33)) { - ret = blockValue * .56; - } else if (mNodeCoins <= (nMoneySupply * .35) && mNodeCoins > (nMoneySupply * .34)) { - ret = blockValue * .55; - } else if (mNodeCoins <= (nMoneySupply * .363) && mNodeCoins > (nMoneySupply * .35)) { - ret = blockValue * .54; - } else if (mNodeCoins <= (nMoneySupply * .376) && mNodeCoins > (nMoneySupply * .363)) { - ret = blockValue * .53; - } else if (mNodeCoins <= (nMoneySupply * .389) && mNodeCoins > (nMoneySupply * .376)) { - ret = blockValue * .52; - } else if (mNodeCoins <= (nMoneySupply * .402) && mNodeCoins > (nMoneySupply * .389)) { - ret = blockValue * .51; - } else if (mNodeCoins <= (nMoneySupply * .415) && mNodeCoins > (nMoneySupply * .402)) { - ret = blockValue * .50; - } else if (mNodeCoins <= (nMoneySupply * .428) && mNodeCoins > (nMoneySupply * .415)) { - ret = blockValue * .49; - } else if (mNodeCoins <= (nMoneySupply * .441) && mNodeCoins > (nMoneySupply * .428)) { - ret = blockValue * .48; - } else if (mNodeCoins <= (nMoneySupply * .454) && mNodeCoins > (nMoneySupply * .441)) { - ret = blockValue * .47; - } else if (mNodeCoins <= (nMoneySupply * .467) && mNodeCoins > (nMoneySupply * .454)) { - ret = blockValue * .46; - } else if (mNodeCoins <= (nMoneySupply * .48) && mNodeCoins > (nMoneySupply * .467)) { - ret = blockValue * .45; - } else if (mNodeCoins <= (nMoneySupply * .493) && mNodeCoins > (nMoneySupply * .48)) { - ret = blockValue * .44; - } else if (mNodeCoins <= (nMoneySupply * .506) && mNodeCoins > (nMoneySupply * .493)) { - ret = blockValue * .43; - } else if (mNodeCoins <= (nMoneySupply * .519) && mNodeCoins > (nMoneySupply * .506)) { - ret = blockValue * .42; - } else if (mNodeCoins <= (nMoneySupply * .532) && mNodeCoins > (nMoneySupply * .519)) { - ret = blockValue * .41; - } else if (mNodeCoins <= (nMoneySupply * .545) && mNodeCoins > (nMoneySupply * .532)) { - ret = blockValue * .40; - } else if (mNodeCoins <= (nMoneySupply * .558) && mNodeCoins > (nMoneySupply * .545)) { - ret = blockValue * .39; - } else if (mNodeCoins <= (nMoneySupply * .571) && mNodeCoins > (nMoneySupply * .558)) { - ret = blockValue * .38; - } else if (mNodeCoins <= (nMoneySupply * .584) && mNodeCoins > (nMoneySupply * .571)) { - ret = blockValue * .37; - } else if (mNodeCoins <= (nMoneySupply * .597) && mNodeCoins > (nMoneySupply * .584)) { - ret = blockValue * .36; - } else if (mNodeCoins <= (nMoneySupply * .61) && mNodeCoins > (nMoneySupply * .597)) { - ret = blockValue * .35; - } else if (mNodeCoins <= (nMoneySupply * .623) && mNodeCoins > (nMoneySupply * .61)) { - ret = blockValue * .34; - } else if (mNodeCoins <= (nMoneySupply * .636) && mNodeCoins > (nMoneySupply * .623)) { - ret = blockValue * .33; - } else if (mNodeCoins <= (nMoneySupply * .649) && mNodeCoins > (nMoneySupply * .636)) { - ret = blockValue * .32; - } else if (mNodeCoins <= (nMoneySupply * .662) && mNodeCoins > (nMoneySupply * .649)) { - ret = blockValue * .31; - } else if (mNodeCoins <= (nMoneySupply * .675) && mNodeCoins > (nMoneySupply * .662)) { - ret = blockValue * .30; - } else if (mNodeCoins <= (nMoneySupply * .688) && mNodeCoins > (nMoneySupply * .675)) { - ret = blockValue * .29; - } else if (mNodeCoins <= (nMoneySupply * .701) && mNodeCoins > (nMoneySupply * .688)) { - ret = blockValue * .28; - } else if (mNodeCoins <= (nMoneySupply * .714) && mNodeCoins > (nMoneySupply * .701)) { - ret = blockValue * .27; - } else if (mNodeCoins <= (nMoneySupply * .727) && mNodeCoins > (nMoneySupply * .714)) { - ret = blockValue * .26; - } else if (mNodeCoins <= (nMoneySupply * .74) && mNodeCoins > (nMoneySupply * .727)) { - ret = blockValue * .25; - } else if (mNodeCoins <= (nMoneySupply * .753) && mNodeCoins > (nMoneySupply * .74)) { - ret = blockValue * .24; - } else if (mNodeCoins <= (nMoneySupply * .766) && mNodeCoins > (nMoneySupply * .753)) { - ret = blockValue * .23; - } else if (mNodeCoins <= (nMoneySupply * .779) && mNodeCoins > (nMoneySupply * .766)) { - ret = blockValue * .22; - } else if (mNodeCoins <= (nMoneySupply * .792) && mNodeCoins > (nMoneySupply * .779)) { - ret = blockValue * .21; - } else if (mNodeCoins <= (nMoneySupply * .805) && mNodeCoins > (nMoneySupply * .792)) { - ret = blockValue * .20; - } else if (mNodeCoins <= (nMoneySupply * .818) && mNodeCoins > (nMoneySupply * .805)) { - ret = blockValue * .19; - } else if (mNodeCoins <= (nMoneySupply * .831) && mNodeCoins > (nMoneySupply * .818)) { - ret = blockValue * .18; - } else if (mNodeCoins <= (nMoneySupply * .844) && mNodeCoins > (nMoneySupply * .831)) { - ret = blockValue * .17; - } else if (mNodeCoins <= (nMoneySupply * .857) && mNodeCoins > (nMoneySupply * .844)) { - ret = blockValue * .16; - } else if (mNodeCoins <= (nMoneySupply * .87) && mNodeCoins > (nMoneySupply * .857)) { - ret = blockValue * .15; - } else if (mNodeCoins <= (nMoneySupply * .883) && mNodeCoins > (nMoneySupply * .87)) { - ret = blockValue * .14; - } else if (mNodeCoins <= (nMoneySupply * .896) && mNodeCoins > (nMoneySupply * .883)) { - ret = blockValue * .13; - } else if (mNodeCoins <= (nMoneySupply * .909) && mNodeCoins > (nMoneySupply * .896)) { - ret = blockValue * .12; - } else if (mNodeCoins <= (nMoneySupply * .922) && mNodeCoins > (nMoneySupply * .909)) { - ret = blockValue * .11; - } else if (mNodeCoins <= (nMoneySupply * .935) && mNodeCoins > (nMoneySupply * .922)) { - ret = blockValue * .10; - } else if (mNodeCoins <= (nMoneySupply * .945) && mNodeCoins > (nMoneySupply * .935)) { - ret = blockValue * .09; - } else if (mNodeCoins <= (nMoneySupply * .961) && mNodeCoins > (nMoneySupply * .945)) { - ret = blockValue * .08; - } else if (mNodeCoins <= (nMoneySupply * .974) && mNodeCoins > (nMoneySupply * .961)) { - ret = blockValue * .07; - } else if (mNodeCoins <= (nMoneySupply * .987) && mNodeCoins > (nMoneySupply * .974)) { - ret = blockValue * .06; - } else if (mNodeCoins <= (nMoneySupply * .99) && mNodeCoins > (nMoneySupply * .987)) { - ret = blockValue * .05; - } else { - ret = blockValue * .01; - } - } - } - + int64_t ret = blockValue / 5 * 3; return ret; } @@ -2516,8 +2243,8 @@ void CheckForkWarningConditions() if (pindexBestForkTip && pindexBestForkBase) { if (pindexBestForkBase->phashBlock) { LogPrintf("CheckForkWarningConditions: Warning: Large valid fork found\n forking the chain at height %d (%s)\n lasting to height %d (%s).\nChain state database corruption likely.\n", - pindexBestForkBase->nHeight, pindexBestForkBase->phashBlock->ToString(), - pindexBestForkTip->nHeight, pindexBestForkTip->phashBlock->ToString()); + pindexBestForkBase->nHeight, pindexBestForkBase->phashBlock->ToString(), + pindexBestForkTip->nHeight, pindexBestForkTip->phashBlock->ToString()); fLargeWorkForkFound = true; } } else { @@ -2586,12 +2313,12 @@ void static InvalidChainFound(CBlockIndex* pindexNew) pindexBestInvalid = pindexNew; LogPrintf("InvalidChainFound: invalid block=%s height=%d log2_work=%.8g date=%s\n", - pindexNew->GetBlockHash().ToString(), pindexNew->nHeight, - log(pindexNew->nChainWork.getdouble()) / log(2.0), DateTimeStrFormat("%Y-%m-%d %H:%M:%S", - pindexNew->GetBlockTime())); + pindexNew->GetBlockHash().ToString(), pindexNew->nHeight, + log(pindexNew->nChainWork.getdouble()) / log(2.0), DateTimeStrFormat("%Y-%m-%d %H:%M:%S", + pindexNew->GetBlockTime())); LogPrintf("InvalidChainFound: current best=%s height=%d log2_work=%.8g date=%s\n", - chainActive.Tip()->GetBlockHash().ToString(), chainActive.Height(), log(chainActive.Tip()->nChainWork.getdouble()) / log(2.0), - DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime())); + chainActive.Tip()->GetBlockHash().ToString(), chainActive.Height(), log(chainActive.Tip()->nChainWork.getdouble()) / log(2.0), + DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime())); CheckForkWarningConditions(); } @@ -2641,7 +2368,7 @@ bool CScriptCheck::operator()() return true; } -bool CheckInputs(const CTransaction& tx, CValidationState& state, const CCoinsViewCache& inputs, bool fScriptChecks, unsigned int flags, bool cacheStore, std::vector* pvChecks) +bool CheckInputs(const CTransaction& tx, CValidationState& state, const CCoinsViewCache& inputs, bool fScriptChecks, unsigned int flags, bool cacheSigStore, bool cacheFullScriptStore, std::vector* pvChecks) { if (!tx.IsCoinBase() && !tx.IsZerocoinSpend()) { if (pvChecks) @@ -2652,6 +2379,23 @@ bool CheckInputs(const CTransaction& tx, CValidationState& state, const CCoinsVi if (!inputs.HaveInputs(tx)) return state.Invalid(error("CheckInputs() : %s inputs unavailable", tx.GetHash().ToString())); + // First check if script executions have been cached with the same + // flags. Note that this assumes that the inputs provided are + // correct (ie that the transaction hash which is in tx's prevouts + // properly commits to the scriptPubKey in the inputs view of that + // transaction). + uint256 hashCacheEntry; + // We only use the first 19 bytes of nonce to avoid a second SHA + // round - giving us 19 + 32 + 4 = 55 bytes (+ 8 + 1 = 64) + static_assert(55 - sizeof(flags) - 32 >= 128/8, "Want at least 128 bits of nonce for script execution cache"); + CSHA256().Write(scriptExecutionCacheNonce.begin(), 55 - sizeof(flags) - 32).Write(tx.GetWitnessHash().begin(), 32).Write((unsigned char*)&flags, sizeof(flags)).Finalize(hashCacheEntry.begin()); + { + AssertLockHeld(cs_main); //TODO: Remove this requirement by making CuckooCache not require external locks + if (scriptExecutionCache.contains(hashCacheEntry, !cacheFullScriptStore)) { + return true; + } + } + // While checking, GetBestBlock() refers to the parent block. // This is also true for mempool checks. CBlockIndex* pindexPrev = mapBlockIndex.find(inputs.GetBestBlock())->second; @@ -2667,32 +2411,32 @@ bool CheckInputs(const CTransaction& tx, CValidationState& state, const CCoinsVi if (coins->IsCoinBase() || coins->IsCoinStake()) { if (nSpendHeight - coins->nHeight < Params().COINBASE_MATURITY()) return state.Invalid( - error("CheckInputs() : tried to spend coinbase at depth %d, coinstake=%d", nSpendHeight - coins->nHeight, coins->IsCoinStake()), - REJECT_INVALID, "bad-txns-premature-spend-of-coinbase"); + error("CheckInputs() : tried to spend coinbase at depth %d, coinstake=%d", nSpendHeight - coins->nHeight, coins->IsCoinStake()), + 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"), - REJECT_INVALID, "bad-txns-inputvalues-outofrange"); + REJECT_INVALID, "bad-txns-inputvalues-outofrange"); } if (!tx.IsCoinStake()) { if (nValueIn < tx.GetValueOut()) 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"); + 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()), - REJECT_INVALID, "bad-txns-fee-negative"); + REJECT_INVALID, "bad-txns-fee-negative"); nFees += nTxFee; if (!MoneyRange(nFees)) return state.DoS(100, error("CheckInputs() : nFees out of range"), - REJECT_INVALID, "bad-txns-fee-outofrange"); + REJECT_INVALID, "bad-txns-fee-outofrange"); } // The first loop above does all the inexpensive checks. // Only if ALL inputs pass do we perform expensive ECDSA signature checks. @@ -2708,7 +2452,7 @@ bool CheckInputs(const CTransaction& tx, CValidationState& state, const CCoinsVi assert(coins); // Verify signature - CScriptCheck check(*coins, tx, i, flags, cacheStore); + CScriptCheck check(*coins, tx, i, flags, cacheSigStore); if (pvChecks) { pvChecks->push_back(CScriptCheck()); check.swap(pvChecks->back()); @@ -2721,7 +2465,7 @@ bool CheckInputs(const CTransaction& tx, CValidationState& state, const CCoinsVi // avoid splitting the network between upgraded and // non-upgraded nodes. CScriptCheck check2(*coins, tx, i, - flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS, cacheStore); + flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS, cacheSigStore); if (check2()) return state.Invalid(false, REJECT_NONSTANDARD, strprintf("non-mandatory-script-verify-flag (%s)", ScriptErrorString(check.GetScriptError()))); } @@ -2736,6 +2480,13 @@ bool CheckInputs(const CTransaction& tx, CValidationState& state, const CCoinsVi } } } + + if (cacheFullScriptStore && !pvChecks) { + AssertLockHeld(cs_main); + // We executed all of the provided scripts, and were told to + // cache the result. Do so now. + scriptExecutionCache.insert(hashCacheEntry); + } } return true; @@ -2783,7 +2534,7 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex } if (tx.IsZerocoinMint()) { //erase all zerocoinmints in this transaction - for (const CTxOut txout : tx.vout) { + for (const CTxOut& txout : tx.vout) { if (txout.scriptPubKey.empty() || !txout.scriptPubKey.IsZerocoinMint()) continue; @@ -2826,7 +2577,7 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex if (!tx.IsCoinBase() && !tx.IsZerocoinSpend()) { // not coinbases or zerocoinspend because they dont have traditional inputs const CTxUndo& txundo = blockUndo.vtxundo[i - 1]; if (txundo.vprevout.size() != tx.vin.size()) - return error("DisconnectBlock(), transaction and undo data inconsistent - txundo.vprevout.siz=%d tx.vin.siz=%d", txundo.vprevout.size(), tx.vin.size()); + return error("DisconnectBlock() : transaction and undo data inconsistent - txundo.vprevout.siz=%d tx.vin.siz=%d", txundo.vprevout.size(), tx.vin.size()); for (unsigned int j = tx.vin.size(); j-- > 0;) { const COutPoint& out = tx.vin[j].prevout; const CTxInUndo& undo = txundo.vprevout[j]; @@ -2898,6 +2649,23 @@ void static FlushBlockFile(bool fFinalize = false) } } +bool AbortNode(const std::string& strMessage, const std::string& userMessage) +{ + strMiscWarning = strMessage; + LogPrintf("*** %s\n", strMessage); + uiInterface.ThreadSafeMessageBox( + userMessage.empty() ? _("Error: A fatal internal error occured, see debug.log for details") : userMessage, + "", CClientUIInterface::MSG_ERROR); + StartShutdown(); + return false; +} + +bool AbortNode(CValidationState& state, const std::string& strMessage, const std::string& userMessage = "") +{ + AbortNode(strMessage, userMessage); + return state.Error(strMessage); +} + bool FindUndoPos(CValidationState& state, int nFile, CDiskBlockPos& pos, unsigned int nAddSize); static CCheckQueue scriptcheckqueue(128); @@ -2990,7 +2758,7 @@ bool RecalculateOHMCSupply(int nHeightStart) CAmount nValueIn = 0; CAmount nValueOut = 0; - for (const CTransaction tx : block.vtx) { + for (const CTransaction& tx : block.vtx) { for (unsigned int i = 0; i < tx.vin.size(); i++) { if (tx.IsCoinBase()) break; @@ -3078,14 +2846,14 @@ bool ReindexAccumulators(list& listMissingCheckpoints, string& strError return true; } -bool UpdateZOHMCSupply(const CBlock& block, CBlockIndex* pindex) +bool UpdateZPHRSupply(const CBlock& block, CBlockIndex* pindex) { std::list listMints; BlockToZerocoinMintList(block, listMints); std::list listSpends = ZerocoinSpendListFromBlock(block); // Initialize zerocoin supply to the supply from previous block - if (pindex->pprev && pindex->pprev->GetBlockHeader().nVersion > 5) { + if (pindex->pprev && pindex->pprev->GetBlockHeader().nVersion > 3) { for (auto& denom : zerocoinDenomList) { pindex->mapZerocoinSupply.at(denom) = pindex->pprev->mapZerocoinSupply.at(denom); } @@ -3194,11 +2962,11 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin if (pindex->nHeight <= Params().LAST_POW_BLOCK() && block.IsProofOfStake()) return state.DoS(100, error("ConnectBlock() : PoS period not active"), - REJECT_INVALID, "PoS-early"); + REJECT_INVALID, "PoS-early"); if (pindex->nHeight > Params().LAST_POW_BLOCK() && block.IsProofOfWork()) return state.DoS(100, error("ConnectBlock() : PoW period ended"), - REJECT_INVALID, "PoW-ended"); + REJECT_INVALID, "PoW-ended"); bool fScriptChecks = pindex->nHeight >= Checkpoints::GetTotalBlocksEstimate(); @@ -3216,35 +2984,16 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin // 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 == 91880 && pindex->GetBlockHash() == uint256("0x00000000000743f190a18c5577a3c2d2a1f610ae9601ac046a38084ccb7cd721"))); if (fEnforceBIP30) { for (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"), - REJECT_INVALID, "bad-txns-BIP30"); + REJECT_INVALID, "bad-txns-BIP30"); } } - // BIP16 didn't become active until Apr 1 2012 - int64_t nBIP16SwitchTime = 1333238400; - bool fStrictPayToScriptHash = (pindex->GetBlockTime() >= nBIP16SwitchTime); - - // unsigned int flags = fStrictPayToScriptHash ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE; - // Get the script flags for this block - 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 && CBlockIndex::IsSuperMajority(3, pindex->pprev, Params().EnforceBlockUpgradeMajority())) { - flags |= SCRIPT_VERIFY_DERSIG; - } - - // Start enforcing CHECKLOCKTIMEVERIFY, (BIP65) for block.nVersion=4 - // blocks, when 75% of the network has upgraded: - if (block.nVersion >= 4 && CBlockIndex::IsSuperMajority(4, pindex->pprev, Params().EnforceBlockUpgradeMajority())) { - flags |= SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY; - } - CCheckQueueControl control(fScriptChecks && nScriptCheckThreads ? &scriptcheckqueue : NULL); int64_t nTimeStart = GetTimeMicros(); @@ -3268,6 +3017,8 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin vector vSpendsInBlock; uint256 hashBlock = block.GetHash(); + unsigned int flags = SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_DERSIG; + if (GetSporkValue(SPORK_20_SEGWIT_ACTIVATION) < block.nTime) { flags |= SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY | SCRIPT_VERIFY_CHECKSEQUENCEVERIFY; } @@ -3306,7 +3057,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin if (!ContextualCheckZerocoinSpend(tx, spend, pindex, hashBlock)) return state.DoS(100, error("%s: failed to add block %s with invalid zerocoinspend", __func__, tx.GetHash().GetHex()), REJECT_INVALID); - } + } // Check that zOHMC mints are not already known if (tx.IsZerocoinMint()) { @@ -3327,7 +3078,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin } else if (!tx.IsCoinBase()) { if (!view.HaveInputs(tx)) return state.DoS(100, error("ConnectBlock() : inputs missing/spent"), - REJECT_INVALID, "bad-txns-inputs-missingorspent"); + REJECT_INVALID, "bad-txns-inputs-missingorspent"); // Check that zOHMC mints are not already known if (tx.IsZerocoinMint()) { @@ -3359,9 +3110,10 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin nSigOpsCost += GetTransactionSigOpCost(tx, view, flags); if (nSigOpsCost > MAX_BLOCK_SIGOPS_COST) return state.DoS(100, error("ConnectBlock(): too many sigops"), - REJECT_INVALID, "bad-blk-sigops"); + REJECT_INVALID, "bad-blk-sigops"); - if (!CheckInputs(tx, state, view, fScriptChecks, flags, false, nScriptCheckThreads ? &vChecks : NULL)) + bool fCacheResults = fJustCheck; /* Don't cache results if we're actually connecting blocks (still consult the cache, though) */ + if (!CheckInputs(tx, state, view, fScriptChecks, flags, fCacheResults, fCacheResults, nScriptCheckThreads ? &vChecks : NULL)) return false; control.Add(vChecks); } @@ -3384,21 +3136,21 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin } } for(const CTxOut &txout : tx.vout) - BuildAddrIndex(txout.scriptPubKey, pos, vPosAddrid); + BuildAddrIndex(txout.scriptPubKey, pos, vPosAddrid); } UpdateCoins(tx, state, view, i == 0 ? undoDummy : blockundo.vtxundo.back(), pindex->nHeight); pos.nTxOffset += ::GetSerializeSize(tx, SER_DISK, CLIENT_VERSION); } - UpdateZOHMCSupply(block, pindex); + UpdateZPHRSupply(block, pindex); // track money supply and mint amount info CAmount nMoneySupplyPrev = pindex->pprev ? pindex->pprev->nMoneySupply : 0; pindex->nMoneySupply = nMoneySupplyPrev + nValueOut - nValueIn; pindex->nMint = pindex->nMoneySupply - nMoneySupplyPrev + nFees; -// LogPrintf("XX69----------> ConnectBlock(): nValueOut: %s, nValueIn: %s, nFees: %s, nMint: %s zOHMCSpent: %s\n", +// LogPrintf("XX69----------> ConnectBlock(): nValueOut: %s, nValueIn: %s, nFees: %s, nMint: %s zPHRSpent: %s\n", // FormatMoney(nValueOut), FormatMoney(nValueIn), // FormatMoney(nFees), FormatMoney(pindex->nMint), FormatMoney(nAmountZerocoinSpent)); @@ -3414,7 +3166,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin //Check that the block does not overmint if (!IsBlockValueValid(block, nExpectedMint, pindex->nMint) && (pindex->pprev->nHeight != 84702)) { // bug patched at block 90000, too far to roll back return state.DoS(100, error("ConnectBlock() : reward pays too much (actual=%s vs limit=%s)", - FormatMoney(pindex->nMint), FormatMoney(nExpectedMint)), REJECT_INVALID, "bad-cb-amount"); + FormatMoney(pindex->nMint), FormatMoney(nExpectedMint)), REJECT_INVALID, "bad-cb-amount"); } // Ensure that accumulator checkpoints are valid and in the same state as this instance of the chain @@ -3500,7 +3252,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin return state.Error("Failed to write address index"); // add new entries - for (const CTransaction tx: block.vtx) { + for (const CTransaction& tx: block.vtx) { if (tx.IsCoinBase() || tx.IsZerocoinSpend()) continue; for (const CTxIn in: tx.vin) { @@ -3509,7 +3261,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin } } - + // delete old entries for (auto it = mapStakeSpent.begin(); it != mapStakeSpent.end();) { if (it->second < pindex->nHeight - Params().MaxReorganizationDepth()) { @@ -3520,7 +3272,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin it++; } } - + // add this block to the view's block chain view.SetBestBlock(pindex->GetBlockHash()); @@ -3570,24 +3322,23 @@ bool static FlushStateToDisk(CValidationState& state, FlushStateMode mode) // First make sure all block and undo data is flushed to disk. FlushBlockFile(); // Then update all block file information (which may refer to block and undo files). - bool fileschanged = false; - for (set::iterator it = setDirtyFileInfo.begin(); it != setDirtyFileInfo.end();) { - if (!pblocktree->WriteBlockFileInfo(*it, vinfoBlockFile[*it])) { - return state.Error("Failed to write to block index"); + { + std::vector > vFiles; + vFiles.reserve(setDirtyFileInfo.size()); + for (std::set::iterator it = setDirtyFileInfo.begin(); it != setDirtyFileInfo.end(); ) { + vFiles.push_back(std::make_pair(*it, &vinfoBlockFile[*it])); + setDirtyFileInfo.erase(it++); } - fileschanged = true; - setDirtyFileInfo.erase(it++); - } - if (fileschanged && !pblocktree->WriteLastBlockFile(nLastBlockFile)) { - return state.Error("Failed to write to block index"); - } - for (set::iterator it = setDirtyBlockIndex.begin(); it != setDirtyBlockIndex.end();) { - if (!pblocktree->WriteBlockIndex(CDiskBlockIndex(*it))) { - return state.Error("Failed to write to block index"); + std::vector vBlocks; + vBlocks.reserve(setDirtyBlockIndex.size()); + for (std::set::iterator it = setDirtyBlockIndex.begin(); it != setDirtyBlockIndex.end(); ) { + vBlocks.push_back(*it); + setDirtyBlockIndex.erase(it++); + } + if (!pblocktree->WriteBatchSync(vFiles, nLastBlockFile, vBlocks)) { + return AbortNode(state, "Files to write to block index database"); } - setDirtyBlockIndex.erase(it++); } - pblocktree->Sync(); // Finally flush the chainstate (which may refer to block index entries). if (!pcoinsTip->Flush()) return state.Error("Failed to write to coin database"); @@ -3623,9 +3374,9 @@ void static UpdateTip(CBlockIndex* pindexNew) mempool.AddTransactionsUpdated(1); LogPrintf("UpdateTip: new best=%s height=%d log2_work=%.8g tx=%lu date=%s progress=%f cache=%u\n", - chainActive.Tip()->GetBlockHash().ToString(), chainActive.Height(), log(chainActive.Tip()->nChainWork.getdouble()) / log(2.0), (unsigned long)chainActive.Tip()->nChainTx, - DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime()), - Checkpoints::GuessVerificationProgress(chainActive.Tip()), (unsigned int)pcoinsTip->GetCacheSize()); + chainActive.Tip()->GetBlockHash().ToString(), chainActive.Height(), log(chainActive.Tip()->nChainWork.getdouble()) / log(2.0), (unsigned long)chainActive.Tip()->nChainTx, + DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime()), + Checkpoints::GuessVerificationProgress(chainActive.Tip()), (unsigned int)pcoinsTip->GetCacheSize()); cvBlockChange.notify_all(); @@ -3974,7 +3725,7 @@ static bool ActivateBestChainStep(CValidationState& state, CBlockIndex* pindexMo nHeight = nTargetHeight; // Connect new blocks. - for (CBlockIndex* pindexConnect : reverse_iterate (vpindexToConnect)) { + BOOST_REVERSE_FOREACH (CBlockIndex* pindexConnect, vpindexToConnect) { if (!ConnectTip(state, pindexConnect, pindexConnect == pindexMostWork ? pblock : NULL, fAlreadyChecked)) { if (state.IsInvalid()) { // The block violates a consensus rule. @@ -4051,8 +3802,8 @@ bool ActivateBestChain(CValidationState& state, CBlock* pblock, bool fAlreadyChe { LOCK(cs_vNodes); for (CNode* pnode : vNodes) - if (chainActive.Height() > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate)) - pnode->PushInventory(CInv(MSG_BLOCK, hashNewTip)); + if (chainActive.Height() > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate)) + pnode->PushInventory(CInv(MSG_BLOCK, hashNewTip)); } // Notify external listeners about the new tip. // Note: uiInterface, should switch main signals. @@ -4064,7 +3815,7 @@ bool ActivateBestChain(CValidationState& state, CBlock* pblock, bool fAlreadyChe if (pblock) size = GetSerializeSize(*pblock, SER_NETWORK, PROTOCOL_VERSION); // If the size is over 1 MB notify external listeners, and it is within the last 5 minutes - if (size > MAX_BLOCK_SIZE && pblock->GetBlockTime() > GetAdjustedTime() - 300) { + if (size > MAX_BLOCK_SIZE_LEGACY && pblock->GetBlockTime() > GetAdjustedTime() - 300) { uiInterface.NotifyBlockSize(static_cast(size), hashNewTip); } } @@ -4347,7 +4098,7 @@ 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"), - REJECT_INVALID, "high-hash"); + REJECT_INVALID, "high-hash"); return true; } @@ -4361,13 +4112,13 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo // redundant with the call in AcceptBlockHeader. if (!CheckBlockHeader(block, state, block.IsProofOfWork())) return state.DoS(100, error("CheckBlock() : CheckBlockHeader failed"), - REJECT_INVALID, "bad-header", true); + REJECT_INVALID, "bad-header", true); // Check timestamp LogPrint("debug", "%s: block=%s is proof of stake=%d\n", __func__, block.GetHash().ToString().c_str(), block.IsProofOfStake()); if (block.GetBlockTime() > GetAdjustedTime() + (block.IsProofOfStake() ? 180 : 7200)) // 3 minute future drift for PoS return state.Invalid(error("CheckBlock() : block timestamp too far in the future"), - REJECT_INVALID, "time-too-new"); + REJECT_INVALID, "time-too-new"); // Check the merkle root. if (fCheckMerkleRoot) { @@ -4375,14 +4126,14 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo uint256 hashMerkleRoot2 = block.BuildMerkleTree(&mutated); if (block.hashMerkleRoot != hashMerkleRoot2) return state.DoS(100, error("CheckBlock() : hashMerkleRoot mismatch"), - REJECT_INVALID, "bad-txnmrklroot", true); + 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"), - REJECT_INVALID, "bad-txns-duplicate", true); + REJECT_INVALID, "bad-txns-duplicate", true); } // All potential-corruption validation must be done before we do any @@ -4394,16 +4145,16 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo // Size limits if (block.vtx.empty() || block.vtx.size() > MAX_BLOCK_BASE_SIZE || ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) > MAX_BLOCK_BASE_SIZE) return state.DoS(100, error("CheckBlock() : size limits failed"), - REJECT_INVALID, "bad-blk-length"); + 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"), - REJECT_INVALID, "bad-cb-missing"); + 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"), - REJECT_INVALID, "bad-cb-multiple"); + REJECT_INVALID, "bad-cb-multiple"); if (block.IsProofOfStake()) { int commitpos = GetWitnessCommitmentIndex(block); @@ -4445,7 +4196,7 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo mapRejectedBlocks.insert(make_pair(block.GetHash(), GetTime())); LogPrintf("CheckBlock() : found conflicting transaction with transaction lock %s %s\n", mapLockedInputs[in.prevout].ToString(), tx.GetHash().ToString()); return state.DoS(0, error("CheckBlock() : found conflicting transaction with transaction lock"), - REJECT_INVALID, "conflicting-tx-ix"); + REJECT_INVALID, "conflicting-tx-ix"); } } } @@ -4477,7 +4228,7 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo if (!IsBlockPayeeValid(block, nHeight)) { mapRejectedBlocks.insert(make_pair(block.GetHash(), GetTime())); return state.DoS(0, error("CheckBlock() : Couldn't find karmanode/budget payment"), - REJECT_INVALID, "bad-cb-payee"); + REJECT_INVALID, "bad-cb-payee"); } } else { if (fDebug) @@ -4492,7 +4243,7 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo } if (nSigOps * WITNESS_SCALE_FACTOR > MAX_BLOCK_SIGOPS_COST) return state.DoS(100, error("CheckBlock() : out-of-bounds SigOpCount"), - REJECT_INVALID, "bad-blk-sigops", true); + REJECT_INVALID, "bad-blk-sigops", true); return true; } @@ -4528,7 +4279,6 @@ bool CheckWork(const CBlock block, CBlockIndex* const pindexPrev) bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex* const pindexPrev) { - const Consensus::Params& consensus = Params().GetConsensus(); uint256 hash = block.GetHash(); if (hash == Params().HashGenesisBlock()) @@ -4547,13 +4297,13 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta if (block.GetBlockTime() <= pindexPrev->GetMedianTimePast()) { LogPrintf("Block time = %d , GetMedianTimePast = %d \n", block.GetBlockTime(), pindexPrev->GetMedianTimePast()); return state.Invalid(error("%s : block's timestamp is too early", __func__), - REJECT_INVALID, "time-too-old"); + 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), - REJECT_CHECKPOINT, "checkpoint mismatch"); + REJECT_CHECKPOINT, "checkpoint mismatch"); // Don't accept any forks from the main chain prior to last checkpoint CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint(); @@ -4561,30 +4311,16 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta return state.DoS(0, 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 && CBlockIndex::IsSuperMajority(2, pindexPrev, Params().RejectBlockOutdatedMajority())) { + if (block.nVersion < 2 && + CBlockIndex::IsSuperMajority(2, pindexPrev, Params().RejectBlockOutdatedMajority())) { return state.Invalid(error("%s : rejected nVersion=1 block", __func__), - REJECT_OBSOLETE, "bad-version"); + REJECT_OBSOLETE, "bad-version"); } // Reject block.nVersion=2 blocks when 95% (75% on testnet) of the network has upgraded: if (block.nVersion < 3 && CBlockIndex::IsSuperMajority(3, pindexPrev, Params().RejectBlockOutdatedMajority())) { return state.Invalid(error("%s : rejected nVersion=2 block", __func__), - REJECT_OBSOLETE, "bad-version"); - } - - // Reject block.nVersion=3 blocks when 95% (75% on testnet) of the network has upgraded: - if (block.nVersion < 4 && CBlockIndex::IsSuperMajority(4, pindexPrev, Params().RejectBlockOutdatedMajority())) { - return state.Invalid(error("%s : rejected nVersion=3 block", __func__), - REJECT_OBSOLETE, "bad-version"); - } - - // Reject outdated version blocks - if ((block.nVersion < 6 && nHeight >= 1) && - (consensus.NetworkUpgradeActive(nHeight, Consensus::UPGRADE_V3_0_BLOCKTIME) || - consensus.NetworkUpgradeActive(nHeight, Consensus::UPGRADE_V3_0_BLOCKREWARD))) - { - std::string stringErr = strprintf("rejected block version %d at height %d", block.nVersion, nHeight); - return state.Invalid(false, REJECT_OBSOLETE, "bad-version", stringErr); + REJECT_OBSOLETE, "bad-version"); } return true; @@ -4679,11 +4415,11 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIn { const int nHeight = pindexPrev == NULL ? 0 : pindexPrev->nHeight + 1; - // Version 6 header must be used after Params().Zerocoin_StartHeight(). And never before. + // Version 4 header must be used after Params().Zerocoin_StartHeight(). And never before. if (nHeight > Params().Zerocoin_StartHeight()) { if(block.nVersion < Params().Zerocoin_HeaderVersion()) return state.DoS(50, error("CheckBlockHeader() : block version must be above 4 after ZerocoinStartHeight"), - REJECT_INVALID, "block-version"); + REJECT_INVALID, "block-version"); vector vBlockSerials; for (const CTransaction& tx : block.vtx) { @@ -4706,14 +4442,14 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIn } else { if (block.nVersion >= Params().Zerocoin_HeaderVersion()) return state.DoS(50, error("CheckBlockHeader() : block version must be below 4 before ZerocoinStartHeight"), - REJECT_INVALID, "block-version"); + REJECT_INVALID, "block-version"); } // Check that all transactions are finalized for (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"); - } + if (!IsFinalTx(tx, nHeight, block.GetBlockTime())) { + 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 // if 750 of the last 1,000 blocks are version 2 or greater (51/100 if testnet): @@ -4735,7 +4471,7 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIn // {0xaa, 0x21, 0xa9, 0xed}, and the following 32 bytes are SHA256(witness root, witness nonce). In case there are // multiple, the last one is used. bool fHaveWitness = false; - if (GetSporkValue(SPORK_20_SEGWIT_ACTIVATION) < pindexPrev->nTime) { + if (pindexPrev != nullptr && GetSporkValue(SPORK_20_SEGWIT_ACTIVATION) < pindexPrev->nTime) { int commitpos = GetWitnessCommitmentIndex(block); if (commitpos != -1) { if (!IsSporkActive(SPORK_21_SEGWIT_ON_COINBASE)) { @@ -5109,7 +4845,7 @@ bool ProcessNewBlock(CValidationState& state, CNode* pfrom, CBlock* pblock, CDis } LogPrintf("%s : ACCEPTED in %ld milliseconds with size=%d\n", __func__, GetTimeMillis() - nStartTime, - pblock->GetSerializeSize(SER_DISK, CLIENT_VERSION)); + pblock->GetSerializeSize(SER_DISK, CLIENT_VERSION)); return true; } @@ -5117,7 +4853,7 @@ bool ProcessNewBlock(CValidationState& state, CNode* pfrom, CBlock* pblock, CDis bool TestBlockValidity(CValidationState& state, const CBlock& block, CBlockIndex* const pindexPrev, bool fCheckPOW, bool fCheckMerkleRoot) { AssertLockHeld(cs_main); - assert(pindexPrev && chainActive.Tip()); + assert(pindexPrev && pindexPrev == chainActive.Tip()); CCoinsViewCache viewNew(pcoinsTip); CBlockIndex indexDummy(block); @@ -5139,17 +4875,6 @@ bool TestBlockValidity(CValidationState& state, const CBlock& block, CBlockIndex } -bool AbortNode(const std::string& strMessage, const std::string& userMessage) -{ - strMiscWarning = strMessage; - LogPrintf("*** %s\n", strMessage); - uiInterface.ThreadSafeMessageBox( - userMessage.empty() ? _("Error: A fatal internal error occured, see debug.log for details") : userMessage, - "", CClientUIInterface::MSG_ERROR); - StartShutdown(); - return false; -} - bool CheckDiskSpace(uint64_t nAdditionalBytes) { uint64_t nFreeBytesAvailable = filesystem::space(GetDataDir()).available; @@ -5234,15 +4959,12 @@ bool static LoadBlockIndexDB(string& strError) // Calculate nChainWork vector > vSortedByHeight; vSortedByHeight.reserve(mapBlockIndex.size()); - for (const std::pair & item : mapBlockIndex) { + for (const std::pair& item : mapBlockIndex) { CBlockIndex* pindex = item.second; vSortedByHeight.push_back(make_pair(pindex->nHeight, pindex)); } sort(vSortedByHeight.begin(), vSortedByHeight.end()); - for (const std::pair & item : vSortedByHeight) { - // Stop if shutdown was requested - if (ShutdownRequested()) return false; - + for (const PAIRTYPE(int, CBlockIndex*) & item : vSortedByHeight) { CBlockIndex* pindex = item.second; pindex->nChainWork = (pindex->pprev ? pindex->pprev->nChainWork : 0) + GetBlockProof(*pindex); if (pindex->nStatus & BLOCK_HAVE_DATA) { @@ -5287,7 +5009,7 @@ bool static LoadBlockIndexDB(string& strError) // Check presence of blk files LogPrintf("Checking all blk files are present...\n"); set setBlkDataFiles; - for (const std::pair & item : mapBlockIndex) { + for (const std::pair& item : mapBlockIndex) { CBlockIndex* pindex = item.second; if (pindex->nStatus & BLOCK_HAVE_DATA) { setBlkDataFiles.insert(pindex->nFile); @@ -5329,9 +5051,9 @@ bool static LoadBlockIndexDB(string& strError) PruneBlockIndexCandidates(); LogPrintf("LoadBlockIndexDB(): hashBestChain=%s height=%d date=%s progress=%f\n", - chainActive.Tip()->GetBlockHash().ToString(), chainActive.Height(), - DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime()), - Checkpoints::GuessVerificationProgress(chainActive.Tip())); + chainActive.Tip()->GetBlockHash().ToString(), chainActive.Height(), + DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime()), + Checkpoints::GuessVerificationProgress(chainActive.Tip())); return true; } @@ -5561,7 +5283,7 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos* dbp) int nLoaded = 0; try { // This takes over fileIn and calls fclose() on it in the CBufferedFile destructor - CBufferedFile blkdat(fileIn, 2*MAX_BLOCK_SIZE, MAX_BLOCK_SIZE+8, SER_DISK, CLIENT_VERSION); + CBufferedFile blkdat(fileIn, 2*MAX_BLOCK_SIZE_CURRENT, MAX_BLOCK_SIZE_CURRENT+8, SER_DISK, CLIENT_VERSION); uint64_t nRewind = blkdat.GetPos(); while (!blkdat.eof()) { boost::this_thread::interruption_point(); @@ -5580,7 +5302,7 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos* dbp) continue; // read size blkdat >> nSize; - if (nSize < 80 || nSize > MAX_BLOCK_SIZE) + if (nSize < 80 || nSize > MAX_BLOCK_SIZE_CURRENT) continue; } catch (const std::exception&) { // no valid block header found; don't complain @@ -5601,7 +5323,7 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos* dbp) uint256 hash = block.GetHash(); if (hash != Params().HashGenesisBlock() && mapBlockIndex.find(block.hashPrevBlock) == mapBlockIndex.end()) { LogPrint("reindex", "%s: Out of order block %s, parent %s not known\n", __func__, hash.ToString(), - block.hashPrevBlock.ToString()); + block.hashPrevBlock.ToString()); if (dbp) mapBlocksUnknownParent.insert(std::make_pair(block.hashPrevBlock, *dbp)); continue; @@ -5629,7 +5351,7 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos* dbp) std::multimap::iterator it = range.first; if (ReadBlockFromDisk(block, it->second)) { LogPrintf("%s: Processing out of order child %s of %s\n", __func__, block.GetHash().ToString(), - head.ToString()); + head.ToString()); CValidationState dummy; if (ProcessNewBlock(dummy, NULL, &block, &it->second)) { nLoaded++; @@ -5829,7 +5551,7 @@ string GetWarnings(string strFor) // Alerts { LOCK(cs_mapAlerts); - for (std::pair & item : mapAlerts) { + for (PAIRTYPE(const uint256, CAlert) & item : mapAlerts) { const CAlert& alert = item.second; if (alert.AppliesToMe() && alert.nPriority > nPriority) { nPriority = alert.nPriority; @@ -5856,61 +5578,61 @@ string GetWarnings(string strFor) bool static AlreadyHave(const CInv& inv) { switch (inv.type) { - case MSG_WITNESS_TX: - case MSG_TX: { - bool txInMap = false; - txInMap = mempool.exists(inv.hash); - return txInMap || mapOrphanTransactions.count(inv.hash) || - pcoinsTip->HaveCoins(inv.hash); - } - case MSG_BLOCK: - case MSG_WITNESS_BLOCK: - return mapBlockIndex.count(inv.hash); - case MSG_TXLOCK_REQUEST: - return mapTxLockReq.count(inv.hash) || - mapTxLockReqRejected.count(inv.hash); - case MSG_TXLOCK_VOTE: - return mapTxLockVote.count(inv.hash); - case MSG_SPORK: - return mapSporks.count(inv.hash); - case MSG_KARMANODE_WINNER: - if (karmanodePayments.mapKarmanodePayeeVotes.count(inv.hash)) { - karmanodeSync.AddedKarmanodeWinner(inv.hash); - return true; - } - return false; - case MSG_BUDGET_VOTE: - if (budget.mapSeenKarmanodeBudgetVotes.count(inv.hash)) { - karmanodeSync.AddedBudgetItem(inv.hash); - return true; - } - return false; - case MSG_BUDGET_PROPOSAL: - if (budget.mapSeenKarmanodeBudgetProposals.count(inv.hash)) { - karmanodeSync.AddedBudgetItem(inv.hash); - return true; - } - return false; - case MSG_BUDGET_FINALIZED_VOTE: - if (budget.mapSeenFinalizedBudgetVotes.count(inv.hash)) { - karmanodeSync.AddedBudgetItem(inv.hash); - return true; - } - return false; - case MSG_BUDGET_FINALIZED: - if (budget.mapSeenFinalizedBudgets.count(inv.hash)) { - karmanodeSync.AddedBudgetItem(inv.hash); - return true; - } - return false; - case MSG_KARMANODE_ANNOUNCE: - if (mnodeman.mapSeenKarmanodeBroadcast.count(inv.hash)) { - karmanodeSync.AddedKarmanodeList(inv.hash); - return true; - } - return false; - case MSG_KARMANODE_PING: - return mnodeman.mapSeenKarmanodePing.count(inv.hash); + case MSG_WITNESS_TX: + case MSG_TX: { + bool txInMap = false; + txInMap = mempool.exists(inv.hash); + return txInMap || mapOrphanTransactions.count(inv.hash) || + pcoinsTip->HaveCoins(inv.hash); + } + case MSG_BLOCK: + case MSG_WITNESS_BLOCK: + return mapBlockIndex.count(inv.hash); + case MSG_TXLOCK_REQUEST: + return mapTxLockReq.count(inv.hash) || + mapTxLockReqRejected.count(inv.hash); + case MSG_TXLOCK_VOTE: + return mapTxLockVote.count(inv.hash); + case MSG_SPORK: + return mapSporks.count(inv.hash); + case MSG_KARMANODE_WINNER: + if (karmanodePayments.mapKarmanodePayeeVotes.count(inv.hash)) { + karmanodeSync.AddedKarmanodeWinner(inv.hash); + return true; + } + return false; + case MSG_BUDGET_VOTE: + if (budget.mapSeenKarmanodeBudgetVotes.count(inv.hash)) { + karmanodeSync.AddedBudgetItem(inv.hash); + return true; + } + return false; + case MSG_BUDGET_PROPOSAL: + if (budget.mapSeenKarmanodeBudgetProposals.count(inv.hash)) { + karmanodeSync.AddedBudgetItem(inv.hash); + return true; + } + return false; + case MSG_BUDGET_FINALIZED_VOTE: + if (budget.mapSeenFinalizedBudgetVotes.count(inv.hash)) { + karmanodeSync.AddedBudgetItem(inv.hash); + return true; + } + return false; + case MSG_BUDGET_FINALIZED: + if (budget.mapSeenFinalizedBudgets.count(inv.hash)) { + karmanodeSync.AddedBudgetItem(inv.hash); + return true; + } + return false; + case MSG_KARMANODE_ANNOUNCE: + if (mnodeman.mapSeenKarmanodeBroadcast.count(inv.hash)) { + karmanodeSync.AddedKarmanodeList(inv.hash); + return true; + } + return false; + case MSG_KARMANODE_PING: + return mnodeman.mapSeenKarmanodePing.count(inv.hash); } // Don't know what it is, just say we already got one return true; @@ -5977,8 +5699,8 @@ void static ProcessGetData(CNode* pfrom) // however we MUST always provide at least what the remote peer needs typedef std::pair PairType; for (PairType& pair : merkleBlock.vMatchedTxn) - if (!pfrom->setInventoryKnown.count(CInv(MSG_TX, pair.second))) - pfrom->PushMessageWithFlag(SERIALIZE_TRANSACTION_NO_WITNESS, NetMsgType::TX, block.vtx[pair.first]); + if (!pfrom->setInventoryKnown.count(CInv(MSG_TX, pair.second))) + pfrom->PushMessageWithFlag(SERIALIZE_TRANSACTION_NO_WITNESS, NetMsgType::TX, block.vtx[pair.first]); } // else // no response @@ -6194,6 +5916,14 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, vRecv >> LIMITED_STRING(pfrom->strSubVer, 256); pfrom->cleanSubVer = SanitizeString(pfrom->strSubVer); } + // broken releases with wrong blockchain data + if (pfrom->cleanSubVer == "/Ohmcoin Core:1.1.0/" || + pfrom->cleanSubVer == "/Ohmcoin Core:1.3.0/" || + pfrom->cleanSubVer == "/Ohmcoin Core:1.3.1/") { + LOCK(cs_main); + Misbehaving(pfrom->GetId(), 100); // instantly ban them because they have bad block data + return false; + } if (!vRecv.empty()) vRecv >> pfrom->nStartingHeight; if (!vRecv.empty()) @@ -6232,7 +5962,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, pfrom->PushMessage(NetMsgType::VERACK); pfrom->ssSend.SetVersion(min(pfrom->nVersion, PROTOCOL_VERSION)); - // Ohmcoin: We use certain sporks during IBD, so check to see if they are + // Phore: We use certain sporks during IBD, so check to see if they are // available. If not, ask the first peer connected for them. bool fMissingSporks = !pSporkDB->SporkExists(SPORK_22_ZEROCOIN_MAINTENANCE_MODE); @@ -6272,8 +6002,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // Relay alerts { LOCK(cs_mapAlerts); - for (std::pair & item : mapAlerts) - item.second.RelayTo(pfrom); + for (PAIRTYPE(const uint256, CAlert) & item : mapAlerts) + item.second.RelayTo(pfrom); } pfrom->fSuccessfullyConnected = true; @@ -6283,9 +6013,9 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, remoteAddr = ", peeraddr=" + pfrom->addr.ToString(); LogPrintf("receive version message: %s: version %d, blocks=%d, us=%s, peer=%d%s\n", - pfrom->cleanSubVer, pfrom->nVersion, - pfrom->nStartingHeight, addrMe.ToString(), pfrom->id, - remoteAddr); + pfrom->cleanSubVer, pfrom->nVersion, + pfrom->nStartingHeight, addrMe.ToString(), pfrom->id, + remoteAddr); int64_t nTimeOffset = nTime - GetTime(); pfrom->nTimeOffset = nTimeOffset; @@ -6420,7 +6150,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // doing this will result in the received block being rejected as an orphan in case it is // not a direct successor. if (State(pfrom->GetId())->fHaveWitness && - (GetSporkValue(SPORK_20_SEGWIT_ACTIVATION) > chainActive.Tip()->nTime || State(pfrom->GetId())->fHaveWitness)) { + (GetSporkValue(SPORK_20_SEGWIT_ACTIVATION) > chainActive.Tip()->nTime || State(pfrom->GetId())->fHaveWitness)) { inv.type = MSG_WITNESS_BLOCK; } vToFetch.push_back(inv); @@ -6695,11 +6425,11 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, int nDoS = 0; if (state.IsInvalid(nDoS)) { LogPrint("mempoolrej", "%s from peer=%d %s was not accepted into the memory pool: %s\n", tx.GetHash().ToString(), - pfrom->id, pfrom->cleanSubVer, - state.GetRejectReason()); + pfrom->id, pfrom->cleanSubVer, + state.GetRejectReason()); if (state.GetRejectCode() < REJECT_INTERNAL) pfrom->PushMessage(NetMsgType::REJECT, strCommand, state.GetRejectCode(), - state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), inv.hash); + state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), inv.hash); if (nDoS > 0 && (!state.CorruptionPossible() || State(pfrom->id)->fHaveWitness)) Misbehaving(pfrom->GetId(), nDoS); } @@ -6794,7 +6524,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, int nDoS; if(state.IsInvalid(nDoS)) { pfrom->PushMessage(NetMsgType::REJECT, strCommand, state.GetRejectCode(), - state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), inv.hash); + state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), inv.hash); if(nDoS > 0) { TRY_LOCK(cs_main, lockMain); if(lockMain) Misbehaving(pfrom->GetId(), nDoS); @@ -6809,16 +6539,16 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } - // This asymmetric behavior for inbound and outbound connections was introduced - // to prevent a fingerprinting attack: an attacker can send specific fake addresses - // to users' AddrMan and later request them by sending getaddr messages. - // Making users (which are behind NAT and can only make outgoing connections) ignore - // getaddr message mitigates the attack. + // This asymmetric behavior for inbound and outbound connections was introduced + // to prevent a fingerprinting attack: an attacker can send specific fake addresses + // to users' AddrMan and later request them by sending getaddr messages. + // Making users (which are behind NAT and can only make outgoing connections) ignore + // getaddr message mitigates the attack. else if ((strCommand == NetMsgType::GETADDR) && (pfrom->fInbound)) { pfrom->vAddrToSend.clear(); vector vAddr = addrman.GetAddr(); for (const CAddress& addr : vAddr) - pfrom->PushAddress(addr); + pfrom->PushAddress(addr); } @@ -6909,12 +6639,12 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, if (!(sProblem.empty())) { LogPrint("net", "pong peer=%d %s: %s, %x expected, %x received, %u bytes\n", - pfrom->id, - pfrom->cleanSubVer, - sProblem, - pfrom->nPingNonceSent, - nonce, - nAvail); + pfrom->id, + pfrom->cleanSubVer, + sProblem, + pfrom->nPingNonceSent, + nonce, + nAvail); } if (bPingFinished) { pfrom->nPingNonceSent = 0; @@ -6933,7 +6663,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, { LOCK(cs_vNodes); for (CNode* pnode : vNodes) - alert.RelayTo(pnode); + alert.RelayTo(pnode); } } else { // Small DoS penalty so peers that send us lots of @@ -6949,9 +6679,9 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } else if (!(nLocalServices & NODE_BLOOM) && - (strCommand == NetMsgType::FILTERLOAD || - strCommand == NetMsgType::FILTERADD || - strCommand == NetMsgType::FILTERCLEAR)) { + (strCommand == NetMsgType::FILTERLOAD || + strCommand == NetMsgType::FILTERADD || + strCommand == NetMsgType::FILTERCLEAR)) { LogPrintf("bloom message=%s\n", strCommand); LOCK(cs_main); Misbehaving(pfrom->GetId(), 100); @@ -7046,29 +6776,9 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // Those old clients won't react to the changes of the other (new) SPORK because at the time of their implementation // it was the one which was commented out int ActiveProtocol() - -// SPORK_17 was used for 71010. Leave it 'ON' so they don't see < 70711 nodes. They won't react to SPORK_15 - // messages because it's not in their code -/* - if (IsSporkActive(SPORK_16_NEW_PROTOCOL_ENFORCEMENT_3)) { - if (chainActive.Tip()->nHeight >= Params().ModifierUpgradeBlock()) - return MIN_PEER_PROTO_VERSION_AFTER_ENFORCEMENT; - } - return MIN_PEER_PROTO_VERSION_BEFORE_ENFORCEMENT; -*/ - - - // SPORK_17 is used for 71011. Nodes < 71010 won't see it and still get their protocol version via SPORK_17 and their - // own ModifierUpgradeBlock() - { - if (IsSporkActive(SPORK_23_NEW_BLOCKTIME_ENFORCEMENT)) - // Enforce protocol 71025 and greater. + if (IsSporkActive(SPORK_14_NEW_PROTOCOL_ENFORCEMENT)) return MIN_PEER_PROTO_VERSION_AFTER_ENFORCEMENT; - if (IsSporkActive(SPORK_18_NEW_PROTOCOL_ENFORCEMENT_5)) - // Enforce protocol 71011 - return MIN_PEER_MNANNOUNCE; - // Default protocol return MIN_PEER_PROTO_VERSION_BEFORE_ENFORCEMENT; } @@ -7140,7 +6850,7 @@ 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", - SanitizeString(strCommand), nMessageSize, nChecksum, hdr.nChecksum); + SanitizeString(strCommand), nMessageSize, nChecksum, hdr.nChecksum); continue; } @@ -7276,7 +6986,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle) } for (const CBlockReject& reject : state.rejects) - pto->PushMessage(NetMsgType::REJECT, (string) "block", reject.chRejectCode, reject.strRejectReason, reject.hashBlock); + pto->PushMessage(NetMsgType::REJECT, (string) "block", reject.chRejectCode, reject.strRejectReason, reject.hashBlock); state.rejects.clear(); // Start block sync @@ -7359,7 +7069,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle) // 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().TargetSpacingLegacy() * (4 + state.vBlocksInFlight.front().nValidatedQueuedBefore)) { + 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; } @@ -7377,7 +7087,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle) vGetData.push_back(CInv(State(staller)->fHaveWitness ? MSG_WITNESS_BLOCK : MSG_BLOCK, pindex->GetBlockHash())); MarkBlockAsInFlight(pto->GetId(), pindex->GetBlockHash(), pindex); LogPrint("net", "Requesting block %s (%d) peer=%d\n", pindex->GetBlockHash().ToString(), - pindex->nHeight, pto->id); + pindex->nHeight, pto->id); } } if (state.nBlocksInFlight == 0 && staller != -1) { diff --git a/src/main.h b/src/main.h index d9c1721..217726a 100755 --- a/src/main.h +++ b/src/main.h @@ -403,7 +403,7 @@ int64_t GetTransactionSigOpCost(const CTransaction& tx, const CCoinsViewCache& i * This does not modify the UTXO set. If pvChecks is not NULL, script checks are pushed onto it * instead of being performed inline. */ -bool CheckInputs(const CTransaction& tx, CValidationState& state, const CCoinsViewCache& view, bool fScriptChecks, unsigned int flags, bool cacheStore, std::vector* pvChecks = NULL); +bool CheckInputs(const CTransaction& tx, CValidationState& state, const CCoinsViewCache& view, bool fScriptChecks, unsigned int flags, bool cacheSigStore, bool cacheFullScriptStore, std::vector* 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); @@ -659,4 +659,6 @@ struct CBlockTemplate { int64_t GetVirtualTransactionSize(const CTransaction& tx); int64_t GetVirtualTransactionSize(int64_t nCost); +void InitScriptExecutionCache(); + #endif // BITCOIN_MAIN_H diff --git a/src/miner.cpp b/src/miner.cpp index 6d99d95..5d93956 100755 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -166,8 +166,10 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn, CWallet* pwallet, nLastCoinStakeSearchTime = nSearchTime; } - if (!fStakeFound) + if (!fStakeFound) { + LogPrint("staking", "CreateNewBlock(): stake not found\n"); return NULL; + } } // Block resource limits @@ -384,14 +386,14 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn, CWallet* pwallet, if (!view.HaveInputs(tx)) continue; - // double check that there are no double spent zPhr spends in this block or tx + // double check that there are no double spent zOHMC spends in this block or tx if (tx.IsZerocoinSpend()) { int nHeightTx = 0; if (IsTransactionInChain(tx.GetHash(), nHeightTx)) continue; bool fDoubleSerial = false; - for (const CTxIn txIn : tx.vin) { + for (const CTxIn& txIn : tx.vin) { if (txIn.scriptSig.IsZerocoinSpend()) { libzerocoin::CoinSpend spend = TxInToZerocoinSpend(txIn); int effectiveHeight = libzerocoin::ExtractVersionFromSerial(spend.getCoinSerialNumber()) < libzerocoin::PrivateCoin::PUBKEY_VERSION ? Params().Zerocoin_LastOldParams() : Params().Zerocoin_LastOldParams() + 1; @@ -417,7 +419,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn, CWallet* pwallet, // policy here, but we still have to ensure that the block we // create only contains transactions that are valid in new blocks. CValidationState state; - if (!CheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true)) + if (!CheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true, false)) continue; CTxUndo txundo; @@ -431,7 +433,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn, CWallet* pwallet, ++nBlockTx; nFees += nTxFees; - for (const CBigNum bnSerial : vTxSerials) + for (const CBigNum& bnSerial : vTxSerials) vBlockSerials.emplace_back(bnSerial); if (fPrintPriority) { @@ -545,8 +547,19 @@ int64_t nHPSTimerStart = 0; CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey, CWallet* pwallet, bool fProofOfStake) { CPubKey pubkey; - if (!reservekey.GetReservedKey(pubkey)) - return NULL; + if (!reservekey.GetReservedKey(pubkey, false)) + return nullptr; + + const int nHeightNext = chainActive.Tip()->nHeight + 1; + static int nLastPOWBlock = Params().LAST_POW_BLOCK(); + + // If we're building a late PoW block, don't continue + if ((nHeightNext > nLastPOWBlock) && !fProofOfStake) { + LogPrintf("%s: Aborting PoW block creation during PoS phase\n", __func__); + // sleep 1/2 a block time so we don't go into a tight loop. + MilliSleep((Params().TargetSpacing() * 1000) >> 1); + return nullptr; + } CScript scriptPubKey = CScript() << ToByteVector(pubkey) << OP_CHECKSIG; return CreateNewBlock(scriptPubKey, pwallet, fProofOfStake); @@ -593,6 +606,9 @@ bool ProcessBlockFound(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey) } bool fGenerateBitcoins = false; +bool fMintableCoins = false; +int nMintableLastCheck = 0; + // ***TODO*** that part changed in bitcoin, we are using a mix with old one here for now @@ -609,17 +625,29 @@ void BitcoinMiner(CWallet* pwallet, bool fProofOfStake) while (fGenerateBitcoins || fProofOfStake) { if (fProofOfStake) { if (chainActive.Tip()->nHeight < Params().LAST_POW_BLOCK()) { - MilliSleep(5000); + // The last PoW block hasn't even been mined yet. + MilliSleep(Params().TargetSpacing() * 1000); // sleep a block continue; } + + //control the amount of times the client will check for mintable coins + if ((GetTime() - nMintableLastCheck > 5 * 60)) // 5 minute check time + { + nMintableLastCheck = GetTime(); + fMintableCoins = pwallet->MintableCoins(); + } - while (chainActive.Tip()->nTime < 1504595227 || vNodes.empty() || pwallet->IsLocked() || - nReserveBalance >= pwallet->GetBalance() || !karmanodeSync.IsSynced()) { + while (vNodes.empty() || pwallet->IsLocked() || !fMintableCoins || (pwallet->GetBalance() > 0 && + nReserveBalance >= pwallet->GetBalance()) || !karmanodeSync.IsSynced()) { nLastCoinStakeSearchInterval = 0; MilliSleep(5000); - if (!fGenerateBitcoins && !fProofOfStake) - continue; - } + // Do a separate 1 minute check here to ensure fMintableCoins is updated + if (!fMintableCoins && (GetTime() - nMintableLastCheck > 1 * 60)) // 1 minute check time + { + nMintableLastCheck = GetTime(); + fMintableCoins = pwallet->MintableCoins(); + } + } if (mapHashedBlocks.count(chainActive.Tip()->nHeight)) //search our map of hashed blocks, see if bestblock has been hashed yet { @@ -629,10 +657,16 @@ void BitcoinMiner(CWallet* pwallet, bool fProofOfStake) continue; } } + } else { // PoW + if ((chainActive.Tip()->nHeight - 6) > Params().LAST_POW_BLOCK()) + { + // Run for a little while longer, just in case there is a rewind on the chain. + LogPrintf("%s: Exiting Proof of Work Mining Thread at height: %d\n", + __func__, chainActive.Tip()->nHeight); + return; + } } - MilliSleep(1000); - // // Create new block // @@ -653,7 +687,7 @@ void BitcoinMiner(CWallet* pwallet, bool fProofOfStake) LogPrintf("CPUMiner : proof-of-stake block found %s \n", pblock->GetHash().ToString().c_str()); if (!pblock->SignBlock(*pwallet)) { - LogPrintf("BitcoinMiner(): Signing new block failed \n"); + LogPrintf("%s: Signing new block failed \n", __func__); continue; } @@ -682,7 +716,7 @@ void BitcoinMiner(CWallet* pwallet, bool fProofOfStake) if (hash <= hashTarget) { // Found a solution SetThreadPriority(THREAD_PRIORITY_NORMAL); - LogPrintf("BitcoinMiner:\n"); + LogPrintf("%s:\n", __func__); LogPrintf("proof-of-work found \n hash: %s \ntarget: %s\n", hash.GetHex(), hashTarget.GetHex()); ProcessBlockFound(pblock, *pwallet, reservekey); SetThreadPriority(THREAD_PRIORITY_LOWEST); @@ -754,12 +788,12 @@ void static ThreadBitcoinMiner(void* parg) BitcoinMiner(pwallet, false); boost::this_thread::interruption_point(); } catch (std::exception& e) { - LogPrintf("ThreadBitcoinMiner() exception"); + LogPrintf("OhmcoinMiner() exception"); } catch (...) { - LogPrintf("ThreadBitcoinMiner() exception"); + LogPrintf("OhmcoinMiner() exception"); } - LogPrintf("ThreadBitcoinMiner exiting\n"); + LogPrintf("OhmcoinMiner exiting\n"); } void GenerateBitcoins(bool fGenerate, CWallet* pwallet, int nThreads) diff --git a/src/miner.h b/src/miner.h index 67b0714..d6fb20d 100755 --- a/src/miner.h +++ b/src/miner.h @@ -18,18 +18,21 @@ class CWallet; struct CBlockTemplate; -/** Run the miner threads */ -void GenerateBitcoins(bool fGenerate, CWallet* pwallet, int nThreads); /** Generate a new block, without valid proof-of-work */ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn, CWallet* pwallet, bool fProofOfStake); -CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey, CWallet* pwallet, bool fProofOfStake); /** Modify the extranonce in a block */ void IncrementExtraNonce(CBlock* pblock, const CBlockIndex* pindexPrev, unsigned int& nExtraNonce); /** Check mined block */ void UpdateTime(CBlockHeader* block, const CBlockIndex* pindexPrev); -void BitcoinMiner(CWallet* pwallet, bool fProofOfStake); -void ThreadStakeMinter(); +#ifdef ENABLE_WALLET + /** Run the miner threads */ + void GenerateBitcoins(bool fGenerate, CWallet* pwallet, int nThreads); + /** Generate a new block, without valid proof-of-work */ + CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey, CWallet* pwallet, bool fProofOfStake); + void BitcoinMiner(CWallet* pwallet, bool fProofOfStake); + void ThreadStakeMinter(); +#endif // ENABLE_WALLET extern double dHashesPerSec; extern int64_t nHPSTimerStart; diff --git a/src/net.cpp b/src/net.cpp index 840acde..5a4eb2c 100755 --- a/src/net.cpp +++ b/src/net.cpp @@ -63,14 +63,14 @@ using namespace std; namespace { -const int MAX_OUTBOUND_CONNECTIONS = 16; + const int MAX_OUTBOUND_CONNECTIONS = 16; -struct ListenSocket { - SOCKET socket; - bool whitelisted; + struct ListenSocket { + SOCKET socket; + bool whitelisted; - ListenSocket(SOCKET socket, bool whitelisted) : socket(socket), whitelisted(whitelisted) {} -}; + ListenSocket(SOCKET socket, bool whitelisted) : socket(socket), whitelisted(whitelisted) {} + }; } /** Services this node implementation cares about */ @@ -233,7 +233,7 @@ void AdvertizeLocal(CNode* pnode) // tells us that it sees us as in case it has a better idea of our // address than we do. if (IsPeerAddrLocalGood(pnode) && (!addrLocal.IsRoutable() || - GetRand((GetnScore(addrLocal) > LOCAL_MANUAL) ? 8 : 2) == 0)) { + GetRand((GetnScore(addrLocal) > LOCAL_MANUAL) ? 8 : 2) == 0)) { addrLocal.SetIP(pnode->addrLocal); } if (addrLocal.IsRoutable()) { @@ -361,8 +361,8 @@ CNode* FindNode(const CSubNet& subNet) { LOCK(cs_vNodes); for (CNode* pnode : vNodes) - if (subNet.Match((CNetAddr)pnode->addr)) - return (pnode); + if (subNet.Match((CNetAddr)pnode->addr)) + return (pnode); return NULL; } @@ -411,14 +411,14 @@ CNode* ConnectNode(CAddress addrConnect, const char* pszDest, bool obfuScationMa /// debug print LogPrint("net", "trying connection %s lastseen=%.1fhrs\n", - pszDest ? pszDest : addrConnect.ToString(), - pszDest ? 0.0 : (double)(GetAdjustedTime() - addrConnect.nTime) / 3600.0); + pszDest ? pszDest : addrConnect.ToString(), + pszDest ? 0.0 : (double)(GetAdjustedTime() - addrConnect.nTime) / 3600.0); // Connect SOCKET hSocket; bool proxyConnectionFailed = false; if (pszDest ? ConnectSocketByName(addrConnect, hSocket, pszDest, Params().GetDefaultPort(), nConnectTimeout, &proxyConnectionFailed) : - ConnectSocket(addrConnect, hSocket, nConnectTimeout, &proxyConnectionFailed)) { + ConnectSocket(addrConnect, hSocket, nConnectTimeout, &proxyConnectionFailed)) { if (!IsSelectableSocket(hSocket)) { LogPrintf("Cannot create connection: non-selectable socket created (fd >= FD_SETSIZE ?)\n"); CloseSocket(hSocket); @@ -490,7 +490,7 @@ void CNode::PushVersion() else LogPrint("net", "send version message: version %d, blocks=%d, us=%s, peer=%d\n", PROTOCOL_VERSION, nBestHeight, addrMe.ToString(), id); PushMessage(NetMsgType::VERSION, PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe, - nLocalHostNonce, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector()), nBestHeight, true); + nLocalHostNonce, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector()), nBestHeight, true); } @@ -962,14 +962,14 @@ void ThreadSocketHandler() { TRY_LOCK(pnode->cs_vRecvMsg, lockRecv); if (lockRecv && (pnode->vRecvMsg.empty() || !pnode->vRecvMsg.front().complete() || - pnode->GetTotalRecvSize() <= ReceiveFloodSize())) + pnode->GetTotalRecvSize() <= ReceiveFloodSize())) FD_SET(pnode->hSocket, &fdsetRecv); } } } int nSelect = select(have_fds ? hSocketMax + 1 : 0, - &fdsetRecv, &fdsetSend, &fdsetError, &timeout); + &fdsetRecv, &fdsetSend, &fdsetError, &timeout); boost::this_thread::interruption_point(); if (nSelect == SOCKET_ERROR) { @@ -1281,7 +1281,7 @@ void DumpAddresses() adb.Write(addrman); LogPrint("net", "Flushed %d addresses to peers.dat %dms\n", - addrman.size(), GetTimeMillis() - nStart); + addrman.size(), GetTimeMillis() - nStart); } void DumpData() @@ -1618,7 +1618,7 @@ bool BindListenPort(const CService& addrBind, string& strError, bool fWhiteliste // and enable it by default or not. Try to enable it, if possible. if (addrBind.IsIPv6()) { #ifdef IPV6_V6ONLY -#ifdef WIN32 + #ifdef WIN32 setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&nOne, sizeof(int)); #else setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (void*)&nOne, sizeof(int)); @@ -1723,7 +1723,7 @@ void StartNode(boost::thread_group& threadGroup, CScheduler& scheduler) CNode::SweepBanned(); //sweap out unused entries LogPrintf("Loaded %i addresses from peers.dat %dms\n", - addrman.size(), GetTimeMillis() - nStart); + addrman.size(), GetTimeMillis() - nStart); fAddressesInitialized = true; if (semOutbound == NULL) { @@ -1915,28 +1915,28 @@ void CNode::Fuzz(int nChance) if (GetRand(nChance) != 0) return; // Fuzz 1 of every nChance messages switch (GetRand(3)) { - case 0: - // xor a random byte with a random value: - if (!ssSend.empty()) { - CDataStream::size_type pos = GetRand(ssSend.size()); - ssSend[pos] ^= (unsigned char)(GetRand(256)); - } - break; - case 1: - // delete a random byte: - if (!ssSend.empty()) { - CDataStream::size_type pos = GetRand(ssSend.size()); - ssSend.erase(ssSend.begin() + pos); - } - break; - case 2: - // insert a random byte at a random position + case 0: + // xor a random byte with a random value: + if (!ssSend.empty()) { + CDataStream::size_type pos = GetRand(ssSend.size()); + ssSend[pos] ^= (unsigned char)(GetRand(256)); + } + break; + case 1: + // delete a random byte: + if (!ssSend.empty()) { + CDataStream::size_type pos = GetRand(ssSend.size()); + ssSend.erase(ssSend.begin() + pos); + } + break; + case 2: + // insert a random byte at a random position { CDataStream::size_type pos = GetRand(ssSend.size()); char ch = (char)GetRand(256); ssSend.insert(ssSend.begin() + pos, ch); } - break; + break; } // Chance of more than one change half the time: // (more changes exponentially less likely): @@ -2312,5 +2312,5 @@ void DumpBanlist() } LogPrint("net", "Flushed %d banned node ips/subnets to banlist.dat %dms\n", - banmap.size(), GetTimeMillis() - nStart); + banmap.size(), GetTimeMillis() - nStart); } diff --git a/src/obfuscation.cpp b/src/obfuscation.cpp index 6501014..6161b7f 100644 --- a/src/obfuscation.cpp +++ b/src/obfuscation.cpp @@ -4,7 +4,7 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "obfuscation.h" -#include "coincontrol.h" +#include "wallet/coincontrol.h" #include "consensus/validation.h" #include "init.h" #include "main.h" @@ -1683,7 +1683,7 @@ bool CObfuscationPool::SendRandomPaymentToSelf() CScript scriptChange; CPubKey vchPubKey; - assert(reservekey.GetReservedKey(vchPubKey)); // should never fail, as we just unlocked + assert(reservekey.GetReservedKey(vchPubKey, false)); // should never fail, as we just unlocked scriptChange = GetScriptForDestination(vchPubKey.GetID()); CWalletTx wtx; @@ -1725,7 +1725,7 @@ bool CObfuscationPool::MakeCollateralAmounts() CScript scriptCollateral; CPubKey vchPubKey; - assert(reservekeyCollateral.GetReservedKey(vchPubKey)); // should never fail, as we just unlocked + assert(reservekeyCollateral.GetReservedKey(vchPubKey, false)); // should never fail, as we just unlocked scriptCollateral = GetScriptForDestination(vchPubKey.GetID()); vecSend.push_back(make_pair(scriptCollateral, OBFUSCATION_COLLATERAL * 4)); @@ -1780,7 +1780,7 @@ bool CObfuscationPool::CreateDenominated(CAmount nTotalValue) CScript scriptCollateral; CPubKey vchPubKey; - assert(reservekeyCollateral.GetReservedKey(vchPubKey)); // should never fail, as we just unlocked + assert(reservekeyCollateral.GetReservedKey(vchPubKey, false)); // should never fail, as we just unlocked scriptCollateral = GetScriptForDestination(vchPubKey.GetID()); // ****** Add collateral outputs ************ / @@ -1798,7 +1798,7 @@ bool CObfuscationPool::CreateDenominated(CAmount nTotalValue) CScript scriptDenom; CPubKey vchPubKey; //use a unique change address - assert(reservekeyDenom.GetReservedKey(vchPubKey)); // should never fail, as we just unlocked + assert(reservekeyDenom.GetReservedKey(vchPubKey, false)); // should never fail, as we just unlocked scriptDenom = GetScriptForDestination(vchPubKey.GetID()); // TODO: do not keep reservekeyDenom here reservekeyDenom.KeepKey(); diff --git a/src/ohmcoind.cpp b/src/ohmcoind.cpp index b1a0530..7e5a4f3 100644 --- a/src/ohmcoind.cpp +++ b/src/ohmcoind.cpp @@ -10,6 +10,7 @@ #include "init.h" #include "main.h" #include "noui.h" +#include "scheduler.h" #include "rpc/server.h" #include "ui_interface.h" #include "util.h" @@ -40,7 +41,7 @@ static bool fDaemon; -void WaitForShutdown() +void WaitForShutdown(boost::thread_group* threadGroup) { bool fShutdown = ShutdownRequested(); // Tell the main threads to shutdown. @@ -48,7 +49,10 @@ void WaitForShutdown() MilliSleep(200); fShutdown = ShutdownRequested(); } - Interrupt(); + if (threadGroup) { + Interrupt(*threadGroup); + threadGroup->join_all(); + } } ////////////////////////////////////////////////////////////////////////////// @@ -57,6 +61,9 @@ void WaitForShutdown() // bool AppInit(int argc, char* argv[]) { + boost::thread_group threadGroup; + CScheduler scheduler; + bool fRet = false; // @@ -132,8 +139,9 @@ bool AppInit(int argc, char* argv[]) } #endif SoftSetBoolArg("-server", true); - - fRet = AppInit2(); + + std::vector words; + fRet = AppInit2(threadGroup, scheduler, words); } catch (std::exception& e) { PrintExceptionContinue(&e, "AppInit()"); } catch (...) { @@ -141,9 +149,12 @@ bool AppInit(int argc, char* argv[]) } if (!fRet) { - Interrupt(); + Interrupt(threadGroup); + // 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 } else { - WaitForShutdown(); + WaitForShutdown(&threadGroup); } Shutdown(); diff --git a/src/primitives/block.h b/src/primitives/block.h index 6a07e08..ed6097e 100755 --- a/src/primitives/block.h +++ b/src/primitives/block.h @@ -14,6 +14,8 @@ /** The maximum allowed size for a serialized block, in bytes (network rule) */ static const unsigned int MAX_BLOCK_SIZE = 1000000; +static const unsigned int MAX_BLOCK_SIZE_CURRENT = 2000000; +static const unsigned int MAX_BLOCK_SIZE_LEGACY = 1000000; /** Nodes collect new transactions into a block, hash them into a hash tree, * and scan through nonce values to make the block's hash satisfy proof-of-work diff --git a/src/primitives/transaction.cpp b/src/primitives/transaction.cpp index 19874a3..569c66f 100755 --- a/src/primitives/transaction.cpp +++ b/src/primitives/transaction.cpp @@ -156,7 +156,7 @@ CAmount CTransaction::GetValueOut() const CAmount CTransaction::GetZerocoinMinted() const { - for (const CTxOut txOut : vout) { + for (const CTxOut& txOut : vout) { if(!txOut.scriptPubKey.IsZerocoinMint()) continue; @@ -168,7 +168,7 @@ CAmount CTransaction::GetZerocoinMinted() const bool CTransaction::UsesUTXO(const COutPoint out) { - for (const CTxIn in : vin) { + for (const CTxIn& in : vin) { if (in.prevout == out) return true; } @@ -191,7 +191,7 @@ CAmount CTransaction::GetZerocoinSpent() const return 0; CAmount nValueOut = 0; - for (const CTxIn txin : vin) { + for (const CTxIn& txin : vin) { if(!txin.scriptSig.IsZerocoinSpend()) continue; @@ -204,7 +204,7 @@ CAmount CTransaction::GetZerocoinSpent() const int CTransaction::GetZerocoinMintCount() const { int nCount = 0; - for (const CTxOut out : vout) { + for (const CTxOut& out : vout) { if (out.scriptPubKey.IsZerocoinMint()) nCount++; } diff --git a/src/pubkey.cpp b/src/pubkey.cpp index faf37d6..f71ab1b 100755 --- a/src/pubkey.cpp +++ b/src/pubkey.cpp @@ -108,7 +108,7 @@ bool CPubKey::Derive(CPubKey& pubkeyChild, unsigned char ccChild[32], unsigned i return ret; } -void CExtPubKey::Encode(unsigned char code[74]) const +void CExtPubKey::Encode(unsigned char code[BIP32_EXTKEY_SIZE]) const { code[0] = nDepth; memcpy(code + 1, vchFingerprint, 4); @@ -121,7 +121,7 @@ void CExtPubKey::Encode(unsigned char code[74]) const memcpy(code + 41, pubkey.begin(), 33); } -void CExtPubKey::Decode(const unsigned char code[74]) +void CExtPubKey::Decode(const unsigned char code[BIP32_EXTKEY_SIZE]) { nDepth = code[0]; memcpy(vchFingerprint, code + 1, 4); diff --git a/src/pubkey.h b/src/pubkey.h index 92e7b7a..702a1c3 100755 --- a/src/pubkey.h +++ b/src/pubkey.h @@ -13,7 +13,7 @@ #include #include -/** +/** * secp256k1: * const unsigned int PRIVATE_KEY_SIZE = 279; * const unsigned int PUBLIC_KEY_SIZE = 65; @@ -23,6 +23,8 @@ * script supports up to 75 for single byte push */ +const unsigned int BIP32_EXTKEY_SIZE = 74; + /** A reference to a CKey: the Hash160 of its serialized public key */ class CKeyID : public uint160 { @@ -61,7 +63,7 @@ class CPubKey bool static ValidSize(const std::vector &vch) { return vch.size() > 0 && GetLen(vch[0]) == vch.size(); } - + //! Construct an invalid public key. CPubKey() { @@ -155,7 +157,7 @@ class CPubKey /* * Check syntactic correctness. - * + * * Note that this is consensus critical as CheckSig() calls it! */ bool IsValid() const @@ -215,6 +217,29 @@ struct CExtPubKey { void Encode(unsigned char code[74]) const; void Decode(const unsigned char code[74]); bool Derive(CExtPubKey& out, unsigned int nChild) const; + unsigned int GetSerializeSize(int nType, int nVersion) const + { + return BIP32_EXTKEY_SIZE+1; //add one byte for the size (compact int) + } + template + void Serialize(Stream& s, int nType, int nVersion) const + { + unsigned int len = BIP32_EXTKEY_SIZE; + ::WriteCompactSize(s, len); + unsigned char code[BIP32_EXTKEY_SIZE]; + Encode(code); + s.write((const char *)&code[0], len); + } + template + void Unserialize(Stream& s, int nType, int nVersion) + { + unsigned int len = ::ReadCompactSize(s); + unsigned char code[BIP32_EXTKEY_SIZE]; + if (len != BIP32_EXTKEY_SIZE) + throw std::runtime_error("Invalid extended key size\n"); + s.read((char *)&code[0], len); + Decode(code); + } }; -#endif // BITCOIN_PUBKEY_H +#endif // BITCOIN_PUBKEY_H \ No newline at end of file diff --git a/src/qt/addresstablemodel.cpp b/src/qt/addresstablemodel.cpp index c5f3d07..a623ff1 100755 --- a/src/qt/addresstablemodel.cpp +++ b/src/qt/addresstablemodel.cpp @@ -11,7 +11,6 @@ #include "base58.h" #include "wallet/wallet.h" -#include "askpassphrasedialog.h" #include #include @@ -384,14 +383,14 @@ QString AddressTableModel::addRow(const QString& type, const QString& label, con } else if (type == Receive) { // Generate a new address to associate with given label CPubKey newKey; - if (!wallet->GetKeyFromPool(newKey)) { - WalletModel::UnlockContext ctx(walletModel->requestUnlock(AskPassphraseDialog::Context::Unlock_Full, true)); + if (!wallet->GetKeyFromPool(newKey, false)) { + WalletModel::UnlockContext ctx(walletModel->requestUnlock(true)); if (!ctx.isValid()) { // Unlock wallet failed or was cancelled editStatus = WALLET_UNLOCK_FAILURE; return QString(); } - if (!wallet->GetKeyFromPool(newKey)) { + if (!wallet->GetKeyFromPool(newKey, false)) { editStatus = KEY_GENERATION_FAILURE; return QString(); } diff --git a/src/qt/askpassphrasedialog.cpp b/src/qt/askpassphrasedialog.cpp index 4551d36..73ea6ea 100755 --- a/src/qt/askpassphrasedialog.cpp +++ b/src/qt/askpassphrasedialog.cpp @@ -19,11 +19,10 @@ #include -AskPassphraseDialog::AskPassphraseDialog(Mode mode, QWidget* parent, WalletModel* model, Context context) : QDialog(parent), +AskPassphraseDialog::AskPassphraseDialog(Mode mode, QWidget* parent, WalletModel* model) : QDialog(parent), ui(new Ui::AskPassphraseDialog), mode(mode), model(model), - context(context), fCapsLock(false) { ui->setupUi(this); @@ -79,18 +78,7 @@ AskPassphraseDialog::AskPassphraseDialog(Mode mode, QWidget* parent, WalletModel break; } - // Set checkbox "For anonymization, automint, and staking only" depending on from where we were called - if (context == Context::Unlock_Menu || context == Context::Mint_zOHMC || context == Context::BIP_38) { - ui->anonymizationCheckBox->setChecked(true); - } - else { - ui->anonymizationCheckBox->setChecked(false); - } - - // It doesn't make sense to show the checkbox for sending Ohmcoin because you wouldn't check it anyway. - if (context == Context::Send_OHMC || context == Context::Send_zOHMC) { - ui->anonymizationCheckBox->hide(); - } + ui->anonymizationCheckBox->setChecked(model->isAnonymizeOnlyUnlocked()); textChanged(); connect(ui->passEdit1, SIGNAL(textChanged(QString)), this, SLOT(textChanged())); @@ -109,7 +97,6 @@ AskPassphraseDialog::~AskPassphraseDialog() void AskPassphraseDialog::accept() { - SecureString oldpass, newpass1, newpass2; if (!model) return; oldpass.reserve(MAX_PASSPHRASE_SIZE); diff --git a/src/qt/askpassphrasedialog.h b/src/qt/askpassphrasedialog.h index 19e4841..cd97599 100755 --- a/src/qt/askpassphrasedialog.h +++ b/src/qt/askpassphrasedialog.h @@ -6,6 +6,7 @@ #define BITCOIN_QT_ASKPASSPHRASEDIALOG_H #include +#include "allocators.h" class WalletModel; @@ -29,33 +30,18 @@ class AskPassphraseDialog : public QDialog Decrypt /**< Ask passphrase and decrypt wallet */ }; - // Context from where / for what the passphrase dialog was called to set the status of the checkbox - // Partly redundant to Mode above, but offers more flexibility for future enhancements - enum class Context { - Unlock_Menu, /** Unlock wallet from menu */ - Unlock_Full, /** Wallet needs to be fully unlocked */ - Encrypt, /** Encrypt unencrypted wallet */ - ToggleLock, /** Toggle wallet lock state */ - ChangePass, /** Change passphrase */ - Send_OHMC, /** Send OHMC */ - Send_zOHMC, /** Send zOHMC */ - Mint_zOHMC, /** Mint zOHMC */ - BIP_38, /** BIP38 menu */ - Multi_Sig, /** Multi-Signature dialog */ - Sign_Message /** Sign/verify message dialog */ - }; - - explicit AskPassphraseDialog(Mode mode, QWidget* parent, WalletModel* model, Context context); + explicit AskPassphraseDialog(Mode mode, QWidget* parent, WalletModel* model); ~AskPassphraseDialog(); void accept(); + SecureString getPassword() { return oldpass; } private: Ui::AskPassphraseDialog* ui; Mode mode; WalletModel* model; - Context context; bool fCapsLock; + SecureString oldpass, newpass1, newpass2; private slots: void textChanged(); diff --git a/src/qt/bip38tooldialog.cpp b/src/qt/bip38tooldialog.cpp index 25d5bd4..6fbc2e5 100755 --- a/src/qt/bip38tooldialog.cpp +++ b/src/qt/bip38tooldialog.cpp @@ -15,7 +15,6 @@ #include "bip38.h" #include "init.h" #include "wallet/wallet.h" -#include "askpassphrasedialog.h" #include #include @@ -146,7 +145,7 @@ void Bip38ToolDialog::on_encryptKeyButton_ENC_clicked() return; } - WalletModel::UnlockContext ctx(model->requestUnlock(AskPassphraseDialog::Context::BIP_38, true)); + WalletModel::UnlockContext ctx(model->requestUnlock(true)); if (!ctx.isValid()) { ui->statusLabel_ENC->setStyleSheet("QLabel { color: red; }"); ui->statusLabel_ENC->setText(tr("Wallet unlock was cancelled.")); @@ -209,7 +208,7 @@ void Bip38ToolDialog::on_decryptKeyButton_DEC_clicked() void Bip38ToolDialog::on_importAddressButton_DEC_clicked() { - WalletModel::UnlockContext ctx(model->requestUnlock(AskPassphraseDialog::Context::BIP_38, true)); + WalletModel::UnlockContext ctx(model->requestUnlock(true)); if (!ctx.isValid()) { ui->statusLabel_DEC->setStyleSheet("QLabel { color: red; }"); ui->statusLabel_DEC->setText(tr("Wallet unlock was cancelled.")); diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index b378d83..b2c53e0 100755 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -67,6 +67,7 @@ BitcoinGUI::BitcoinGUI(const NetworkStyle* networkStyle, QWidget* parent) : QMai unitDisplayControl(0), labelStakingIcon(0), labelEncryptionIcon(0), + labelWalletHDStatusIcon(0), labelConnectionsIcon(0), labelBlocksIcon(0), labelTorIcon(0), @@ -186,6 +187,7 @@ BitcoinGUI::BitcoinGUI(const NetworkStyle* networkStyle, QWidget* parent) : QMai unitDisplayControl = new UnitDisplayStatusBarControl(); labelStakingIcon = new QLabel(); labelEncryptionIcon = new QPushButton(); + labelWalletHDStatusIcon = new QLabel(); labelEncryptionIcon->setObjectName("labelEncryptionIcon"); labelEncryptionIcon->setFlat(true); // Make the button look like a label, but clickable labelEncryptionIcon->setStyleSheet(".QPushButton { background-color: rgba(255, 255, 255, 0);}"); @@ -203,6 +205,7 @@ BitcoinGUI::BitcoinGUI(const NetworkStyle* networkStyle, QWidget* parent) : QMai frameBlocksLayout->addWidget(unitDisplayControl); frameBlocksLayout->addStretch(); frameBlocksLayout->addWidget(labelEncryptionIcon); + frameBlocksLayout->addWidget(labelWalletHDStatusIcon); } frameBlocksLayout->addStretch(); frameBlocksLayout->addWidget(labelStakingIcon); @@ -692,6 +695,7 @@ bool BitcoinGUI::addWallet(const QString& name, WalletModel* walletModel) if (!walletFrame) return false; setWalletActionsEnabled(true); + rpcConsole->setWalletModel(walletModel); return walletFrame->addWallet(name, walletModel); } @@ -1220,7 +1224,7 @@ bool BitcoinGUI::eventFilter(QObject* object, QEvent* event) } return QMainWindow::eventFilter(object, event); } - +#ifdef ENABLE_WALLET void BitcoinGUI::setStakingStatus() { if (pwalletMain) @@ -1237,7 +1241,14 @@ void BitcoinGUI::setStakingStatus() } } -#ifdef ENABLE_WALLET +void BitcoinGUI::setHDStatus(int hdEnabled) +{ + labelWalletHDStatusIcon->setPixmap(QIcon(hdEnabled ? ":/icons/hd_enabled" : ":/icons/hd_disabled").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE)); + labelWalletHDStatusIcon->setToolTip(hdEnabled ? tr("HD key generation is enabled") : tr("HD key generation is disabled")); + // eventually disable the QLabel to set its opacity to 50% + labelWalletHDStatusIcon->setEnabled(hdEnabled); +} + bool BitcoinGUI::handlePaymentRequest(const SendCoinsRecipient& recipient) { // URI has to be valid @@ -1383,13 +1394,13 @@ static bool ThreadSafeMessageBox(BitcoinGUI* gui, const std::string& message, co void BitcoinGUI::subscribeToCoreSignals() { // Connect signals to client - uiInterface.ThreadSafeMessageBox.connect(boost::bind(ThreadSafeMessageBox, this, boost::placeholders::_1, boost::placeholders::_2, boost::placeholders::_3)); + uiInterface.ThreadSafeMessageBox.connect(boost::bind(ThreadSafeMessageBox, this, boost::arg<1>(), boost::arg<2>(), boost::arg<3>())); } void BitcoinGUI::unsubscribeFromCoreSignals() { // Disconnect signals from client - uiInterface.ThreadSafeMessageBox.disconnect(boost::bind(ThreadSafeMessageBox, this, boost::placeholders::_1, boost::placeholders::_2, boost::placeholders::_3)); + uiInterface.ThreadSafeMessageBox.disconnect(boost::bind(ThreadSafeMessageBox, this, boost::arg<1>(), boost::arg<2>(), boost::arg<3>())); } /** Get restart command-line parameters and request restart */ diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index 0e9ff52..44dd2fc 100755 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -87,6 +87,7 @@ class BitcoinGUI : public QMainWindow QLabel* labelStakingIcon; QPushButton* labelEncryptionIcon; QLabel* labelTorIcon; + QLabel *labelWalletHDStatusIcon; QPushButton* labelConnectionsIcon; QLabel* labelBlocksIcon; QLabel* progressBarLabel; @@ -184,10 +185,13 @@ public slots: @param[in] ret pointer to a bool that will be modified to whether Ok was clicked (modal only) */ void message(const QString& title, const QString& message, unsigned int style, bool* ret = NULL); - - void setStakingStatus(); - #ifdef ENABLE_WALLET + void setStakingStatus(); + /** Set the hd-enabled status as shown in the UI. + setHDStatus current hd enabled status + @see WalletModel::hdEnabled + */ + void setHDStatus(int hdEnabled); /** Set the encryption status as shown in the UI. @param[in] status current encryption status @see WalletModel::EncryptionStatus diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp index ba3e0d9..63f5112 100755 --- a/src/qt/clientmodel.cpp +++ b/src/qt/clientmodel.cpp @@ -286,18 +286,18 @@ static void BannedListChanged(ClientModel *clientmodel) void ClientModel::subscribeToCoreSignals() { // Connect signals to client - uiInterface.ShowProgress.connect(boost::bind(ShowProgress, this, boost::placeholders::_1, boost::placeholders::_2)); - uiInterface.NotifyNumConnectionsChanged.connect(boost::bind(NotifyNumConnectionsChanged, this, boost::placeholders::_1)); - uiInterface.NotifyAlertChanged.connect(boost::bind(NotifyAlertChanged, this, boost::placeholders::_1, boost::placeholders::_2)); + uiInterface.ShowProgress.connect(boost::bind(ShowProgress, this, boost::arg<1>(), boost::arg<2>())); + uiInterface.NotifyNumConnectionsChanged.connect(boost::bind(NotifyNumConnectionsChanged, this, boost::arg<1>())); + uiInterface.NotifyAlertChanged.connect(boost::bind(NotifyAlertChanged, this, boost::arg<1>(), boost::arg<2>())); uiInterface.BannedListChanged.connect(boost::bind(BannedListChanged, this)); } void ClientModel::unsubscribeFromCoreSignals() { // Disconnect signals from client - uiInterface.ShowProgress.disconnect(boost::bind(ShowProgress, this, boost::placeholders::_1, boost::placeholders::_2)); - uiInterface.NotifyNumConnectionsChanged.disconnect(boost::bind(NotifyNumConnectionsChanged, this, boost::placeholders::_1)); - uiInterface.NotifyAlertChanged.disconnect(boost::bind(NotifyAlertChanged, this, boost::placeholders::_1, boost::placeholders::_2)); + uiInterface.ShowProgress.disconnect(boost::bind(ShowProgress, this, boost::arg<1>(), boost::arg<2>())); + uiInterface.NotifyNumConnectionsChanged.disconnect(boost::bind(NotifyNumConnectionsChanged, this, boost::arg<1>())); + uiInterface.NotifyAlertChanged.disconnect(boost::bind(NotifyAlertChanged, this, boost::arg<1>(), boost::arg<2>())); uiInterface.BannedListChanged.disconnect(boost::bind(BannedListChanged, this)); } diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index 36f507c..c4f7044 100755 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -14,7 +14,7 @@ #include "optionsmodel.h" #include "walletmodel.h" -#include "coincontrol.h" +#include "wallet/coincontrol.h" #include "main.h" #include "obfuscation.h" #include "wallet/wallet.h" diff --git a/src/qt/configurekarmanodepage.h b/src/qt/configurekarmanodepage.h index 521f032..06d7214 100644 --- a/src/qt/configurekarmanodepage.h +++ b/src/qt/configurekarmanodepage.h @@ -59,8 +59,8 @@ class ConfigureKarmanodePage : public QDialog { return counters; } - - int setCounters(int counter) + + void setCounters(int counter) { counters = counter; } diff --git a/src/qt/forms/rpcconsole.ui b/src/qt/forms/rpcconsole.ui index c1f90aa..7c11587 100755 --- a/src/qt/forms/rpcconsole.ui +++ b/src/qt/forms/rpcconsole.ui @@ -1606,7 +1606,37 @@ - + + + + + 100 + 23 + + + + Upgrade non-hd wallet to hd + + + + + + + -rescan: + + + + + + + Upgrade non-hd wallet to hd + + + true + + + + Qt::Vertical diff --git a/src/qt/forms/startoptions.ui b/src/qt/forms/startoptions.ui new file mode 100644 index 0000000..3b12719 --- /dev/null +++ b/src/qt/forms/startoptions.ui @@ -0,0 +1,25 @@ + + + StartOptions + + + + 0 + 0 + 222 + 222 + + + + StartOptions Dialog + + + + + + + + + + + diff --git a/src/qt/forms/startoptionsdialog.ui b/src/qt/forms/startoptionsdialog.ui new file mode 100644 index 0000000..45f6a28 --- /dev/null +++ b/src/qt/forms/startoptionsdialog.ui @@ -0,0 +1,92 @@ + + + StartOptionsDialog + + + + 0 + 0 + 598 + 222 + + + + + 0 + 0 + + + + + 550 + 0 + + + + StartOptions Error + + + + QLayout::SetMinimumSize + + + + + Placeholder text + + + Qt::RichText + + + true + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + StartOptionsDialog + accept() + + + 20 + 20 + + + 20 + 20 + + + + + buttonBox + rejected() + StartOptionsDialog + reject() + + + 20 + 20 + + + 20 + 20 + + + + + diff --git a/src/qt/forms/startoptionsmain.ui b/src/qt/forms/startoptionsmain.ui new file mode 100644 index 0000000..1a9b91d --- /dev/null +++ b/src/qt/forms/startoptionsmain.ui @@ -0,0 +1,100 @@ + + + StartOptionsMain + + + + 0 + 0 + 650 + 400 + + + + + 0 + 0 + + + + + 550 + 0 + + + + StartOptionsMain Dialog + + + + QLayout::SetMinimumSize + + + + + + 0 + 0 + + + + #frame2{ + background-color: #161616; + border: none; + padding: 0; + } + + + 0 + + + + + false + + + + + + + + + + + + &Restore + + + + + + + &New Wallet + + + + + + + + + + + &Back + + + + + + + &Next + + + + + + + + + + diff --git a/src/qt/forms/startoptionsrestore.ui b/src/qt/forms/startoptionsrestore.ui new file mode 100644 index 0000000..2c2ccbd --- /dev/null +++ b/src/qt/forms/startoptionsrestore.ui @@ -0,0 +1,76 @@ + + + StartOptionsRestore + + + + 0 + 0 + 598 + 222 + + + + + 0 + 0 + + + + + 550 + 0 + + + + StartOptionsRestore Dialog + + + + QLayout::SetMinimumSize + + + + + 30 + + + + + + + + + buttonBox + accepted() + StartOptionsRestore + accept() + + + 20 + 20 + + + 20 + 20 + + + + + buttonBox + rejected() + StartOptionsRestore + reject() + + + 20 + 20 + + + 20 + 20 + + + + + diff --git a/src/qt/forms/startoptionsrevealed.ui b/src/qt/forms/startoptionsrevealed.ui new file mode 100644 index 0000000..7e4735d --- /dev/null +++ b/src/qt/forms/startoptionsrevealed.ui @@ -0,0 +1,49 @@ + + + StartOptionsRevealed + + + + 0 + 0 + 598 + 222 + + + + + 0 + 0 + + + + + 550 + 0 + + + + + 10 + true + + + + StartOptionsRevealed Dialog + + + + QLayout::SetMinimumSize + + + + + 0 + + + + + + + + diff --git a/src/qt/forms/startoptionssort.ui b/src/qt/forms/startoptionssort.ui new file mode 100644 index 0000000..1ac18da --- /dev/null +++ b/src/qt/forms/startoptionssort.ui @@ -0,0 +1,109 @@ + + + StartOptionsSort + + + + 0 + 0 + 598 + 180 + + + + + 0 + 0 + + + + + 550 + 0 + + + + + 75 + false + true + + + + StartOptionsSort Dialog + + + + + + + QLayout::SetMinimumSize + + + + + + 0 + 0 + + + + + 16777215 + 20 + + + + Placeholder text + + + Qt::RichText + + + Qt::AlignCenter + + + true + + + + + + + + 0 + 0 + + + + + 16777215 + 20 + + + + Placeholder text + + + Qt::RichText + + + Qt::AlignCenter + + + true + + + + + + + 0 + + + + + + + + diff --git a/src/qt/karmanodelist.cpp b/src/qt/karmanodelist.cpp index ddc956c..583c1ab 100755 --- a/src/qt/karmanodelist.cpp +++ b/src/qt/karmanodelist.cpp @@ -269,7 +269,7 @@ void KarmanodeList::on_startButton_clicked() WalletModel::EncryptionStatus encStatus = walletModel->getEncryptionStatus(); if (encStatus == walletModel->Locked || encStatus == walletModel->UnlockedForAnonymizationOnly) { - WalletModel::UnlockContext ctx(walletModel->requestUnlock(AskPassphraseDialog::Context::Unlock_Full)); + WalletModel::UnlockContext ctx(walletModel->requestUnlock()); if (!ctx.isValid()) return; // Unlock wallet was cancelled @@ -436,7 +436,7 @@ void KarmanodeList::on_startAllButton_clicked() WalletModel::EncryptionStatus encStatus = walletModel->getEncryptionStatus(); if (encStatus == walletModel->Locked || encStatus == walletModel->UnlockedForAnonymizationOnly) { - WalletModel::UnlockContext ctx(walletModel->requestUnlock(AskPassphraseDialog::Context::Unlock_Full)); + WalletModel::UnlockContext ctx(walletModel->requestUnlock()); if (!ctx.isValid()) return; // Unlock wallet was cancelled @@ -467,7 +467,7 @@ void KarmanodeList::on_startMissingButton_clicked() WalletModel::EncryptionStatus encStatus = walletModel->getEncryptionStatus(); if (encStatus == walletModel->Locked || encStatus == walletModel->UnlockedForAnonymizationOnly) { - WalletModel::UnlockContext ctx(walletModel->requestUnlock(AskPassphraseDialog::Context::Unlock_Full)); + WalletModel::UnlockContext ctx(walletModel->requestUnlock()); if (!ctx.isValid()) return; // Unlock wallet was cancelled diff --git a/src/qt/multisigdialog.cpp b/src/qt/multisigdialog.cpp index 1619d8d..91c4585 100644 --- a/src/qt/multisigdialog.cpp +++ b/src/qt/multisigdialog.cpp @@ -668,7 +668,7 @@ bool MultisigDialog::signMultisigTx(CMutableTransaction& tx, string& errorOut, Q } }else{ if (model->getEncryptionStatus() == model->Locked) { - if (!model->requestUnlock(AskPassphraseDialog::Context::Multi_Sig, true).isValid()) { + if (!model->requestUnlock(true).isValid()) { // Unlock wallet was cancelled throw runtime_error("Error: Your wallet is locked. Please enter the wallet passphrase first."); } diff --git a/src/qt/multisigdialog.h b/src/qt/multisigdialog.h index 152f2c2..eaf37a2 100644 --- a/src/qt/multisigdialog.h +++ b/src/qt/multisigdialog.h @@ -12,7 +12,7 @@ #include "script/script.h" #include "primitives/transaction.h" #include "coins.h" -#include "coincontrol.h" +#include "wallet/coincontrol.h" #include "walletmodel.h" #include "coincontroldialog.h" diff --git a/src/qt/ohmcoin.cpp b/src/qt/ohmcoin.cpp index b69549b..d5639d6 100644 --- a/src/qt/ohmcoin.cpp +++ b/src/qt/ohmcoin.cpp @@ -27,9 +27,12 @@ #include "walletmodel.h" #endif +#include + #include "init.h" #include "main.h" #include "rpc/server.h" +#include "scheduler.h" #include "ui_interface.h" #include "util.h" @@ -52,6 +55,7 @@ #include #include #include +#include #if defined(QT_STATICPLUGIN) #include @@ -160,7 +164,7 @@ class BitcoinCore : public QObject { Q_OBJECT public: - explicit BitcoinCore(); + explicit BitcoinCore(std::vector& wordlist); public slots: void initialize(); @@ -169,15 +173,19 @@ public slots: signals: void initializeResult(bool success); - void shutdownResult(); + void shutdownResult(int retval); void runawayException(const QString& message); private: + boost::thread_group threadGroup; + CScheduler scheduler; + /// Flag indicating a restart bool execute_restart; /// Pass fatal exception message to UI thread void handleRunawayException(std::exception* e); + std::vector words; }; /** Main Ohmcoin application object */ @@ -195,10 +203,13 @@ class BitcoinApplication : public QApplication /// Create options model void createOptionsModel(); /// Create main window - void createWindow(const NetworkStyle* networkStyle); + bool createWindow(const NetworkStyle* networkStyle); /// Create splash screen void createSplashScreen(const NetworkStyle* networkStyle); + /// Get mnemonic words on first startup + bool setupMnemonicWords(std::vector& wordlist); + /// Request core initialization void requestInitialize(); /// Request core shutdown @@ -212,7 +223,7 @@ class BitcoinApplication : public QApplication public slots: void initializeResult(bool success); - void shutdownResult(); + void shutdownResult(int retval); /// Handle runaway exceptions. Shows a message box with the problem and quits the program. void handleRunawayException(const QString& message); @@ -233,6 +244,7 @@ public slots: PaymentServer* paymentServer; WalletModel* walletModel; #endif + std::vector wordlist; int returnValue; void startThread(); @@ -240,7 +252,7 @@ public slots: #include "ohmcoin.moc" -BitcoinCore::BitcoinCore() : QObject() +BitcoinCore::BitcoinCore(std::vector& wordlist) : QObject(), words(wordlist) { } @@ -256,7 +268,7 @@ void BitcoinCore::initialize() try { qDebug() << __func__ << ": Running AppInit2 in thread"; - bool rv = AppInit2(); + int rv = AppInit2(threadGroup, scheduler, words); emit initializeResult(rv); } catch (std::exception& e) { handleRunawayException(&e); @@ -271,10 +283,11 @@ void BitcoinCore::restart(QStringList args) execute_restart = false; try { qDebug() << __func__ << ": Running Restart in thread"; - Interrupt(); + Interrupt(threadGroup); + threadGroup.join_all(); PrepareShutdown(); qDebug() << __func__ << ": Shutdown finished"; - Q_EMIT shutdownResult(); + emit shutdownResult(1); CExplicitNetCleanup::callCleanup(); QProcess::startDetached(QApplication::applicationFilePath(), args); qDebug() << __func__ << ": Restart initiated..."; @@ -291,10 +304,11 @@ void BitcoinCore::shutdown() { try { qDebug() << __func__ << ": Running Shutdown in thread"; - Interrupt(); + Interrupt(threadGroup); + threadGroup.join_all(); Shutdown(); qDebug() << __func__ << ": Shutdown finished"; - Q_EMIT shutdownResult(); + emit shutdownResult(1); } catch (std::exception& e) { handleRunawayException(&e); } catch (...) { @@ -354,13 +368,39 @@ void BitcoinApplication::createOptionsModel() optionsModel = new OptionsModel(); } -void BitcoinApplication::createWindow(const NetworkStyle* networkStyle) +// this will be used to get mnemonic words +bool BitcoinApplication::setupMnemonicWords(std::vector& wordlist) { + namespace fs = boost::filesystem; + if (GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) { + LogPrintf("Wallet disabled!\n"); + } + + if (GetBoolArg("-skipmnemonicstartupui", false)) { + return true; + } + + std::string walletFile = GetArg("-wallet", "wallet.dat"); + if (fs::exists(walletFile)) return true; + + if (CheckIfWalletDatExists()) return true; + + StartOptionsMain dlg(nullptr); + dlg.exec(); + wordlist = dlg.getWords(); + return false; +} + +bool BitcoinApplication::createWindow(const NetworkStyle* networkStyle) { + /// doesn't check if wallet is enabled, It will be assumbed if the user is using the gui wallet is enabled + if (!setupMnemonicWords(wordlist)) { + if (wordlist.empty()) return false; + } window = new BitcoinGUI(networkStyle, 0); pollShutdownTimer = new QTimer(window); connect(pollShutdownTimer, SIGNAL(timeout()), window, SLOT(detectShutdown())); - pollShutdownTimer->start(200); + return true; } void BitcoinApplication::createSplashScreen(const NetworkStyle* networkStyle) @@ -379,12 +419,12 @@ void BitcoinApplication::startThread() if (coreThread) return; coreThread = new QThread(this); - BitcoinCore* executor = new BitcoinCore(); + BitcoinCore* executor = new BitcoinCore(wordlist); executor->moveToThread(coreThread); /* communication to and from thread */ connect(executor, SIGNAL(initializeResult(bool)), this, SLOT(initializeResult(bool))); - connect(executor, SIGNAL(shutdownResult()), this, SLOT(shutdownResult())); + connect(executor, SIGNAL(shutdownResult(int)), this, SLOT(shutdownResult(int))); connect(executor, SIGNAL(runawayException(QString)), this, SLOT(handleRunawayException(QString))); connect(this, SIGNAL(requestedInitialize()), executor, SLOT(initialize())); connect(this, SIGNAL(requestedShutdown()), executor, SLOT(shutdown())); @@ -477,8 +517,9 @@ void BitcoinApplication::initializeResult(bool success) } } -void BitcoinApplication::shutdownResult() +void BitcoinApplication::shutdownResult(int retval) { + qDebug() << __func__ << ": Shutdown result: " << retval; quit(); // Exit main loop after shutdown finished } @@ -628,7 +669,9 @@ int main(int argc, char* argv[]) app.createSplashScreen(networkStyle.data()); try { - app.createWindow(networkStyle.data()); + if (!app.createWindow(networkStyle.data())) { + return EXIT_FAILURE; + } app.requestInitialize(); #if defined(Q_OS_WIN) WinShutdownMonitor::registerShutdownBlockReason(QObject::tr("Ohmcoin Core didn't yet exit safely..."), (HWND)app.getMainWinId()); diff --git a/src/qt/ohmcoin.qrc b/src/qt/ohmcoin.qrc index 0831e33..0cde280 100644 --- a/src/qt/ohmcoin.qrc +++ b/src/qt/ohmcoin.qrc @@ -65,6 +65,8 @@ res/icons/staking_active.png res/icons/staking_inactive.png res/icons/onion.png + res/icons/hd_enabled.png + res/icons/hd_disabled.png res/css/default.css diff --git a/src/qt/paymentrequestplus.cpp b/src/qt/paymentrequestplus.cpp index 78e5f46..3fa7b56 100755 --- a/src/qt/paymentrequestplus.cpp +++ b/src/qt/paymentrequestplus.cpp @@ -11,7 +11,6 @@ #include -#include #include #include diff --git a/src/qt/paymentrequestplus.h b/src/qt/paymentrequestplus.h index 72b2b96..79e7fd8 100755 --- a/src/qt/paymentrequestplus.h +++ b/src/qt/paymentrequestplus.h @@ -12,6 +12,8 @@ #include "base58.h" +#include + #include #include #include diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp index 6dcfeae..5cd6740 100755 --- a/src/qt/paymentserver.cpp +++ b/src/qt/paymentserver.cpp @@ -19,7 +19,6 @@ #include -#include #include #include @@ -578,7 +577,7 @@ void PaymentServer::fetchPaymentACK(CWallet* wallet, SendCoinsRecipient recipien QString account = tr("Refund from %1").arg(recipient.authenticatedMerchant); std::string strAccount = account.toStdString(); CPubKey newKey; - if (wallet->GetKeyFromPool(newKey)) { + if (wallet->GetKeyFromPool(newKey, false)) { // BIP70 requests encode the scriptPubKey directly, so we are not restricted to address // types supported by the receiver. As a result, we choose the address format we also // use for change. Despite an actual payment and not change, this is a close match: diff --git a/src/qt/privacydialog.cpp b/src/qt/privacydialog.cpp index 3163c74..2b3d1b8 100755 --- a/src/qt/privacydialog.cpp +++ b/src/qt/privacydialog.cpp @@ -14,7 +14,7 @@ #include "optionsmodel.h" #include "sendcoinsentry.h" #include "walletmodel.h" -#include "coincontrol.h" +#include "wallet/coincontrol.h" #include "zohmccontroldialog.h" #include "spork.h" @@ -176,7 +176,7 @@ void PrivacyDialog::on_pushButtonMintzOHMC_clicked() // Request unlock if wallet was locked or unlocked for mixing: WalletModel::EncryptionStatus encStatus = walletModel->getEncryptionStatus(); if (encStatus == walletModel->Locked) { - WalletModel::UnlockContext ctx(walletModel->requestUnlock(AskPassphraseDialog::Context::Mint_zOHMC, true)); + WalletModel::UnlockContext ctx(walletModel->requestUnlock(true)); if (!ctx.isValid()) { // Unlock wallet was cancelled ui->TEMintStatus->setPlainText(tr("Error: Your wallet is locked. Please enter the wallet passphrase first.")); @@ -282,7 +282,7 @@ void PrivacyDialog::on_pushButtonSpendzOHMC_clicked() // Request unlock if wallet was locked or unlocked for mixing: WalletModel::EncryptionStatus encStatus = walletModel->getEncryptionStatus(); if (encStatus == walletModel->Locked || encStatus == walletModel->UnlockedForAnonymizationOnly) { - WalletModel::UnlockContext ctx(walletModel->requestUnlock(AskPassphraseDialog::Context::Send_zOHMC, true)); + WalletModel::UnlockContext ctx(walletModel->requestUnlock(true)); if (!ctx.isValid()) { // Unlock wallet was cancelled return; diff --git a/src/qt/proposalfilterproxy.cpp b/src/qt/proposalfilterproxy.cpp index bac6b88..0996e18 100644 --- a/src/qt/proposalfilterproxy.cpp +++ b/src/qt/proposalfilterproxy.cpp @@ -42,7 +42,7 @@ bool ProposalFilterProxy::filterAcceptsRow(int sourceRow, const QModelIndex &sou int yesVotes = index.data(ProposalTableModel::YesVotesRole).toInt(); int noVotes = index.data(ProposalTableModel::NoVotesRole).toInt(); int abstainVotes = index.data(ProposalTableModel::AbstainVotesRole).toInt(); - int votedNeeded = index.data(ProposalTableModel::VotesNeededRole).toInt(); + int votesNeeded = index.data(ProposalTableModel::VotesNeededRole).toInt(); if (proposalStartDate < startDate) return false; if (proposalEndDate < endDate) return false; diff --git a/src/qt/proposallist.cpp b/src/qt/proposallist.cpp index 15bcfde..8716a9a 100644 --- a/src/qt/proposallist.cpp +++ b/src/qt/proposallist.cpp @@ -5,7 +5,7 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "activekarmanode.h" -#include "db.h" +#include "wallet/db.h" #include "guiutil.h" #include "init.h" #include "main.h" @@ -20,6 +20,7 @@ #include "karmanode-payments.h" #include "karmanodeconfig.h" #include "karmanodeman.h" +#include "walletmodel.h" #include "rpc/server.h" #include "ui_interface.h" #include "utilmoneystr.h" @@ -48,7 +49,6 @@ ProposalList::ProposalList(QWidget *parent) : QWidget(parent), proposalTableModel(0), proposalProxyModel(0), proposalList(0), columnResizingFixer(0) { - proposalTableModel = new ProposalTableModel(this); QSettings settings; setContentsMargins(20,0,20,0); @@ -233,14 +233,14 @@ ProposalList::ProposalList(QWidget *parent) : QAction *voteYesAction = new QAction(tr("Vote Yes"), this); QAction *voteAbstainAction = new QAction(tr("Vote Abstain"), this); QAction *voteNoAction = new QAction(tr("Vote No"), this); - QAction *copyUrlAction = new QAction(tr("Copy proposal URL"), this); + QAction *openUrlAction = new QAction(tr("Visit proposal website"), this); contextMenu = new QMenu(this); contextMenu->addAction(voteYesAction); contextMenu->addAction(voteAbstainAction); contextMenu->addAction(voteNoAction); contextMenu->addSeparator(); - contextMenu->addAction(copyUrlAction); + contextMenu->addAction(openUrlAction); connect(view, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextualMenu(QPoint))); @@ -254,8 +254,6 @@ ProposalList::ProposalList(QWidget *parent) : connect(voteYesAction, SIGNAL(triggered()), this, SLOT(voteYes())); connect(voteNoAction, SIGNAL(triggered()), this, SLOT(voteNo())); connect(voteAbstainAction, SIGNAL(triggered()), this, SLOT(voteAbstain())); - connect(copyUrlAction, SIGNAL(triggered()), this, SLOT(copyProposalUrl())); - connect(proposalWidget, SIGNAL(textChanged(QString)), this, SLOT(changedProposal(QString))); connect(startDateWidget, SIGNAL(textChanged(QString)), this, SLOT(chooseStartDate(QString))); connect(endDateWidget, SIGNAL(textChanged(QString)), this, SLOT(chooseEndDate(QString))); @@ -267,45 +265,73 @@ ProposalList::ProposalList(QWidget *parent) : connect(amountWidget, SIGNAL(textChanged(QString)), this, SLOT(changedAmount(QString))); connect(votesNeededWidget, SIGNAL(textChanged(QString)), this, SLOT(changedVotesNeeded(QString))); - proposalProxyModel = new ProposalFilterProxy(this); - proposalProxyModel->setDynamicSortFilter(true); - proposalProxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive); - proposalProxyModel->setSortCaseSensitivity(Qt::CaseInsensitive); - proposalProxyModel->setSortRole(Qt::EditRole); - proposalProxyModel->setSourceModel(proposalTableModel); - - proposalList->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - proposalList->setModel(proposalProxyModel); - proposalList->setAlternatingRowColors(true); - proposalList->setSelectionBehavior(QAbstractItemView::SelectRows); - proposalList->setSortingEnabled(true); - proposalList->sortByColumn(ProposalTableModel::StartDate, Qt::DescendingOrder); - proposalList->verticalHeader()->hide(); - - proposalList->setColumnWidth(ProposalTableModel::Proposal, PROPOSAL_COLUMN_WIDTH); - proposalList->setColumnWidth(ProposalTableModel::Amount, AMOUNT_COLUMN_WIDTH); - proposalList->setColumnWidth(ProposalTableModel::StartDate, START_DATE_COLUMN_WIDTH); - proposalList->setColumnWidth(ProposalTableModel::EndDate, END_DATE_COLUMN_WIDTH); - proposalList->setColumnWidth(ProposalTableModel::TotalPaymentCount, TOTAL_PAYMENT_COLUMN_WIDTH); - proposalList->setColumnWidth(ProposalTableModel::RemainingPaymentCount, REMAINING_PAYMENT_COLUMN_WIDTH); - proposalList->setColumnWidth(ProposalTableModel::YesVotes, YES_VOTES_COLUMN_WIDTH); - proposalList->setColumnWidth(ProposalTableModel::NoVotes, NO_VOTES_COLUMN_WIDTH); - proposalList->setColumnWidth(ProposalTableModel::AbstainVotes, ABSTAIN_COLUMN_WIDTH); - proposalList->setColumnWidth(ProposalTableModel::VotesNeeded, VOTES_NEEDED_COLUMN_WIDTH); - - columnResizingFixer = new GUIUtil::TableViewLastColumnResizingFixer(proposalList, VOTES_NEEDED_COLUMN_WIDTH, MINIMUM_COLUMN_WIDTH); + connect(view, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(openProposalUrl())); + connect(view, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextualMenu(QPoint))); + connect(openUrlAction, SIGNAL(triggered()), this, SLOT(openProposalUrl())); nLastUpdate = GetTime(); timer = new QTimer(this); connect(timer, SIGNAL(timeout()), this, SLOT(refreshProposals())); timer->start(1000); +} - setLayout(vlayout); +void ProposalList::setModel(WalletModel* model) +{ + + QSettings settings; + proposalTableModel = new ProposalTableModel(this); + this->model = model; + + if (model) { + proposalProxyModel = new ProposalFilterProxy(this); + proposalProxyModel->setDynamicSortFilter(true); + proposalProxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive); + proposalProxyModel->setSortCaseSensitivity(Qt::CaseInsensitive); + proposalProxyModel->setSortRole(Qt::EditRole); + proposalProxyModel->setSourceModel(proposalTableModel); + + proposalList->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + proposalList->setModel(proposalProxyModel); + proposalList->setAlternatingRowColors(true); + proposalList->setSelectionBehavior(QAbstractItemView::SelectRows); + proposalList->setSortingEnabled(true); + proposalList->sortByColumn(ProposalTableModel::StartDate, Qt::DescendingOrder); + proposalList->verticalHeader()->hide(); + + proposalList->setColumnWidth(ProposalTableModel::Proposal, PROPOSAL_COLUMN_WIDTH); + proposalList->setColumnWidth(ProposalTableModel::Amount, AMOUNT_COLUMN_WIDTH); + proposalList->setColumnWidth(ProposalTableModel::StartDate, START_DATE_COLUMN_WIDTH); + proposalList->setColumnWidth(ProposalTableModel::EndDate, END_DATE_COLUMN_WIDTH); + proposalList->setColumnWidth(ProposalTableModel::TotalPaymentCount, TOTAL_PAYMENT_COLUMN_WIDTH); + proposalList->setColumnWidth(ProposalTableModel::RemainingPaymentCount, REMAINING_PAYMENT_COLUMN_WIDTH); + proposalList->setColumnWidth(ProposalTableModel::YesVotes, YES_VOTES_COLUMN_WIDTH); + proposalList->setColumnWidth(ProposalTableModel::NoVotes, NO_VOTES_COLUMN_WIDTH); + proposalList->setColumnWidth(ProposalTableModel::AbstainVotes, ABSTAIN_COLUMN_WIDTH); + proposalList->setColumnWidth(ProposalTableModel::VotesNeeded, VOTES_NEEDED_COLUMN_WIDTH); + + columnResizingFixer = new GUIUtil::TableViewLastColumnResizingFixer(proposalList, VOTES_NEEDED_COLUMN_WIDTH, MINIMUM_COLUMN_WIDTH); + } } void ProposalList::createProposal() { + + WalletModel::EncryptionStatus encStatus = model->getEncryptionStatus(); + + if (encStatus == model->Locked || encStatus == model->UnlockedForAnonymizationOnly) { + WalletModel::UnlockContext ctx(model->requestUnlock()); + + if (!ctx.isValid()) return; // Unlock wallet was cancelled + + ProposalDialog dlg(ProposalDialog::PrepareProposal, this); + if (QDialog::Accepted == dlg.exec()) + { + refreshProposals(true); + } + return; + } + ProposalDialog dlg(ProposalDialog::PrepareProposal, this); if (QDialog::Accepted == dlg.exec()) { diff --git a/src/qt/proposallist.h b/src/qt/proposallist.h index e8b0a81..9506b5c 100644 --- a/src/qt/proposallist.h +++ b/src/qt/proposallist.h @@ -17,6 +17,7 @@ class ProposalFilterProxy; class CKarmanode; +class WalletModel; QT_BEGIN_NAMESPACE class QComboBox; @@ -39,7 +40,7 @@ class ProposalList : public QWidget public: explicit ProposalList(QWidget *parent = 0); - void setModel(); + void setModel(WalletModel* model); enum DateEnum { @@ -67,8 +68,9 @@ class ProposalList : public QWidget }; private: - ProposalTableModel *proposalTableModel; + WalletModel* model; ProposalFilterProxy *proposalProxyModel; + ProposalTableModel *proposalTableModel; QTableView *proposalList; int64_t nLastUpdate = 0; diff --git a/src/qt/proposaltablemodel.h b/src/qt/proposaltablemodel.h index 8d61735..e1de2b9 100644 --- a/src/qt/proposaltablemodel.h +++ b/src/qt/proposaltablemodel.h @@ -35,7 +35,7 @@ class ProposalTableModel : public QAbstractTableModel Q_OBJECT public: - explicit ProposalTableModel( QObject *parent = 0); + explicit ProposalTableModel(QObject *parent = 0); ~ProposalTableModel(); enum ColumnIndex { diff --git a/src/qt/res/css/default.css b/src/qt/res/css/default.css index ae78cc1..7fb7349 100755 --- a/src/qt/res/css/default.css +++ b/src/qt/res/css/default.css @@ -992,7 +992,7 @@ QWidget .QFrame#frame > .QLabel { min-height: 30px; } QWidget .QFrame#frame .QLabel#label_5 { - /* PHR Balances Label */ + /* OHMC Balances Label */ qproperty-alignment: 'AlignVCenter | AlignLeft'; min-width: 160px; background-color: transparent; @@ -1129,7 +1129,7 @@ QWidget .QFrame#frame_4 .QLabel#label_5z_3 { padding-right: 5px; } QWidget .QFrame#frame_4 .QLabel#labelzBalanceText { - /* Available zPHR Label */ + /* Available zOHMC Label */ qproperty-alignment: 'AlignVCenter | AlignRight'; min-width: 160px; background-color: #00CD8D; @@ -1141,7 +1141,7 @@ QWidget .QFrame#frame_4 .QLabel#labelzBalanceText { /* min-height:35px; */ } QWidget .QFrame#frame_4 .QLabel#labelzBalance { - /* Available zPHR Balance */ + /* Available zOHMC Balance */ qproperty-alignment: 'AlignVCenter | AlignLeft'; font-size: 12px; font-weight: bold; @@ -1149,7 +1149,7 @@ QWidget .QFrame#frame_4 .QLabel#labelzBalance { margin-left: 0px; } QWidget .QFrame#frame_4 .QLabel#labelzBalanceUnconfirmedText { - /* Unconfirmed zPHR Label */ + /* Unconfirmed zOHMC Label */ qproperty-alignment: 'AlignVCenter | AlignRight'; min-width: 160px; background-color: #00CD8D; @@ -1161,7 +1161,7 @@ QWidget .QFrame#frame_4 .QLabel#labelzBalanceUnconfirmedText { /* min-height:35px; */ } QWidget .QFrame#frame_4 .QLabel#labelzBalanceUnconfirmed { - /* Unconfirmed zPHR Balance */ + /* Unconfirmed zOHMC Balance */ qproperty-alignment: 'AlignVCenter | AlignLeft'; font-size: 12px; font-weight: bold; @@ -1169,7 +1169,7 @@ QWidget .QFrame#frame_4 .QLabel#labelzBalanceUnconfirmed { margin-left: 0px; } QWidget .QFrame#frame_4 .QLabel#labelzBalanceMatureText { - /* Mature zPHR Label */ + /* Mature zOHMC Label */ qproperty-alignment: 'AlignVCenter | AlignRight'; min-width: 160px; background-color: #00CD8D; @@ -1181,7 +1181,7 @@ QWidget .QFrame#frame_4 .QLabel#labelzBalanceMatureText { /* min-height:35px; */ } QWidget .QFrame#frame_4 .QLabel#labelzBalanceMature { - /* Mature zPHR Balance */ + /* Mature zOHMC Balance */ qproperty-alignment: 'AlignVCenter | AlignLeft'; font-size: 12px; font-weight: bold; @@ -1189,7 +1189,7 @@ QWidget .QFrame#frame_4 .QLabel#labelzBalanceMature { margin-left: 0px; } QWidget .QFrame#frame_4 .QLabel#labelzBalanceImmatureText { - /* Immature zPHR Label */ + /* Immature zOHMC Label */ qproperty-alignment: 'AlignVCenter | AlignRight'; min-width: 160px; background-color: #00CD8D; @@ -1201,7 +1201,7 @@ QWidget .QFrame#frame_4 .QLabel#labelzBalanceImmatureText { /* min-height:35px; */ } QWidget .QFrame#frame_4 .QLabel#labelzBalanceImmature { - /* Immature zPHR Balance */ + /* Immature zOHMC Balance */ qproperty-alignment: 'AlignVCenter | AlignLeft'; font-size: 12px; font-weight: bold; @@ -1220,7 +1220,7 @@ QWidget .QFrame#frame_3 .QLabel#label_5z { padding-right: 5px; } QWidget .QFrame#frame_3 .QLabel#labelBalanceTextz { - /* Available PHR Label */ + /* Available OHMC Label */ qproperty-alignment: 'AlignVCenter | AlignRight'; min-width: 160px; background-color: #00CD8D; @@ -1233,7 +1233,7 @@ QWidget .QFrame#frame_3 .QLabel#labelBalanceTextz { /* min-height:35px; */ } QWidget .QFrame#frame_3 .QLabel#labelBalancez { - /* Available PHR Balance */ + /* Available OHMC Balance */ qproperty-alignment: 'AlignVCenter | AlignLeft'; font-size: 12px; font-weight: bold; @@ -1241,7 +1241,7 @@ QWidget .QFrame#frame_3 .QLabel#labelBalancez { margin-left: 0px; } QWidget .QFrame#frame_3 .QLabel#labelzBalanceTextz { - /* Available zPHR Label */ + /* Available zOHMC Label */ qproperty-alignment: 'AlignVCenter | AlignRight'; min-width: 160px; background-color: #00CD8D; @@ -1253,7 +1253,7 @@ QWidget .QFrame#frame_3 .QLabel#labelzBalanceTextz { /* min-height:35px; */ } QWidget .QFrame#frame_3 .QLabel#labelzBalancez { - /* Available zPHR Balance */ + /* Available zOHMC Balance */ qproperty-alignment: 'AlignVCenter | AlignLeft'; font-size: 12px; font-weight: bold; @@ -1261,7 +1261,7 @@ QWidget .QFrame#frame_3 .QLabel#labelzBalancez { margin-left: 0px; } QWidget .QFrame#frame_3 .QLabel#labelLockedBalanceText { - /* Available zPHR Label */ + /* Available zOHMC Label */ qproperty-alignment: 'AlignVCenter | AlignRight'; min-width: 160px; background-color: #00CD8D; @@ -1273,7 +1273,7 @@ QWidget .QFrame#frame_3 .QLabel#labelLockedBalanceText { /* min-height:35px; */ } QWidget .QFrame#frame_3 .QLabel#labelLockedBalance { - /* Available zPHR Balance */ + /* Available zOHMC Balance */ qproperty-alignment: 'AlignVCenter | AlignLeft'; font-size: 12px; font-weight: normal; @@ -1281,7 +1281,7 @@ QWidget .QFrame#frame_3 .QLabel#labelLockedBalance { margin-left: 0px; } QWidget .QFrame#frame_3 .QLabel#labelUnLockedBalanceText { - /* Available zPHR Label */ + /* Available zOHMC Label */ qproperty-alignment: 'AlignVCenter | AlignRight'; min-width: 160px; background-color: #00CD8D; @@ -1293,7 +1293,7 @@ QWidget .QFrame#frame_3 .QLabel#labelUnLockedBalanceText { /* min-height:35px; */ } QWidget .QFrame#frame_3 .QLabel#labelUnLockedBalance { - /* Available zPHR Balance */ + /* Available zOHMC Balance */ qproperty-alignment: 'AlignVCenter | AlignLeft'; font-size: 12px; font-weight: normal; @@ -2037,5 +2037,72 @@ QAbstractScrollArea::corner { } #addressBookButton_SM { - background:none; -} \ No newline at end of file + background:none; +} + + +/*Seed Words Generator*/ +QListView { + background-color: #132232; + border: 2px solid #132232; +} + +QListView::item { + color: white; + height: 36px; +} + +QGraphicsView { + background-color: #132232; + border: 2px solid #132232; +} + +QRadioButton { + height: 40px; + text-align: center; + font-size: 20px; + padding: 20px; + border-radius: 8px; +} +QRadioButton:focus { + background-color: #000; +} +QRadioButton::indicator { + display: none; + opacity: 0; + width: 0px; + height: 0px; +} +QRadioButton:checked { + background-color: transparent; + border: 2px solid #2388ed; +} +QRadioButton:unchecked { + background-color: transparent; + border-width: 2px; + border-color: #777; +} +QRadioButton::unchecked: hover { + background-color: #1f1f1f; +} + +QListWidget { + border-color: #132232; +} +QListWidget::item { + border-radius: 8px; + border: none; + color: #fff; +} +QListWidget::item:selected { + border: 2px solid #2388ed; + border-radius: 8px; + padding-left: 4px; + background: transparent; +} +QListWidget::item:focus { + border: 1px solid #1f1f1f; + background: #1f1f1f; ; + border-radius: 8px; + padding-left: 4px; +} diff --git a/src/qt/res/icons/hd_disabled.png b/src/qt/res/icons/hd_disabled.png new file mode 100644 index 0000000..687b6d2 Binary files /dev/null and b/src/qt/res/icons/hd_disabled.png differ diff --git a/src/qt/res/icons/hd_enabled.png b/src/qt/res/icons/hd_enabled.png new file mode 100644 index 0000000..568dde1 Binary files /dev/null and b/src/qt/res/icons/hd_enabled.png differ diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index c76402f..69fc586 100755 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -9,6 +9,7 @@ #include "bantablemodel.h" #include "clientmodel.h" +#include "walletmodel.h" #include "guiutil.h" #include "peertablemodel.h" @@ -17,6 +18,11 @@ #include "rpc/client.h" #include "rpc/server.h" #include "util.h" + +#include "init.h" +#include +#include "askpassphrasedialog.h" + #ifdef ENABLE_WALLET #include "wallet/wallet.h" #endif // ENABLE_WALLET @@ -257,6 +263,7 @@ void RPCExecutor::request(const QString& command) RPCConsole::RPCConsole(QWidget* parent) : QDialog(parent), ui(new Ui::RPCConsole), clientModel(0), + walletModel(0), historyPtr(0), cachedNodeid(-1), peersTableContextMenu(0), @@ -285,6 +292,7 @@ RPCConsole::RPCConsole(QWidget* parent) : QDialog(parent), connect(ui->btn_upgradewallet, SIGNAL(clicked()), this, SLOT(walletUpgrade())); connect(ui->btn_reindex, SIGNAL(clicked()), this, SLOT(walletReindex())); connect(ui->btn_resync, SIGNAL(clicked()), this, SLOT(walletResync())); + connect(ui->btn_convert_to_hd_Wallet, SIGNAL(clicked()), this, SLOT(walletUpgradeToHd())); // set library version labels ui->openSSLVersion->setText(SSLeay_version(SSLEAY_VERSION)); @@ -508,6 +516,11 @@ void RPCConsole::setClientModel(ClientModel* model) } } +void RPCConsole::setWalletModel(WalletModel* walletModel) +{ + this->walletModel = walletModel; +} + static QString categoryClass(int category) { switch (category) { @@ -582,6 +595,106 @@ void RPCConsole::walletResync() buildParameterlist(RESYNC); } +/** Restart wallet with "-resync" and upgrade to a HD wallet*/ +void RPCConsole::walletUpgradeToHd() +{ + QString upgradeWarning = tr("This will convert you non-HD wallet to a HD wallet

"); + upgradeWarning += tr("Make sure to make a backup of your wallet ahead of time

"); + upgradeWarning += tr("You shouldn't force close the wallet while this is running

"); + upgradeWarning += tr("Do you want to continue?.
"); + QMessageBox::StandardButton retval = QMessageBox::question(this, tr("Confirm upgrade to HD wallet"), + upgradeWarning, + QMessageBox::Yes | QMessageBox::Cancel, + QMessageBox::Cancel); + + if (retval != QMessageBox::Yes) { + // Resync canceled + return; + } + + if (IsInitialBlockDownload()) { + throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "Cannot set a new HD seed while still in Initial Block Download"); + } + + LOCK2(cs_main, pwalletMain->cs_wallet); + + // Do not do anything to HD wallets + if (pwalletMain->IsHDEnabled()) { + throw JSONRPCError(RPC_WALLET_ERROR, "Cannot upgrade a wallet to hd if It is already upgraded to hd."); + } + + std::vector words; + SecureString strWalletPass; + strWalletPass.reserve(100); + + int prev_version = pwalletMain->GetVersion(); + + int nMaxVersion = GetArg("-upgradewallet", 0); + if (nMaxVersion == 0) // the -upgradewallet without argument case + { + LogPrintf("Performing wallet upgrade to %i\n", FEATURE_LATEST); + nMaxVersion = CLIENT_VERSION; + pwalletMain->SetMinVersion(FEATURE_LATEST); // permanently upgrade the wallet immediately + } else + LogPrintf("Allowing wallet upgrade up to %i\n", nMaxVersion); + if (nMaxVersion < pwalletMain->GetVersion()) { + throw JSONRPCError(RPC_WALLET_ERROR, "Cannot downgrade wallet"); + } + + pwalletMain->SetMaxVersion(nMaxVersion); + + // Do not upgrade versions to any version between HD_SPLIT and FEATURE_PRE_SPLIT_KEYPOOL unless already supporting HD_SPLIT + int max_version = pwalletMain->GetVersion(); + if (!pwalletMain->CanSupportFeature(FEATURE_HD) && max_version >=FEATURE_HD && max_version < FEATURE_PRE_SPLIT_KEYPOOL) { + throw JSONRPCError(RPC_WALLET_ERROR, "Cannot upgrade a non HD split wallet without upgrading to support pre split keypool. Please use -upgradewallet=169900 or -upgradewallet with no version specified."); + } + + bool hd_upgrade = false; + bool split_upgrade = false; + if (pwalletMain->CanSupportFeature(FEATURE_HD) && !pwalletMain->IsHDEnabled()) { + LogPrintf("Upgrading wallet to HD\n"); + pwalletMain->SetMinVersion(FEATURE_HD); + + if (walletModel->getEncryptionStatus() == WalletModel::Locked || walletModel->getEncryptionStatus() == WalletModel::UnlockedForAnonymizationOnly) { + AskPassphraseDialog dlg(AskPassphraseDialog::Mode::Unlock, this, walletModel); + dlg.exec(); + strWalletPass = dlg.getPassword(); + } else { + strWalletPass = std::string().c_str(); + } + + StartOptionsMain dlg(nullptr); + dlg.exec(); + words = dlg.getWords(); + + pwalletMain->GenerateNewHDChain(words, strWalletPass); + + hd_upgrade = true; + } + + // Upgrade to HD chain split if necessary + if (pwalletMain->CanSupportFeature(FEATURE_HD)) { + LogPrintf("Upgrading wallet to use HD chain split\n"); + pwalletMain->SetMinVersion(FEATURE_PRE_SPLIT_KEYPOOL); + split_upgrade = FEATURE_HD > prev_version; + } + + // Mark all keys currently in the keypool as pre-split + if (split_upgrade) { + pwalletMain->MarkPreSplitKeys(); + } + + // Regenerate the keypool if upgraded to HD + if (hd_upgrade) { + if (!pwalletMain->TopUpKeyPool()) { + throw JSONRPCError(RPC_WALLET_ERROR, "Unable to generate keys\n"); + } + } + + buildParameterlist(RESCAN); + +} + /** Build command-line parameter list for restart */ void RPCConsole::buildParameterlist(QString arg) { @@ -628,12 +741,16 @@ void RPCConsole::clear() "td.message { font-family: Courier, Courier New, Lucida Console, monospace; font-size: 12px; } " // Todo: Remove fixed font-size "td.cmd-request { color: #006060; } " "td.cmd-error { color: red; } " + ".secwarning { color: red; }" "b { color: #006060; } "); message(CMD_REPLY, (tr("Welcome to the Ohmcoin RPC console.") + "
" + tr("Use up and down arrows to navigate history, and Ctrl-L to clear screen.") + "
" + - tr("Type help for an overview of available commands.")), - true); + tr("Type help for an overview of available commands.") + + "

" + + tr("WARNING: Scammers have been active, telling users to type commands here, stealing their wallet contents. Do not use this console without fully understanding the ramifications of a command.") + + "
"), + true); } void RPCConsole::reject() diff --git a/src/qt/rpcconsole.h b/src/qt/rpcconsole.h index 2073f08..1c9800a 100755 --- a/src/qt/rpcconsole.h +++ b/src/qt/rpcconsole.h @@ -14,6 +14,7 @@ #include class ClientModel; +class WalletModel; class RPCTimerInterface; namespace Ui @@ -36,6 +37,7 @@ class RPCConsole : public QDialog ~RPCConsole(); void setClientModel(ClientModel* model); + void setWalletModel(WalletModel* walletModel); enum MessageClass { MC_ERROR, @@ -80,6 +82,7 @@ public slots: void walletUpgrade(); void walletReindex(); void walletResync(); + void walletUpgradeToHd(); void reject(); void message(int category, const QString& message, bool html = false); @@ -146,6 +149,7 @@ public slots: Ui::RPCConsole* ui; ClientModel* clientModel; + WalletModel* walletModel; QStringList history; int historyPtr; NodeId cachedNodeid; diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index 492686f..48f308d 100755 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -18,7 +18,7 @@ #include "walletmodel.h" #include "base58.h" -#include "coincontrol.h" +#include "wallet/coincontrol.h" #include "ui_interface.h" #include "utilmoneystr.h" #include "wallet/wallet.h" @@ -323,7 +323,7 @@ void SendCoinsDialog::on_sendButton_clicked() // will call relock WalletModel::EncryptionStatus encStatus = model->getEncryptionStatus(); if (encStatus == model->Locked || encStatus == model->UnlockedForAnonymizationOnly) { - WalletModel::UnlockContext ctx(model->requestUnlock(AskPassphraseDialog::Context::Send_OHMC, true)); + WalletModel::UnlockContext ctx(model->requestUnlock(true)); if (!ctx.isValid()) { // Unlock wallet was cancelled fNewRecipientAllowed = true; @@ -641,7 +641,7 @@ void SendCoinsDialog::processSendCoinsReturn(const WalletModel::SendCoinsReturn& // Unlock wallet if it wasn't fully unlocked already if(fAskForUnlock) { - model->requestUnlock(AskPassphraseDialog::Context::Unlock_Full, false); + model->requestUnlock(false); if(model->getEncryptionStatus () != WalletModel::Unlocked) { msgParams.first = tr("Error: The wallet was unlocked only to anonymize coins. Unlock canceled."); } diff --git a/src/qt/signverifymessagedialog.cpp b/src/qt/signverifymessagedialog.cpp index f76f139..f1e5dbf 100755 --- a/src/qt/signverifymessagedialog.cpp +++ b/src/qt/signverifymessagedialog.cpp @@ -130,7 +130,7 @@ void SignVerifyMessageDialog::on_signMessageButton_SM_clicked() return; } - WalletModel::UnlockContext ctx(model->requestUnlock(AskPassphraseDialog::Context::Sign_Message, true)); + WalletModel::UnlockContext ctx(model->requestUnlock(true)); if (!ctx.isValid()) { ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }"); ui->statusLabel_SM->setText(tr("Wallet unlock was cancelled.")); diff --git a/src/qt/splashscreen.cpp b/src/qt/splashscreen.cpp index b86cc7f..29b5a5b 100755 --- a/src/qt/splashscreen.cpp +++ b/src/qt/splashscreen.cpp @@ -132,28 +132,28 @@ static void ShowProgress(Splash* splash, const std::string& title, int nProgress #ifdef ENABLE_WALLET static void ConnectWallet(Splash* splash, CWallet* wallet) { - wallet->ShowProgress.connect(boost::bind(ShowProgress, splash, boost::placeholders::_1, boost::placeholders::_2)); + wallet->ShowProgress.connect(boost::bind(ShowProgress, splash, boost::arg<1>(), boost::arg<2>())); } #endif void Splash::subscribeToCoreSignals() { // Connect signals to client - uiInterface.InitMessage.connect(boost::bind(InitMessage, this, boost::placeholders::_1)); - uiInterface.ShowProgress.connect(boost::bind(ShowProgress, this, boost::placeholders::_1, boost::placeholders::_2)); + uiInterface.InitMessage.connect(boost::bind(InitMessage, this, boost::arg<1>())); + uiInterface.ShowProgress.connect(boost::bind(ShowProgress, this, boost::arg<1>(), boost::arg<2>())); #ifdef ENABLE_WALLET - uiInterface.LoadWallet.connect(boost::bind(ConnectWallet, this, boost::placeholders::_1)); + uiInterface.LoadWallet.connect(boost::bind(ConnectWallet, this, boost::arg<1>())); #endif } void Splash::unsubscribeFromCoreSignals() { // Disconnect signals from client - uiInterface.InitMessage.disconnect(boost::bind(InitMessage, this, boost::placeholders::_1)); - uiInterface.ShowProgress.disconnect(boost::bind(ShowProgress, this, boost::placeholders::_1, boost::placeholders::_2)); + uiInterface.InitMessage.disconnect(boost::bind(InitMessage, this, boost::arg<1>())); + uiInterface.ShowProgress.disconnect(boost::bind(ShowProgress, this, boost::arg<1>(), boost::arg<2>())); #ifdef ENABLE_WALLET if (pwalletMain) - pwalletMain->ShowProgress.disconnect(boost::bind(ShowProgress, this, boost::placeholders::_1, boost::placeholders::_2)); + pwalletMain->ShowProgress.disconnect(boost::bind(ShowProgress, this, boost::arg<1>(), boost::arg<2>())); #endif } diff --git a/src/qt/startoptions.cpp b/src/qt/startoptions.cpp new file mode 100644 index 0000000..f1f7a05 --- /dev/null +++ b/src/qt/startoptions.cpp @@ -0,0 +1,27 @@ +// +// Created by Kolby on 6/19/2019. +// + + +#include +#include + + + + +StartOptions::StartOptions(QWidget *parent) + : QWidget(parent), ui(new Ui::StartOptions) + { + ui->setupUi(this); + + +} + +int StartOptions::getRows(){ + rows = 4; + return rows; +}; + +StartOptions::~StartOptions() { + delete ui; +} diff --git a/src/qt/startoptions.h b/src/qt/startoptions.h new file mode 100644 index 0000000..6e12442 --- /dev/null +++ b/src/qt/startoptions.h @@ -0,0 +1,28 @@ +// +// Created by Kolby on 6/19/2019. +// + + +#include + +namespace Ui { + class StartOptions; +} + +/** Dialog to ask for passphrases. Used for encryption only + */ +class StartOptions : public QWidget { + Q_OBJECT + +public: + explicit StartOptions(QWidget *parent = nullptr); + ~StartOptions(); + int getRows(); + + +private: + int rows; + Ui::StartOptions *ui; + + +}; diff --git a/src/qt/startoptionsdialog.cpp b/src/qt/startoptionsdialog.cpp new file mode 100644 index 0000000..e048a32 --- /dev/null +++ b/src/qt/startoptionsdialog.cpp @@ -0,0 +1,28 @@ +#if defined(HAVE_CONFIG_H) +#include +#endif + +#include +#include + + + + +#include +#include +#include + +StartOptionsDialog::StartOptionsDialog(const QString error_words, QWidget* parent) + : QDialog(parent), ui(new Ui::StartOptionsDialog) { + ui->setupUi(this); + + ui->ErrorLable->setText(error_words); +} + +StartOptionsDialog::~StartOptionsDialog() { + delete ui; +} + +void StartOptionsDialog::accept() { + close(); +} diff --git a/src/qt/startoptionsdialog.h b/src/qt/startoptionsdialog.h new file mode 100644 index 0000000..e8546a3 --- /dev/null +++ b/src/qt/startoptionsdialog.h @@ -0,0 +1,29 @@ +// Copyright (c) 2011-2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#pragma once + +#include + +class CWallet; + +namespace Ui { +class StartOptionsDialog; +} + +/** Dialog to ask for passphrases. Used for encryption only + */ +class StartOptionsDialog : public QDialog { + Q_OBJECT + +public: + explicit StartOptionsDialog(const QString error_words, QWidget *parent); + ~StartOptionsDialog(); + + void accept() override; + +private: + Ui::StartOptionsDialog *ui; +}; + diff --git a/src/qt/startoptionsmain.cpp b/src/qt/startoptionsmain.cpp new file mode 100644 index 0000000..620df53 --- /dev/null +++ b/src/qt/startoptionsmain.cpp @@ -0,0 +1,206 @@ +// +// Created by Kolby on 6/19/2019. +// +#include "startoptionsmain.h" +#include "ui_startoptionsmain.h" +#include + +#include +#include +#include +#include +#include "random.h" + +#include +#include "wallet/bip39.h" + +#include + +#include +#include +#include + +StartOptionsMain::StartOptionsMain(QWidget *parent) + : QDialog(parent), ui(new Ui::StartOptionsMain) + { + ui->setupUi(this); + this->setStyleSheet(GUIUtil::loadStyleSheet()); + + this->setWindowTitle("Phore Wallet Setup"); + + + wordsList = CMnemonic::getListOfAllWordInLanguage(); + + for(unsigned long i=0; i< wordsList.size() ; i++) { + qWordList.append(QString::fromStdString(wordsList[i])); + } + + this->setContentsMargins(0,0,0,0); + ui->QStackTutorialContainer->setContentsMargins(0,0,0,10); + ui->Back->setVisible(false); + ui->Next->setVisible(false); + startOptions = new StartOptions(this); + ui->QStackTutorialContainer->addWidget(startOptions); + ui->QStackTutorialContainer->setCurrentWidget(startOptions); + + +} + +StartOptionsMain::~StartOptionsMain() { + delete ui; +} + +void StartOptionsMain::on_NewWallet_clicked() +{ + pageNum = 2; + ui->NewWallet->setVisible(false); + ui->RestoreWallet->setVisible(false); + ui->Back->setVisible(true); + ui->Next->setVisible(true); + rows = startOptions->getRows(); + + if (rows == 4) { + words = CMnemonic::Generate(256); + } else { + words = CMnemonic::Generate(128); + } + + + + startOptionsRevealed = new StartOptionsRevealed(words, rows, this); + ui->QStackTutorialContainer->addWidget(startOptionsRevealed); + ui->QStackTutorialContainer->setCurrentWidget(startOptionsRevealed); +} + +void StartOptionsMain::on_RestoreWallet_clicked() +{ + pageNum = 4; + ui->NewWallet->setVisible(false); + ui->RestoreWallet->setVisible(false); + ui->Back->setVisible(true); + ui->Next->setVisible(true); + rows = startOptions->getRows(); + + startOptionsRestore = new StartOptionsRestore(qWordList, rows, this); + ui->QStackTutorialContainer->addWidget(startOptionsRestore); + ui->QStackTutorialContainer->setCurrentWidget(startOptionsRestore); +} + +void StartOptionsMain::on_Back_clicked() +{ + /* Pages + * Page 1 : Main page were you select the amount of words and the option + * Path 1 : Create wallet + * Page 2 : Shows you your words + * Page 3 : Order the words + * Path 2 : Restore wallet + * Page 4 Enter words to restore + */ + switch (pageNum){ + case 1:{ + // does nothing as you can not click back on page one + } + case 2:{ + pageNum = 1; + ui->NewWallet->setVisible(true); + ui->RestoreWallet->setVisible(true); + ui->Back->setVisible(false); + ui->Next->setVisible(false); + ui->QStackTutorialContainer->setCurrentWidget(startOptions); + break; + } + case 3:{ + pageNum = 2; + ui->QStackTutorialContainer->addWidget(startOptionsRevealed); + ui->QStackTutorialContainer->setCurrentWidget(startOptionsRevealed); + break; + } + case 4:{ + pageNum = 1; + ui->NewWallet->setVisible(true); + ui->RestoreWallet->setVisible(true); + ui->Back->setVisible(false); + ui->Next->setVisible(false); + ui->QStackTutorialContainer->setCurrentWidget(startOptions); + break; + } + } +} + +void StartOptionsMain::on_Next_clicked() +{ + /* Pages + * Page 1 : Main page were you select the amount of words and the option + * Path 1 : Create wallet + * Page 2 : Shows you your words + * Page 3 : Order the words + * Path 2 : Restore wallet + * Page 4 Enter words to restore + */ + switch (pageNum){ + case 1:{ + // does nothing as you can not click back on page one + } + + case 2:{ + pageNum = 3; + startOptionsSort = new StartOptionsSort(words, rows, this); + ui->QStackTutorialContainer->addWidget(startOptionsSort); + ui->QStackTutorialContainer->setCurrentWidget(startOptionsSort); + break; + } + case 3:{ + words_empty_str = ""; + std::list word_str = startOptionsSort->getOrderedStrings(); + // reverses the lists order + word_str.reverse(); + for (QString &q_word : word_str) { + if (words_empty_str.empty()) + words_empty_str = q_word.toStdString(); + else + words_empty_str += "" + q_word.toStdString(); + } + + words_mnemonic = ""; + for (std::string &q_word : words) { + if (words_mnemonic.empty()) + words_mnemonic = q_word; + else + words_mnemonic += "" + q_word; + } + boost::trim_right(words_empty_str); + boost::trim_right(words_mnemonic); + if(words_empty_str != words_mnemonic) { + QString error = "Your words are in the wrong order Please try again"; + StartOptionsDialog dlg(error, this); + dlg.exec(); + } else { + wordsDone = words; + QApplication::quit(); + } + break; + } + case 4:{ + std::vector word_str = startOptionsRestore->getOrderedStrings(); + + std::string seedphrase = ""; + for (std::string &q_word : word_str) { + if (seedphrase.empty()) + seedphrase = q_word; + else + seedphrase += " " + q_word; + } + // reverses the lists order + if(CMnemonic::Check(seedphrase)){ + wordsDone = word_str; + QApplication::quit(); + } else { + QString error = "Your words are invalid. This could be because, you are using non real words or that they may be misspelt"; + StartOptionsDialog dlg(error, this); + dlg.exec(); + } + + break; + } + } +} diff --git a/src/qt/startoptionsmain.h b/src/qt/startoptionsmain.h new file mode 100644 index 0000000..a3506cf --- /dev/null +++ b/src/qt/startoptionsmain.h @@ -0,0 +1,61 @@ +// +// Created by Kolby on 6/19/2019. +// + +#include +#include + +#include "startoptions.h" +#include +#include +#include + + +#include "wallet/bip39.h" + + +class WalletModel; + +namespace Ui { + class StartOptionsMain; +} + +/** Dialog to ask for passphrases. Used for encryption only + */ +class StartOptionsMain : public QDialog { + Q_OBJECT + +public: + explicit StartOptionsMain(QWidget *parent); + ~StartOptionsMain(); + + std::vector getWords() { return wordsDone; } + + +public slots: + void on_RestoreWallet_clicked(); + void on_Next_clicked(); + void on_Back_clicked(); + void on_NewWallet_clicked(); + +private: + Ui::StartOptionsMain *ui; + QWidget* parent; + int pageNum = 1; + int rows; + QStringList qWordList; + std::vector wordsList; + std::vector words; + std::vector wordsDone; + + StartOptions *startOptions; + StartOptionsRevealed *startOptionsRevealed; + StartOptionsSort *startOptionsSort; + StartOptionsRestore *startOptionsRestore; + std::string words_empty_str; + std::string words_mnemonic; + + +}; + + diff --git a/src/qt/startoptionsrestore.cpp b/src/qt/startoptionsrestore.cpp new file mode 100644 index 0000000..7c8e696 --- /dev/null +++ b/src/qt/startoptionsrestore.cpp @@ -0,0 +1,63 @@ +// +// Created by Kolby on 6/19/2019. +// + + +#include +#include +#include +#include + + + + +QString editLineCorrectCss = "QLineEdit{border-bottom:1px solid #00aeff;}"; +QString editLineInvalidCss = "QLineEdit{border-bottom:1px solid red;}"; + +StartOptionsRestore::StartOptionsRestore(QStringList _wordList, int rows, QWidget *parent) + : QWidget(parent), wordList(_wordList), ui(new Ui::StartOptionsRestore) +{ + ui->setupUi(this); + + for(int i=0; isetStyleSheet("QLabel{background-color:#e3e3e3;padding-left:8px;padding-right:8px;padding-top:2px;padding-bottom:2px;border-radius:4px;}"); + label->setMinimumSize(80,36); + label->setSizePolicy(QSizePolicy::Fixed,QSizePolicy::Fixed); + label->setContentsMargins(8,12,8,12); + label->setAlignment(Qt::AlignCenter); + editList.push_back(label); + connect(label, SIGNAL(textChanged(const QString &)), this, SLOT(textChanged(const QString &))); + ui->gridLayoutRevealed->addWidget(label, i, k, Qt::AlignCenter); + } + } + + +} + +void StartOptionsRestore::textChanged(const QString &text){ + + QObject *senderObj = sender(); + QLineEdit* label = static_cast(senderObj); + if(wordList.contains(text)){ + label->setStyleSheet(editLineCorrectCss); + }else{ + label->setStyleSheet(editLineInvalidCss); + } + +} + +std::vector StartOptionsRestore::getOrderedStrings(){ + std::vector list; + for(QLineEdit* label : editList){ + list.push_back(label->text().toStdString()); + } + return list; +} + +StartOptionsRestore::~StartOptionsRestore() { + delete ui; +} + diff --git a/src/qt/startoptionsrestore.h b/src/qt/startoptionsrestore.h new file mode 100644 index 0000000..fc1dcde --- /dev/null +++ b/src/qt/startoptionsrestore.h @@ -0,0 +1,34 @@ +// +// Created by Kolby on 6/19/2019. +// + +#include +#include +#include +#include + +namespace Ui { + class StartOptionsRestore; +} + +/** Dialog to ask for passphrases. Used for encryption only + */ +class StartOptionsRestore : public QWidget { + Q_OBJECT + +public: + explicit StartOptionsRestore(QStringList wordList, int rows, QWidget *parent = nullptr); + ~StartOptionsRestore(); + std::vector getOrderedStrings(); + +private Q_SLOTS: + void textChanged(const QString &text); + +private: + QStringList wordList; + + Ui::StartOptionsRestore *ui; + std::list editList; + + +}; diff --git a/src/qt/startoptionsrevealed.cpp b/src/qt/startoptionsrevealed.cpp new file mode 100644 index 0000000..aba0827 --- /dev/null +++ b/src/qt/startoptionsrevealed.cpp @@ -0,0 +1,44 @@ +// +// Created by Kolby on 6/19/2019. +// + + +#include +#include +#include + + + +StartOptionsRevealed::StartOptionsRevealed(std::vector& Words, int rows, QWidget *parent) + : QWidget(parent), ui(new Ui::StartOptionsRevealed) + { + ui->setupUi(this); + + for(int i=0; isetStyleSheet("QLabel{background-color:transparent;padding-left:8px;padding-right:8px;border-radius:0px;color:#bbb;border-bottom:2px solid rgb(35,136,237);}"); + label->setMinimumSize(80,36); + label->setSizePolicy(QSizePolicy::Fixed,QSizePolicy::Fixed); + label->setContentsMargins(8,12,8,12); + label->setAlignment(Qt::AlignCenter); + labelsList.push_back(label); + ui->gridLayoutRevealed->addWidget(label, i, k, Qt::AlignCenter); + } + } + int i = 0; + for (QLabel* label : labelsList) { + label->setStyleSheet("QLabel{background-color:transparent;padding-left:8px;padding-right:8px;border-radius:0px;color:#bbb;border-bottom:2px solid rgb(35,136,237);}"); + label->setContentsMargins(8,12,8,12); + label->setText(QString::fromStdString(Words[i])); + i++; + } + + +} + +StartOptionsRevealed::~StartOptionsRevealed() { + delete ui; +} + diff --git a/src/qt/startoptionsrevealed.h b/src/qt/startoptionsrevealed.h new file mode 100644 index 0000000..2dbfeec --- /dev/null +++ b/src/qt/startoptionsrevealed.h @@ -0,0 +1,27 @@ +// +// Created by Kolby on 6/19/2019. +// + +#include +#include +#include "wallet/bip39.h" + +namespace Ui { + class StartOptionsRevealed; +} + +/** Dialog to ask for passphrases. Used for encryption only + */ +class StartOptionsRevealed : public QWidget { + Q_OBJECT + +public: + explicit StartOptionsRevealed(std::vector& Words, int rows, QWidget *parent = nullptr); + ~StartOptionsRevealed(); + + +private: + Ui::StartOptionsRevealed *ui; + std::list labelsList; + +}; diff --git a/src/qt/startoptionssort.cpp b/src/qt/startoptionssort.cpp new file mode 100644 index 0000000..5191d9a --- /dev/null +++ b/src/qt/startoptionssort.cpp @@ -0,0 +1,205 @@ +// +// Created by Kolby on 6/19/2019. +// + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +CustomRectItem::CustomRectItem(QGraphicsItem *parent): + QGraphicsRectItem(parent) +{ + setAcceptDrops(true); + setFlags(QGraphicsItem::ItemIsSelectable); +} + +void StartOptionsSort::keyPressEvent(QKeyEvent *event){ + Q_FOREACH(QGraphicsItem *item, scene->selectedItems()) + if(event->key() == Qt::Key_Backspace){ + + if(CustomRectItem *rItem = qgraphicsitem_cast (item)){ + for (auto const& i : labelsList) + { + if (i->count() < 4) { + i->addItem(rItem->text()); + rItem->setText(QString()); + break; + } + } + } + scene->clearSelection(); + } + QWidget::keyPressEvent(event); +} + +void CustomRectItem::setText(const QString &text){ + this->m_text = text; + update(); +} + +void CustomRectItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, + QWidget *widget){ + QGraphicsRectItem::paint(painter, option, widget); + painter->drawText(boundingRect(),m_text, + QTextOption(Qt::AlignCenter)); +} + +void CustomRectItem::dropEvent(QGraphicsSceneDragDropEvent *event){ + if (event->mimeData()->hasFormat("application/x-qabstractitemmodeldatalist")){ + QByteArray itemData = event->mimeData()->data( + "application/x-qabstractitemmodeldatalist"); + QDataStream stream(&itemData, QIODevice::ReadOnly); + int row, col; + QMap valueMap; + stream >> row >> col >> valueMap; + QString origText = m_text; + if(!valueMap.isEmpty()) + setText(valueMap.value(0).toString()); + + event->setDropAction(Qt::MoveAction); + event->accept(); + + if(!origText.isEmpty()){ + if(QListWidget* lWidget = qobject_cast (event->source())) + lWidget->addItem(origText); + } + } + else + event->ignore(); +} + +StartOptionsSort::StartOptionsSort(std::vector Words, int rows, QWidget *parent) + : QWidget(parent), ui(new Ui::StartOptionsSort) { + ui->setupUi(this); + ui->dragdropLabel->setText( + tr("Please drag and drop your seed words into the " + "correct order to confirm your recovery phrase. ")); + ui->dragdropLabel2->setText( + tr("To remove words click the word then hit backspace.")); + scene = new QGraphicsScene(this); + if(rows == 4) { + scene->setSceneRect(0,0,620,229); + view = new QGraphicsView; + view->setScene(scene); + view->setMinimumSize(QSize(1,230)); + } else { + scene->setSceneRect(0,0,620,154); + view = new QGraphicsView; + view->setScene(scene); + view->setMinimumSize(QSize(1,155)); + } + + view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + + QRectF rect(0,0,90,70); + QRectF rect2(0,0,90,2); + + for(int i=0; iaddItem(listView); + listView->setRect(rect); + + CustomRectItem *listViewBorder = new CustomRectItem; + scene->addItem(listViewBorder); + listViewBorder->setRect(rect2); + listViewBorder->setBrush(QColor(35,136,237)); + listViewBorder->setPos(ki,ii + 50); + listViewBorder->setPen(Qt::NoPen); + + listView->setPos(ki,ii); + QPen myPen(QColor(255,255,255), 2, Qt::MPenStyle); + listView->setPen(myPen); + + graphicsList.push_back(listView); + graphicsList.push_back(listViewBorder); + + } + } + ui->gridLayoutRevealed->addWidget(view, 0, 0, 1, 6, Qt::AlignCenter); + + // Randomizes the word list + std::vector randomWords = Words; + unsigned seed = std::chrono::system_clock::now().time_since_epoch().count(); + shuffle (randomWords.begin(), randomWords.end(), std::default_random_engine(seed)); + + for(int k=0; k<6; k++){ + + QListWidget* itemListWidget = new QListWidget; + QStringList itemList; + if(rows == 4){ + if(k<0){ + itemList.append(QString::fromStdString(randomWords[k])); + itemList.append(QString::fromStdString(randomWords[k + 1])); + itemList.append(QString::fromStdString(randomWords[k + 2])); + itemList.append(QString::fromStdString(randomWords[k + 3])); + } else if(k<6) { + itemList.append(QString::fromStdString(randomWords[k * 4])); + itemList.append(QString::fromStdString(randomWords[k * 4 + 1])); + itemList.append(QString::fromStdString(randomWords[k * 4 + 2])); + itemList.append(QString::fromStdString(randomWords[k * 4 + 3])); + } + } else { + if(k<0){ + itemList.append(QString::fromStdString(randomWords[k])); + itemList.append(QString::fromStdString(randomWords[k + 1])); + } else if(k<6) { + itemList.append(QString::fromStdString(randomWords[k * 2])); + itemList.append(QString::fromStdString(randomWords[k * 2 + 1])); + } + } + itemListWidget->addItems(itemList); + itemListWidget->setFixedWidth(80); + if(rows == 4){ + itemListWidget->setMinimumSize(QSize(80,180)); + itemListWidget->setMaximumSize(QSize(80,180)); + } else { + itemListWidget->setMaximumSize(QSize(80,140)); + } + itemListWidget->setDragEnabled(true); + itemListWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + labelsList.push_back(itemListWidget); + ui->gridLayoutRevealed->addWidget(itemListWidget, 2, k, Qt::AlignCenter); + } + + + setAcceptDrops(true); + setWindowTitle(tr("Draggable Text")); + +} + +std::list StartOptionsSort::getOrderedStrings(){ + std::list list; + for(QGraphicsItem *item : scene->items()) + if(CustomRectItem *rItem = qgraphicsitem_cast (item)) { + list.push_back(rItem->text()); + } + return list; +} + +StartOptionsSort::~StartOptionsSort() { + delete ui; +} diff --git a/src/qt/startoptionssort.h b/src/qt/startoptionssort.h new file mode 100644 index 0000000..b22d179 --- /dev/null +++ b/src/qt/startoptionssort.h @@ -0,0 +1,57 @@ +// +// Created by Kolby on 6/19/2019. +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class QDragEnterEvent; +class QDropEvent; + +namespace Ui { + class StartOptionsSort; +} + +/** Dialog to ask for passphrases. Used for encryption only + */ +class StartOptionsSort : public QWidget { + Q_OBJECT + +public: + explicit StartOptionsSort(std::vector Words, int rows, QWidget *parent = nullptr); + ~StartOptionsSort(); + std::list getOrderedStrings(); + + void keyPressEvent(QKeyEvent *); + +private: + Ui::StartOptionsSort *ui; + std::list labelsList; + std::list graphicsList; + QString m_text; + QGraphicsView* view; + QGraphicsScene* scene; + +}; + +class CustomRectItem : public QGraphicsRectItem +{ +public: + CustomRectItem(QGraphicsItem * parent = 0); + void dropEvent(QGraphicsSceneDragDropEvent *event); + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + void setText(const QString& text); + QString text() const {return m_text;} +private: + QString m_text; +}; \ No newline at end of file diff --git a/src/qt/test/paymentservertests.h b/src/qt/test/paymentservertests.h index 0717111..7e94d88 100755 --- a/src/qt/test/paymentservertests.h +++ b/src/qt/test/paymentservertests.h @@ -5,7 +5,7 @@ #ifndef BITCOIN_QT_TEST_PAYMENTSERVERTESTS_H #define BITCOIN_QT_TEST_PAYMENTSERVERTESTS_H -#include "../paymentserver.h" +#include "paymentserver.h" #include #include diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp index 1863f37..112e713 100755 --- a/src/qt/transactiondesc.cpp +++ b/src/qt/transactiondesc.cpp @@ -12,7 +12,7 @@ #include "transactionrecord.h" #include "base58.h" -#include "db.h" +#include "wallet/db.h" #include "main.h" #include "script/script.h" #include "timedata.h" diff --git a/src/qt/transactionrecord.cpp b/src/qt/transactionrecord.cpp index 48ca219..e62acc8 100755 --- a/src/qt/transactionrecord.cpp +++ b/src/qt/transactionrecord.cpp @@ -76,7 +76,7 @@ QList TransactionRecord::decomposeTransaction(const CWallet* //zerocoin spend outputs bool fFeeAssigned = false; - for (const CTxOut txout : wtx.vout) { + for (const CTxOut& txout : wtx.vout) { // change that was reminted as zerocoins if (txout.IsZerocoinMint()) { // do not display record if this isn't from our wallet diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp index 813b736..3068b27 100755 --- a/src/qt/transactiontablemodel.cpp +++ b/src/qt/transactiontablemodel.cpp @@ -819,13 +819,13 @@ static void ShowProgress(TransactionTableModel* ttm, const std::string& title, i void TransactionTableModel::subscribeToCoreSignals() { // Connect signals to wallet - wallet->NotifyTransactionChanged.connect(boost::bind(NotifyTransactionChanged, this, boost::placeholders::_1, boost::placeholders::_2, boost::placeholders::_3)); - wallet->ShowProgress.connect(boost::bind(ShowProgress, this, boost::placeholders::_1, boost::placeholders::_2)); + wallet->NotifyTransactionChanged.connect(boost::bind(NotifyTransactionChanged, this, boost::arg<1>(), boost::arg<2>(), boost::arg<3>())); + wallet->ShowProgress.connect(boost::bind(ShowProgress, this, boost::arg<1>(), boost::arg<2>())); } void TransactionTableModel::unsubscribeFromCoreSignals() { // Disconnect signals from wallet - wallet->NotifyTransactionChanged.disconnect(boost::bind(NotifyTransactionChanged, this, boost::placeholders::_1, boost::placeholders::_2, boost::placeholders::_3)); - wallet->ShowProgress.disconnect(boost::bind(ShowProgress, this, boost::placeholders::_1, boost::placeholders::_2)); + wallet->NotifyTransactionChanged.disconnect(boost::bind(NotifyTransactionChanged, this, boost::arg<1>(), boost::arg<2>(), boost::arg<3>())); + wallet->ShowProgress.disconnect(boost::bind(ShowProgress, this, boost::arg<1>(), boost::arg<2>())); } diff --git a/src/qt/walletframe.cpp b/src/qt/walletframe.cpp index 202aab8..f4f7bcd 100755 --- a/src/qt/walletframe.cpp +++ b/src/qt/walletframe.cpp @@ -3,6 +3,7 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "walletframe.h" +#include "rpcconsole.h" #include "bitcoingui.h" #include "walletview.h" @@ -218,21 +219,11 @@ void WalletFrame::changePassphrase() walletView->changePassphrase(); } -void WalletFrame::unlockWallet(bool setContext) -{ - if (setContext) { - unlockWallet(AskPassphraseDialog::Context::Unlock_Full); - } - else { - unlockWallet(AskPassphraseDialog::Context::Unlock_Menu); - } -} - -void WalletFrame::unlockWallet(AskPassphraseDialog::Context context) +void WalletFrame::unlockWallet() { WalletView* walletView = currentWalletView(); if (walletView) - walletView->unlockWallet(context); + walletView->unlockWallet(); } void WalletFrame::lockWallet() diff --git a/src/qt/walletframe.h b/src/qt/walletframe.h index 71b8838..137d200 100755 --- a/src/qt/walletframe.h +++ b/src/qt/walletframe.h @@ -90,8 +90,7 @@ public slots: /** Change encrypted wallet passphrase */ void changePassphrase(); /** Ask for passphrase to unlock wallet temporarily */ - void unlockWallet(AskPassphraseDialog::Context context); - void unlockWallet(bool setContext); + void unlockWallet(); /** Lock wallet */ void lockWallet(); /** Toggle Wallet Lock State */ diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index 8b048d7..ac29d72 100755 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -12,7 +12,7 @@ #include "transactiontablemodel.h" #include "base58.h" -#include "db.h" +#include "wallet/db.h" #include "keystore.h" #include "main.h" #include "spork.h" @@ -598,31 +598,31 @@ static void NotifyWalletBacked(WalletModel* model, const bool& fSuccess, const s void WalletModel::subscribeToCoreSignals() { // Connect signals to wallet - wallet->NotifyStatusChanged.connect(boost::bind(&NotifyKeyStoreStatusChanged, this, boost::placeholders::_1)); - wallet->NotifyAddressBookChanged.connect(boost::bind(NotifyAddressBookChanged, this, boost::placeholders::_1, boost::placeholders::_2, boost::placeholders::_3, boost::placeholders::_4, boost::placeholders::_5, boost::placeholders::_6)); - wallet->NotifyTransactionChanged.connect(boost::bind(NotifyTransactionChanged, this, boost::placeholders::_1, boost::placeholders::_2, boost::placeholders::_3)); - wallet->ShowProgress.connect(boost::bind(ShowProgress, this, boost::placeholders::_1, boost::placeholders::_2)); - wallet->NotifyWatchonlyChanged.connect(boost::bind(NotifyWatchonlyChanged, this, boost::placeholders::_1)); - wallet->NotifyMultiSigChanged.connect(boost::bind(NotifyMultiSigChanged, this, boost::placeholders::_1)); - wallet->NotifyZerocoinChanged.connect(boost::bind(NotifyZerocoinChanged, this, boost::placeholders::_1, boost::placeholders::_2, boost::placeholders::_3, boost::placeholders::_4)); - wallet->NotifyWalletBacked.connect(boost::bind(NotifyWalletBacked, this, boost::placeholders::_1, boost::placeholders::_2)); + wallet->NotifyStatusChanged.connect(boost::bind(&NotifyKeyStoreStatusChanged, this, boost::arg<1>())); + wallet->NotifyAddressBookChanged.connect(boost::bind(NotifyAddressBookChanged, this, boost::arg<1>(), boost::arg<2>(), boost::arg<3>(), boost::arg<4>(), boost::arg<5>(), boost::arg<6>())); + wallet->NotifyTransactionChanged.connect(boost::bind(NotifyTransactionChanged, this, boost::arg<1>(), boost::arg<2>(), boost::arg<3>())); + wallet->ShowProgress.connect(boost::bind(ShowProgress, this, boost::arg<1>(), boost::arg<2>())); + wallet->NotifyWatchonlyChanged.connect(boost::bind(NotifyWatchonlyChanged, this, boost::arg<1>())); + wallet->NotifyMultiSigChanged.connect(boost::bind(NotifyMultiSigChanged, this, boost::arg<1>())); + wallet->NotifyZerocoinChanged.connect(boost::bind(NotifyZerocoinChanged, this, boost::arg<1>(), boost::arg<2>(), boost::arg<3>(), boost::arg<4>())); + wallet->NotifyWalletBacked.connect(boost::bind(NotifyWalletBacked, this, boost::arg<1>(), boost::arg<2>())); } void WalletModel::unsubscribeFromCoreSignals() { // Disconnect signals from wallet - wallet->NotifyStatusChanged.disconnect(boost::bind(&NotifyKeyStoreStatusChanged, this, boost::placeholders::_1)); - wallet->NotifyAddressBookChanged.disconnect(boost::bind(NotifyAddressBookChanged, this, boost::placeholders::_1, boost::placeholders::_2, boost::placeholders::_3, boost::placeholders::_4, boost::placeholders::_5, boost::placeholders::_6)); - wallet->NotifyTransactionChanged.disconnect(boost::bind(NotifyTransactionChanged, this, boost::placeholders::_1, boost::placeholders::_2, boost::placeholders::_3)); - wallet->ShowProgress.disconnect(boost::bind(ShowProgress, this, boost::placeholders::_1, boost::placeholders::_2)); - wallet->NotifyWatchonlyChanged.disconnect(boost::bind(NotifyWatchonlyChanged, this, boost::placeholders::_1)); - wallet->NotifyMultiSigChanged.disconnect(boost::bind(NotifyMultiSigChanged, this, boost::placeholders::_1)); - wallet->NotifyZerocoinChanged.disconnect(boost::bind(NotifyZerocoinChanged, this, boost::placeholders::_1, boost::placeholders::_2, boost::placeholders::_3, boost::placeholders::_4)); - wallet->NotifyWalletBacked.disconnect(boost::bind(NotifyWalletBacked, this, boost::placeholders::_1, boost::placeholders::_2)); + wallet->NotifyStatusChanged.disconnect(boost::bind(&NotifyKeyStoreStatusChanged, this, boost::arg<1>())); + wallet->NotifyAddressBookChanged.disconnect(boost::bind(NotifyAddressBookChanged, this, boost::arg<1>(), boost::arg<2>(), boost::arg<3>(), boost::arg<4>(), boost::arg<5>(), boost::arg<6>())); + wallet->NotifyTransactionChanged.disconnect(boost::bind(NotifyTransactionChanged, this, boost::arg<1>(), boost::arg<2>(), boost::arg<3>())); + wallet->ShowProgress.disconnect(boost::bind(ShowProgress, this, boost::arg<1>(), boost::arg<2>())); + wallet->NotifyWatchonlyChanged.disconnect(boost::bind(NotifyWatchonlyChanged, this, boost::arg<1>())); + wallet->NotifyMultiSigChanged.disconnect(boost::bind(NotifyMultiSigChanged, this, boost::arg<1>())); + wallet->NotifyZerocoinChanged.disconnect(boost::bind(NotifyZerocoinChanged, this, boost::arg<1>(), boost::arg<2>(), boost::arg<3>(), boost::arg<4>())); + wallet->NotifyWalletBacked.disconnect(boost::bind(NotifyWalletBacked, this, boost::arg<1>(), boost::arg<2>())); } // WalletModel::UnlockContext implementation -WalletModel::UnlockContext WalletModel::requestUnlock(AskPassphraseDialog::Context context, bool relock) +WalletModel::UnlockContext WalletModel::requestUnlock(bool relock) { bool was_locked = getEncryptionStatus() == Locked; @@ -634,7 +634,7 @@ WalletModel::UnlockContext WalletModel::requestUnlock(AskPassphraseDialog::Conte if (was_locked) { // Request UI to unlock wallet - emit requireUnlock(context); + emit requireUnlock(); } // If wallet is still locked, unlock was failed or cancelled, mark context as invalid bool valid = getEncryptionStatus() != Locked; @@ -782,6 +782,11 @@ bool WalletModel::isMine(CTxDestination address) return IsMine(*wallet, address); } +bool WalletModel::hdEnabled() const +{ + return wallet->IsHDEnabled(); +} + OutputType WalletModel::getDefaultAddressType() const { return g_address_type; diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h index b527e83..e2c53ea 100755 --- a/src/qt/walletmodel.h +++ b/src/qt/walletmodel.h @@ -198,7 +198,7 @@ class WalletModel : public QObject void CopyFrom(const UnlockContext& rhs); }; - UnlockContext requestUnlock(AskPassphraseDialog::Context context, bool relock = false); + UnlockContext requestUnlock(bool relock = false); bool getPubKey(const CKeyID& address, CPubKey& vchPubKeyOut) const; bool isMine(CTxDestination address); @@ -216,7 +216,7 @@ class WalletModel : public QObject string GetUniqueWalletBackupName(); void loadReceiveRequests(std::vector& vReceiveRequests); bool saveReceiveRequest(const std::string& sAddress, const int64_t nId, const std::string& sRequest); - + bool hdEnabled() const; OutputType getDefaultAddressType() const; private: @@ -266,7 +266,7 @@ class WalletModel : public QObject // Signal emitted when wallet needs to be unlocked // It is valid behaviour for listeners to keep the wallet locked after this signal; // this means that the unlocking failed or was cancelled. - void requireUnlock(AskPassphraseDialog::Context context); + void requireUnlock(); // Fired when a message should be reported to the user void message(const QString& title, const QString& message, unsigned int style); diff --git a/src/qt/walletview.cpp b/src/qt/walletview.cpp index 7903ee4..dcccf01 100755 --- a/src/qt/walletview.cpp +++ b/src/qt/walletview.cpp @@ -119,9 +119,11 @@ WalletView::WalletView(QWidget* parent) : QStackedWidget(parent), privacyPage = new PrivacyDialog(); receiveCoinsPage = new ReceiveCoinsDialog(); sendCoinsPage = new SendCoinsDialog(); + proposalList = new ProposalList(this); addWidget(overviewPage); addWidget(transactionsPage); + addWidget(proposalList); addWidget(privacyPage); addWidget(receiveCoinsPage); addWidget(sendCoinsPage); @@ -133,13 +135,6 @@ WalletView::WalletView(QWidget* parent) : QStackedWidget(parent), addWidget(karmanodeListPage); } - QVBoxLayout* vbox_2 = new QVBoxLayout(); - proposalList = new ProposalList(this); - vbox_2->addWidget(proposalList); - vbox_2->setStretch(1, 1); - proposalListPage = new QWidget(this); - proposalListPage->setLayout(vbox_2); - addWidget(proposalListPage); // Clicking on a transaction on the overview pre-selects the transaction on the transaction history page connect(overviewPage, SIGNAL(transactionClicked(QModelIndex)), transactionView, SLOT(focusTransaction(QModelIndex))); @@ -178,6 +173,9 @@ void WalletView::setBitcoinGUI(BitcoinGUI* gui) // Pass through transaction notifications connect(this, SIGNAL(incomingTransaction(QString, int, CAmount, QString, QString)), gui, SLOT(incomingTransaction(QString, int, CAmount, QString, QString))); + + // Connect HD enabled state signal + connect(this, SIGNAL(hdEnabledStatusChanged(int)), gui, SLOT(setHDStatus(int))); } } @@ -198,6 +196,7 @@ void WalletView::setWalletModel(WalletModel* walletModel) this->walletModel = walletModel; // Put transaction list in tabs + proposalList->setModel(walletModel); transactionView->setModel(walletModel); overviewPage->setWalletModel(walletModel); QSettings settings; @@ -216,12 +215,15 @@ void WalletView::setWalletModel(WalletModel* walletModel) connect(walletModel, SIGNAL(encryptionStatusChanged(int)), this, SIGNAL(encryptionStatusChanged(int))); updateEncryptionStatus(); + // update HD status + Q_EMIT hdEnabledStatusChanged(walletModel->hdEnabled()); + // Balloon pop-up for new transaction connect(walletModel->getTransactionTableModel(), SIGNAL(rowsInserted(QModelIndex, int, int)), this, SLOT(processNewTransaction(QModelIndex, int, int))); // Ask for passphrase if needed - connect(walletModel, SIGNAL(requireUnlock(AskPassphraseDialog::Context)), this, SLOT(unlockWallet(AskPassphraseDialog::Context))); + connect(walletModel, SIGNAL(requireUnlock()), this, SLOT(unlockWallet())); // Show progress dialog connect(walletModel, SIGNAL(showProgress(QString, int)), this, SLOT(showProgress(QString, int))); @@ -286,7 +288,7 @@ void WalletView::gotoPrivacyPage() void WalletView::gotoProposalPage() { - setCurrentWidget(proposalListPage); + setCurrentWidget(proposalList); } @@ -365,7 +367,7 @@ void WalletView::encryptWallet(bool status) if (!walletModel) return; AskPassphraseDialog dlg(status ? AskPassphraseDialog::Mode::Encrypt : AskPassphraseDialog::Mode::Decrypt, this, - walletModel, AskPassphraseDialog::Context::Encrypt); + walletModel); dlg.exec(); updateEncryptionStatus(); @@ -391,18 +393,18 @@ void WalletView::backupWallet() void WalletView::changePassphrase() { - AskPassphraseDialog dlg(AskPassphraseDialog::Mode::ChangePass, this, walletModel, AskPassphraseDialog::Context::ChangePass); + AskPassphraseDialog dlg(AskPassphraseDialog::Mode::ChangePass, this, walletModel); dlg.exec(); } -void WalletView::unlockWallet(AskPassphraseDialog::Context context) +void WalletView::unlockWallet() { if (!walletModel) return; // Unlock wallet when requested by wallet model if (walletModel->getEncryptionStatus() == WalletModel::Locked || walletModel->getEncryptionStatus() == WalletModel::UnlockedForAnonymizationOnly) { - AskPassphraseDialog dlg(AskPassphraseDialog::Mode::UnlockAnonymize, this, walletModel, context); + AskPassphraseDialog dlg(AskPassphraseDialog::Mode::UnlockAnonymize, this, walletModel); dlg.exec(); } } @@ -424,7 +426,7 @@ void WalletView::toggleLockWallet() // Unlock the wallet when requested if (encStatus == walletModel->Locked) { - AskPassphraseDialog dlg(AskPassphraseDialog::Mode::UnlockAnonymize, this, walletModel, AskPassphraseDialog::Context::ToggleLock); + AskPassphraseDialog dlg(AskPassphraseDialog::Mode::UnlockAnonymize, this, walletModel); dlg.exec(); } diff --git a/src/qt/walletview.h b/src/qt/walletview.h index dbcc82a..273d819 100755 --- a/src/qt/walletview.h +++ b/src/qt/walletview.h @@ -70,10 +70,9 @@ class WalletView : public QStackedWidget SendCoinsDialog* sendCoinsPage; BlockExplorer* explorerWindow; KarmanodeList* karmanodeListPage; - QWidget* proposalListPage; TransactionView* transactionView; - ProposalList* proposalList; + ProposalList *proposalList; QProgressDialog* progressDialog; QLabel* transactionSum; @@ -118,7 +117,7 @@ public slots: /** Change encrypted wallet passphrase */ void changePassphrase(); /** Ask for passphrase to unlock wallet temporarily */ - void unlockWallet(AskPassphraseDialog::Context context); + void unlockWallet(); /** Lock wallet */ void lockWallet(); /** Toggle wallet lock state */ @@ -145,6 +144,8 @@ public slots: void message(const QString& title, const QString& message, unsigned int style); /** Encryption status of wallet changed */ void encryptionStatusChanged(int status); + /** HD-Enabled status of wallet changed (only possible during startup) */ + void hdEnabledStatusChanged(int hdEnabled); /** Notify that a new transaction appeared */ void incomingTransaction(const QString& date, int unit, const CAmount& amount, const QString& type, const QString& address); }; diff --git a/src/random.cpp b/src/random.cpp index 65fa41f..6f4f415 100755 --- a/src/random.cpp +++ b/src/random.cpp @@ -6,6 +6,7 @@ #include "random.h" #include "crypto/sha512.h" +#include "support/cleanse.h" #ifdef WIN32 #include "compat.h" // for Windows API #include @@ -20,7 +21,6 @@ #include #endif -#include #include #include @@ -42,7 +42,7 @@ void RandAddSeed() // Seed with CPU performance counter int64_t nCounter = GetPerformanceCounter(); RAND_add(&nCounter, sizeof(nCounter), 1.5); - OPENSSL_cleanse((void*)&nCounter, sizeof(nCounter)); + memory_cleanse((void*)&nCounter, sizeof(nCounter)); } static void RandAddSeedPerfmon() @@ -72,7 +72,7 @@ static void RandAddSeedPerfmon() RegCloseKey(HKEY_PERFORMANCE_DATA); if (ret == ERROR_SUCCESS) { RAND_add(begin_ptr(vData), nSize, nSize / 100.0); - OPENSSL_cleanse(begin_ptr(vData), nSize); + memory_cleanse(begin_ptr(vData), nSize); LogPrint("rand", "%s: %lu bytes\n", __func__, nSize); } else { static bool warned = false; // Warn only once @@ -133,7 +133,7 @@ void GetStrongRandBytes(unsigned char* out, int num) // Produce output hasher.Finalize(buf); memcpy(out, buf, num); - OPENSSL_cleanse((void*)&buf, sizeof(buf)); + memory_cleanse((void*)&buf, sizeof(buf)); } uint64_t GetRand(uint64_t nMax) diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 2cc9c3e..88a328a 100755 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -742,16 +742,30 @@ UniValue getchaintips(const UniValue& params, bool fHelp) 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. */ + /* + * Idea: the set of chain tips is ::ChainActive().tip, plus orphan blocks which do not have another orphan building off of them. + * Algorithm: + * - Make one pass through g_blockman.m_block_index, picking out the orphan blocks, and also storing a set of the orphan block's pprev pointers. + * - Iterate through the orphan blocks. If the block isn't pointed to by another orphan, it is a chain tip. + * - add ::ChainActive().Tip() + */ std::set setTips; - for (const std::pair & item : mapBlockIndex) - setTips.insert(item.second); - for (const std::pair & item : mapBlockIndex) { - const CBlockIndex* pprev = item.second->pprev; - if (pprev) - setTips.erase(pprev); + std::set setOrphans; + std::set setPrevs; + + for (const std::pair& item : mapBlockIndex) + { + if (!chainActive.Contains(item.second)) { + setOrphans.insert(item.second); + setPrevs.insert(item.second->pprev); + } + } + + for (std::set::iterator it = setOrphans.begin(); it != setOrphans.end(); ++it) + { + if (setPrevs.erase(*it) == 0) { + setTips.insert(*it); + } } // Always report the currently active tip. diff --git a/src/rpc/budget.cpp b/src/rpc/budget.cpp index 274e563..7b12d53 100755 --- a/src/rpc/budget.cpp +++ b/src/rpc/budget.cpp @@ -2,7 +2,7 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "activekarmanode.h" -#include "db.h" +#include "wallet/db.h" #include "init.h" #include "main.h" #include "karmanode-budget.h" @@ -12,6 +12,10 @@ #include "rpc/server.h" #include "utilmoneystr.h" +#ifdef ENABLE_WALLET +#include "wallet/wallet.h" +#endif + #include #include diff --git a/src/rpc/karmanode.cpp b/src/rpc/karmanode.cpp index c9bb4af..9d51369 100755 --- a/src/rpc/karmanode.cpp +++ b/src/rpc/karmanode.cpp @@ -4,7 +4,7 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "activekarmanode.h" -#include "db.h" +#include "wallet/db.h" #include "init.h" #include "main.h" #include "karmanode-budget.h" @@ -14,6 +14,10 @@ #include "rpc/server.h" #include "utilmoneystr.h" +#ifdef ENABLE_WALLET +#include "wallet/wallet.h" +#endif + #include #include diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index 4eae15e..cd0c07d 100755 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -141,6 +141,9 @@ UniValue setgenerate(const UniValue& params, bool fHelp) if (params.size() > 0) fGenerate = params[0].get_bool(); + if (fGenerate && (chainActive.Height() >= Params().LAST_POW_BLOCK())) + throw JSONRPCError(RPC_INVALID_REQUEST, "Proof of Work phase has already ended"); + int nGenProcLimit = -1; if (params.size() > 1) { nGenProcLimit = params[1].get_int(); @@ -166,7 +169,7 @@ UniValue setgenerate(const UniValue& params, bool fHelp) UniValue blockHashes(UniValue::VARR); while (nHeight < nHeightEnd) { CPubKey pubkey; - if (!reservekey.GetReservedKey(pubkey)) + if (!reservekey.GetReservedKey(pubkey, false)) throw JSONRPCError(RPC_INTERNAL_ERROR, "Wallet keypool empty"); CScript scriptPubKey = CScript() << ToByteVector(pubkey) << OP_CHECKSIG; diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 2cf7c16..de91cc1 100755 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -404,6 +404,13 @@ UniValue validateaddress(const UniValue& params, bool fHelp) ret.pushKVs(detail); if (pwalletMain && pwalletMain->mapAddressBook.count(dest)) ret.push_back(Pair("account", pwalletMain->mapAddressBook[dest].name)); + CKeyID keyID; + CHDChain hdChainCurrent; + if (pwalletMain && pwalletMain->mapHdPubKeys.count(keyID)) + { + ret.push_back(Pair("hdkeypath", pwalletMain->mapHdPubKeys[keyID].GetKeyPath())); + ret.push_back(Pair("hdmasterkeyid", hdChainCurrent.GetID().GetHex())); + } #endif } return ret; diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 41ff597..cc33420 100755 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -17,7 +17,11 @@ #include "util.h" #include "utilstrencodings.h" -#include +#ifdef ENABLE_WALLET +#include "wallet/wallet.h" +#endif + +#include #include #include #include @@ -62,12 +66,12 @@ void RPCServer::OnStopped(boost::function slot) void RPCServer::OnPreCommand(boost::function slot) { - g_rpcSignals.PreCommand.connect(boost::bind(slot, boost::placeholders::_1)); + g_rpcSignals.PreCommand.connect(boost::bind(slot, boost::arg<1>())); } void RPCServer::OnPostCommand(boost::function slot) { - g_rpcSignals.PostCommand.connect(boost::bind(slot, boost::placeholders::_1)); + g_rpcSignals.PostCommand.connect(boost::bind(slot, boost::arg<1>())); } void RPCTypeCheck(const UniValue& params, @@ -391,6 +395,7 @@ static const CRPCCommand vRPCCommands[] = {"wallet", "autocombinerewards", &autocombinerewards, false, false, true}, {"wallet", "backupwallet", &backupwallet, true, false, true}, {"wallet", "dumpprivkey", &dumpprivkey, true, false, true}, + {"wallet", "dumphdinfo", &dumphdinfo, true, false, true}, {"wallet", "dumpwallet", &dumpwallet, true, false, true}, {"wallet", "dumpallprivatekeys", &dumpallprivatekeys, true, false, true}, {"wallet", "bip38encrypt", &bip38encrypt, true, false, true}, @@ -434,9 +439,11 @@ static const CRPCCommand vRPCCommands[] = {"wallet", "settxfee", &settxfee, true, false, true}, {"wallet", "signmessage", &signmessage, true, false, true}, {"wallet", "walletlock", &walletlock, true, false, true}, + {"wallet", "upgradetohd", &upgradetohd, true, false, true}, {"wallet", "walletpassphrasechange", &walletpassphrasechange, true, false, true}, {"wallet", "walletpassphrase", &walletpassphrase, true, false, true}, + {"zerocoin", "getzerocoinbalance", &getzerocoinbalance, false, false, true}, {"zerocoin", "listmintedzerocoins", &listmintedzerocoins, false, false, true}, {"zerocoin", "listspentzerocoins", &listspentzerocoins, false, false, true}, @@ -591,6 +598,7 @@ UniValue CRPCTable::execute(const std::string &strMethod, const UniValue ¶ms if (fRPCInWarmup) throw JSONRPCError(RPC_IN_WARMUP, rpcWarmupStatus); } + // Find method const CRPCCommand* pcmd = tableRPC[strMethod]; if (!pcmd) @@ -615,7 +623,7 @@ std::vector CRPCTable::listCommands() const std::transform( mapCommands.begin(), mapCommands.end(), std::back_inserter(commandList), - boost::bind(&commandMap::value_type::first,boost::placeholders::_1) ); + boost::bind(&commandMap::value_type::first,boost::arg<1>()) ); return commandList; } diff --git a/src/rpc/server.h b/src/rpc/server.h index 2f0d3a2..180dd80 100755 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -192,6 +192,7 @@ extern UniValue dumpprivkey(const UniValue& params, bool fHelp); // in rpc/dump. extern UniValue importprivkey(const UniValue& params, bool fHelp); extern UniValue importpubkey(const UniValue& params, bool fHelp); extern UniValue importaddress(const UniValue& params, bool fHelp); +extern UniValue dumphdinfo(const UniValue& params, bool fHelp); extern UniValue dumpwallet(const UniValue& params, bool fHelp); extern UniValue dumpallprivatekeys(const UniValue& params, bool fHelp); extern UniValue importwallet(const UniValue& params, bool fHelp); @@ -235,6 +236,7 @@ extern UniValue listaccounts(const UniValue& params, bool fHelp); extern UniValue listsinceblock(const UniValue& params, bool fHelp); extern UniValue gettransaction(const UniValue& params, bool fHelp); extern UniValue backupwallet(const UniValue& params, bool fHelp); +extern UniValue upgradetohd(const UniValue& params, bool fHelp); extern UniValue keypoolrefill(const UniValue& params, bool fHelp); extern UniValue walletpassphrase(const UniValue& params, bool fHelp); extern UniValue walletpassphrasechange(const UniValue& params, bool fHelp); diff --git a/src/script/sigcache.cpp b/src/script/sigcache.cpp index 2c4c14a..a28c2c6 100755 --- a/src/script/sigcache.cpp +++ b/src/script/sigcache.cpp @@ -9,82 +9,81 @@ #include "random.h" #include "uint256.h" #include "util.h" +#include "cuckoocache.h" #include #include namespace { -/** - * Valid signature cache, to avoid doing expensive ECDSA signature checking - * twice for every transaction (once when accepted into memory pool, and - * again when accepted into the block chain) - */ class CSignatureCache { private: - //! sigdata_type is (signature hash, signature, public key): - typedef boost::tuple, CPubKey> sigdata_type; - std::set< sigdata_type> setValid; + //! Entries are SHA256(nonce || signature hash || public key || signature): + uint256 nonce; + typedef CuckooCache::cache map_type; + map_type setValid; boost::shared_mutex cs_sigcache; public: - bool - Get(const uint256 &hash, const std::vector& vchSig, const CPubKey& pubKey) + CSignatureCache() { - boost::shared_lock lock(cs_sigcache); + GetRandBytes(nonce.begin(), 32); + } - sigdata_type k(hash, vchSig, pubKey); - std::set::iterator mi = setValid.find(k); - if (mi != setValid.end()) - return true; - return false; + void + ComputeEntry(uint256& entry, const uint256 &hash, const std::vector& vchSig, const CPubKey& pubkey) + { + CSHA256().Write(nonce.begin(), 32).Write(hash.begin(), 32).Write(&pubkey[0], pubkey.size()).Write(&vchSig[0], vchSig.size()).Finalize(entry.begin()); } - void Set(const uint256 &hash, const std::vector& vchSig, const CPubKey& pubKey) + bool + Get(const uint256& entry, const bool erase) { - // DoS prevention: limit cache size to less than 10MB - // (~200 bytes per cache entry times 50,000 entries) - // Since there are a maximum of 20,000 signature operations per block - // 50,000 is a reasonable default. - int64_t nMaxCacheSize = GetArg("-maxsigcachesize", 50000); - if (nMaxCacheSize <= 0) return; + boost::shared_lock lock(cs_sigcache); + return setValid.contains(entry, erase); + } + void Set(uint256& entry) + { boost::unique_lock lock(cs_sigcache); - - while (static_cast(setValid.size()) > nMaxCacheSize) - { - // Evict a random entry. Random because that helps - // foil would-be DoS attackers who might try to pre-generate - // and re-use a set of valid signatures just-slightly-greater - // than our cache size. - uint256 randomHash = GetRandHash(); - std::vector unused; - std::set::iterator it = - setValid.lower_bound(sigdata_type(randomHash, unused, unused)); - if (it == setValid.end()) - it = setValid.begin(); - setValid.erase(*it); - } - - sigdata_type k(hash, vchSig, pubKey); - setValid.insert(k); + setValid.insert(entry); + } + uint32_t setup_bytes(size_t n) + { + return setValid.setup_bytes(n); } }; +/* In previous versions of this code, signatureCache was a local static variable + * in CachingTransactionSignatureChecker::VerifySignature. We initialize + * signatureCache outside of VerifySignature to avoid the atomic operation per + * call overhead associated with local static variables even though + * signatureCache could be made local to VerifySignature. +*/ +static CSignatureCache signatureCache; + } -bool CachingTransactionSignatureChecker::VerifySignature(const std::vector& vchSig, const CPubKey& pubkey, const uint256& sighash) const +void InitSignatureCache() { - static CSignatureCache signatureCache; + // nMaxCacheSize is unsigned. If -maxsigcachesize is set to zero, + // setup_bytes creates the minimum possible cache (2 elements). + size_t nMaxCacheSize = std::min(std::max((int64_t)0, GetArg("-maxsigcachesize", DEFAULT_MAX_SIG_CACHE_SIZE) / 2), MAX_MAX_SIG_CACHE_SIZE) * ((size_t) 1 << 20); + size_t nElems = signatureCache.setup_bytes(nMaxCacheSize); + LogPrintf("Using %zu MiB out of %zu/2 requested for signature cache, able to store %zu elements\n", + (nElems*sizeof(uint256)) >>20, (nMaxCacheSize*2)>>20, nElems); +} - if (signatureCache.Get(sighash, vchSig, pubkey)) +bool CachingTransactionSignatureChecker::VerifySignature(const std::vector& vchSig, const CPubKey& pubkey, const uint256& sighash) const +{ + uint256 entry; + signatureCache.ComputeEntry(entry, sighash, vchSig, pubkey); + if (signatureCache.Get(entry, !store)) return true; - if (!TransactionSignatureChecker::VerifySignature(vchSig, pubkey, sighash)) return false; - if (store) - signatureCache.Set(sighash, vchSig, pubkey); + signatureCache.Set(entry); return true; } diff --git a/src/script/sigcache.h b/src/script/sigcache.h index 7b8fd30..d08478f 100755 --- a/src/script/sigcache.h +++ b/src/script/sigcache.h @@ -10,8 +10,36 @@ #include +// DoS prevention: limit cache size to 32MB (over 1000000 entries on 64-bit +// systems). Due to how we count cache size, actual memory usage is slightly +// more (~32.25 MB) +static const unsigned int DEFAULT_MAX_SIG_CACHE_SIZE = 32; +// Maximum sig cache size allowed +static const int64_t MAX_MAX_SIG_CACHE_SIZE = 16384; + class CPubKey; +/** + * We're hashing a nonce into the entries themselves, so we don't need extra + * blinding in the set hash computation. + * + * This may exhibit platform endian dependent behavior but because these are + * nonced hashes (random) and this state is only ever used locally it is safe. + * All that matters is local consistency. + */ +class SignatureCacheHasher +{ +public: + template + uint32_t operator()(const uint256& key) const + { + static_assert(hash_select <8, "SignatureCacheHasher only has 8 hashes available."); + uint32_t u; + std::memcpy(&u, key.begin()+4*hash_select, 4); + return u; + } +}; + class CachingTransactionSignatureChecker : public TransactionSignatureChecker { private: @@ -23,4 +51,6 @@ class CachingTransactionSignatureChecker : public TransactionSignatureChecker bool VerifySignature(const std::vector& vchSig, const CPubKey& vchPubKey, const uint256& sighash) const; }; +void InitSignatureCache(); + #endif // BITCOIN_SCRIPT_SIGCACHE_H diff --git a/src/script/standard.cpp b/src/script/standard.cpp index eb1ff0f..2532c96 100755 --- a/src/script/standard.cpp +++ b/src/script/standard.cpp @@ -440,6 +440,7 @@ CScript GetScriptForDestination(const CTxDestination& dest) return script; } + CScript GetScriptForMultisig(int nRequired, const std::vector& keys) { CScript script; diff --git a/src/serialize.h b/src/serialize.h index e412d0e..b57a715 100755 --- a/src/serialize.h +++ b/src/serialize.h @@ -45,7 +45,7 @@ inline T* NCONST_PTR(const T* val) return const_cast(val); } -/** +/** * Get begin pointer of vector (non-const version). * @note These functions avoid the undefined case of indexing into an empty * vector, as well as that of indexing after the end of the vector. @@ -82,18 +82,18 @@ inline const T* end_ptr(const std::vector& v) enum { // primary actions - SER_NETWORK = (1 << 0), + SER_NETWORK = (1 << 0), SER_DISK = (1 << 1), SER_GETHASH = (1 << 2), }; #define READWRITE(obj) (::SerReadWrite(s, (obj), nType, nVersion, ser_action)) -/** +/** * Implement three methods for serializable objects. These are actually wrappers over * "SerializationOp" template, which implements the body of each class' serialization * code. Adding "ADD_SERIALIZE_METHODS" in the body of the class causes these wrappers to be - * added as members. + * added as members. */ #define ADD_SERIALIZE_METHODS \ size_t GetSerializeSize(int nType, int nVersion) const \ @@ -401,16 +401,16 @@ uint64_t ReadCompactSize(Stream& is) * sure the encoding is one-to-one, one is subtracted from all but the last digit. * Thus, the byte sequence a[] with length len, where all but the last byte * has bit 128 set, encodes the number: - * + * * (a[len-1] & 0x7F) + sum(i=1..len-1, 128^i*((a[len-i-1] & 0x7F)+1)) - * + * * Properties: * * Very small (0-127: 1 byte, 128-16511: 2 bytes, 16512-2113663: 3 bytes) * * Every integer has exactly one encoding * * Encoding does not depend on size of original integer type * * No redundancy: every (infinite) byte sequence corresponds to a list * of encoded integers. - * + * * 0: [0x00] 256: [0x81 0x00] * 1: [0x01] 16383: [0xFE 0x7F] * 127: [0x7F] 16384: [0xFF 0x00] @@ -468,7 +468,7 @@ I ReadVarInt(Stream& is) #define VARINT(obj) REF(WrapVarInt(REF(obj))) #define LIMITED_STRING(obj, n) REF(LimitedString(REF(obj))) -/** +/** * Wrapper for serializing arrays and POD. */ class CFlatData diff --git a/src/streams.h b/src/streams.h index 614922f..e31ec60 100755 --- a/src/streams.h +++ b/src/streams.h @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include diff --git a/src/support/lockedpool.cpp b/src/support/lockedpool.cpp new file mode 100644 index 0000000..bd5082b --- /dev/null +++ b/src/support/lockedpool.cpp @@ -0,0 +1,372 @@ +// Copyright (c) 2016 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include +#include + +#include + +#ifdef WIN32 +#ifdef _WIN32_WINNT +#undef _WIN32_WINNT +#endif +#define _WIN32_WINNT 0x0501 +#define WIN32_LEAN_AND_MEAN 1 +#ifndef NOMINMAX +#define NOMINMAX +#endif +#include +#else +#include // for PAGESIZE +#include // for mmap +#include // for getrlimit +#include // for sysconf +#endif + +#include + +LockedPoolManager *LockedPoolManager::_instance = nullptr; +std::once_flag LockedPoolManager::init_flag; + +/*******************************************************************************/ +// Utilities +// +/** Align up to power of 2 */ +static inline size_t align_up(size_t x, size_t align) { + return (x + align - 1) & ~(align - 1); +} + +/*******************************************************************************/ +// Implementation: Arena + +Arena::Arena(void *base_in, size_t size_in, size_t alignment_in) + : base(static_cast(base_in)), + end(static_cast(base_in) + size_in), alignment(alignment_in) { + // Start with one free chunk that covers the entire arena + chunks_free.emplace(base, size_in); +} + +Arena::~Arena() = default; + +void *Arena::alloc(size_t size) { + // Round to next multiple of alignment + size = align_up(size, alignment); + + // Don't handle zero-sized chunks + if (size == 0) return nullptr; + + // Pick a large enough free-chunk + auto it = + std::find_if(chunks_free.begin(), chunks_free.end(), + [=](const std::map::value_type &chunk) { + return chunk.second >= size; + }); + if (it == chunks_free.end()) return nullptr; + + // Create the used-chunk, taking its space from the end of the free-chunk + auto alloced = + chunks_used.emplace(it->first + it->second - size, size).first; + if (!(it->second -= size)) chunks_free.erase(it); + return reinterpret_cast(alloced->first); +} + +/* extend the Iterator if other begins at its end */ +template +bool extend(Iterator it, const Pair &other) { + if (it->first + it->second == other.first) { + it->second += other.second; + return true; + } + return false; +} + +void Arena::free(void *ptr) { + // Freeing the nullptr pointer is OK. + if (ptr == nullptr) { + return; + } + + // Remove chunk from used map + auto i = chunks_used.find(static_cast(ptr)); + if (i == chunks_used.end()) { + throw std::runtime_error("Arena: invalid or double free"); + } + auto freed = *i; + chunks_used.erase(i); + + // Add space to free map, coalescing contiguous chunks + auto next = chunks_free.upper_bound(freed.first); + auto prev = + (next == chunks_free.begin()) ? chunks_free.end() : std::prev(next); + if (prev == chunks_free.end() || !extend(prev, freed)) + prev = chunks_free.emplace_hint(next, freed); + if (next != chunks_free.end() && extend(prev, *next)) + chunks_free.erase(next); +} + +Arena::Stats Arena::stats() const { + Arena::Stats r{0, 0, 0, chunks_used.size(), chunks_free.size()}; + for (const auto &chunk : chunks_used) + r.used += chunk.second; + for (const auto &chunk : chunks_free) + r.free += chunk.second; + r.total = r.used + r.free; + return r; +} + +#ifdef ARENA_DEBUG +void printchunk(char *base, size_t sz, bool used) { + std::cout << "0x" << std::hex << std::setw(16) << std::setfill('0') << base + << " 0x" << std::hex << std::setw(16) << std::setfill('0') << sz + << " 0x" << used << std::endl; +} +void Arena::walk() const { + for (const auto &chunk : chunks_used) + printchunk(chunk.first, chunk.second, true); + std::cout << std::endl; + for (const auto &chunk : chunks_free) + printchunk(chunk.first, chunk.second, false); + std::cout << std::endl; +} +#endif + +/*******************************************************************************/ +// Implementation: Win32LockedPageAllocator + +#ifdef WIN32 +/** + * LockedPageAllocator specialized for Windows. + */ +class Win32LockedPageAllocator : public LockedPageAllocator { +public: + Win32LockedPageAllocator(); + void *AllocateLocked(size_t len, bool *lockingSuccess) override; + void FreeLocked(void *addr, size_t len) override; + size_t GetLimit() override; + +private: + size_t page_size; +}; + +Win32LockedPageAllocator::Win32LockedPageAllocator() { + // Determine system page size in bytes + SYSTEM_INFO sSysInfo; + GetSystemInfo(&sSysInfo); + page_size = sSysInfo.dwPageSize; +} +void *Win32LockedPageAllocator::AllocateLocked(size_t len, + bool *lockingSuccess) { + len = align_up(len, page_size); + void *addr = + VirtualAlloc(nullptr, len, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); + if (addr) { + // VirtualLock is used to attempt to keep keying material out of swap. + // Note that it does not provide this as a guarantee, but, in practice, + // memory that has been VirtualLock'd almost never gets written to the + // pagefile except in rare circumstances where memory is extremely low. + *lockingSuccess = VirtualLock(const_cast(addr), len) != 0; + } + return addr; +} +void Win32LockedPageAllocator::FreeLocked(void *addr, size_t len) { + len = align_up(len, page_size); + memory_cleanse(addr, len); + VirtualUnlock(const_cast(addr), len); +} + +size_t Win32LockedPageAllocator::GetLimit() { + // TODO is there a limit on windows, how to get it? + return std::numeric_limits::max(); +} +#endif + +/*******************************************************************************/ +// Implementation: PosixLockedPageAllocator + +#ifndef WIN32 +/** + * LockedPageAllocator specialized for OSes that don't try to be special + * snowflakes. + */ +class PosixLockedPageAllocator : public LockedPageAllocator { +public: + PosixLockedPageAllocator(); + void *AllocateLocked(size_t len, bool *lockingSuccess) override; + void FreeLocked(void *addr, size_t len) override; + size_t GetLimit() override; + +private: + size_t page_size; +}; + +PosixLockedPageAllocator::PosixLockedPageAllocator() { +// Determine system page size in bytes +#if defined(PAGESIZE) // defined in climits + page_size = PAGESIZE; +#else // assume some POSIX OS + page_size = sysconf(_SC_PAGESIZE); +#endif +} + +// Some systems (at least OS X) do not define MAP_ANONYMOUS yet and define +// MAP_ANON which is deprecated +#ifndef MAP_ANONYMOUS +#define MAP_ANONYMOUS MAP_ANON +#endif + +void *PosixLockedPageAllocator::AllocateLocked(size_t len, + bool *lockingSuccess) { + void *addr; + len = align_up(len, page_size); + addr = mmap(nullptr, len, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (addr) { + *lockingSuccess = mlock(addr, len) == 0; + } + return addr; +} +void PosixLockedPageAllocator::FreeLocked(void *addr, size_t len) { + len = align_up(len, page_size); + memory_cleanse(addr, len); + munlock(addr, len); + munmap(addr, len); +} +size_t PosixLockedPageAllocator::GetLimit() { +#ifdef RLIMIT_MEMLOCK + struct rlimit rlim; + if (getrlimit(RLIMIT_MEMLOCK, &rlim) == 0) { + if (rlim.rlim_cur != RLIM_INFINITY) { + return rlim.rlim_cur; + } + } +#endif + return std::numeric_limits::max(); +} +#endif + +/*******************************************************************************/ +// Implementation: LockedPool + +LockedPool::LockedPool(std::unique_ptr allocator_in, + LockingFailed_Callback lf_cb_in) + : allocator(std::move(allocator_in)), lf_cb(lf_cb_in), + cumulative_bytes_locked(0) {} + +LockedPool::~LockedPool() = default; +void *LockedPool::alloc(size_t size) { + std::lock_guard lock(mutex); + + // Don't handle impossible sizes + if (size == 0 || size > ARENA_SIZE) return nullptr; + + // Try allocating from each current arena + for (auto &arena : arenas) { + void *addr = arena.alloc(size); + if (addr) { + return addr; + } + } + // If that fails, create a new one + if (new_arena(ARENA_SIZE, ARENA_ALIGN)) { + return arenas.back().alloc(size); + } + return nullptr; +} + +void LockedPool::free(void *ptr) { + std::lock_guard lock(mutex); + // TODO we can do better than this linear search by keeping a map of arena + // extents to arena, and looking up the address. + for (auto &arena : arenas) { + if (arena.addressInArena(ptr)) { + arena.free(ptr); + return; + } + } + throw std::runtime_error( + "LockedPool: invalid address not pointing to any arena"); +} + +LockedPool::Stats LockedPool::stats() const { + std::lock_guard lock(mutex); + LockedPool::Stats r{0, 0, 0, cumulative_bytes_locked, 0, 0}; + for (const auto &arena : arenas) { + Arena::Stats i = arena.stats(); + r.used += i.used; + r.free += i.free; + r.total += i.total; + r.chunks_used += i.chunks_used; + r.chunks_free += i.chunks_free; + } + return r; +} + +bool LockedPool::new_arena(size_t size, size_t align) { + bool locked; + // If this is the first arena, handle this specially: Cap the upper size by + // the process limit. This makes sure that the first arena will at least be + // locked. An exception to this is if the process limit is 0: in this case + // no memory can be locked at all so we'll skip past this logic. + if (arenas.empty()) { + size_t limit = allocator->GetLimit(); + if (limit > 0) { + size = std::min(size, limit); + } + } + void *addr = allocator->AllocateLocked(size, &locked); + if (!addr) { + return false; + } + if (locked) { + cumulative_bytes_locked += size; + } else if (lf_cb) { + // Call the locking-failed callback if locking failed + if (!lf_cb()) { + // If the callback returns false, free the memory and fail, + // otherwise consider the user warned and proceed. + allocator->FreeLocked(addr, size); + return false; + } + } + arenas.emplace_back(allocator.get(), addr, size, align); + return true; +} + +LockedPool::LockedPageArena::LockedPageArena(LockedPageAllocator *allocator_in, + void *base_in, size_t size_in, + size_t align_in) + : Arena(base_in, size_in, align_in), base(base_in), size(size_in), + allocator(allocator_in) {} +LockedPool::LockedPageArena::~LockedPageArena() { + allocator->FreeLocked(base, size); +} + +/*******************************************************************************/ +// Implementation: LockedPoolManager +// +LockedPoolManager::LockedPoolManager( + std::unique_ptr allocator_in) + : LockedPool(std::move(allocator_in), &LockedPoolManager::LockingFailed) {} + +bool LockedPoolManager::LockingFailed() { + // TODO: log something but how? without including util.h + return true; +} + +void LockedPoolManager::CreateInstance() { +// Using a local static instance guarantees that the object is initialized when +// it's first needed and also deinitialized after all objects that use it are +// done with it. I can think of one unlikely scenario where we may have a static +// deinitialization order/problem, but the check in LockedPoolManagerBase's +// destructor helps us detect if that ever happens. +#ifdef WIN32 + std::unique_ptr allocator( + new Win32LockedPageAllocator()); +#else + std::unique_ptr allocator( + new PosixLockedPageAllocator()); +#endif + static LockedPoolManager instance(std::move(allocator)); + LockedPoolManager::_instance = &instance; +} diff --git a/src/support/lockedpool.h b/src/support/lockedpool.h new file mode 100644 index 0000000..7af71bf --- /dev/null +++ b/src/support/lockedpool.h @@ -0,0 +1,245 @@ +// Copyright (c) 2016 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_SUPPORT_LOCKEDPOOL_H +#define BITCOIN_SUPPORT_LOCKEDPOOL_H + +#include +#include +#include +#include +#include + +/** + * OS-dependent allocation and deallocation of locked/pinned memory pages. + * Abstract base class. + */ +class LockedPageAllocator { +public: + virtual ~LockedPageAllocator() = default; + /** + * Allocate and lock memory pages. + * If len is not a multiple of the system page size, it is rounded up. + * Returns 0 in case of allocation failure. + * + * If locking the memory pages could not be accomplished it will still + * return the memory, however the lockingSuccess flag will be false. + * lockingSuccess is undefined if the allocation fails. + */ + virtual void *AllocateLocked(size_t len, bool *lockingSuccess) = 0; + + /** + * Unlock and free memory pages. + * Clear the memory before unlocking. + */ + virtual void FreeLocked(void *addr, size_t len) = 0; + + /** + * Get the total limit on the amount of memory that may be locked by this + * process, in bytes. Return size_t max if there is no limit or the limit is + * unknown. Return 0 if no memory can be locked at all. + */ + virtual size_t GetLimit() = 0; +}; + +/** + * An arena manages a contiguous region of memory by dividing it into chunks. + */ +class Arena { +public: + Arena(void *base, size_t size, size_t alignment); + virtual ~Arena(); + + Arena(const Arena &other) = delete; // non construction-copyable + Arena &operator=(const Arena &) = delete; // non copyable + + /** Memory statistics. */ + struct Stats { + size_t used; + size_t free; + size_t total; + size_t chunks_used; + size_t chunks_free; + }; + + /** + * Allocate size bytes from this arena. + * Returns pointer on success, or 0 if memory is full or the application + * tried to allocate 0 bytes. + */ + void *alloc(size_t size); + + /** + * Free a previously allocated chunk of memory. + * Freeing the zero pointer has no effect. + * Raises std::runtime_error in case of error. + */ + void free(void *ptr); + + /** Get arena usage statistics */ + Stats stats() const; + +#ifdef ARENA_DEBUG + void walk() const; +#endif + + /** + * Return whether a pointer points inside this arena. + * This returns base <= ptr < (base+size) so only use it for (inclusive) + * chunk starting addresses. + */ + bool addressInArena(void *ptr) const { return ptr >= base && ptr < end; } + +private: + /** + * Map of chunk address to chunk information. This class makes use of the + * sorted order to merge previous and next chunks during deallocation. + */ + std::map chunks_free; + std::map chunks_used; + /** Base address of arena */ + char *base; + /** End address of arena */ + char *end; + /** Minimum chunk alignment */ + size_t alignment; +}; + +/** + * Pool for locked memory chunks. + * + * To avoid sensitive key data from being swapped to disk, the memory in this + * pool is locked/pinned. + * + * An arena manages a contiguous region of memory. The pool starts out with one + * arena but can grow to multiple arenas if the need arises. + * + * Unlike a normal C heap, the administrative structures are separate from the + * managed memory. This has been done as the sizes and bases of objects are not + * in themselves sensitive information, as to conserve precious locked memory. + * In some operating systems the amount of memory that can be locked is small. + */ +class LockedPool { +public: + /** + * Size of one arena of locked memory. This is a compromise. + * Do not set this too low, as managing many arenas will increase allocation + * and deallocation overhead. Setting it too high allocates more locked + * memory from the OS than strictly necessary. + */ + static const size_t ARENA_SIZE = 256 * 1024; + /** + * Chunk alignment. Another compromise. Setting this too high will waste + * memory, setting it too low will facilitate fragmentation. + */ + static const size_t ARENA_ALIGN = 16; + + /** + * Callback when allocation succeeds but locking fails. + */ + typedef bool (*LockingFailed_Callback)(); + + /** Memory statistics. */ + struct Stats { + size_t used; + size_t free; + size_t total; + size_t locked; + size_t chunks_used; + size_t chunks_free; + }; + + /** + * Create a new LockedPool. This takes ownership of the MemoryPageLocker, + * you can only instantiate this with LockedPool(std::move(...)). + * + * The second argument is an optional callback when locking a newly + * allocated arena failed. If this callback is provided and returns false, + * the allocation fails (hard fail), if it returns true the allocation + * proceeds, but it could warn. + */ + explicit LockedPool(std::unique_ptr allocator, + LockingFailed_Callback lf_cb_in = nullptr); + ~LockedPool(); + + LockedPool(const LockedPool &other) = delete; // non construction-copyable + LockedPool &operator=(const LockedPool &) = delete; // non copyable + + /** + * Allocate size bytes from this arena. + * Returns pointer on success, or 0 if memory is full or the application + * tried to allocate 0 bytes. + */ + void *alloc(size_t size); + + /** + * Free a previously allocated chunk of memory. + * Freeing the zero pointer has no effect. + * Raises std::runtime_error in case of error. + */ + void free(void *ptr); + + /** Get pool usage statistics */ + Stats stats() const; + +private: + std::unique_ptr allocator; + + /** Create an arena from locked pages */ + class LockedPageArena : public Arena { + public: + LockedPageArena(LockedPageAllocator *alloc_in, void *base_in, + size_t size, size_t align); + ~LockedPageArena() override; + + private: + void *base; + size_t size; + LockedPageAllocator *allocator; + }; + + bool new_arena(size_t size, size_t align); + + std::list arenas; + LockingFailed_Callback lf_cb; + size_t cumulative_bytes_locked; + /** + * Mutex protects access to this pool's data structures, including arenas. + */ + mutable std::mutex mutex; +}; + +/** + * Singleton class to keep track of locked (ie, non-swappable) memory, for use + * in std::allocator templates. + * + * Some implementations of the STL allocate memory in some constructors (i.e., + * see MSVC's vector implementation where it allocates 1 byte of memory in + * the allocator). Due to the unpredictable order of static initializers, we + * have to make sure the LockedPoolManager instance exists before any other + * STL-based objects that use secure_allocator are created. So instead of having + * LockedPoolManager also be static-initialized, it is created on demand. + */ +class LockedPoolManager : public LockedPool { +public: + /** Return the current instance, or create it once */ + static LockedPoolManager &Instance() { + std::call_once(LockedPoolManager::init_flag, + LockedPoolManager::CreateInstance); + return *LockedPoolManager::_instance; + } + +private: + explicit LockedPoolManager(std::unique_ptr allocator); + + /** Create a new LockedPoolManager specialized to the OS */ + static void CreateInstance(); + /** Called when locking fails, warn the user here */ + static bool LockingFailed(); + + static LockedPoolManager *_instance; + static std::once_flag init_flag; +}; + +#endif // BITCOIN_SUPPORT_LOCKEDPOOL_H diff --git a/src/test/bip32_tests.cpp b/src/test/bip32_tests.cpp index 348be7a..b1ff9b2 100755 --- a/src/test/bip32_tests.cpp +++ b/src/test/bip32_tests.cpp @@ -104,6 +104,21 @@ void RunTest(const TestVector &test) { } key = keyNew; pubkey = pubkeyNew; + CDataStream ssPub(SER_DISK, CLIENT_VERSION); + ssPub << pubkeyNew; + BOOST_CHECK(ssPub.size() == BIP32_EXTKEY_SIZE+1); + + CDataStream ssPriv(SER_DISK, CLIENT_VERSION); + ssPriv << keyNew; + BOOST_CHECK(ssPriv.size() == BIP32_EXTKEY_SIZE+1); + + CExtPubKey pubCheck; + CExtKey privCheck; + ssPub >> pubCheck; + ssPriv >> privCheck; + + BOOST_CHECK(pubCheck == pubkeyNew); + BOOST_CHECK(privCheck == keyNew); } } diff --git a/src/test/bip39_tests.cpp b/src/test/bip39_tests.cpp new file mode 100644 index 0000000..9b502b9 --- /dev/null +++ b/src/test/bip39_tests.cpp @@ -0,0 +1,71 @@ +// Copyright (c) 2014-2017 The Dash Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +/* +#include "base58.h" +#include "data/bip39_vectors.json.h" +#include "key.h" +#include "util.h" +#include "utilstrencodings.h" +#include "test/test_phore.h" +#include "bip39.h" + +#include + +#include + +// In script_tests.cpp +extern UniValue read_json(const std::string& jsondata); + +BOOST_FIXTURE_TEST_SUITE(bip39_tests, BasicTestingSetup) + +// https://github.com/trezor/python-mnemonic/blob/b502451a33a440783926e04428115e0bed87d01f/vectors.json +BOOST_AUTO_TEST_CASE(bip39_vectors) + { + UniValue tests = read_json(std::string(json_tests::bip39_vectors, json_tests::bip39_vectors + sizeof(json_tests::bip39_vectors))); + + for (unsigned int i = 0; i < tests.size(); i++) { + // printf("%d\n", i); + UniValue test = tests[i]; + std::string strTest = test.write(); + if (test.size() < 4) // Allow for extra stuff (useful for comments) + { + BOOST_ERROR("Bad test: " << strTest); + continue; + } + + std::vector vData = ParseHex(test[0].get_str()); + SecureVector data(vData.begin(), vData.end()); + + SecureString m = CMnemonic::FromData(data, data.size()); + std::string strMnemonic = test[1].get_str(); + SecureString mnemonic(strMnemonic.begin(), strMnemonic.end()); + + // printf("%s\n%s\n", m.c_str(), mnemonic.c_str()); + BOOST_CHECK(m == mnemonic); + BOOST_CHECK(CMnemonic::Check(mnemonic)); + + SecureVector seed; + SecureString passphrase("TREZOR"); + CMnemonic::ToSeed(mnemonic, passphrase, seed); + // printf("seed: %s\n", HexStr(std::string(seed.begin(), seed.end())).c_str()); + BOOST_CHECK(HexStr(std::string(seed.begin(), seed.end())) == test[2].get_str()); + + CExtKey key; + CExtPubKey pubkey; + + key.SetMaster(&seed[0], 64); + pubkey = key.Neuter(); + + CBitcoinExtKey b58key; + b58key.SetKey(key); + printf("CBitcoinExtKey: %s\n", b58key.ToString().c_str()); + printf("testKey: %s\n", test[3].get_str().c_str()); + + BOOST_CHECK(b58key.ToString() == test[3].get_str()); + } + } + +BOOST_AUTO_TEST_SUITE_END() +*/ diff --git a/src/test/budget_tests.cpp b/src/test/budget_tests.cpp index c3d0f52..0ba28fc 100644 --- a/src/test/budget_tests.cpp +++ b/src/test/budget_tests.cpp @@ -18,15 +18,17 @@ void CheckBudgetValue(int nHeight, std::string strNetwork, CAmount nExpectedValu BOOST_CHECK_MESSAGE(nBudget == nExpectedValue, strError); } +/* there is no Zerocoin_Block_V2_Start yet BOOST_AUTO_TEST_CASE(budget_value) { SelectParams(CBaseChainParams::TESTNET); - nHeightTest = Params().Zerocoin_Block_V2_Start() + 1; + int nHeightTest = Params().Zerocoin_Block_V2_Start() + 1; CheckBudgetValue(nHeightTest, "testnet", 7300*COIN); SelectParams(CBaseChainParams::MAIN); int nHeightTest = Params().Zerocoin_Block_V2_Start() + 1; CheckBudgetValue(nHeightTest, "mainnet", 43200*COIN); } +*/ BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/crypto_tests.cpp b/src/test/crypto_tests.cpp index 26708f5..f13a651 100755 --- a/src/test/crypto_tests.cpp +++ b/src/test/crypto_tests.cpp @@ -16,6 +16,7 @@ #include #include +#include BOOST_AUTO_TEST_SUITE(crypto_tests) @@ -248,6 +249,29 @@ BOOST_AUTO_TEST_CASE(hmac_sha512_testvectors) { "b6022cac3c4982b10d5eeb55c3e4de15134676fb6de0446065c97440fa8c6a58"); } +BOOST_AUTO_TEST_CASE(pbkdf2_hmac_sha512_test) { + // test vectors from + // https://github.com/trezor/trezor-crypto/blob/87c920a7e747f7ed40b6ae841327868ab914435b/tests.c#L1936-L1957 + // https://stackoverflow.com/questions/15593184/pbkdf2-hmac-sha-512-test-vectors + uint8_t k[64], s[40]; + + strcpy((char *)s, "salt"); + PKCS5_PBKDF2_HMAC("password", 8, s, 4, 1, EVP_sha512(), 64, k); + BOOST_CHECK(HexStr(k, k + 64) == "867f70cf1ade02cff3752599a3a53dc4af34c7a669815ae5d513554e1c8cf252c02d470a285a0501bad999bfe943c08f050235d7d68b1da55e63f73b60a57fce"); + + strcpy((char *)s, "salt"); + PKCS5_PBKDF2_HMAC("password", 8, s, 4, 2, EVP_sha512(), 64, k); + BOOST_CHECK(HexStr(k, k + 64) == "e1d9c16aa681708a45f5c7c4e215ceb66e011a2e9f0040713f18aefdb866d53cf76cab2868a39b9f7840edce4fef5a82be67335c77a6068e04112754f27ccf4e"); + + strcpy((char *)s, "salt"); + PKCS5_PBKDF2_HMAC("password", 8, s, 4, 4096, EVP_sha512(), 64, k); + BOOST_CHECK(HexStr(k, k + 64) == "d197b1b33db0143e018b12f3d1d1479e6cdebdcc97c5c0f87f6902e072f457b5143f30602641b3d55cd335988cb36b84376060ecd532e039b742a239434af2d5"); + + strcpy((char *)s, "saltSALTsaltSALTsaltSALTsaltSALTsalt"); + PKCS5_PBKDF2_HMAC("passwordPASSWORDpassword", 3*8, s, 9*4, 4096, EVP_sha512(), 64, k); + BOOST_CHECK(HexStr(k, k + 64) == "8c0511f4c6e597c6ac6315d8f0362e225f3c501495ba23b868c005174dc4ee71115b59f9e60cd9532fa33e0f75aefe30225c583a186cd82bd4daea9724a3d3b8"); +} + void TestRFC6979(const std::string& hexkey, const std::string& hexmsg, const std::vector& hexout) { std::vector key = ParseHex(hexkey); diff --git a/src/test/data/bip39_vectors.json b/src/test/data/bip39_vectors.json new file mode 100644 index 0000000..8c4bdb9 --- /dev/null +++ b/src/test/data/bip39_vectors.json @@ -0,0 +1,146 @@ +[ + [ + "00000000000000000000000000000000", + "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about", + "c55257c360c07c72029aebc1b53c05ed0362ada38ead3e3e9efa3708e53495531f09a6987599d18264c1e1c92f2cf141630c7a3c4ab7c81b2f001698e7463b04", + "TDt9EWvD5T5T44hAatc3DkJpKCCPhGkyqPsjd5ruhbxZ5GUsrAVyEFcVZ4PYWUk2TqnMtPtgJD4jL53k1gcg8YkJL8opjx8RtDsoFUDo14EtGNC" + ], + [ + "7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f", + "legal winner thank year wave sausage worth useful legal winner thank yellow", + "2e8905819b8723fe2c1d161860e5ee1830318dbf49a83bd451cfb8440c28bd6fa457fe1296106559a3c80937a1c1069be3a3a5bd381ee6260e8d9739fce1f607", + "TDt9EWvD5T5T44hAZsiW1o8UdttgDghQnDERfzifWyhuELHRhbArVSum3TEkdgJaKoQCw2saMAc3JSFWWJoVKSGEHzKqDDJaVS2ZEiTvkj4Trbr" + ], + [ + "80808080808080808080808080808080", + "letter advice cage absurd amount doctor acoustic avoid letter advice cage above", + "d71de856f81a8acc65e6fc851a38d4d7ec216fd0796d0a6827a3ad6ed5511a30fa280f12eb2e47ed2ac03b5c462a0358d18d69fe4f985ec81778c1b370b652a8", + "TDt9EWvD5T5T44hAa5G3PDiYh7DS9tXQcDxFR6ssHFfeEKpspoGkxyjwMB9hT3Z3PnTZ1h1MvU6G7b4iUjiKsJMEqJpxWja7jdLnMiAfcijc4Ca" + ], + [ + "ffffffffffffffffffffffffffffffff", + "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo wrong", + "ac27495480225222079d7be181583751e86f571027b0497b5b5d11218e0a8a13332572917f0f8e5a589620c6f15b11c61dee327651a14c34e18231052e48c069", + "TDt9EWvD5T5T44hAZgdBp9eaUdCHnjy97mjaLkvwhQFjGXY4gXSRuXoepBPYbuBv3fkU3giDD3LBcTDByZ9cgCC6TtiThtiEsX15ntxDt7vQoib" + ], + [ + "000000000000000000000000000000000000000000000000", + "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon agent", + "035895f2f481b1b0f01fcf8c289c794660b289981a78f8106447707fdd9666ca06da5a9a565181599b79f53b844d8a71dd9f439c52a3d7b3e8a79c906ac845fa", + "TDt9EWvD5T5T44hAaxnbsBQqu6LTbYy6A1PN1bTnaFv5YGxkx5VBGfHmYUfsFGYbnRPAAjJUGRd32vV9SDyzuF4EfEVxmc5vWumjiMP2KnVNB8Z" + ], + [ + "7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f", + "legal winner thank year wave sausage worth useful legal winner thank year wave sausage worth useful legal will", + "f2b94508732bcbacbcc020faefecfc89feafa6649a5491b8c952cede496c214a0c7b3c392d168748f2d4a612bada0753b52a1c7ac53c1e93abd5c6320b9e95dd", + "TDt9EWvD5T5T44hAaYUXMkvxMADQ9zhjop6UbpwLLx1bbCjttMfGxHLDqRtMS27gqg451sXtNGzWQkPPGYFTE6TdsDvbQo8ULKWYzrprA4Qxs6u" + ], + [ + "808080808080808080808080808080808080808080808080", + "letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic avoid letter always", + "107d7c02a5aa6f38c58083ff74f04c607c2d2c0ecc55501dadd72d025b751bc27fe913ffb796f841c49b1d33b610cf0e91d3aa239027f5e99fe4ce9e5088cd65", + "TDt9EWvD5T5T44hAagwacABiEtBHEY8fCoDjUkVpUGZRXvE6o3WBjqJQnmJd2b2xXr7AA5q2fKzLVkjwRTFT5SUTvvYm69xCoQVieEstFRcLiT2" + ], + [ + "ffffffffffffffffffffffffffffffffffffffffffffffff", + "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo when", + "0cd6e5d827bb62eb8fc1e262254223817fd068a74b5b449cc2f667c3f1f985a76379b43348d952e2265b4cd129090758b3e3c2c49103b5051aac2eaeb890a528", + "TDt9EWvD5T5T44hAaHjB5vseqkfrJK3nFwRDQbW5CughzCVk6f9pJz2XWrmnympKNzUH3ijoEKEf4ccRdFdZnusGNCx81jQsRRccQx3U5va4Bn8" + ], + [ + "0000000000000000000000000000000000000000000000000000000000000000", + "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art", + "bda85446c68413707090a52022edd26a1c9462295029f2e60cd7c4f2bbd3097170af7a4d73245cafa9c3cca8d561a7c3de6f5d4a10be8ed2a5e608d68f92fcc8", + "TDt9EWvD5T5T44hAaEPZat4XWQtcRb15DSnP2FdSvDxLzmLjZ2m74uSmbT3qyvbRRG9EfUbUMJ61XpKzBUWdzB9dTcYFHqLFHuCCynoLpnz1AcX" + ], + [ + "7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f", + "legal winner thank year wave sausage worth useful legal winner thank year wave sausage worth useful legal winner thank year wave sausage worth title", + "bc09fca1804f7e69da93c2f2028eb238c227f2e9dda30cd63699232578480a4021b146ad717fbb7e451ce9eb835f43620bf5c514db0f8add49f5d121449d3e87", + "TDt9EWvD5T5T44hAajaFdE7jFDNUvg1q6foTwavjAZgAEheBu7Jp1XMXCWe44BELBA3wgKXPGKnRQA5LvYcxpdaipKjvJh7xbbD3u9y4qcjjo24" + ], + [ + "8080808080808080808080808080808080808080808080808080808080808080", + "letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic bless", + "c0c519bd0e91a2ed54357d9d1ebef6f5af218a153624cf4f2da911a0ed8f7a09e2ef61af0aca007096df430022f7a2b6fb91661a9589097069720d015e4e982f", + "TDt9EWvD5T5T44hAaQ1AQa8RPRFkFZ1M8LfbydsXg8rxwxi9fmu2wASVYPCnekGehh216yc6U4RWx9gUz7ro9T9RpVCQRFR4PEAFKpZfLe1Xmrb" + ], + [ + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo vote", + "dd48c104698c30cfe2b6142103248622fb7bb0ff692eebb00089b32d22484e1613912f0a5b694407be899ffd31ed3992c456cdf60f5d4564b8ba3f05a69890ad", + "TDt9EWvD5T5T44hAZhod1J7MRWSzHYW31yADNhBUcBrNY81NzLhEvkKrvDxz4C24kVQCQVWjtWQwfq8EiQbmYZkSHEFtEkVJdAD4ZmVFkE3gmvP" + ], + [ + "9e885d952ad362caeb4efe34a8e91bd2", + "ozone drill grab fiber curtain grace pudding thank cruise elder eight picnic", + "274ddc525802f7c828d8ef7ddbcdc5304e87ac3535913611fbbfa986d0c9e5476c91689f9c8a54fd55bd38606aa6a8595ad213d4c9c9f9aca3fb217069a41028", + "TDt9EWvD5T5T44hAa17Xt5mnAs197UbgtowcGXzCGuWUtKdDoNe7hGCDHwnqVjPX9CgtvGgXu6vcKxChUuPyoc15cNwNF1p2GUiE84wRKybTHuQ" + ], + [ + "6610b25967cdcca9d59875f5cb50b0ea75433311869e930b", + "gravity machine north sort system female filter attitude volume fold club stay feature office ecology stable narrow fog", + "628c3827a8823298ee685db84f55caa34b5cc195a778e52d45f59bcf75aba68e4d7590e101dc414bc1bbd5737666fbbef35d1f1903953b66624f910feef245ac", + "TDt9EWvD5T5T44hAb71WecQApoJYwVaZKEhAgpaqrRf4nkr4f1bkPF11wX3FDisTuRvdovj39U91fDx3wNXpMrity58VKPkk5pDtW621bvY3U5L" + ], + [ + "68a79eaca2324873eacc50cb9c6eca8cc68ea5d936f98787c60c7ebc74e6ce7c", + "hamster diagram private dutch cause delay private meat slide toddler razor book happy fancy gospel tennis maple dilemma loan word shrug inflict delay length", + "64c87cde7e12ecf6704ab95bb1408bef047c22db4cc7491c4271d170a1b213d20b385bc1588d9c7b38f1b39d415665b8a9030c9ec653d75e65f847d8fc1fc440", + "TDt9EWvD5T5T44hAZj1YiBTHAQoCMVjVAwvLjzJENDDkTaEnj6bnPUfL4PsbwjU5cvg9jeLpzkMfxuypVQjx8Hcsf8G5Dh5KBMKe2wYXb7EbojZ" + ], + [ + "c0ba5a8e914111210f2bd131f3d5e08d", + "scheme spot photo card baby mountain device kick cradle pact join borrow", + "ea725895aaae8d4c1cf682c1bfd2d358d52ed9f0f0591131b559e2724bb234fca05aa9c02c57407e04ee9dc3b454aa63fbff483a8b11de949624b9f1831a9612", + "TDt9EWvD5T5T44hAaTP2s9p3UygTLhKiN7pZYaXc3ZwieVchqQxEWrTmRyyGneg1JGnSsbfuTn4ANQWDdDmcNt4thjA2Pv9odnbB2cwenaLHk9c" + ], + [ + "6d9be1ee6ebd27a258115aad99b7317b9c8d28b6d76431c3", + "horn tenant knee talent sponsor spell gate clip pulse soap slush warm silver nephew swap uncle crack brave", + "fd579828af3da1d32544ce4db5c73d53fc8acc4ddb1e3b251a31179cdb71e853c56d2fcb11aed39898ce6c34b10b5382772db8796e52837b54468aeb312cfc3d", + "TDt9EWvD5T5T44hAacZpfh9ngwvBbwtZ2fiE3vAKnxBkeKpKyjv2GN2PtJgCvCTGJedkvPs13eihotf97Ti1Egn2VhexLtw9XU9dxwybxPRagzN" + ], + [ + "9f6a2878b2520799a44ef18bc7df394e7061a224d2c33cd015b157d746869863", + "panda eyebrow bullet gorilla call smoke muffin taste mesh discover soft ostrich alcohol speed nation flash devote level hobby quick inner drive ghost inside", + "72be8e052fc4919d2adf28d5306b5474b0069df35b02303de8c1729c9538dbb6fc2d731d5f832193cd9fb6aeecbc469594a70e3dd50811b5067f3b88b28c3e8d", + "TDt9EWvD5T5T44hAZhwAKyU7GcxwDpCa1kKyZtgJtZoHQMtxDKmPsG4iBciaRUWFqFMXfUPK2gLNmmmi1WeVosqXuTNyGb7SsYtC9aUaMLNsMPd" + ], + [ + "23db8160a31d3e0dca3688ed941adbf3", + "cat swing flag economy stadium alone churn speed unique patch report train", + "deb5f45449e615feff5640f2e49f933ff51895de3b4381832b3139941c57b59205a42480c52175b6efcffaa58a2503887c1e8b363a707256bdd2b587b46541f5", + "TDt9EWvD5T5T44hAbTaWoxrb9jfPdPvp5QtT5YS5iF62TPUvTCY4VKJQr5bQwnTNEerKB1QazXrfVJhm9sMJH2qCAE7PCpNojvRVkPHcHMvBs8s" + ], + [ + "8197a4a47f0425faeaa69deebc05ca29c0a5b5cc76ceacc0", + "light rule cinnamon wrap drastic word pride squirrel upgrade then income fatal apart sustain crack supply proud access", + "4cbdff1ca2db800fd61cae72a57475fdc6bab03e441fd63f96dabd1f183ef5b782925f00105f318309a7e9c3ea6967c7801e46c8a58082674c860a37b93eda02", + "TDt9EWvD5T5T44hAb9TFvjiZNdza3URue2mYMMFEfAMZAYNqq1XLTkzm2Db9Xjn3xaV6Nm9Q5Q6pXLJYeH3XivpPTeU8TjcrU6L1piZyUCxXmze" + ], + [ + "066dca1a2bb7e8a1db2832148ce9933eea0f3ac9548d793112d9a95c9407efad", + "all hour make first leader extend hole alien behind guard gospel lava path output census museum junior mass reopen famous sing advance salt reform", + "26e975ec644423f4a4c4f4215ef09b4bd7ef924e85d1d17c4cf3f136c2863cf6df0a475045652c57eb5fb41513ca2a2d67722b77e954b4b3fc11f7590449191d", + "TDt9EWvD5T5T44hAb3o3qdwHkcr5rS5JcCkREKxi3rQ1cdaf6Vz8P1Din9wSbqKWfnHKV5fpjKWm49kway9hNAx8sDRYY2z4nXYbPTMjiaZjoyX" + ], + [ + "f30f8c1da665478f49b001d94c5fc452", + "vessel ladder alter error federal sibling chat ability sun glass valve picture", + "2aaa9242daafcee6aa9d7269f17d4efe271e1b9a529178d7dc139cd18747090bf9d60295d0ce74309a78852a9caadf0af48aae1c6253839624076224374bc63f", + "TDt9EWvD5T5T44hAZc4s9iNMqzHgpKZ4QhkrjcuJrVKxWR6QGsKUVYECPQyJiwfj56duSpBxg39XJyc4JcCkWFzemWfiqzSv2XNZx5dZdjAHYjo" + ], + [ + "c10ec20dc3cd9f652c7fac2f1230f7a3c828389a14392f05", + "scissors invite lock maple supreme raw rapid void congress muscle digital elegant little brisk hair mango congress clump", + "7b4a10be9d98e6cba265566db7f136718e1398c71cb581e1b2f464cac1ceedf4f3e274dc270003c670ad8d02c4558b2f8e39edea2775c9e232c7cb798b069e88", + "TDt9EWvD5T5T44hAbmnoaEC4T8Vjj4ubQZEg4C7LAZjoZ3vjDhcBEjjuDegRSFnUGcmNcHTTd6R6DMhtTQWo1VaAsZDGT9jAeNiqeM2QBk2E4kr" + ], + [ + "f585c11aec520db57dd353c69554b21a89b20fb0650966fa0a9d6f74fd989d8f", + "void come effort suffer camp survey warrior heavy shoot primary clutch crush open amazing screen patrol group space point ten exist slush involve unfold", + "01f5bced59dec48e362f2c45b5de68b9fd6c92c6634f44d6d40aab69056506f0e35524a518034ddc1192e1dacd32c1ed3eaa3c3b131c88ed8e7e54c49a5d0998", + "TDt9EWvD5T5T44hAaMRAQWM2ALS6K6xi2gyS8Fri9JSJjTkqC5VTtxtdmCLd89G8EbPNKbSNH7g1J1hYCzZsbotdBAqGbkESHaH9y1narBksvjo" + ] +] \ No newline at end of file diff --git a/src/test/rpc_wallet_tests.cpp b/src/test/rpc_wallet_tests.cpp index a6eed22..e94a3e8 100755 --- a/src/test/rpc_wallet_tests.cpp +++ b/src/test/rpc_wallet_tests.cpp @@ -22,6 +22,9 @@ extern UniValue CallRPC(string args); extern CWallet* pwalletMain; +// there is no CBitcoinAddress +#if 0 + BOOST_AUTO_TEST_SUITE(rpc_wallet_tests) BOOST_AUTO_TEST_CASE(rpc_addmultisig) @@ -183,3 +186,5 @@ BOOST_AUTO_TEST_CASE(rpc_wallet) } BOOST_AUTO_TEST_SUITE_END() + +#endif diff --git a/src/test/script_P2SH_tests.cpp b/src/test/script_P2SH_tests.cpp index f088d1d..59d3365 100755 --- a/src/test/script_P2SH_tests.cpp +++ b/src/test/script_P2SH_tests.cpp @@ -11,7 +11,7 @@ #include "script/sign.h" #ifdef ENABLE_WALLET -#include "wallet_ismine.h" +#include "wallet/wallet_ismine.h" #endif #include diff --git a/src/test/script_standard_tests.cpp b/src/test/script_standard_tests.cpp index 435db8e..ddb08ad 100644 --- a/src/test/script_standard_tests.cpp +++ b/src/test/script_standard_tests.cpp @@ -4,7 +4,7 @@ #include "key.h" #include "keystore.h" -#include "wallet_ismine.h" +#include "wallet/wallet_ismine.h" #include "script/script.h" #include "script/script_error.h" #include "script/standard.h" diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index 9d45085..e3c850e 100755 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -14,7 +14,7 @@ #include "script/sign.h" #include "util.h" #include "utilstrencodings.h" -#include "rpcserver.h" +#include "rpc/server.h" #if defined(HAVE_CONSENSUS_LIB) #include "script/bitcoinconsensus.h" diff --git a/src/test/test_ohmcoin.cpp b/src/test/test_ohmcoin.cpp index 2deab41..5bd8a58 100644 --- a/src/test/test_ohmcoin.cpp +++ b/src/test/test_ohmcoin.cpp @@ -10,15 +10,15 @@ #include "ui_interface.h" #include "util.h" #ifdef ENABLE_WALLET -#include "db.h" -#include "wallet.h" +#include "wallet/db.h" +#include "wallet/wallet.h" #endif #include #include #include -CClientUIInterface uiInterface; +//CClientUIInterface uiInterface; CWallet* pwalletMain; extern bool fPrintToConsole; diff --git a/src/test/zerocoin_denomination_tests.cpp b/src/test/zerocoin_denomination_tests.cpp index 91e3d5f..3e79b9b 100644 --- a/src/test/zerocoin_denomination_tests.cpp +++ b/src/test/zerocoin_denomination_tests.cpp @@ -4,7 +4,7 @@ #include "amount.h" #include "chainparams.h" -#include "coincontrol.h" +#include "wallet/coincontrol.h" #include "denomination_functions.h" #include "main.h" #include "txdb.h" diff --git a/src/test/zerocoin_implementation_tests.cpp b/src/test/zerocoin_implementation_tests.cpp index b1c619f..cd2839a 100644 --- a/src/test/zerocoin_implementation_tests.cpp +++ b/src/test/zerocoin_implementation_tests.cpp @@ -14,7 +14,7 @@ #include #include #include -#include "wallet.h" +#include "wallet/wallet.h" #include "zohmcwallet.h" using namespace libzerocoin; @@ -109,7 +109,7 @@ bool CheckZerocoinSpendNoDB(const CTransaction tx, string& strError) //max needed non-mint outputs should be 2 - one for redemption address and a possible 2nd for change if (tx.vout.size() > 2){ int outs = 0; - for (const CTxOut out : tx.vout) { + for (const CTxOut& out : tx.vout) { if (out.IsZerocoinMint()) continue; outs++; @@ -123,7 +123,7 @@ bool CheckZerocoinSpendNoDB(const CTransaction tx, string& strError) //compute the txout hash that is used for the zerocoinspend signatures CMutableTransaction txTemp; - for (const CTxOut out : tx.vout) { + for (const CTxOut& out : tx.vout) { txTemp.vout.push_back(out); } // uint256 hashTxOut = txTemp.GetHash(); diff --git a/src/test/zerocoin_transactions_tests.cpp b/src/test/zerocoin_transactions_tests.cpp index da68b48..48f8f89 100644 --- a/src/test/zerocoin_transactions_tests.cpp +++ b/src/test/zerocoin_transactions_tests.cpp @@ -5,7 +5,7 @@ #include "libzerocoin/Denominations.h" #include "amount.h" #include "chainparams.h" -#include "coincontrol.h" +#include "wallet/coincontrol.h" #include "main.h" #include "wallet/wallet.h" #include "wallet/walletdb.h" diff --git a/src/torcontrol.cpp b/src/torcontrol.cpp index 7cf996c..b5bd77e 100644 --- a/src/torcontrol.cpp +++ b/src/torcontrol.cpp @@ -460,7 +460,7 @@ TorController::TorController(struct event_base* _base, const std::string& _targe if (!reconnect_ev) LogPrintf("tor: Failed to create event for reconnection: out of memory?\n"); // Start connection attempts immediately - if (!conn.Connect(_target, boost::bind(&TorController::connected_cb, this, boost::placeholders::_1), + if (!conn.Connect(_target, boost::bind(&TorController::connected_cb, this, boost::arg<1>()), boost::bind(&TorController::disconnected_cb, this, _1) )) { LogPrintf("tor: Initiating connection to Tor control port %s failed\n", _target); } @@ -540,7 +540,7 @@ void TorController::auth_cb(TorControlConnection& _conn, const TorControlReply& // Note that the 'virtual' port doesn't have to be the same as our internal port, but this is just a convenient // choice. TODO; refactor the shutdown sequence some day. _conn.Command(strprintf("ADD_ONION %s Port=%i,127.0.0.1:%i", private_key, GetListenPort(), GetListenPort()), - boost::bind(&TorController::add_onion_cb, this, boost::placeholders::_1, boost::placeholders::_2)); + boost::bind(&TorController::add_onion_cb, this, boost::arg<1>(), boost::arg<2>())); } else { LogPrintf("tor: Authentication failed\n"); } @@ -599,7 +599,7 @@ void TorController::authchallenge_cb(TorControlConnection& _conn, const TorContr } std::vector computedClientHash = ComputeResponse(TOR_SAFE_CLIENTKEY, cookie, clientNonce, serverNonce); - _conn.Command("AUTHENTICATE " + HexStr(computedClientHash), boost::bind(&TorController::auth_cb, this, boost::placeholders::_1, boost::placeholders::_2)); + _conn.Command("AUTHENTICATE " + HexStr(computedClientHash), boost::bind(&TorController::auth_cb, this, boost::arg<1>(), boost::arg<2>())); } else { LogPrintf("tor: Invalid reply to AUTHCHALLENGE\n"); } @@ -648,23 +648,23 @@ void TorController::protocolinfo_cb(TorControlConnection& _conn, const TorContro if (methods.count("HASHEDPASSWORD")) { LogPrint("tor", "tor: Using HASHEDPASSWORD authentication\n"); boost::replace_all(torpassword, "\"", "\\\""); - _conn.Command("AUTHENTICATE \"" + torpassword + "\"", boost::bind(&TorController::auth_cb, this, boost::placeholders::_1, boost::placeholders::_2)); + _conn.Command("AUTHENTICATE \"" + torpassword + "\"", boost::bind(&TorController::auth_cb, this, boost::arg<1>(), boost::arg<2>())); } else { LogPrintf("tor: Password provided with -torpassword, but HASHEDPASSWORD authentication is not available\n"); } } else if (methods.count("NULL")) { LogPrint("tor", "tor: Using NULL authentication\n"); - _conn.Command("AUTHENTICATE", boost::bind(&TorController::auth_cb, this, boost::placeholders::_1, boost::placeholders::_2)); + _conn.Command("AUTHENTICATE", boost::bind(&TorController::auth_cb, this, boost::arg<1>(), boost::arg<2>())); } else if (methods.count("SAFECOOKIE")) { // Cookie: hexdump -e '32/1 "%02x""\n"' ~/.tor/control_auth_cookie LogPrint("tor", "tor: Using SAFECOOKIE authentication, reading cookie authentication from %s\n", cookiefile); std::pair status_cookie = ReadBinaryFile(cookiefile, TOR_COOKIE_SIZE); if (status_cookie.first && status_cookie.second.size() == TOR_COOKIE_SIZE) { - // _conn.Command("AUTHENTICATE " + HexStr(status_cookie.second), boost::bind(&TorController::auth_cb, this, boost::placeholders::_1, boost::placeholders::_2)); + // _conn.Command("AUTHENTICATE " + HexStr(status_cookie.second), boost::bind(&TorController::auth_cb, this, boost::arg<1>(), boost::arg<2>())); cookie = std::vector(status_cookie.second.begin(), status_cookie.second.end()); clientNonce = std::vector(TOR_NONCE_SIZE, 0); GetRandBytes(&clientNonce[0], TOR_NONCE_SIZE); - _conn.Command("AUTHCHALLENGE SAFECOOKIE " + HexStr(clientNonce), boost::bind(&TorController::authchallenge_cb, this, boost::placeholders::_1, boost::placeholders::_2)); + _conn.Command("AUTHCHALLENGE SAFECOOKIE " + HexStr(clientNonce), boost::bind(&TorController::authchallenge_cb, this, boost::arg<1>(), boost::arg<2>())); } else { if (status_cookie.first) { LogPrintf("tor: Authentication cookie %s is not exactly %i bytes, as is required by the spec\n", cookiefile, TOR_COOKIE_SIZE); @@ -686,7 +686,7 @@ void TorController::connected_cb(TorControlConnection& _conn) { reconnect_timeout = RECONNECT_TIMEOUT_START; // First send a PROTOCOLINFO command to figure out what authentication is expected - if (!_conn.Command("PROTOCOLINFO 1", boost::bind(&TorController::protocolinfo_cb, this, boost::placeholders::_1, boost::placeholders::_2))) + if (!_conn.Command("PROTOCOLINFO 1", boost::bind(&TorController::protocolinfo_cb, this, boost::arg<1>(), boost::arg<2>()))) LogPrintf("tor: Error sending initial protocolinfo command\n"); } diff --git a/src/txdb.cpp b/src/txdb.cpp index ac54c8e..900df69 100755 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -86,12 +86,19 @@ CBlockTreeDB::CBlockTreeDB(size_t nCacheSize, bool fMemory, bool fWipe) : CLevel bool CBlockTreeDB::WriteBlockIndex(const CDiskBlockIndex& blockindex) { - return Write(make_pair('b', blockindex.GetBlockHash()), blockindex); + return Write(std::make_pair('b', blockindex.GetBlockHash()), blockindex); } -bool CBlockTreeDB::WriteBlockFileInfo(int nFile, const CBlockFileInfo& info) -{ - return Write(make_pair('f', nFile), info); +bool CBlockTreeDB::WriteBatchSync(const std::vector >& fileInfo, int nLastFile, const std::vector& blockinfo) { + CLevelDBBatch batch; + for (std::vector >::const_iterator it=fileInfo.begin(); it != fileInfo.end(); it++) { + batch.Write(std::make_pair('f', it->first), *it->second); + } + batch.Write('l', nLastFile); + for (std::vector::const_iterator it=blockinfo.begin(); it != blockinfo.end(); it++) { + batch.Write(std::make_pair('b', (*it)->GetBlockHash()), CDiskBlockIndex(*it)); + } + return WriteBatch(batch, true); } bool CBlockTreeDB::ReadBlockFileInfo(int nFile, CBlockFileInfo& info) @@ -99,11 +106,6 @@ bool CBlockTreeDB::ReadBlockFileInfo(int nFile, CBlockFileInfo& info) return Read(make_pair('f', nFile), info); } -bool CBlockTreeDB::WriteLastBlockFile(int nFile) -{ - return Write('l', nFile); -} - bool CBlockTreeDB::WriteReindexing(bool fReindexing) { if (fReindexing) diff --git a/src/txdb.h b/src/txdb.h index de2fcf2..ecc5ede 100755 --- a/src/txdb.h +++ b/src/txdb.h @@ -56,10 +56,9 @@ class CBlockTreeDB : public CLevelDBWrapper public: bool WriteBlockIndex(const CDiskBlockIndex& blockindex); + bool WriteBatchSync(const std::vector >& fileInfo, int nLastFile, const std::vector& blockinfo); bool ReadBlockFileInfo(int nFile, CBlockFileInfo& fileinfo); - bool WriteBlockFileInfo(int nFile, const CBlockFileInfo& fileinfo); bool ReadLastBlockFile(int& nFile); - bool WriteLastBlockFile(int nFile); bool WriteReindexing(bool fReindex); bool ReadReindexing(bool& fReindex); bool ReadTxIndex(const uint256& txid, CDiskTxPos& pos); diff --git a/src/ui_interface.cpp b/src/ui_interface.cpp new file mode 100644 index 0000000..694dff1 --- /dev/null +++ b/src/ui_interface.cpp @@ -0,0 +1,30 @@ +// Copyright (c) 2010-2016 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "ui_interface.h" +#include "util.h" + +CClientUIInterface uiInterface; + +bool InitError(const std::string& str) +{ + uiInterface.ThreadSafeMessageBox(str, "", CClientUIInterface::MSG_ERROR); + return false; +} + +bool ShowSeedPhrase(const std::string &str) { + uiInterface.ThreadSafeMessageBox(str, "", CClientUIInterface::MSG_SEED); + return false; +} + + +void InitWarning(const std::string& str) +{ + uiInterface.ThreadSafeMessageBox(str, "", CClientUIInterface::MSG_WARNING); +} + +std::string AmountErrMsg(const char* const optname, const std::string& strValue) +{ + return strprintf(_("Invalid amount for -%s=: '%s'"), optname, strValue); +} diff --git a/src/ui_interface.h b/src/ui_interface.h index 7fc60e0..97eb92f 100755 --- a/src/ui_interface.h +++ b/src/ui_interface.h @@ -72,6 +72,7 @@ class CClientUIInterface /** Predefined combinations for certain default usage cases */ MSG_INFORMATION = ICON_INFORMATION, MSG_WARNING = (ICON_WARNING | BTN_OK | MODAL), + MSG_SEED = (ICON_WARNING | BTN_OK | MODAL | SECURE), MSG_ERROR = (ICON_ERROR | BTN_OK | MODAL) }; @@ -112,6 +113,17 @@ class CClientUIInterface boost::signals2::signal BannedListChanged; }; +/** Show warning message **/ +void InitWarning(const std::string& str); + +/** Show error message **/ +bool InitError(const std::string& str); + +//! Show 12-word seed phrase and confirm +bool ShowSeedPhrase(const std::string& str); + +std::string AmountErrMsg(const char* const optname, const std::string& strValue); + extern CClientUIInterface uiInterface; /** diff --git a/src/undo.h b/src/undo.h index 6b009f9..73e6328 100755 --- a/src/undo.h +++ b/src/undo.h @@ -74,4 +74,4 @@ class CTxUndo } }; -#endif // BITCOIN_UNDO_H +#endif // BITCOIN_UNDO_H \ No newline at end of file diff --git a/src/util.cpp b/src/util.cpp index b44f596..05687e8 100755 --- a/src/util.cpp +++ b/src/util.cpp @@ -18,13 +18,14 @@ #include "sync.h" #include "utilstrencodings.h" #include "utiltime.h" +// to be removed +#include "ui_interface.h" #include #include #include #include -#include // for OPENSSL_cleanse() #include @@ -246,6 +247,7 @@ bool LogAcceptCategory(const char* category) ptrCategory->insert(string("mnpayments")); ptrCategory->insert(string("zero")); ptrCategory->insert(string("knbudget")); + ptrCategory->insert(string("staking")); } } const set& setCategories = *ptrCategory.get(); @@ -575,6 +577,18 @@ static boost::filesystem::path pathCached; static boost::filesystem::path pathCachedNetSpecific; static CCriticalSection csPathCached; +bool CheckIfWalletDatExists(bool fNetSpecific) { + + namespace fs = boost::filesystem; + + std::string walletFile = GetArg("-wallet", "wallet.dat"); + boost::filesystem::path path(walletFile); + if (!path.is_complete()) + path = GetDataDir(fNetSpecific) / path; + + return fs::exists(path); +} + const boost::filesystem::path& GetDataDir(bool fNetSpecific) { namespace fs = boost::filesystem; diff --git a/src/util.h b/src/util.h index 74d5c75..852b5fe 100755 --- a/src/util.h +++ b/src/util.h @@ -20,6 +20,7 @@ #include "tinyformat.h" #include "utiltime.h" + #include #include #include @@ -29,6 +30,16 @@ #include #include +// Debugging macros +// Uncomment the following line to enable debugging messages +// or enable on a per file basis prior to inclusion of util.h +//#define ENABLE_OHMCOIN_DEBUG +#ifdef ENABLE_OHMCOIN_DEBUG +#define DBG( x ) x +#else +#define DBG( x ) +#endif + //Ohmcoin only features extern bool fMasterNode; @@ -116,6 +127,7 @@ void AllocateFileRange(FILE* file, unsigned int offset, unsigned int length); bool RenameOver(boost::filesystem::path src, boost::filesystem::path dest); bool TryCreateDirectory(const boost::filesystem::path& p); boost::filesystem::path GetDefaultDataDir(); +bool CheckIfWalletDatExists(bool fNetSpecific = true); const boost::filesystem::path& GetDataDir(bool fNetSpecific = true); boost::filesystem::path GetConfigFile(); boost::filesystem::path GetKarmanodeConfigFile(); diff --git a/src/utilsplitstring.h b/src/utilsplitstring.h new file mode 100644 index 0000000..1241cf7 --- /dev/null +++ b/src/utilsplitstring.h @@ -0,0 +1,42 @@ +// Copyright (c) 2018 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include +#include +#include +#include +#include + +#pragma once +/** + * Tokenizes a string by any of the given separators. + * @param[in] tokens The container (either an instance of std::vector + * or std::set) to add tokenized string parts to. + * @param[in] str The string to tokenize. + * @param[in] anyOfSeparator A string with valid separators. + * @param[in] mergeEmpty Set to true to merge adjacent separators (empty tokens); otherwise false (default). + */ +template +void Split(ContainerT& tokens, const std::string& str, const std::string& anyOfSeparator, bool mergeEmpty = false) { + static_assert(std::is_same, ContainerT>::value || + std::is_same, ContainerT>::value, + "ContainerT must be of type std::vector or std::set"); + auto insertIt = std::inserter(tokens, tokens.end()); + if (str.empty()) { + *insertIt = ""; + return; + } + const auto begin = str.cbegin(); + const auto end = str.cend(); + for (auto it = begin; it < end;) { + bool foundSeparator = false; + auto tokenIt = it; + while (tokenIt < end && !(foundSeparator = anyOfSeparator.find(*tokenIt) != std::string::npos)) { ++tokenIt; } + if (tokenIt != begin && (!mergeEmpty || tokenIt != it)) { *insertIt = std::string(it, tokenIt); } + if (foundSeparator) { + if (tokenIt == begin) { *insertIt = ""; } + if (tokenIt == end - 1) { *insertIt = ""; } + } + it = tokenIt + 1; + } +} diff --git a/src/utilstrencodings.cpp b/src/utilstrencodings.cpp index 41f88e6..a59f332 100755 --- a/src/utilstrencodings.cpp +++ b/src/utilstrencodings.cpp @@ -16,7 +16,6 @@ #include #include -#include // for OPENSSL_cleanse() #include @@ -278,7 +277,7 @@ SecureString EncodeBase64Secure(const SecureString& input) SecureString output(bptr->data, bptr->length); // Cleanse secure data buffer from memory - OPENSSL_cleanse((void*)bptr->data, bptr->length); + memory_cleanse((void*)bptr->data, bptr->length); // Free memory BIO_free_all(b64); @@ -585,3 +584,17 @@ int atoi(const std::string& str) { return atoi(str.c_str()); } + +// Replaces boost::join +std::string join(const std::vector& words, const std::string &separator, const std::string &concluder) { + + std::stringstream ss; + for (size_t i=0;i0) ss << separator; + ss << words[i]; + } + + ss << concluder; + + return ss.str(); +} diff --git a/src/utilstrencodings.h b/src/utilstrencodings.h index d6b4211..7a36096 100755 --- a/src/utilstrencodings.h +++ b/src/utilstrencodings.h @@ -20,6 +20,9 @@ #define UEND(a) ((unsigned char*)&((&(a))[1])) #define ARRAYLEN(array) (sizeof(array) / sizeof((array)[0])) +/** This is needed because the foreach macro can't get over the comma in pair */ +#define PAIRTYPE(t1, t2) std::pair + std::string SanitizeString(const std::string& str); std::vector ParseHex(const char* psz); std::vector ParseHex(const std::string& str); @@ -151,4 +154,8 @@ bool ConvertBits(O& out, I it, I end) { return true; } + +// Join words with separator +std::string join(const std::vector& words, const std::string &separator = ", ", const std::string &concluder = ""); + #endif // BITCOIN_UTILSTRENCODINGS_H diff --git a/src/validationinterface.cpp b/src/validationinterface.cpp index e47b2b2..ee567b2 100755 --- a/src/validationinterface.cpp +++ b/src/validationinterface.cpp @@ -13,31 +13,31 @@ CMainSignals& GetMainSignals() } void RegisterValidationInterface(CValidationInterface* pwalletIn) { -// XX42 g_signals.EraseTransaction.connect(boost::bind(&CValidationInterface::EraseFromWallet, pwalletIn, boost::placeholders::_1)); - g_signals.UpdatedBlockTip.connect(boost::bind(&CValidationInterface::UpdatedBlockTip, pwalletIn, boost::placeholders::_1)); - g_signals.SyncTransaction.connect(boost::bind(&CValidationInterface::SyncTransaction, pwalletIn, boost::placeholders::_1, boost::placeholders::_2)); - g_signals.NotifyTransactionLock.connect(boost::bind(&CValidationInterface::NotifyTransactionLock, pwalletIn, boost::placeholders::_1)); - g_signals.UpdatedTransaction.connect(boost::bind(&CValidationInterface::UpdatedTransaction, pwalletIn, boost::placeholders::_1)); - g_signals.SetBestChain.connect(boost::bind(&CValidationInterface::SetBestChain, pwalletIn, boost::placeholders::_1)); - g_signals.Inventory.connect(boost::bind(&CValidationInterface::Inventory, pwalletIn, boost::placeholders::_1)); +// XX42 g_signals.EraseTransaction.connect(boost::bind(&CValidationInterface::EraseFromWallet, pwalletIn, boost::arg<1>())); + g_signals.UpdatedBlockTip.connect(boost::bind(&CValidationInterface::UpdatedBlockTip, pwalletIn, boost::arg<1>())); + g_signals.SyncTransaction.connect(boost::bind(&CValidationInterface::SyncTransaction, pwalletIn, boost::arg<1>(), boost::arg<2>())); + g_signals.NotifyTransactionLock.connect(boost::bind(&CValidationInterface::NotifyTransactionLock, pwalletIn, boost::arg<1>())); + g_signals.UpdatedTransaction.connect(boost::bind(&CValidationInterface::UpdatedTransaction, pwalletIn, boost::arg<1>())); + g_signals.SetBestChain.connect(boost::bind(&CValidationInterface::SetBestChain, pwalletIn, boost::arg<1>())); + g_signals.Inventory.connect(boost::bind(&CValidationInterface::Inventory, pwalletIn, boost::arg<1>())); g_signals.Broadcast.connect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn)); - g_signals.BlockChecked.connect(boost::bind(&CValidationInterface::BlockChecked, pwalletIn, boost::placeholders::_1, boost::placeholders::_2)); -// XX42 g_signals.ScriptForMining.connect(boost::bind(&CValidationInterface::GetScriptForMining, pwalletIn, boost::placeholders::_1)); - g_signals.BlockFound.connect(boost::bind(&CValidationInterface::ResetRequestCount, pwalletIn, boost::placeholders::_1)); + g_signals.BlockChecked.connect(boost::bind(&CValidationInterface::BlockChecked, pwalletIn, boost::arg<1>(), boost::arg<2>())); +// XX42 g_signals.ScriptForMining.connect(boost::bind(&CValidationInterface::GetScriptForMining, pwalletIn, boost::arg<1>())); + g_signals.BlockFound.connect(boost::bind(&CValidationInterface::ResetRequestCount, pwalletIn, boost::arg<1>())); } void UnregisterValidationInterface(CValidationInterface* pwalletIn) { - g_signals.BlockFound.disconnect(boost::bind(&CValidationInterface::ResetRequestCount, pwalletIn, boost::placeholders::_1)); -// XX42 g_signals.ScriptForMining.disconnect(boost::bind(&CValidationInterface::GetScriptForMining, pwalletIn, boost::placeholders::_1)); - g_signals.BlockChecked.disconnect(boost::bind(&CValidationInterface::BlockChecked, pwalletIn, boost::placeholders::_1, boost::placeholders::_2)); + g_signals.BlockFound.disconnect(boost::bind(&CValidationInterface::ResetRequestCount, pwalletIn, boost::arg<1>())); +// XX42 g_signals.ScriptForMining.disconnect(boost::bind(&CValidationInterface::GetScriptForMining, pwalletIn, boost::arg<1>())); + g_signals.BlockChecked.disconnect(boost::bind(&CValidationInterface::BlockChecked, pwalletIn, boost::arg<1>(), boost::arg<2>())); g_signals.Broadcast.disconnect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn)); - g_signals.Inventory.disconnect(boost::bind(&CValidationInterface::Inventory, pwalletIn, boost::placeholders::_1)); - g_signals.SetBestChain.disconnect(boost::bind(&CValidationInterface::SetBestChain, pwalletIn, boost::placeholders::_1)); - g_signals.UpdatedTransaction.disconnect(boost::bind(&CValidationInterface::UpdatedTransaction, pwalletIn, boost::placeholders::_1)); - g_signals.NotifyTransactionLock.disconnect(boost::bind(&CValidationInterface::NotifyTransactionLock, pwalletIn, boost::placeholders::_1)); - g_signals.SyncTransaction.disconnect(boost::bind(&CValidationInterface::SyncTransaction, pwalletIn, boost::placeholders::_1, boost::placeholders::_2)); - g_signals.UpdatedBlockTip.disconnect(boost::bind(&CValidationInterface::UpdatedBlockTip, pwalletIn, boost::placeholders::_1)); -// XX42 g_signals.EraseTransaction.disconnect(boost::bind(&CValidationInterface::EraseFromWallet, pwalletIn, boost::placeholders::_1)); + g_signals.Inventory.disconnect(boost::bind(&CValidationInterface::Inventory, pwalletIn, boost::arg<1>())); + g_signals.SetBestChain.disconnect(boost::bind(&CValidationInterface::SetBestChain, pwalletIn, boost::arg<1>())); + g_signals.UpdatedTransaction.disconnect(boost::bind(&CValidationInterface::UpdatedTransaction, pwalletIn, boost::arg<1>())); + g_signals.NotifyTransactionLock.disconnect(boost::bind(&CValidationInterface::NotifyTransactionLock, pwalletIn, boost::arg<1>())); + g_signals.SyncTransaction.disconnect(boost::bind(&CValidationInterface::SyncTransaction, pwalletIn, boost::arg<1>(), boost::arg<2>())); + g_signals.UpdatedBlockTip.disconnect(boost::bind(&CValidationInterface::UpdatedBlockTip, pwalletIn, boost::arg<1>())); +// XX42 g_signals.EraseTransaction.disconnect(boost::bind(&CValidationInterface::EraseFromWallet, pwalletIn, boost::arg<1>())); } void UnregisterAllValidationInterfaces() { diff --git a/src/wallet/arrayslice.h b/src/wallet/arrayslice.h new file mode 100644 index 0000000..43eb958 --- /dev/null +++ b/src/wallet/arrayslice.h @@ -0,0 +1,45 @@ +/** + * Copyright (c) 2011-2019 libbitcoin developers (see AUTHORS) + * + * This file is part of libbitcoin. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#ifndef PHORE_ARRAYSLICE_H +#define PHORE_ARRAYSLICE_H + +#include + +template +class array_slice +{ +public: + template + array_slice(const Container& container) : begin_(container.data()), end_(container.data() + container.size()) {} + + array_slice(const Iterable* begin, const Iterable* end) : begin_(begin), end_(end) {} + + const Iterable* begin() const { return begin_; } + const Iterable* end() const { return end_; } + const Iterable* data() const { return begin_; } + std::size_t size() const { return end_ - begin_; } + bool empty() const { return end_ == begin_; } + +private: + const Iterable* begin_; + const Iterable* end_; +}; + +#endif //PHORE_ARRAYSLICE_H diff --git a/src/wallet/bip39.cpp b/src/wallet/bip39.cpp new file mode 100644 index 0000000..f946a4b --- /dev/null +++ b/src/wallet/bip39.cpp @@ -0,0 +1,239 @@ +/** + * Copyright (c) 2013-2014 Tomas Dzetkulic + * Copyright (c) 2013-2014 Pavol Rusnak + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +// Source: +// https://github.com/trezor/trezor-crypto + +#include "wallet/bip39.h" +#include "wallet/bip39_english.h" +#include "crypto/sha256.h" +#include +#include +#include "random.h" + +#include + +std::vector CMnemonic::Generate(int strength) +{ + assert(strength == 256); + + SecureVector data(32); + GetRandBytes(&data[0], 32); + std::vector mnemonic = FromData(data, strength / 8); + return mnemonic; +} + +// SecureString CMnemonic::FromData(const uint8_t *data, int len) +std::vector CMnemonic::FromData(const SecureVector& data, int len) +{ + + SecureVector checksum(32); + CSHA256().Write(&data[0], len).Finalize(&checksum[0]); + + // data + SecureVector bits(len); + memcpy(&bits[0], &data[0], len); + // checksum + bits.push_back(checksum[0]); + + int mlen = len * 3 / 4; + std::vector mnemonic; + + int i, j, idx; + for (i = 0; i < mlen; i++) { + idx = 0; + for (j = 0; j < 11; j++) { + idx <<= 1; + idx += (bits[(i * 11 + j) / 8] & (1 << (7 - ((i * 11 + j) % 8)))) > 0; + } + mnemonic.push_back(wordlist[idx]); + } + + return mnemonic; +} + +std::vector CMnemonic::getListOfAllWordInLanguage() { + + std::vector words; + + for (unsigned long i=0; i< 2048 ; i++) { + words.push_back(wordlist[i]); + } + return words; +} + +bool CMnemonic::Check(std::string mnemonic) +{ + if (mnemonic.empty()) { + return false; + } + + uint32_t nWordCount{}; + + for (size_t i = 0; i < mnemonic.size(); ++i) { + if (mnemonic[i] == ' ') { + nWordCount++; + } + } + nWordCount++; + // check number of words + if (nWordCount != 12 && nWordCount != 18 && nWordCount != 24) { + return false; + } + + SecureString ssCurrentWord; + SecureVector bits(32 + 1); + + uint32_t nWordIndex, ki, nBitsCount{}; + + for (size_t i = 0; i < mnemonic.size(); ++i) + { + ssCurrentWord = ""; + while (i + ssCurrentWord.size() < mnemonic.size() && mnemonic[i + ssCurrentWord.size()] != ' ') { + if (ssCurrentWord.size() >= 9) { + return false; + } + ssCurrentWord += mnemonic[i + ssCurrentWord.size()]; + } + i += ssCurrentWord.size(); + nWordIndex = 0; + for (;;) { + if (!wordlist[nWordIndex]) { // word not found + return false; + } + if (ssCurrentWord == wordlist[nWordIndex]) { // word found on index nWordIndex + for (ki = 0; ki < 11; ki++) { + if (nWordIndex & (1 << (10 - ki))) { + bits[nBitsCount / 8] |= 1 << (7 - (nBitsCount % 8)); + } + nBitsCount++; + } + break; + } + nWordIndex++; + } + } + if (nBitsCount != nWordCount * 11) { + return false; + } + bits[32] = bits[nWordCount * 4 / 3]; + CSHA256().Write(&bits[0], nWordCount * 4 / 3).Finalize(&bits[0]); + + bool fResult = 0; + if (nWordCount == 12) { + fResult = (bits[0] & 0xF0) == (bits[32] & 0xF0); // compare first 4 bits + } else + if (nWordCount == 18) { + fResult = (bits[0] & 0xFC) == (bits[32] & 0xFC); // compare first 6 bits + } else + if (nWordCount == 24) { + fResult = bits[0] == bits[32]; // compare 8 bits + } + + return fResult; +} + +bool CMnemonic::Check(SecureString mnemonic) +{ + if (mnemonic.empty()) { + return false; + } + + uint32_t nWordCount{}; + + for (size_t i = 0; i < mnemonic.size(); ++i) { + if (mnemonic[i] == ' ') { + nWordCount++; + } + } + nWordCount++; + // check number of words + if (nWordCount != 12 && nWordCount != 18 && nWordCount != 24) { + return false; + } + + SecureString ssCurrentWord; + SecureVector bits(32 + 1); + + uint32_t nWordIndex, ki, nBitsCount{}; + + for (size_t i = 0; i < mnemonic.size(); ++i) + { + ssCurrentWord = ""; + while (i + ssCurrentWord.size() < mnemonic.size() && mnemonic[i + ssCurrentWord.size()] != ' ') { + if (ssCurrentWord.size() >= 9) { + return false; + } + ssCurrentWord += mnemonic[i + ssCurrentWord.size()]; + } + i += ssCurrentWord.size(); + nWordIndex = 0; + for (;;) { + if (!wordlist[nWordIndex]) { // word not found + return false; + } + if (ssCurrentWord == wordlist[nWordIndex]) { // word found on index nWordIndex + for (ki = 0; ki < 11; ki++) { + if (nWordIndex & (1 << (10 - ki))) { + bits[nBitsCount / 8] |= 1 << (7 - (nBitsCount % 8)); + } + nBitsCount++; + } + break; + } + nWordIndex++; + } + } + if (nBitsCount != nWordCount * 11) { + return false; + } + bits[32] = bits[nWordCount * 4 / 3]; + CSHA256().Write(&bits[0], nWordCount * 4 / 3).Finalize(&bits[0]); + + bool fResult = 0; + if (nWordCount == 12) { + fResult = (bits[0] & 0xF0) == (bits[32] & 0xF0); // compare first 4 bits + } else + if (nWordCount == 18) { + fResult = (bits[0] & 0xFC) == (bits[32] & 0xFC); // compare first 6 bits + } else + if (nWordCount == 24) { + fResult = bits[0] == bits[32]; // compare 8 bits + } + + return fResult; +} + + +// passphrase must be at most 256 characters or code may crash +void CMnemonic::ToSeed(SecureString mnemonic, SecureString passphrase, SecureVector& seedRet) +{ + SecureString ssSalt = SecureString("mnemonic") + passphrase; + SecureVector vchSalt(ssSalt.begin(), ssSalt.end()); + seedRet.resize(64); + // int PKCS5_PBKDF2_HMAC(const char *pass, int passlen, + // const unsigned char *salt, int saltlen, int iter, + // const EVP_MD *digest, + // int keylen, unsigned char *out); + PKCS5_PBKDF2_HMAC(mnemonic.c_str(), mnemonic.size(), &vchSalt[0], vchSalt.size(), 2048, EVP_sha512(), 64, &seedRet[0]); +} \ No newline at end of file diff --git a/src/wallet/bip39.h b/src/wallet/bip39.h new file mode 100644 index 0000000..7b07e22 --- /dev/null +++ b/src/wallet/bip39.h @@ -0,0 +1,41 @@ +/** + * Copyright (c) 2013-2014 Tomas Dzetkulic + * Copyright (c) 2013-2014 Pavol Rusnak + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef PHORE_BIP39_H +#define PHORE_BIP39_H + +#include "allocators.h" + +class CMnemonic +{ +public: + static std::vector Generate(int strength); // strength in bits + static std::vector FromData(const SecureVector& data, int len); + static std::vector getListOfAllWordInLanguage(); + static bool Check(std::string mnemonic); + static bool Check(SecureString mnemonic); + // passphrase must be at most 256 characters or code may crash + static void ToSeed(SecureString mnemonic, SecureString passphrase, SecureVector& seedRet); +}; + +#endif \ No newline at end of file diff --git a/src/wallet/bip39_english.h b/src/wallet/bip39_english.h new file mode 100644 index 0000000..0fad761 --- /dev/null +++ b/src/wallet/bip39_english.h @@ -0,0 +1,2074 @@ +/** + * Copyright (c) 2013-2014 Tomas Dzetkulic + * Copyright (c) 2013-2014 Pavol Rusnak + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +const char * const wordlist[] = { + "abandon", + "ability", + "able", + "about", + "above", + "absent", + "absorb", + "abstract", + "absurd", + "abuse", + "access", + "accident", + "account", + "accuse", + "achieve", + "acid", + "acoustic", + "acquire", + "across", + "act", + "action", + "actor", + "actress", + "actual", + "adapt", + "add", + "addict", + "address", + "adjust", + "admit", + "adult", + "advance", + "advice", + "aerobic", + "affair", + "afford", + "afraid", + "again", + "age", + "agent", + "agree", + "ahead", + "aim", + "air", + "airport", + "aisle", + "alarm", + "album", + "alcohol", + "alert", + "alien", + "all", + "alley", + "allow", + "almost", + "alone", + "alpha", + "already", + "also", + "alter", + "always", + "amateur", + "amazing", + "among", + "amount", + "amused", + "analyst", + "anchor", + "ancient", + "anger", + "angle", + "angry", + "animal", + "ankle", + "announce", + "annual", + "another", + "answer", + "antenna", + "antique", + "anxiety", + "any", + "apart", + "apology", + "appear", + "apple", + "approve", + "april", + "arch", + "arctic", + "area", + "arena", + "argue", + "arm", + "armed", + "armor", + "army", + "around", + "arrange", + "arrest", + "arrive", + "arrow", + "art", + "artefact", + "artist", + "artwork", + "ask", + "aspect", + "assault", + "asset", + "assist", + "assume", + "asthma", + "athlete", + "atom", + "attack", + "attend", + "attitude", + "attract", + "auction", + "audit", + "august", + "aunt", + "author", + "auto", + "autumn", + "average", + "avocado", + "avoid", + "awake", + "aware", + "away", + "awesome", + "awful", + "awkward", + "axis", + "baby", + "bachelor", + "bacon", + "badge", + "bag", + "balance", + "balcony", + "ball", + "bamboo", + "banana", + "banner", + "bar", + "barely", + "bargain", + "barrel", + "base", + "basic", + "basket", + "battle", + "beach", + "bean", + "beauty", + "because", + "become", + "beef", + "before", + "begin", + "behave", + "behind", + "believe", + "below", + "belt", + "bench", + "benefit", + "best", + "betray", + "better", + "between", + "beyond", + "bicycle", + "bid", + "bike", + "bind", + "biology", + "bird", + "birth", + "bitter", + "black", + "blade", + "blame", + "blanket", + "blast", + "bleak", + "bless", + "blind", + "blood", + "blossom", + "blouse", + "blue", + "blur", + "blush", + "board", + "boat", + "body", + "boil", + "bomb", + "bone", + "bonus", + "book", + "boost", + "border", + "boring", + "borrow", + "boss", + "bottom", + "bounce", + "box", + "boy", + "bracket", + "brain", + "brand", + "brass", + "brave", + "bread", + "breeze", + "brick", + "bridge", + "brief", + "bright", + "bring", + "brisk", + "broccoli", + "broken", + "bronze", + "broom", + "brother", + "brown", + "brush", + "bubble", + "buddy", + "budget", + "buffalo", + "build", + "bulb", + "bulk", + "bullet", + "bundle", + "bunker", + "burden", + "burger", + "burst", + "bus", + "business", + "busy", + "butter", + "buyer", + "buzz", + "cabbage", + "cabin", + "cable", + "cactus", + "cage", + "cake", + "call", + "calm", + "camera", + "camp", + "can", + "canal", + "cancel", + "candy", + "cannon", + "canoe", + "canvas", + "canyon", + "capable", + "capital", + "captain", + "car", + "carbon", + "card", + "cargo", + "carpet", + "carry", + "cart", + "case", + "cash", + "casino", + "castle", + "casual", + "cat", + "catalog", + "catch", + "category", + "cattle", + "caught", + "cause", + "caution", + "cave", + "ceiling", + "celery", + "cement", + "census", + "century", + "cereal", + "certain", + "chair", + "chalk", + "champion", + "change", + "chaos", + "chapter", + "charge", + "chase", + "chat", + "cheap", + "check", + "cheese", + "chef", + "cherry", + "chest", + "chicken", + "chief", + "child", + "chimney", + "choice", + "choose", + "chronic", + "chuckle", + "chunk", + "churn", + "cigar", + "cinnamon", + "circle", + "citizen", + "city", + "civil", + "claim", + "clap", + "clarify", + "claw", + "clay", + "clean", + "clerk", + "clever", + "click", + "client", + "cliff", + "climb", + "clinic", + "clip", + "clock", + "clog", + "close", + "cloth", + "cloud", + "clown", + "club", + "clump", + "cluster", + "clutch", + "coach", + "coast", + "coconut", + "code", + "coffee", + "coil", + "coin", + "collect", + "color", + "column", + "combine", + "come", + "comfort", + "comic", + "common", + "company", + "concert", + "conduct", + "confirm", + "congress", + "connect", + "consider", + "control", + "convince", + "cook", + "cool", + "copper", + "copy", + "coral", + "core", + "corn", + "correct", + "cost", + "cotton", + "couch", + "country", + "couple", + "course", + "cousin", + "cover", + "coyote", + "crack", + "cradle", + "craft", + "cram", + "crane", + "crash", + "crater", + "crawl", + "crazy", + "cream", + "credit", + "creek", + "crew", + "cricket", + "crime", + "crisp", + "critic", + "crop", + "cross", + "crouch", + "crowd", + "crucial", + "cruel", + "cruise", + "crumble", + "crunch", + "crush", + "cry", + "crystal", + "cube", + "culture", + "cup", + "cupboard", + "curious", + "current", + "curtain", + "curve", + "cushion", + "custom", + "cute", + "cycle", + "dad", + "damage", + "damp", + "dance", + "danger", + "daring", + "dash", + "daughter", + "dawn", + "day", + "deal", + "debate", + "debris", + "decade", + "december", + "decide", + "decline", + "decorate", + "decrease", + "deer", + "defense", + "define", + "defy", + "degree", + "delay", + "deliver", + "demand", + "demise", + "denial", + "dentist", + "deny", + "depart", + "depend", + "deposit", + "depth", + "deputy", + "derive", + "describe", + "desert", + "design", + "desk", + "despair", + "destroy", + "detail", + "detect", + "develop", + "device", + "devote", + "diagram", + "dial", + "diamond", + "diary", + "dice", + "diesel", + "diet", + "differ", + "digital", + "dignity", + "dilemma", + "dinner", + "dinosaur", + "direct", + "dirt", + "disagree", + "discover", + "disease", + "dish", + "dismiss", + "disorder", + "display", + "distance", + "divert", + "divide", + "divorce", + "dizzy", + "doctor", + "document", + "dog", + "doll", + "dolphin", + "domain", + "donate", + "donkey", + "donor", + "door", + "dose", + "double", + "dove", + "draft", + "dragon", + "drama", + "drastic", + "draw", + "dream", + "dress", + "drift", + "drill", + "drink", + "drip", + "drive", + "drop", + "drum", + "dry", + "duck", + "dumb", + "dune", + "during", + "dust", + "dutch", + "duty", + "dwarf", + "dynamic", + "eager", + "eagle", + "early", + "earn", + "earth", + "easily", + "east", + "easy", + "echo", + "ecology", + "economy", + "edge", + "edit", + "educate", + "effort", + "egg", + "eight", + "either", + "elbow", + "elder", + "electric", + "elegant", + "element", + "elephant", + "elevator", + "elite", + "else", + "embark", + "embody", + "embrace", + "emerge", + "emotion", + "employ", + "empower", + "empty", + "enable", + "enact", + "end", + "endless", + "endorse", + "enemy", + "energy", + "enforce", + "engage", + "engine", + "enhance", + "enjoy", + "enlist", + "enough", + "enrich", + "enroll", + "ensure", + "enter", + "entire", + "entry", + "envelope", + "episode", + "equal", + "equip", + "era", + "erase", + "erode", + "erosion", + "error", + "erupt", + "escape", + "essay", + "essence", + "estate", + "eternal", + "ethics", + "evidence", + "evil", + "evoke", + "evolve", + "exact", + "example", + "excess", + "exchange", + "excite", + "exclude", + "excuse", + "execute", + "exercise", + "exhaust", + "exhibit", + "exile", + "exist", + "exit", + "exotic", + "expand", + "expect", + "expire", + "explain", + "expose", + "express", + "extend", + "extra", + "eye", + "eyebrow", + "fabric", + "face", + "faculty", + "fade", + "faint", + "faith", + "fall", + "false", + "fame", + "family", + "famous", + "fan", + "fancy", + "fantasy", + "farm", + "fashion", + "fat", + "fatal", + "father", + "fatigue", + "fault", + "favorite", + "feature", + "february", + "federal", + "fee", + "feed", + "feel", + "female", + "fence", + "festival", + "fetch", + "fever", + "few", + "fiber", + "fiction", + "field", + "figure", + "file", + "film", + "filter", + "final", + "find", + "fine", + "finger", + "finish", + "fire", + "firm", + "first", + "fiscal", + "fish", + "fit", + "fitness", + "fix", + "flag", + "flame", + "flash", + "flat", + "flavor", + "flee", + "flight", + "flip", + "float", + "flock", + "floor", + "flower", + "fluid", + "flush", + "fly", + "foam", + "focus", + "fog", + "foil", + "fold", + "follow", + "food", + "foot", + "force", + "forest", + "forget", + "fork", + "fortune", + "forum", + "forward", + "fossil", + "foster", + "found", + "fox", + "fragile", + "frame", + "frequent", + "fresh", + "friend", + "fringe", + "frog", + "front", + "frost", + "frown", + "frozen", + "fruit", + "fuel", + "fun", + "funny", + "furnace", + "fury", + "future", + "gadget", + "gain", + "galaxy", + "gallery", + "game", + "gap", + "garage", + "garbage", + "garden", + "garlic", + "garment", + "gas", + "gasp", + "gate", + "gather", + "gauge", + "gaze", + "general", + "genius", + "genre", + "gentle", + "genuine", + "gesture", + "ghost", + "giant", + "gift", + "giggle", + "ginger", + "giraffe", + "girl", + "give", + "glad", + "glance", + "glare", + "glass", + "glide", + "glimpse", + "globe", + "gloom", + "glory", + "glove", + "glow", + "glue", + "goat", + "goddess", + "gold", + "good", + "goose", + "gorilla", + "gospel", + "gossip", + "govern", + "gown", + "grab", + "grace", + "grain", + "grant", + "grape", + "grass", + "gravity", + "great", + "green", + "grid", + "grief", + "grit", + "grocery", + "group", + "grow", + "grunt", + "guard", + "guess", + "guide", + "guilt", + "guitar", + "gun", + "gym", + "habit", + "hair", + "half", + "hammer", + "hamster", + "hand", + "happy", + "harbor", + "hard", + "harsh", + "harvest", + "hat", + "have", + "hawk", + "hazard", + "head", + "health", + "heart", + "heavy", + "hedgehog", + "height", + "hello", + "helmet", + "help", + "hen", + "hero", + "hidden", + "high", + "hill", + "hint", + "hip", + "hire", + "history", + "hobby", + "hockey", + "hold", + "hole", + "holiday", + "hollow", + "home", + "honey", + "hood", + "hope", + "horn", + "horror", + "horse", + "hospital", + "host", + "hotel", + "hour", + "hover", + "hub", + "huge", + "human", + "humble", + "humor", + "hundred", + "hungry", + "hunt", + "hurdle", + "hurry", + "hurt", + "husband", + "hybrid", + "ice", + "icon", + "idea", + "identify", + "idle", + "ignore", + "ill", + "illegal", + "illness", + "image", + "imitate", + "immense", + "immune", + "impact", + "impose", + "improve", + "impulse", + "inch", + "include", + "income", + "increase", + "index", + "indicate", + "indoor", + "industry", + "infant", + "inflict", + "inform", + "inhale", + "inherit", + "initial", + "inject", + "injury", + "inmate", + "inner", + "innocent", + "input", + "inquiry", + "insane", + "insect", + "inside", + "inspire", + "install", + "intact", + "interest", + "into", + "invest", + "invite", + "involve", + "iron", + "island", + "isolate", + "issue", + "item", + "ivory", + "jacket", + "jaguar", + "jar", + "jazz", + "jealous", + "jeans", + "jelly", + "jewel", + "job", + "join", + "joke", + "journey", + "joy", + "judge", + "juice", + "jump", + "jungle", + "junior", + "junk", + "just", + "kangaroo", + "keen", + "keep", + "ketchup", + "key", + "kick", + "kid", + "kidney", + "kind", + "kingdom", + "kiss", + "kit", + "kitchen", + "kite", + "kitten", + "kiwi", + "knee", + "knife", + "knock", + "know", + "lab", + "label", + "labor", + "ladder", + "lady", + "lake", + "lamp", + "language", + "laptop", + "large", + "later", + "latin", + "laugh", + "laundry", + "lava", + "law", + "lawn", + "lawsuit", + "layer", + "lazy", + "leader", + "leaf", + "learn", + "leave", + "lecture", + "left", + "leg", + "legal", + "legend", + "leisure", + "lemon", + "lend", + "length", + "lens", + "leopard", + "lesson", + "letter", + "level", + "liar", + "liberty", + "library", + "license", + "life", + "lift", + "light", + "like", + "limb", + "limit", + "link", + "lion", + "liquid", + "list", + "little", + "live", + "lizard", + "load", + "loan", + "lobster", + "local", + "lock", + "logic", + "lonely", + "long", + "loop", + "lottery", + "loud", + "lounge", + "love", + "loyal", + "lucky", + "luggage", + "lumber", + "lunar", + "lunch", + "luxury", + "lyrics", + "machine", + "mad", + "magic", + "magnet", + "maid", + "mail", + "main", + "major", + "make", + "mammal", + "man", + "manage", + "mandate", + "mango", + "mansion", + "manual", + "maple", + "marble", + "march", + "margin", + "marine", + "market", + "marriage", + "mask", + "mass", + "master", + "match", + "material", + "math", + "matrix", + "matter", + "maximum", + "maze", + "meadow", + "mean", + "measure", + "meat", + "mechanic", + "medal", + "media", + "melody", + "melt", + "member", + "memory", + "mention", + "menu", + "mercy", + "merge", + "merit", + "merry", + "mesh", + "message", + "metal", + "method", + "middle", + "midnight", + "milk", + "million", + "mimic", + "mind", + "minimum", + "minor", + "minute", + "miracle", + "mirror", + "misery", + "miss", + "mistake", + "mix", + "mixed", + "mixture", + "mobile", + "model", + "modify", + "mom", + "moment", + "monitor", + "monkey", + "monster", + "month", + "moon", + "moral", + "more", + "morning", + "mosquito", + "mother", + "motion", + "motor", + "mountain", + "mouse", + "move", + "movie", + "much", + "muffin", + "mule", + "multiply", + "muscle", + "museum", + "mushroom", + "music", + "must", + "mutual", + "myself", + "mystery", + "myth", + "naive", + "name", + "napkin", + "narrow", + "nasty", + "nation", + "nature", + "near", + "neck", + "need", + "negative", + "neglect", + "neither", + "nephew", + "nerve", + "nest", + "net", + "network", + "neutral", + "never", + "news", + "next", + "nice", + "night", + "noble", + "noise", + "nominee", + "noodle", + "normal", + "north", + "nose", + "notable", + "note", + "nothing", + "notice", + "novel", + "now", + "nuclear", + "number", + "nurse", + "nut", + "oak", + "obey", + "object", + "oblige", + "obscure", + "observe", + "obtain", + "obvious", + "occur", + "ocean", + "october", + "odor", + "off", + "offer", + "office", + "often", + "oil", + "okay", + "old", + "olive", + "olympic", + "omit", + "once", + "one", + "onion", + "online", + "only", + "open", + "opera", + "opinion", + "oppose", + "option", + "orange", + "orbit", + "orchard", + "order", + "ordinary", + "organ", + "orient", + "original", + "orphan", + "ostrich", + "other", + "outdoor", + "outer", + "output", + "outside", + "oval", + "oven", + "over", + "own", + "owner", + "oxygen", + "oyster", + "ozone", + "pact", + "paddle", + "page", + "pair", + "palace", + "palm", + "panda", + "panel", + "panic", + "panther", + "paper", + "parade", + "parent", + "park", + "parrot", + "party", + "pass", + "patch", + "path", + "patient", + "patrol", + "pattern", + "pause", + "pave", + "payment", + "peace", + "peanut", + "pear", + "peasant", + "pelican", + "pen", + "penalty", + "pencil", + "people", + "pepper", + "perfect", + "permit", + "person", + "pet", + "phone", + "photo", + "phrase", + "physical", + "piano", + "picnic", + "picture", + "piece", + "pig", + "pigeon", + "pill", + "pilot", + "pink", + "pioneer", + "pipe", + "pistol", + "pitch", + "pizza", + "place", + "planet", + "plastic", + "plate", + "play", + "please", + "pledge", + "pluck", + "plug", + "plunge", + "poem", + "poet", + "point", + "polar", + "pole", + "police", + "pond", + "pony", + "pool", + "popular", + "portion", + "position", + "possible", + "post", + "potato", + "pottery", + "poverty", + "powder", + "power", + "practice", + "praise", + "predict", + "prefer", + "prepare", + "present", + "pretty", + "prevent", + "price", + "pride", + "primary", + "print", + "priority", + "prison", + "private", + "prize", + "problem", + "process", + "produce", + "profit", + "program", + "project", + "promote", + "proof", + "property", + "prosper", + "protect", + "proud", + "provide", + "public", + "pudding", + "pull", + "pulp", + "pulse", + "pumpkin", + "punch", + "pupil", + "puppy", + "purchase", + "purity", + "purpose", + "purse", + "push", + "put", + "puzzle", + "pyramid", + "quality", + "quantum", + "quarter", + "question", + "quick", + "quit", + "quiz", + "quote", + "rabbit", + "raccoon", + "race", + "rack", + "radar", + "radio", + "rail", + "rain", + "raise", + "rally", + "ramp", + "ranch", + "random", + "range", + "rapid", + "rare", + "rate", + "rather", + "raven", + "raw", + "razor", + "ready", + "real", + "reason", + "rebel", + "rebuild", + "recall", + "receive", + "recipe", + "record", + "recycle", + "reduce", + "reflect", + "reform", + "refuse", + "region", + "regret", + "regular", + "reject", + "relax", + "release", + "relief", + "rely", + "remain", + "remember", + "remind", + "remove", + "render", + "renew", + "rent", + "reopen", + "repair", + "repeat", + "replace", + "report", + "require", + "rescue", + "resemble", + "resist", + "resource", + "response", + "result", + "retire", + "retreat", + "return", + "reunion", + "reveal", + "review", + "reward", + "rhythm", + "rib", + "ribbon", + "rice", + "rich", + "ride", + "ridge", + "rifle", + "right", + "rigid", + "ring", + "riot", + "ripple", + "risk", + "ritual", + "rival", + "river", + "road", + "roast", + "robot", + "robust", + "rocket", + "romance", + "roof", + "rookie", + "room", + "rose", + "rotate", + "rough", + "round", + "route", + "royal", + "rubber", + "rude", + "rug", + "rule", + "run", + "runway", + "rural", + "sad", + "saddle", + "sadness", + "safe", + "sail", + "salad", + "salmon", + "salon", + "salt", + "salute", + "same", + "sample", + "sand", + "satisfy", + "satoshi", + "sauce", + "sausage", + "save", + "say", + "scale", + "scan", + "scare", + "scatter", + "scene", + "scheme", + "school", + "science", + "scissors", + "scorpion", + "scout", + "scrap", + "screen", + "script", + "scrub", + "sea", + "search", + "season", + "seat", + "second", + "secret", + "section", + "security", + "seed", + "seek", + "segment", + "select", + "sell", + "seminar", + "senior", + "sense", + "sentence", + "series", + "service", + "session", + "settle", + "setup", + "seven", + "shadow", + "shaft", + "shallow", + "share", + "shed", + "shell", + "sheriff", + "shield", + "shift", + "shine", + "ship", + "shiver", + "shock", + "shoe", + "shoot", + "shop", + "short", + "shoulder", + "shove", + "shrimp", + "shrug", + "shuffle", + "shy", + "sibling", + "sick", + "side", + "siege", + "sight", + "sign", + "silent", + "silk", + "silly", + "silver", + "similar", + "simple", + "since", + "sing", + "siren", + "sister", + "situate", + "six", + "size", + "skate", + "sketch", + "ski", + "skill", + "skin", + "skirt", + "skull", + "slab", + "slam", + "sleep", + "slender", + "slice", + "slide", + "slight", + "slim", + "slogan", + "slot", + "slow", + "slush", + "small", + "smart", + "smile", + "smoke", + "smooth", + "snack", + "snake", + "snap", + "sniff", + "snow", + "soap", + "soccer", + "social", + "sock", + "soda", + "soft", + "solar", + "soldier", + "solid", + "solution", + "solve", + "someone", + "song", + "soon", + "sorry", + "sort", + "soul", + "sound", + "soup", + "source", + "south", + "space", + "spare", + "spatial", + "spawn", + "speak", + "special", + "speed", + "spell", + "spend", + "sphere", + "spice", + "spider", + "spike", + "spin", + "spirit", + "split", + "spoil", + "sponsor", + "spoon", + "sport", + "spot", + "spray", + "spread", + "spring", + "spy", + "square", + "squeeze", + "squirrel", + "stable", + "stadium", + "staff", + "stage", + "stairs", + "stamp", + "stand", + "start", + "state", + "stay", + "steak", + "steel", + "stem", + "step", + "stereo", + "stick", + "still", + "sting", + "stock", + "stomach", + "stone", + "stool", + "story", + "stove", + "strategy", + "street", + "strike", + "strong", + "struggle", + "student", + "stuff", + "stumble", + "style", + "subject", + "submit", + "subway", + "success", + "such", + "sudden", + "suffer", + "sugar", + "suggest", + "suit", + "summer", + "sun", + "sunny", + "sunset", + "super", + "supply", + "supreme", + "sure", + "surface", + "surge", + "surprise", + "surround", + "survey", + "suspect", + "sustain", + "swallow", + "swamp", + "swap", + "swarm", + "swear", + "sweet", + "swift", + "swim", + "swing", + "switch", + "sword", + "symbol", + "symptom", + "syrup", + "system", + "table", + "tackle", + "tag", + "tail", + "talent", + "talk", + "tank", + "tape", + "target", + "task", + "taste", + "tattoo", + "taxi", + "teach", + "team", + "tell", + "ten", + "tenant", + "tennis", + "tent", + "term", + "test", + "text", + "thank", + "that", + "theme", + "then", + "theory", + "there", + "they", + "thing", + "this", + "thought", + "three", + "thrive", + "throw", + "thumb", + "thunder", + "ticket", + "tide", + "tiger", + "tilt", + "timber", + "time", + "tiny", + "tip", + "tired", + "tissue", + "title", + "toast", + "tobacco", + "today", + "toddler", + "toe", + "together", + "toilet", + "token", + "tomato", + "tomorrow", + "tone", + "tongue", + "tonight", + "tool", + "tooth", + "top", + "topic", + "topple", + "torch", + "tornado", + "tortoise", + "toss", + "total", + "tourist", + "toward", + "tower", + "town", + "toy", + "track", + "trade", + "traffic", + "tragic", + "train", + "transfer", + "trap", + "trash", + "travel", + "tray", + "treat", + "tree", + "trend", + "trial", + "tribe", + "trick", + "trigger", + "trim", + "trip", + "trophy", + "trouble", + "truck", + "true", + "truly", + "trumpet", + "trust", + "truth", + "try", + "tube", + "tuition", + "tumble", + "tuna", + "tunnel", + "turkey", + "turn", + "turtle", + "twelve", + "twenty", + "twice", + "twin", + "twist", + "two", + "type", + "typical", + "ugly", + "umbrella", + "unable", + "unaware", + "uncle", + "uncover", + "under", + "undo", + "unfair", + "unfold", + "unhappy", + "uniform", + "unique", + "unit", + "universe", + "unknown", + "unlock", + "until", + "unusual", + "unveil", + "update", + "upgrade", + "uphold", + "upon", + "upper", + "upset", + "urban", + "urge", + "usage", + "use", + "used", + "useful", + "useless", + "usual", + "utility", + "vacant", + "vacuum", + "vague", + "valid", + "valley", + "valve", + "van", + "vanish", + "vapor", + "various", + "vast", + "vault", + "vehicle", + "velvet", + "vendor", + "venture", + "venue", + "verb", + "verify", + "version", + "very", + "vessel", + "veteran", + "viable", + "vibrant", + "vicious", + "victory", + "video", + "view", + "village", + "vintage", + "violin", + "virtual", + "virus", + "visa", + "visit", + "visual", + "vital", + "vivid", + "vocal", + "voice", + "void", + "volcano", + "volume", + "vote", + "voyage", + "wage", + "wagon", + "wait", + "walk", + "wall", + "walnut", + "want", + "warfare", + "warm", + "warrior", + "wash", + "wasp", + "waste", + "water", + "wave", + "way", + "wealth", + "weapon", + "wear", + "weasel", + "weather", + "web", + "wedding", + "weekend", + "weird", + "welcome", + "west", + "wet", + "whale", + "what", + "wheat", + "wheel", + "when", + "where", + "whip", + "whisper", + "wide", + "width", + "wife", + "wild", + "will", + "win", + "window", + "wine", + "wing", + "wink", + "winner", + "winter", + "wire", + "wisdom", + "wise", + "wish", + "witness", + "wolf", + "woman", + "wonder", + "wood", + "wool", + "word", + "work", + "world", + "worry", + "worth", + "wrap", + "wreck", + "wrestle", + "wrist", + "write", + "wrong", + "yard", + "year", + "yellow", + "you", + "young", + "youth", + "zebra", + "zero", + "zone", + "zoo", + 0, +}; \ No newline at end of file diff --git a/src/coincontrol.h b/src/wallet/coincontrol.h similarity index 100% rename from src/coincontrol.h rename to src/wallet/coincontrol.h diff --git a/src/crypter.cpp b/src/wallet/crypter.cpp similarity index 69% rename from src/crypter.cpp rename to src/wallet/crypter.cpp index 94456a3..0c41c97 100755 --- a/src/crypter.cpp +++ b/src/wallet/crypter.cpp @@ -22,11 +22,11 @@ bool CCrypter::SetKeyFromPassphrase(const SecureString& strKeyData, const std::v int i = 0; if (nDerivationMethod == 0) i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha512(), &chSalt[0], - (unsigned char*)&strKeyData[0], strKeyData.size(), nRounds, chKey, chIV); + (unsigned char*)&strKeyData[0], strKeyData.size(), nRounds, chKey, chIV); if (i != (int)WALLET_CRYPTO_KEY_SIZE) { - OPENSSL_cleanse(chKey, sizeof(chKey)); - OPENSSL_cleanse(chIV, sizeof(chIV)); + memory_cleanse(chKey, sizeof(chKey)); + memory_cleanse(chIV, sizeof(chIV)); return false; } @@ -238,10 +238,10 @@ bool DecryptAES256(const SecureString& sKey, const std::string& sCiphertext, con if (fOk) fOk = EVP_DecryptFinal_ex(ctx, (unsigned char*)(&sPlaintext[0]) + nPLen, &nFLen); EVP_CIPHER_CTX_cleanup(ctx); #else - if (fOk) fOk = EVP_DecryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, (const unsigned char*)&sKey[0], (const unsigned char*)&sIV[0]); if (fOk) fOk = EVP_DecryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, (const unsigned char*)&sKey[0], (const unsigned char*)&sIV[0]); - if (fOk) fOk = EVP_DecryptUpdate(&ctx, (unsigned char*)&sPlaintext[0], &nPLen, (const unsigned char*)&sCiphertext[0], nLen); if (fOk) fOk = EVP_DecryptUpdate(&ctx, (unsigned char*)&sPlaintext[0], &nPLen, (const unsigned char*)&sCiphertext[0], nLen); - if (fOk) fOk = EVP_DecryptFinal_ex(&ctx, (unsigned char*)(&sPlaintext[0]) + nPLen, &nFLen); if (fOk) fOk = EVP_DecryptFinal_ex(&ctx, (unsigned char*)(&sPlaintext[0]) + nPLen, &nFLen); - EVP_CIPHER_CTX_cleanup(&ctx); EVP_CIPHER_CTX_cleanup(&ctx); + if (fOk) fOk = EVP_DecryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, (const unsigned char*)&sKey[0], (const unsigned char*)&sIV[0]); + if (fOk) fOk = EVP_DecryptUpdate(&ctx, (unsigned char*)&sPlaintext[0], &nPLen, (const unsigned char*)&sCiphertext[0], nLen); + if (fOk) fOk = EVP_DecryptFinal_ex(&ctx, (unsigned char*)(&sPlaintext[0]) + nPLen, &nFLen); + EVP_CIPHER_CTX_cleanup(&ctx); #endif if (!fOk) return false; @@ -313,9 +313,22 @@ bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn) LogPrintf("The wallet is probably corrupted: Some keys decrypt but not all."); assert(false); } - if (keyFail || !keyPass) + if (keyFail || (!keyPass && cryptedHDChain.IsNull())) return false; vMasterKey = vMasterKeyIn; + if(!cryptedHDChain.IsNull()) { + bool chainPass = false; + // try to decrypt seed and make sure it matches + CHDChain hdChainTmp; + if (DecryptHDChain(hdChainTmp)) { + // make sure seed matches this chain + chainPass = cryptedHDChain.GetID() == hdChainTmp.GetSeedHash(); + } + if (!chainPass) { + vMasterKey.clear(); + return false; + } + } fDecryptionThoroughlyChecked = true; uint256 hashSeed; @@ -341,6 +354,200 @@ bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn) return true; } +bool CCryptoKeyStore::EncryptHDChain(const CKeyingMaterial& vMasterKeyIn) +{ + // should call EncryptKeys first + if (!IsCrypted()) + return false; + + if (!cryptedHDChain.IsNull()) + return true; + + if (cryptedHDChain.IsCrypted()) + return true; + + // make sure seed matches this chain + if (hdChain.GetID() != hdChain.GetSeedHash()) + return false; + + std::vector vchCryptedSeed; + if (!EncryptSecret(vMasterKeyIn, hdChain.GetSeed(), hdChain.GetID(), vchCryptedSeed)) + return false; + + hdChain.Debug(__func__); + cryptedHDChain = hdChain; + cryptedHDChain.SetCrypted(true); + + SecureVector vchSecureCryptedSeed(vchCryptedSeed.begin(), vchCryptedSeed.end()); + if (!cryptedHDChain.SetSeed(vchSecureCryptedSeed, false)) + return false; + + SecureVector vchMnemonic; + SecureVector vchMnemonicPassphrase; + + // it's ok to have no mnemonic if wallet was initialized via hdseed + if (hdChain.GetMnemonic(vchMnemonic, vchMnemonicPassphrase)) { + std::vector vchCryptedMnemonic; + std::vector vchCryptedMnemonicPassphrase; + + if (!vchMnemonic.empty() && !EncryptSecret(vMasterKeyIn, vchMnemonic, hdChain.GetID(), vchCryptedMnemonic)) + return false; + if (!vchMnemonicPassphrase.empty() && !EncryptSecret(vMasterKeyIn, vchMnemonicPassphrase, hdChain.GetID(), vchCryptedMnemonicPassphrase)) + return false; + + SecureVector vchSecureCryptedMnemonic(vchCryptedMnemonic.begin(), vchCryptedMnemonic.end()); + SecureVector vchSecureCryptedMnemonicPassphrase(vchCryptedMnemonicPassphrase.begin(), vchCryptedMnemonicPassphrase.end()); + if (!cryptedHDChain.SetMnemonic(vchSecureCryptedMnemonic, vchSecureCryptedMnemonicPassphrase, false)) + return false; + } + + if (!hdChain.SetNull()) + return false; + + return true; +} + +bool CCryptoKeyStore::EncryptHDChainUpgrade(const CKeyingMaterial& vMasterKeyIn, const CHDChain& chain) +{ + hdChain = chain; + // should call EncryptKeys first + if (!IsCrypted()) + return false; + + if (!cryptedHDChain.IsNull()) + return true; + + if (cryptedHDChain.IsCrypted()) + return true; + + // make sure seed matches this chain + if (hdChain.GetID() != hdChain.GetSeedHash()) + return false; + + std::vector vchCryptedSeed; + if (!EncryptSecret(vMasterKeyIn, hdChain.GetSeed(), hdChain.GetID(), vchCryptedSeed)) + return false; + + hdChain.Debug(__func__); + cryptedHDChain = hdChain; + cryptedHDChain.SetCrypted(true); + + SecureVector vchSecureCryptedSeed(vchCryptedSeed.begin(), vchCryptedSeed.end()); + if (!cryptedHDChain.SetSeed(vchSecureCryptedSeed, false)) + return false; + + SecureVector vchMnemonic; + SecureVector vchMnemonicPassphrase; + + // it's ok to have no mnemonic if wallet was initialized via hdseed + if (hdChain.GetMnemonic(vchMnemonic, vchMnemonicPassphrase)) { + std::vector vchCryptedMnemonic; + std::vector vchCryptedMnemonicPassphrase; + + if (!vchMnemonic.empty() && !EncryptSecret(vMasterKeyIn, vchMnemonic, hdChain.GetID(), vchCryptedMnemonic)) + return false; + if (!vchMnemonicPassphrase.empty() && !EncryptSecret(vMasterKeyIn, vchMnemonicPassphrase, hdChain.GetID(), vchCryptedMnemonicPassphrase)) + return false; + + SecureVector vchSecureCryptedMnemonic(vchCryptedMnemonic.begin(), vchCryptedMnemonic.end()); + SecureVector vchSecureCryptedMnemonicPassphrase(vchCryptedMnemonicPassphrase.begin(), vchCryptedMnemonicPassphrase.end()); + if (!cryptedHDChain.SetMnemonic(vchSecureCryptedMnemonic, vchSecureCryptedMnemonicPassphrase, false)) + return false; + } + + if (!hdChain.SetNull()) + return false; + + return true; +} + + +bool CCryptoKeyStore::DecryptHDChain(CHDChain& hdChainRet) const +{ + if (!IsCrypted()) + return true; + + if (cryptedHDChain.IsNull()) + return false; + + if (!cryptedHDChain.IsCrypted()) + return false; + + SecureVector vchSecureSeed; + SecureVector vchSecureCryptedSeed = cryptedHDChain.GetSeed(); + std::vector vchCryptedSeed(vchSecureCryptedSeed.begin(), vchSecureCryptedSeed.end()); + if (!DecryptSecret(vMasterKey, vchCryptedSeed, cryptedHDChain.GetID(), vchSecureSeed)) + return false; + + hdChainRet = cryptedHDChain; + if (!hdChainRet.SetSeed(vchSecureSeed, false)) + return false; + + // hash of decrypted seed must match chain id + if (hdChainRet.GetSeedHash() != cryptedHDChain.GetID()) + return false; + + SecureVector vchSecureCryptedMnemonic; + SecureVector vchSecureCryptedMnemonicPassphrase; + + // it's ok to have no mnemonic if wallet was initialized via hdseed + if (cryptedHDChain.GetMnemonic(vchSecureCryptedMnemonic, vchSecureCryptedMnemonicPassphrase)) { + SecureVector vchSecureMnemonic; + SecureVector vchSecureMnemonicPassphrase; + + std::vector vchCryptedMnemonic(vchSecureCryptedMnemonic.begin(), vchSecureCryptedMnemonic.end()); + std::vector vchCryptedMnemonicPassphrase(vchSecureCryptedMnemonicPassphrase.begin(), vchSecureCryptedMnemonicPassphrase.end()); + + if (!vchCryptedMnemonic.empty() && !DecryptSecret(vMasterKey, vchCryptedMnemonic, cryptedHDChain.GetID(), vchSecureMnemonic)) + return false; + if (!vchCryptedMnemonicPassphrase.empty() && !DecryptSecret(vMasterKey, vchCryptedMnemonicPassphrase, cryptedHDChain.GetID(), vchSecureMnemonicPassphrase)) + return false; + + if (!hdChainRet.SetMnemonic(vchSecureMnemonic, vchSecureMnemonicPassphrase, false)) + return false; + } + + hdChainRet.SetCrypted(false); + hdChainRet.Debug(__func__); + + return true; +} + +bool CCryptoKeyStore::SetHDChain(const CHDChain& chain) +{ + if (IsCrypted()) + return false; + + if (chain.IsCrypted()) + return false; + + hdChain = chain; + return true; +} + +bool CCryptoKeyStore::SetCryptedHDChain(const CHDChain& chain) +{ + if (!SetCrypted()) + return false; + + if (!chain.IsCrypted()) + return false; + + cryptedHDChain = chain; + return true; +} + +bool CCryptoKeyStore::GetHDChain(CHDChain& hdChainRet) const +{ + if(IsCrypted()) { + hdChainRet = cryptedHDChain; + return !cryptedHDChain.IsNull(); + } + + hdChainRet = hdChain; + return !hdChain.IsNull(); +} + bool CCryptoKeyStore::AddKeyPubKey(const CKey& key, const CPubKey& pubkey) { { @@ -466,7 +673,7 @@ bool CCryptoKeyStore::AddDeterministicSeed(const uint256& seed) } strErr = "save zohmcseed to wallet"; } - //the use case for this is no password set seed, mint dzOHMC, + //the use case for this is no password set seed, mint dzOHMC, return error("s%: Failed to %s\n", __func__, strErr); } diff --git a/src/crypter.h b/src/wallet/crypter.h similarity index 93% rename from src/crypter.h rename to src/wallet/crypter.h index 1df323f..9e74255 100755 --- a/src/crypter.h +++ b/src/wallet/crypter.h @@ -17,13 +17,13 @@ const unsigned int WALLET_CRYPTO_SALT_SIZE = 8; /** * Private key encryption is done based on a CMasterKey, * which holds a salt and random encryption key. - * + * * CMasterKeys are encrypted using AES-256-CBC using a key * derived using derivation method nDerivationMethod * (0 == EVP_sha512()) and derivation iterations nDeriveIterations. * vchOtherDerivationParameters is provided for alternative algorithms * which may require more parameters (such as scrypt). - * + * * Wallet Private Keys are then encrypted using AES-256-CBC * with the double-sha256 of the public key as the IV, and the * master key's key as the encryption key (see keystore.[ch]). @@ -83,8 +83,8 @@ class CCrypter void CleanKey() { - OPENSSL_cleanse(chKey, sizeof(chKey)); - OPENSSL_cleanse(chIV, sizeof(chIV)); + memory_cleanse(chKey, sizeof(chKey)); + memory_cleanse(chIV, sizeof(chIV)); fKeySet = false; } @@ -122,6 +122,7 @@ class CCryptoKeyStore : public CBasicKeyStore { private: CryptedKeyMap mapCryptedKeys; + CHDChain cryptedHDChain; CKeyingMaterial vMasterKey; @@ -138,6 +139,12 @@ class CCryptoKeyStore : public CBasicKeyStore //! will encrypt previously unencrypted keys bool EncryptKeys(CKeyingMaterial& vMasterKeyIn); + bool EncryptHDChain(const CKeyingMaterial& vMasterKeyIn); + bool EncryptHDChainUpgrade(const CKeyingMaterial& vMasterKeyIn, const CHDChain& chain); + bool DecryptHDChain(CHDChain& hdChainRet) const; + bool SetHDChain(const CHDChain& chain); + bool SetCryptedHDChain(const CHDChain& chain); + bool Unlock(const CKeyingMaterial& vMasterKeyIn); public: @@ -194,7 +201,7 @@ class CCryptoKeyStore : public CBasicKeyStore bool GetDeterministicSeed(const uint256& hashSeed, uint256& seed); bool AddDeterministicSeed(const uint256& seed); - + bool GetHDChain(CHDChain& hdChainRet) const; /** * Wallet status (encrypted, locked) changed. * Note: Called without locks held. @@ -202,4 +209,4 @@ class CCryptoKeyStore : public CBasicKeyStore boost::signals2::signal NotifyStatusChanged; }; -#endif // BITCOIN_CRYPTER_H +#endif // BITCOIN_CRYPTER_H \ No newline at end of file diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp index af2fa80..960dc45 100755 --- a/src/wallet/db.cpp +++ b/src/wallet/db.cpp @@ -3,7 +3,7 @@ // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include "db.h" +#include "wallet/db.h" #include "addrman.h" #include "hash.h" @@ -21,8 +21,6 @@ #include #include -#include - using namespace std; using namespace boost; diff --git a/src/wallet/hdchain.cpp b/src/wallet/hdchain.cpp new file mode 100644 index 0000000..9b4f2b4 --- /dev/null +++ b/src/wallet/hdchain.cpp @@ -0,0 +1,215 @@ +// Copyright (c) 2014-2017 The Dash Core developers +// Distributed under the MIT software license, see the accompanying + +#include "base58.h" +#include "chainparams.h" +#include "hdchain.h" +#include "tinyformat.h" +#include "util.h" +#include +#include + +bool CHDChain::SetNull() +{ + LOCK(cs_accounts); + nVersion = CURRENT_VERSION; + id = uint256(); + fCrypted = false; + vchSeed.clear(); + vchMnemonic.clear(); + vchMnemonicPassphrase.clear(); + mapAccounts.clear(); + // default blank account + mapAccounts.insert(std::pair(0, CHDAccount())); + return IsNull(); +} + +bool CHDChain::IsNull() const +{ + return vchSeed.empty() || id == uint256(); +} + +void CHDChain::SetCrypted(bool fCryptedIn) +{ + fCrypted = fCryptedIn; +} + +bool CHDChain::IsCrypted() const +{ + return fCrypted; +} + +void CHDChain::Debug(std::string strName) const +{ + DBG( + std::cout << __func__ << ": ---" << strName << "---" << std::endl; + if (fCrypted) { + std::cout << "mnemonic: ***CRYPTED***" << std::endl; + std::cout << "mnemonicpassphrase: ***CRYPTED***" << std::endl; + std::cout << "seed: ***CRYPTED***" << std::endl; + } else { + std::cout << "mnemonic: " << std::string(vchMnemonic.begin(), vchMnemonic.end()).c_str() << std::endl; + std::cout << "mnemonicpassphrase: " << std::string(vchMnemonicPassphrase.begin(), vchMnemonicPassphrase.end()).c_str() << std::endl; + std::cout << "seed: " << HexStr(vchSeed).c_str() << std::endl; + + CExtKey extkey; + extkey.SetMaster(&vchSeed[0], vchSeed.size()); + + CBitcoinExtKey b58extkey; + b58extkey.SetKey(extkey); + std::cout << "extended private masterkey: " << b58extkey.ToString().c_str() << std::endl; + + CExtPubKey extpubkey; + extpubkey = extkey.Neuter(); + + CBitcoinExtPubKey b58extpubkey; + b58extpubkey.SetKey(extpubkey); + std::cout << "extended public masterkey: " << b58extpubkey.ToString().c_str() << std::endl; + } + ); +} + +bool CHDChain::SetMnemonic(const SecureVector& vchMnemonic, const SecureVector& vchMnemonicPassphrase, bool fUpdateID) +{ + return SetMnemonic(SecureString(vchMnemonic.begin(), vchMnemonic.end()), SecureString(vchMnemonicPassphrase.begin(), vchMnemonicPassphrase.end()), fUpdateID); +} + +bool CHDChain::SetMnemonic(const SecureString& ssMnemonic, const SecureString& ssMnemonicPassphrase, bool fUpdateID) +{ + SecureString ssMnemonicTmp = ssMnemonic; + + if (fUpdateID) { + // can't (re)set mnemonic if seed was already set + if (!IsNull()) + return false; + + // empty mnemonic i.e. "generate a new one" + if (ssMnemonic.empty()) { + std::vector ssMnemonicTmp3 = CMnemonic::Generate(256); + std::string ssMnemonicTmp2 = join(ssMnemonicTmp3," "); + ssMnemonicTmp = SecureString(ssMnemonicTmp2.begin(), ssMnemonicTmp2.end()); + } + // NOTE: default mnemonic passphrase is an empty string + + // printf("mnemonic: %s\n", ssMnemonicTmp.c_str()); + if (!CMnemonic::Check(ssMnemonicTmp)) { + throw std::runtime_error(std::string(__func__) + ": invalid mnemonic: `" + std::string(ssMnemonicTmp.c_str()) + "`"); + } + + CMnemonic::ToSeed(ssMnemonicTmp, ssMnemonicPassphrase, vchSeed); + id = GetSeedHash(); + } + + vchMnemonic = SecureVector(ssMnemonicTmp.begin(), ssMnemonicTmp.end()); + vchMnemonicPassphrase = SecureVector(ssMnemonicPassphrase.begin(), ssMnemonicPassphrase.end()); + + return !IsNull(); +} + +bool CHDChain::GetMnemonic(SecureVector& vchMnemonicRet, SecureVector& vchMnemonicPassphraseRet) const +{ + // mnemonic was not set, fail + if (vchMnemonic.empty()) + return false; + + vchMnemonicRet = vchMnemonic; + vchMnemonicPassphraseRet = vchMnemonicPassphrase; + return true; +} + +bool CHDChain::GetMnemonic(SecureString& ssMnemonicRet, SecureString& ssMnemonicPassphraseRet) const +{ + // mnemonic was not set, fail + if (vchMnemonic.empty()) + return false; + + ssMnemonicRet = SecureString(vchMnemonic.begin(), vchMnemonic.end()); + ssMnemonicPassphraseRet = SecureString(vchMnemonicPassphrase.begin(), vchMnemonicPassphrase.end()); + + return true; +} + +bool CHDChain::SetSeed(const SecureVector& vchSeedIn, bool fUpdateID) +{ + vchSeed = vchSeedIn; + + if (fUpdateID) { + id = GetSeedHash(); + } + + return !IsNull(); +} + +SecureVector CHDChain::GetSeed() const +{ + return vchSeed; +} + +uint256 CHDChain::GetSeedHash() +{ + return Hash(vchSeed.begin(), vchSeed.end()); +} + +void CHDChain::DeriveChildExtKey(uint32_t nAccountIndex, bool fInternal, uint32_t nChildIndex, CExtKey& extKeyRet) +{ + // Use BIP44 keypath scheme i.e. m / purpose' / coin_type' / account' / change / address_index + CExtKey masterKey; //hd master key + CExtKey purposeKey; //key at m/purpose' + CExtKey cointypeKey; //key at m/purpose'/coin_type' + CExtKey accountKey; //key at m/purpose'/coin_type'/account' + CExtKey changeKey; //key at m/purpose'/coin_type'/account'/change + CExtKey childKey; //key at m/purpose'/coin_type'/account'/change/address_index + + masterKey.SetMaster(&vchSeed[0], vchSeed.size()); + + // Use hardened derivation for purpose, coin_type and account + // (keys >= 0x80000000 are hardened after bip32) + const uint32_t BIP32_HARDENED_KEY_LIMIT = 0x80000000; + + // derive m/purpose' + masterKey.Derive(purposeKey, 44 | BIP32_HARDENED_KEY_LIMIT); + // derive m/purpose'/coin_type' + purposeKey.Derive(cointypeKey, Params().ExtCoinType() | BIP32_HARDENED_KEY_LIMIT); + // derive m/purpose'/coin_type'/account' + cointypeKey.Derive(accountKey, nAccountIndex | BIP32_HARDENED_KEY_LIMIT); + // derive m/purpose'/coin_type'/account/change + accountKey.Derive(changeKey, fInternal ? 1 : 0); + // derive m/purpose'/coin_type'/account/change/address_index + changeKey.Derive(extKeyRet, nChildIndex); +} + +void CHDChain::AddAccount() +{ + LOCK(cs_accounts); + mapAccounts.insert(std::pair(mapAccounts.size(), CHDAccount())); +} + +bool CHDChain::GetAccount(uint32_t nAccountIndex, CHDAccount& hdAccountRet) +{ + LOCK(cs_accounts); + if (nAccountIndex > mapAccounts.size() - 1) + return false; + hdAccountRet = mapAccounts[nAccountIndex]; + return true; +} + +bool CHDChain::SetAccount(uint32_t nAccountIndex, const CHDAccount& hdAccount) +{ + LOCK(cs_accounts); + // can only replace existing accounts + if (nAccountIndex > mapAccounts.size() - 1) + return false; + mapAccounts[nAccountIndex] = hdAccount; + return true; +} + +size_t CHDChain::CountAccounts() +{ + LOCK(cs_accounts); + return mapAccounts.size(); +} + +std::string CHDPubKey::GetKeyPath() const +{ + return strprintf("m/44'/%d'/%d'/%d/%d", Params().ExtCoinType(), nAccountIndex, nChangeIndex, extPubKey.nChild); +} \ No newline at end of file diff --git a/src/wallet/hdchain.h b/src/wallet/hdchain.h new file mode 100644 index 0000000..b635934 --- /dev/null +++ b/src/wallet/hdchain.h @@ -0,0 +1,153 @@ +// Copyright (c) 2014-2017 The Dash Core developers +// Distributed under the MIT software license, see the accompanying +#ifndef PHORE_HDCHAIN_H +#define PHORE_HDCHAIN_H + +#include "key.h" +#include "sync.h" +#include "bip39.h" + +/* hd account data model */ +class CHDAccount +{ +public: + uint32_t nExternalChainCounter; + uint32_t nInternalChainCounter; + + CHDAccount() : nExternalChainCounter(0), nInternalChainCounter(0) {} + + ADD_SERIALIZE_METHODS; + template + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) + { + READWRITE(nExternalChainCounter); + READWRITE(nInternalChainCounter); + } +}; + +/* simple HD chain data model */ +class CHDChain +{ +private: + static const int CURRENT_VERSION = 1; + int nVersion; + + uint256 id; + + bool fCrypted; + + SecureVector vchSeed; + SecureVector vchMnemonic; + SecureVector vchMnemonicPassphrase; + + std::map mapAccounts; + // critical section to protect mapAccounts + mutable CCriticalSection cs_accounts; + +public: + + CHDChain() : nVersion(CHDChain::CURRENT_VERSION) { SetNull(); } + CHDChain(const CHDChain& other) : + nVersion(other.nVersion), + id(other.id), + fCrypted(other.fCrypted), + vchSeed(other.vchSeed), + vchMnemonic(other.vchMnemonic), + vchMnemonicPassphrase(other.vchMnemonicPassphrase), + mapAccounts(other.mapAccounts) + {} + + ADD_SERIALIZE_METHODS; + template + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) + { + LOCK(cs_accounts); + READWRITE(this->nVersion); + nVersion = this->nVersion; + READWRITE(id); + READWRITE(fCrypted); + READWRITE(vchSeed); + READWRITE(vchMnemonic); + READWRITE(vchMnemonicPassphrase); + READWRITE(mapAccounts); + } + + void swap(CHDChain& first, CHDChain& second) // nothrow + { + // enable ADL (not necessary in our case, but good practice) + using std::swap; + + // by swapping the members of two classes, + // the two classes are effectively swapped + swap(first.nVersion, second.nVersion); + swap(first.id, second.id); + swap(first.fCrypted, second.fCrypted); + swap(first.vchSeed, second.vchSeed); + swap(first.vchMnemonic, second.vchMnemonic); + swap(first.vchMnemonicPassphrase, second.vchMnemonicPassphrase); + swap(first.mapAccounts, second.mapAccounts); + } + CHDChain& operator=(CHDChain from) + { + swap(*this, from); + return *this; + } + + bool SetNull(); + bool IsNull() const; + + void SetCrypted(bool fCryptedIn); + bool IsCrypted() const; + + void Debug(std::string strName) const; + + bool SetMnemonic(const SecureVector& vchMnemonic, const SecureVector& vchMnemonicPassphrase, bool fUpdateID); + bool SetMnemonic(const SecureString& ssMnemonic, const SecureString& ssMnemonicPassphrase, bool fUpdateID); + bool GetMnemonic(SecureVector& vchMnemonicRet, SecureVector& vchMnemonicPassphraseRet) const; + bool GetMnemonic(SecureString& ssMnemonicRet, SecureString& ssMnemonicPassphraseRet) const; + + bool SetSeed(const SecureVector& vchSeedIn, bool fUpdateID); + SecureVector GetSeed() const; + + uint256 GetID() const { return id; } + + uint256 GetSeedHash(); + void DeriveChildExtKey(uint32_t nAccountIndex, bool fInternal, uint32_t nChildIndex, CExtKey& extKeyRet); + + void AddAccount(); + bool GetAccount(uint32_t nAccountIndex, CHDAccount& hdAccountRet); + bool SetAccount(uint32_t nAccountIndex, const CHDAccount& hdAccount); + size_t CountAccounts(); +}; + +/* hd pubkey data model */ +class CHDPubKey +{ +private: + static const int CURRENT_VERSION = 1; + int nVersion; + +public: + CExtPubKey extPubKey; + uint256 hdchainID; + uint32_t nAccountIndex; + uint32_t nChangeIndex; + + CHDPubKey() : nVersion(CHDPubKey::CURRENT_VERSION), nAccountIndex(0), nChangeIndex(0) {} + + ADD_SERIALIZE_METHODS; + template + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) + { + READWRITE(this->nVersion); + nVersion = this->nVersion; + READWRITE(extPubKey); + READWRITE(hdchainID); + READWRITE(nAccountIndex); + READWRITE(nChangeIndex); + } + + std::string GetKeyPath() const; +}; + +#endif // PHORE_HDCHAIN_H \ No newline at end of file diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index 8a3a977..3d56129 100755 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -14,7 +14,7 @@ #include "util.h" #include "utilstrencodings.h" #include "utiltime.h" -#include "wallet.h" +#include "wallet/wallet.h" #include #include @@ -426,26 +426,67 @@ UniValue dumpprivkey(const UniValue& params, bool fHelp) return CBitcoinSecret(vchSecret).ToString(); } +UniValue dumphdinfo(const UniValue& params, bool fHelp) +{ + if (pwalletMain == NULL) + return NullUniValue; + + if (fHelp || params.size() != 0) + throw runtime_error( + "dumphdinfo\n" + "Returns an object containing sensitive private info about this HD wallet.\n" + "\nResult:\n" + "{\n" + " \"hdseed\": \"seed\", (string) The HD seed (bip32, in hex)\n" + " \"mnemonic\": \"words\", (string) The mnemonic for this HD wallet (bip39, english words) \n" + " \"mnemonicpassphrase\": \"passphrase\", (string) The mnemonic passphrase for this HD wallet (bip39)\n" + "}\n" + "\nExamples:\n" + + HelpExampleCli("dumphdinfo", "") + + HelpExampleRpc("dumphdinfo", "") + ); + + LOCK(pwalletMain->cs_wallet); + + EnsureWalletIsUnlocked(); + + CHDChain hdChainCurrent; + if (!pwalletMain->GetHDChain(hdChainCurrent)) + throw JSONRPCError(RPC_WALLET_ERROR, "This wallet is not a HD wallet."); + + if (!pwalletMain->GetDecryptedHDChain(hdChainCurrent)) + throw JSONRPCError(RPC_INTERNAL_ERROR, "Cannot decrypt HD seed"); + + SecureString ssMnemonic; + SecureString ssMnemonicPassphrase; + hdChainCurrent.GetMnemonic(ssMnemonic, ssMnemonicPassphrase); + + UniValue obj(UniValue::VOBJ); + obj.push_back(Pair("hdseed", HexStr(hdChainCurrent.GetSeed()))); + obj.push_back(Pair("mnemonic", ssMnemonic.c_str())); + obj.push_back(Pair("mnemonicpassphrase", ssMnemonicPassphrase.c_str())); + + return obj; +} UniValue dumpwallet(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 1) throw runtime_error( - "dumpwallet \"filename\"\n" - "\nThis command has been deprecated and replace with dumpallprivatekeys.\n" - "\nSCAM WARNING: If anyone asks you to run this command and send them the file,\n" - "they will have FULL ACCESS to STEAL your Ohmcoin. Giving this file to someone\n" - "is the same thing as giving them all of the Ohmcoin in your wallet! Never send\n" - "this file to ANYONE that you do not trust with all of your Ohmcoin!!!\n" - "\nArguments:\n" - "1. \"filename\" (string, required) The filename\n" - "\nExamples:\n" + - HelpExampleCli("dumpwallet", "\"test\"") + HelpExampleRpc("dumpwallet", "\"test\"")); + "dumpwallet \"filename\"\n" + "\nDumps all wallet keys in a human-readable format.\n" + + HelpRequiringPassphrase() + "\n" -/* LOCK2(cs_main, pwalletMain->cs_wallet); + "\nArguments:\n" + "1. \"filename\" (string, required) The filename\n" - EnsureWalletIsUnlocked(); + "\nExamples:\n" + + HelpExampleCli("dumpwallet", "\"test\"") + HelpExampleRpc("dumpwallet", "\"test\"")); + LOCK2(cs_main, pwalletMain->cs_wallet); + EnsureWalletIsUnlocked(); + boost::filesystem::path filepath = params[0].get_str().c_str(); + filepath = boost::filesystem::absolute(filepath); ofstream file; file.open(params[0].get_str().c_str()); if (!file.is_open()) @@ -455,7 +496,6 @@ UniValue dumpwallet(const UniValue& params, bool fHelp) std::set setKeyPool; pwalletMain->GetKeyBirthTimes(mapKeyBirth); pwalletMain->GetAllReserveKeys(setKeyPool); - // sort time/key pairs std::vector > vKeyBirth; for (std::map::const_iterator it = mapKeyBirth.begin(); it != mapKeyBirth.end(); it++) { @@ -463,35 +503,70 @@ UniValue dumpwallet(const UniValue& params, bool fHelp) } mapKeyBirth.clear(); std::sort(vKeyBirth.begin(), vKeyBirth.end()); - // produce output file << strprintf("# Wallet dump created by Ohmcoin %s (%s)\n", CLIENT_BUILD, CLIENT_DATE); file << strprintf("# * Created on %s\n", EncodeDumpTime(GetTime())); file << strprintf("# * Best block at time of backup was %i (%s),\n", chainActive.Height(), chainActive.Tip()->GetBlockHash().ToString()); file << strprintf("# mined on %s\n", EncodeDumpTime(chainActive.Tip()->GetBlockTime())); file << "\n"; + // add the base58check encoded extended master if the wallet uses HD + CHDChain hdChainCurrent; + if (pwalletMain->GetHDChain(hdChainCurrent)) + { + if (!pwalletMain->GetDecryptedHDChain(hdChainCurrent)) + throw JSONRPCError(RPC_INTERNAL_ERROR, "Cannot decrypt HD chain"); + + SecureString ssMnemonic; + SecureString ssMnemonicPassphrase; + hdChainCurrent.GetMnemonic(ssMnemonic, ssMnemonicPassphrase); + file << "# mnemonic: " << ssMnemonic << "\n"; + file << "# mnemonic passphrase: " << ssMnemonicPassphrase << "\n\n"; + SecureVector vchSeed = hdChainCurrent.GetSeed(); + file << "# HD seed: " << HexStr(vchSeed) << "\n\n"; + CExtKey masterKey; + masterKey.SetMaster(&vchSeed[0], vchSeed.size()); + CBitcoinExtKey b58extkey; + b58extkey.SetKey(masterKey); + file << "# extended private masterkey: " << b58extkey.ToString() << "\n"; + CExtPubKey masterPubkey; + masterPubkey = masterKey.Neuter(); + CBitcoinExtPubKey b58extpubkey; + b58extpubkey.SetKey(masterPubkey); + file << "# extended public masterkey: " << b58extpubkey.ToString() << "\n\n"; + for (size_t i = 0; i < hdChainCurrent.CountAccounts(); ++i) + { + CHDAccount acc; + if(hdChainCurrent.GetAccount(i, acc)) { + file << "# external chain counter: " << acc.nExternalChainCounter << "\n"; + file << "# internal chain counter: " << acc.nInternalChainCounter << "\n\n"; + } else { + file << "# WARNING: ACCOUNT " << i << " IS MISSING!" << "\n\n"; + } + } + } for (std::vector >::const_iterator it = vKeyBirth.begin(); it != vKeyBirth.end(); it++) { const CKeyID& keyid = it->second; std::string strTime = EncodeDumpTime(it->first); std::string strAddr = EncodeDestination(CTxDestination(keyid)); - CKey key; if (pwalletMain->GetKey(keyid, key)) { + file << strprintf("%s %s ", CBitcoinSecret(key).ToString(), strTime); if (pwalletMain->mapAddressBook.count(keyid)) { - file << strprintf("%s %s label=%s # addr=%s\n", CBitcoinSecret(key).ToString(), strTime, EncodeDumpString(pwalletMain->mapAddressBook[keyid].name), strAddr); + file << strprintf("label=%s", EncodeDumpString(pwalletMain->mapAddressBook[keyid].name)); } else if (setKeyPool.count(keyid)) { - file << strprintf("%s %s reserve=1 # addr=%s\n", CBitcoinSecret(key).ToString(), strTime, strAddr); + file << "reserve=1"; } else { - file << strprintf("%s %s change=1 # addr=%s\n", CBitcoinSecret(key).ToString(), strTime, strAddr); + file << strprintf(" # addr=%s%s\n", strAddr, (pwalletMain->mapHdPubKeys.count(keyid) ? " hdkeypath="+pwalletMain->mapHdPubKeys[keyid].GetKeyPath() : "")); } } } file << "\n"; file << "# End of dump\n"; - file.close(); */ - return NullUniValue; + file.close(); + UniValue reply(UniValue::VOBJ); + reply.push_back(Pair("filename", filepath.string())); + return reply; } - UniValue dumpallprivatekeys(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 1) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 51d118f..5e86757 100755 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -17,8 +17,8 @@ #include "timedata.h" #include "util.h" #include "utilmoneystr.h" -#include "wallet.h" -#include "walletdb.h" +#include "wallet/wallet.h" +#include "wallet/walletdb.h" #include @@ -117,7 +117,7 @@ UniValue getnewaddress(const UniValue& params, bool fHelp) // Generate a new key that is added to wallet CPubKey newKey; - if (!pwalletMain->GetKeyFromPool(newKey)) + if (!pwalletMain->GetKeyFromPool(newKey, false)) throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first"); pwalletMain->LearnRelatedScripts(newKey, output_type); @@ -153,7 +153,7 @@ CTxDestination GetAccountDestination(string strAccount, bool bForceNew = false) // Generate a new key if (!account.vchPubKey.IsValid() || bForceNew || bKeyUsed) { - if (!pwalletMain->GetKeyFromPool(account.vchPubKey)) + if (!pwalletMain->GetKeyFromPool(account.vchPubKey, false)) throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first"); pwalletMain->SetAddressBook(account.vchPubKey.GetID(), strAccount, "receive"); @@ -217,7 +217,7 @@ UniValue getrawchangeaddress(const UniValue& params, bool fHelp) CReserveKey reservekey(pwalletMain); CPubKey vchPubKey; - if (!reservekey.GetReservedKey(vchPubKey)) + if (!reservekey.GetReservedKey(vchPubKey, true)) throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first"); reservekey.KeepKey(); @@ -1784,7 +1784,7 @@ UniValue keypoolrefill(const UniValue& params, bool fHelp) EnsureWalletIsUnlocked(); pwalletMain->TopUpKeyPool(kpSize); - if (pwalletMain->GetKeyPoolSize() < kpSize) + if (pwalletMain->GetKeyPoolSize() < (pwalletMain->IsHDEnabled() ? kpSize * 2 : kpSize)) throw JSONRPCError(RPC_WALLET_ERROR, "Error refreshing keypool."); return NullUniValue; @@ -1978,7 +1978,7 @@ UniValue encryptwallet(const UniValue& params, bool fHelp) // slack space in .dat files; that is bad if the old data is // unencrypted private keys. So: StartShutdown(); - return "wallet encrypted; ohmcoin server stopping, restart to run with encrypted wallet. The keypool has been flushed, you need to make a new backup."; + return "Wallet encrypted; ohmcoin server stopping, restart to run with encrypted wallet. The keypool has been flushed and a new HD seed was generated (if you are using HD). You need to make a new backup."; } UniValue lockunspent(const UniValue& params, bool fHelp) @@ -2126,30 +2126,65 @@ UniValue getwalletinfo(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( - "getwalletinfo\n" - "Returns an object containing various wallet state info.\n" - "\nResult:\n" - "{\n" - " \"walletversion\": xxxxx, (numeric) the wallet version\n" - " \"balance\": xxxxxxx, (numeric) the total OHMC 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" - " \"unlocked_until\": ttt, (numeric) the timestamp in seconds since epoch (midnight Jan 1 1970 GMT) that the wallet is unlocked for transfers, or 0 if the wallet is locked\n" - "}\n" - "\nExamples:\n" + - HelpExampleCli("getwalletinfo", "") + HelpExampleRpc("getwalletinfo", "")); + "getwalletinfo\n" + "Returns an object containing various wallet state info.\n" + "\nResult:\n" + "{\n" + " \"walletversion\": xxxxx, (numeric) the wallet version\n" + " \"balance\": xxxxxxx, (numeric) the total OHMC 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 (only counts external keys)\n" + " \"keypoolsize_hd_internal\": xxxx, (numeric) how many new keys are pre-generated for internal use (used for change outputs, only appears if the wallet is using this feature, otherwise external keys are used)\n" + " \"unlocked_until\": ttt, (numeric) the timestamp in seconds since epoch (midnight Jan 1 1970 GMT) that the wallet is unlocked for transfers, or 0 if the wallet is locked\n" + " \"hdchainid\": \"\", (string) the ID of the HD chain\n" + " \"hdaccountcount\": xxx, (numeric) how many accounts of the HD chain are in this wallet\n" + " [\n" + " {\n" + " \"hdaccountindex\": xxx, (numeric) the index of the account\n" + " \"hdexternalkeyindex\": xxxx, (numeric) current external childkey index\n" + " \"hdinternalkeyindex\": xxxx, (numeric) current internal childkey index\n" + " }\n" + " ,...\n" + " ]\n" + "}\n" + "\nExamples:\n" + + HelpExampleCli("getwalletinfo", "") + HelpExampleRpc("getwalletinfo", "")); LOCK2(cs_main, pwalletMain->cs_wallet); + CHDChain hdChainCurrent; + bool fHDEnabled = pwalletMain->GetHDChain(hdChainCurrent); UniValue obj(UniValue::VOBJ); obj.push_back(Pair("walletversion", pwalletMain->GetVersion())); obj.push_back(Pair("balance", ValueFromAmount(pwalletMain->GetBalance()))); obj.push_back(Pair("txcount", (int)pwalletMain->mapWallet.size())); obj.push_back(Pair("keypoololdest", pwalletMain->GetOldestKeyPoolTime())); - obj.push_back(Pair("keypoolsize", (int)pwalletMain->GetKeyPoolSize())); + obj.push_back(Pair("keypoolsize", (int64_t)pwalletMain->KeypoolCountExternalKeys())); + if (fHDEnabled) { + obj.push_back(Pair("keypoolsize_hd_internal", (int64_t)(pwalletMain->KeypoolCountInternalKeys()))); + } if (pwalletMain->IsCrypted()) obj.push_back(Pair("unlocked_until", nWalletUnlockTime)); + if (fHDEnabled) { + obj.push_back(Pair("hdchainid", hdChainCurrent.GetID().GetHex())); + obj.push_back(Pair("hdaccountcount", (int64_t)hdChainCurrent.CountAccounts())); + UniValue accounts(UniValue::VARR); + for (size_t i = 0; i < hdChainCurrent.CountAccounts(); ++i) + { + CHDAccount acc; + UniValue account(UniValue::VOBJ); + account.push_back(Pair("hdaccountindex", (int64_t)i)); + if(hdChainCurrent.GetAccount(i, acc)) { + account.push_back(Pair("hdexternalkeyindex", (int64_t)acc.nExternalChainCounter)); + account.push_back(Pair("hdinternalkeyindex", (int64_t)acc.nInternalChainCounter)); + } else { + account.push_back(Pair("error", strprintf("account %d is missing", i))); + } + accounts.push_back(account); + } + obj.push_back(Pair("hdaccounts", accounts)); + } return obj; } @@ -2526,6 +2561,113 @@ UniValue multisend(const UniValue& params, bool fHelp) } return printMultiSend(); } + +UniValue upgradetohd(const UniValue& params, bool fHelp) +{ + + if (fHelp || params.size() == 0) { + throw std::runtime_error( + "upgradetohd ( \"mnemonicwords\" \"password\" )\n" + "\nNon-HD wallets will not be upgraded to being a HD wallet. Wallets that are already\n" + "\nNote that you will need to MAKE A NEW BACKUP of your wallet after setting the HD wallet mnemonic.\n" + "\nArguments:\n" + "1. \"words\" (string, optional) The WIF private key to use as the new HD seed; if not provided a random seed will be used.\n" + " The mnemonic value can be retrieved using the dumpwallet command. It is the private key marked hdmaster=1\n" + "2. \"password\" (boolean, optional) If your wallet is encrypted you must have your password here\n" + + "\nExamples:\n" + + HelpExampleCli("upgradetohd", "") + + HelpExampleCli("upgradetohd", "\"mnemonicwords\"") + + HelpExampleCli("upgradetohd", "\"mnemonicwords\" \"password\"")); + } + + if (IsInitialBlockDownload()) { + throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "Cannot set a new HD seed while still in Initial Block Download"); + } + + if (params.size() == 1 && pwalletMain->IsLocked()) { + throw JSONRPCError(RPC_WALLET_ERROR, "Cannot upgrade a encrypted wallet to hd without the password"); + } + + LOCK2(cs_main, pwalletMain->cs_wallet); + + // Do not do anything to HD wallets + if (pwalletMain->IsHDEnabled()) { + throw JSONRPCError(RPC_WALLET_ERROR, "Cannot upgrade a wallet to hd if It is already upgraded to hd."); + } + + EnsureWalletIsUnlocked(pwalletMain); + + std::string words = params[0].get_str(); + + int prev_version = pwalletMain->GetVersion(); + + int nMaxVersion = GetArg("-upgradewallet", 0); + if (nMaxVersion == 0) // the -upgradewallet without argument case + { + LogPrintf("Performing wallet upgrade to %i\n", FEATURE_LATEST); + nMaxVersion = CLIENT_VERSION; + pwalletMain->SetMinVersion(FEATURE_LATEST); // permanently upgrade the wallet immediately + } else + LogPrintf("Allowing wallet upgrade up to %i\n", nMaxVersion); + if (nMaxVersion < pwalletMain->GetVersion()) { + throw JSONRPCError(RPC_WALLET_ERROR, "Cannot downgrade wallet"); + } + + pwalletMain->SetMaxVersion(nMaxVersion); + + // Do not upgrade versions to any version between HD_SPLIT and FEATURE_PRE_SPLIT_KEYPOOL unless already supporting HD_SPLIT + int max_version = pwalletMain->GetVersion(); + if (!pwalletMain->CanSupportFeature(FEATURE_HD) && max_version >=FEATURE_HD && max_version < FEATURE_PRE_SPLIT_KEYPOOL) { + throw JSONRPCError(RPC_WALLET_ERROR, "Cannot upgrade a non HD split wallet without upgrading to support pre split keypool. Please use -upgradewallet=169900 or -upgradewallet with no version specified."); + } + + bool hd_upgrade = false; + bool split_upgrade = false; + if (pwalletMain->CanSupportFeature(FEATURE_HD) && !pwalletMain->IsHDEnabled()) { + LogPrintf("Upgrading wallet to HD\n"); + pwalletMain->SetMinVersion(FEATURE_HD); + + // generate a new master key + SecureString strWalletPass; + strWalletPass.reserve(100); + + // TODO: get rid of this .c_str() by implementing SecureString::operator=(std::string) + // Alternately, find a way to make params[0] mlock()'d to begin with. + if (params.size() < 2){ + strWalletPass = std::string().c_str(); + } else { + strWalletPass = params[1].get_str().c_str(); + } + + pwalletMain->GenerateNewHDChain(words, strWalletPass); + + hd_upgrade = true; + } + + // Upgrade to HD chain split if necessary + if (pwalletMain->CanSupportFeature(FEATURE_HD)) { + LogPrintf("Upgrading wallet to use HD chain split\n"); + pwalletMain->SetMinVersion(FEATURE_PRE_SPLIT_KEYPOOL); + split_upgrade = FEATURE_HD > prev_version; + } + + // Mark all keys currently in the keypool as pre-split + if (split_upgrade) { + pwalletMain->MarkPreSplitKeys(); + } + // Regenerate the keypool if upgraded to HD + if (hd_upgrade) { + if (!pwalletMain->TopUpKeyPool()) { + throw JSONRPCError(RPC_WALLET_ERROR, "Unable to generate keys\n"); + } + } + + pwalletMain->ScanForWalletTransactions(chainActive.Genesis(), true); + + return NullUniValue; +} + UniValue getzerocoinbalance(const UniValue& params, bool fHelp) { @@ -3051,7 +3193,7 @@ UniValue getarchivedzerocoin(const UniValue& params, bool fHelp) list listDMints = walletdb.ListArchivedDeterministicMints(); UniValue arrRet(UniValue::VARR); - for (const CZerocoinMint mint : listMints) { + for (const CZerocoinMint& mint : listMints) { UniValue objMint(UniValue::VOBJ); objMint.push_back(Pair("txid", mint.GetTxHash().GetHex())); objMint.push_back(Pair("denomination", ValueFromAmount(mint.GetDenominationAsAmount()))); @@ -3061,7 +3203,7 @@ UniValue getarchivedzerocoin(const UniValue& params, bool fHelp) arrRet.push_back(objMint); } - for (const CDeterministicMint dMint : listDMints) { + for (const CDeterministicMint& dMint : listDMints) { UniValue objDMint(UniValue::VOBJ); objDMint.push_back(Pair("txid", dMint.GetTxHash().GetHex())); objDMint.push_back(Pair("denomination", ValueFromAmount(libzerocoin::ZerocoinDenominationToAmount(dMint.GetDenomination())))); @@ -3270,7 +3412,7 @@ UniValue reconsiderzerocoins(const UniValue& params, bool fHelp) pwalletMain->ReconsiderZerocoins(listMints, listDMints); UniValue arrRet(UniValue::VARR); - for (const CZerocoinMint mint : listMints) { + for (const CZerocoinMint& mint : listMints) { UniValue objMint(UniValue::VOBJ); objMint.push_back(Pair("txid", mint.GetTxHash().GetHex())); objMint.push_back(Pair("denomination", ValueFromAmount(mint.GetDenominationAsAmount()))); @@ -3279,8 +3421,8 @@ UniValue reconsiderzerocoins(const UniValue& params, bool fHelp) arrRet.push_back(objMint); } - for (const CDeterministicMint dMint : listDMints) { - UniValue objMint(UniValue::VOBJ); + for (const CDeterministicMint& dMint : listDMints) { + UniValue objMint(UniValue::VOBJ); objMint.push_back(Pair("txid", dMint.GetTxHash().GetHex())); objMint.push_back(Pair("denomination", FormatMoney(libzerocoin::ZerocoinDenominationToAmount(dMint.GetDenomination())))); objMint.push_back(Pair("pubcoinhash", dMint.GetPubcoinHash().GetHex())); diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp index 65a43b1..1a95e9d 100755 --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -75,24 +75,24 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) empty_wallet(); // with an empty wallet we can't even pay one cent - BOOST_CHECK(!wallet.SelectCoinsMinConf( 1 * CENT, 1, 6, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK(!wallet.SelectCoinsMinConf( 1 * CENT, 1, 6, vCoins, setCoinsRet, nValueRet, CWallet::CoinSelectStrategy::random)); add_coin(1*CENT, 4); // add a new 1 cent coin // with a new 1 cent coin, we still can't find a mature 1 cent - BOOST_CHECK(!wallet.SelectCoinsMinConf( 1 * CENT, 1, 6, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK(!wallet.SelectCoinsMinConf( 1 * CENT, 1, 6, vCoins, setCoinsRet, nValueRet, CWallet::CoinSelectStrategy::random)); // but we can find a new 1 cent - BOOST_CHECK( wallet.SelectCoinsMinConf( 1 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf( 1 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet, CWallet::CoinSelectStrategy::random)); BOOST_CHECK_EQUAL(nValueRet, 1 * CENT); add_coin(2*CENT); // add a mature 2 cent coin // we can't make 3 cents of mature coins - BOOST_CHECK(!wallet.SelectCoinsMinConf( 3 * CENT, 1, 6, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK(!wallet.SelectCoinsMinConf( 3 * CENT, 1, 6, vCoins, setCoinsRet, nValueRet, CWallet::CoinSelectStrategy::random)); // we can make 3 cents of new coins - BOOST_CHECK( wallet.SelectCoinsMinConf( 3 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf( 3 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet, CWallet::CoinSelectStrategy::random)); BOOST_CHECK_EQUAL(nValueRet, 3 * CENT); add_coin(5*CENT); // add a mature 5 cent coin, @@ -102,33 +102,33 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) // now we have new: 1+10=11 (of which 10 was self-sent), and mature: 2+5+20=27. total = 38 // we can't make 38 cents only if we disallow new coins: - BOOST_CHECK(!wallet.SelectCoinsMinConf(38 * CENT, 1, 6, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK(!wallet.SelectCoinsMinConf(38 * CENT, 1, 6, vCoins, setCoinsRet, nValueRet, CWallet::CoinSelectStrategy::random)); // we can't even make 37 cents if we don't allow new coins even if they're from us - BOOST_CHECK(!wallet.SelectCoinsMinConf(38 * CENT, 6, 6, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK(!wallet.SelectCoinsMinConf(38 * CENT, 6, 6, vCoins, setCoinsRet, nValueRet, CWallet::CoinSelectStrategy::random)); // but we can make 37 cents if we accept new coins from ourself - BOOST_CHECK( wallet.SelectCoinsMinConf(37 * CENT, 1, 6, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf(37 * CENT, 1, 6, vCoins, setCoinsRet, nValueRet, CWallet::CoinSelectStrategy::random)); BOOST_CHECK_EQUAL(nValueRet, 37 * CENT); // and we can make 38 cents if we accept all new coins - BOOST_CHECK( wallet.SelectCoinsMinConf(38 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf(38 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet, CWallet::CoinSelectStrategy::random)); BOOST_CHECK_EQUAL(nValueRet, 38 * CENT); // try making 34 cents from 1,2,5,10,20 - we can't do it exactly - BOOST_CHECK( wallet.SelectCoinsMinConf(34 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf(34 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet, CWallet::CoinSelectStrategy::random)); BOOST_CHECK_GT(nValueRet, 34 * CENT); // but should get more than 34 cents BOOST_CHECK_EQUAL(setCoinsRet.size(), 3U); // the best should be 20+10+5. it's incredibly unlikely the 1 or 2 got included (but possible) // when we try making 7 cents, the smaller coins (1,2,5) are enough. We should see just 2+5 - BOOST_CHECK( wallet.SelectCoinsMinConf( 7 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf( 7 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet, CWallet::CoinSelectStrategy::random)); BOOST_CHECK_EQUAL(nValueRet, 7 * CENT); BOOST_CHECK_EQUAL(setCoinsRet.size(), 2U); // when we try making 8 cents, the smaller coins (1,2,5) are exactly enough. - BOOST_CHECK( wallet.SelectCoinsMinConf( 8 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf( 8 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet, CWallet::CoinSelectStrategy::random)); BOOST_CHECK(nValueRet == 8 * CENT); BOOST_CHECK_EQUAL(setCoinsRet.size(), 3U); // when we try making 9 cents, no subset of smaller coins is enough, and we get the next bigger coin (10) - BOOST_CHECK( wallet.SelectCoinsMinConf( 9 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf( 9 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet, CWallet::CoinSelectStrategy::random)); BOOST_CHECK_EQUAL(nValueRet, 10 * CENT); BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U); @@ -142,30 +142,30 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) add_coin(30*CENT); // now we have 6+7+8+20+30 = 71 cents total // check that we have 71 and not 72 - BOOST_CHECK( wallet.SelectCoinsMinConf(71 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); - BOOST_CHECK(!wallet.SelectCoinsMinConf(72 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf(71 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet, CWallet::CoinSelectStrategy::random)); + BOOST_CHECK(!wallet.SelectCoinsMinConf(72 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet, CWallet::CoinSelectStrategy::random)); // now try making 16 cents. the best smaller coins can do is 6+7+8 = 21; not as good at the next biggest coin, 20 - BOOST_CHECK( wallet.SelectCoinsMinConf(16 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf(16 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet, CWallet::CoinSelectStrategy::random)); BOOST_CHECK_EQUAL(nValueRet, 20 * CENT); // we should get 20 in one coin BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U); add_coin( 5*CENT); // now we have 5+6+7+8+20+30 = 75 cents total // now if we try making 16 cents again, the smaller coins can make 5+6+7 = 18 cents, better than the next biggest coin, 20 - BOOST_CHECK( wallet.SelectCoinsMinConf(16 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf(16 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet, CWallet::CoinSelectStrategy::random)); BOOST_CHECK_EQUAL(nValueRet, 18 * CENT); // we should get 18 in 3 coins BOOST_CHECK_EQUAL(setCoinsRet.size(), 3U); add_coin( 18*CENT); // now we have 5+6+7+8+18+20+30 // and now if we try making 16 cents again, the smaller coins can make 5+6+7 = 18 cents, the same as the next biggest coin, 18 - BOOST_CHECK( wallet.SelectCoinsMinConf(16 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf(16 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet, CWallet::CoinSelectStrategy::random)); BOOST_CHECK_EQUAL(nValueRet, 18 * CENT); // we should get 18 in 1 coin BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U); // because in the event of a tie, the biggest coin wins // now try making 11 cents. we should get 5+6 - BOOST_CHECK( wallet.SelectCoinsMinConf(11 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf(11 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet, CWallet::CoinSelectStrategy::random)); BOOST_CHECK_EQUAL(nValueRet, 11 * CENT); BOOST_CHECK_EQUAL(setCoinsRet.size(), 2U); @@ -174,11 +174,11 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) add_coin( 2*COIN); add_coin( 3*COIN); add_coin( 4*COIN); // now we have 5+6+7+8+18+20+30+100+200+300+400 = 1094 cents - BOOST_CHECK( wallet.SelectCoinsMinConf(95 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf(95 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet, CWallet::CoinSelectStrategy::random)); BOOST_CHECK_EQUAL(nValueRet, 1 * COIN); // we should get 1 BTC in 1 coin BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U); - BOOST_CHECK( wallet.SelectCoinsMinConf(195 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf(195 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet, CWallet::CoinSelectStrategy::random)); BOOST_CHECK_EQUAL(nValueRet, 2 * COIN); // we should get 2 BTC in 1 coin BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U); @@ -192,14 +192,14 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) // try making 1 cent from 0.1 + 0.2 + 0.3 + 0.4 + 0.5 = 1.5 cents // we'll get sub-cent change whatever happens, so can expect 1.0 exactly - BOOST_CHECK( wallet.SelectCoinsMinConf(1 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf(1 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet, CWallet::CoinSelectStrategy::random)); BOOST_CHECK_EQUAL(nValueRet, 1 * CENT); // but if we add a bigger coin, making it possible to avoid sub-cent change, things change: add_coin(1111*CENT); // try making 1 cent from 0.1 + 0.2 + 0.3 + 0.4 + 0.5 + 1111 = 1112.5 cents - BOOST_CHECK( wallet.SelectCoinsMinConf(1 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf(1 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet, CWallet::CoinSelectStrategy::random)); BOOST_CHECK_EQUAL(nValueRet, 1 * CENT); // we should get the exact amount // if we add more sub-cent coins: @@ -207,7 +207,7 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) add_coin(0.7*CENT); // and try again to make 1.0 cents, we can still make 1.0 cents - BOOST_CHECK( wallet.SelectCoinsMinConf(1 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf(1 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet, CWallet::CoinSelectStrategy::random)); BOOST_CHECK_EQUAL(nValueRet, 1 * CENT); // we should get the exact amount // run the 'mtgox' test (see http://blockexplorer.com/tx/29a3efd3ef04f9153d47a990bd7b048a4b2d213daaa5fb8ed670fb85f13bdbcf) @@ -216,7 +216,7 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) for (int i = 0; i < 20; i++) add_coin(50000 * COIN); - BOOST_CHECK( wallet.SelectCoinsMinConf(500000 * COIN, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf(500000 * COIN, 1, 1, vCoins, setCoinsRet, nValueRet, CWallet::CoinSelectStrategy::random)); BOOST_CHECK_EQUAL(nValueRet, 500000 * COIN); // we should get the exact amount BOOST_CHECK_EQUAL(setCoinsRet.size(), 10U); // in ten coins @@ -229,7 +229,7 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) add_coin(0.6 * CENT); add_coin(0.7 * CENT); add_coin(1111 * CENT); - BOOST_CHECK( wallet.SelectCoinsMinConf(1 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf(1 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet, CWallet::CoinSelectStrategy::random)); BOOST_CHECK_EQUAL(nValueRet, 1111 * CENT); // we get the bigger coin BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U); @@ -239,7 +239,7 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) add_coin(0.6 * CENT); add_coin(0.8 * CENT); add_coin(1111 * CENT); - BOOST_CHECK( wallet.SelectCoinsMinConf(1 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf(1 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet, CWallet::CoinSelectStrategy::random)); BOOST_CHECK_EQUAL(nValueRet, 1 * CENT); // we should get the exact amount BOOST_CHECK_EQUAL(setCoinsRet.size(), 2U); // in two coins 0.4+0.6 @@ -250,12 +250,12 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) add_coin(1 * COIN); // trying to make 1.0001 from these three coins - BOOST_CHECK( wallet.SelectCoinsMinConf(1.0001 * COIN, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf(1.0001 * COIN, 1, 1, vCoins, setCoinsRet, nValueRet, CWallet::CoinSelectStrategy::random)); BOOST_CHECK_EQUAL(nValueRet, 1.0105 * COIN); // we should get all coins BOOST_CHECK_EQUAL(setCoinsRet.size(), 3U); // but if we try to make 0.999, we should take the bigger of the two small coins to avoid sub-cent change - BOOST_CHECK( wallet.SelectCoinsMinConf(0.999 * COIN, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf(0.999 * COIN, 1, 1, vCoins, setCoinsRet, nValueRet, CWallet::CoinSelectStrategy::random)); BOOST_CHECK_EQUAL(nValueRet, 1.01 * COIN); // we should get 1 + 0.01 BOOST_CHECK_EQUAL(setCoinsRet.size(), 2U); @@ -267,8 +267,8 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) // picking 50 from 100 coins doesn't depend on the shuffle, // but does depend on randomness in the stochastic approximation code - BOOST_CHECK(wallet.SelectCoinsMinConf(50 * COIN, 1, 6, vCoins, setCoinsRet , nValueRet)); - BOOST_CHECK(wallet.SelectCoinsMinConf(50 * COIN, 1, 6, vCoins, setCoinsRet2, nValueRet)); + BOOST_CHECK(wallet.SelectCoinsMinConf(50 * COIN, 1, 6, vCoins, setCoinsRet , nValueRet, CWallet::CoinSelectStrategy::random)); + BOOST_CHECK(wallet.SelectCoinsMinConf(50 * COIN, 1, 6, vCoins, setCoinsRet2, nValueRet, CWallet::CoinSelectStrategy::random)); BOOST_CHECK(!equal_sets(setCoinsRet, setCoinsRet2)); int fails = 0; @@ -276,8 +276,8 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) { // selecting 1 from 100 identical coins depends on the shuffle; this test will fail 1% of the time // run the test RANDOM_REPEATS times and only complain if all of them fail - BOOST_CHECK(wallet.SelectCoinsMinConf(COIN, 1, 6, vCoins, setCoinsRet , nValueRet)); - BOOST_CHECK(wallet.SelectCoinsMinConf(COIN, 1, 6, vCoins, setCoinsRet2, nValueRet)); + BOOST_CHECK(wallet.SelectCoinsMinConf(COIN, 1, 6, vCoins, setCoinsRet , nValueRet, CWallet::CoinSelectStrategy::random)); + BOOST_CHECK(wallet.SelectCoinsMinConf(COIN, 1, 6, vCoins, setCoinsRet2, nValueRet, CWallet::CoinSelectStrategy::random)); if (equal_sets(setCoinsRet, setCoinsRet2)) fails++; } @@ -293,8 +293,8 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) { // selecting 1 from 100 identical coins depends on the shuffle; this test will fail 1% of the time // run the test RANDOM_REPEATS times and only complain if all of them fail - BOOST_CHECK(wallet.SelectCoinsMinConf(90*CENT, 1, 6, vCoins, setCoinsRet , nValueRet)); - BOOST_CHECK(wallet.SelectCoinsMinConf(90*CENT, 1, 6, vCoins, setCoinsRet2, nValueRet)); + BOOST_CHECK(wallet.SelectCoinsMinConf(90*CENT, 1, 6, vCoins, setCoinsRet , nValueRet, CWallet::CoinSelectStrategy::random)); + BOOST_CHECK(wallet.SelectCoinsMinConf(90*CENT, 1, 6, vCoins, setCoinsRet2, nValueRet, CWallet::CoinSelectStrategy::random)); if (equal_sets(setCoinsRet, setCoinsRet2)) fails++; } diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index e383288..9782f80 100755 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -11,19 +11,23 @@ #include "accumulators.h" #include "base58.h" #include "checkpoints.h" -#include "coincontrol.h" +#include "wallet/coincontrol.h" #include "kernel.h" #include "karmanode-budget.h" #include "net.h" #include "primitives/transaction.h" #include "script/script.h" +#include "script/standard.h" #include "script/sign.h" #include "spork.h" #include "swifttx.h" #include "timedata.h" #include "txdb.h" #include "util.h" +#include "ui_interface.h" #include "utilmoneystr.h" +#include "bip39.h" +#include #include "denomination_functions.h" #include "libzerocoin/Denominations.h" @@ -73,17 +77,12 @@ struct CompareValueOnly { } }; -enum class CWallet::CoinSelectStrategy -{ - random, - descentByAmount, -}; - std::string COutput::ToString() const { return strprintf("COutput(%s, %d, %d) [%s]", tx->GetHash().ToString(), i, nDepth, FormatMoney(tx->vout[i].nValue)); } + const CWalletTx* CWallet::GetWalletTx(const uint256& hash) const { LOCK(cs_wallet); @@ -104,36 +103,201 @@ std::vector CWallet::getWalletTxs() return result; } -CPubKey CWallet::GenerateNewKey() +CPubKey CWallet::GenerateNewKey(uint32_t nAccountIndex, bool fInternal, CWalletDB * walletDB) { AssertLockHeld(cs_wallet); // mapKeyMetadata bool fCompressed = CanSupportFeature(FEATURE_COMPRPUBKEY); // default to compressed public keys if we want 0.6.0 wallets CKey secret; - secret.MakeNewKey(fCompressed); - - // Compressed public keys were introduced in version 0.6.0 - if (fCompressed) - SetMinVersion(FEATURE_COMPRPUBKEY); - CPubKey pubkey = secret.GetPubKey(); - assert(secret.VerifyPubKey(pubkey)); // Create new metadata int64_t nCreationTime = GetTime(); - mapKeyMetadata[pubkey.GetID()] = CKeyMetadata(nCreationTime); - if (!nTimeFirstKey || nCreationTime < nTimeFirstKey) - nTimeFirstKey = nCreationTime; + CKeyMetadata metadata(nCreationTime); + + CPubKey pubkey; + // use HD key derivation if HD was enabled during wallet creation + if (IsHDEnabled()) { + DeriveNewChildKey(metadata, secret, nAccountIndex, fInternal, walletDB); + pubkey = secret.GetPubKey(); + } else { + secret.MakeNewKey(fCompressed); + + // Compressed public keys were introduced in version 0.6.0 + if (fCompressed) + SetMinVersion(FEATURE_COMPRPUBKEY); + + pubkey = secret.GetPubKey(); + assert(secret.VerifyPubKey(pubkey)); + // Create new metadata + mapKeyMetadata[pubkey.GetID()] = metadata; + if (!nTimeFirstKey || nCreationTime < nTimeFirstKey) + nTimeFirstKey = nCreationTime; - if (!AddKeyPubKey(secret, pubkey)) - throw std::runtime_error("CWallet::GenerateNewKey() : AddKey failed"); + if (!AddKeyPubKeyWithDB(secret, pubkey, walletDB)) + throw std::runtime_error(std::string(__func__) + ": AddKey failed"); + } return pubkey; } -bool CWallet::AddKeyPubKey(const CKey& secret, const CPubKey& pubkey) +void CWallet::DeriveNewChildKey(const CKeyMetadata& metadata, CKey& secretRet, uint32_t nAccountIndex, bool fInternal, CWalletDB * walletDB) +{ + CHDChain hdChainTmp; + if (!GetHDChain(hdChainTmp)) { + throw std::runtime_error(std::string(__func__) + ": GetHDChain failed"); + } + + if (!DecryptHDChain(hdChainTmp)) + throw std::runtime_error(std::string(__func__) + ": DecryptHDChainSeed failed"); + // make sure seed matches this chain + if (hdChainTmp.GetID() != hdChainTmp.GetSeedHash()) + throw std::runtime_error(std::string(__func__) + ": Wrong HD chain!"); + + CHDAccount acc; + if (!hdChainTmp.GetAccount(nAccountIndex, acc)) + throw std::runtime_error(std::string(__func__) + ": Wrong HD account!"); + + // derive child key at next index, skip keys already known to the wallet + CExtKey childKey; + uint32_t nChildIndex = fInternal ? acc.nInternalChainCounter : acc.nExternalChainCounter; + do { + hdChainTmp.DeriveChildExtKey(nAccountIndex, fInternal, nChildIndex, childKey); + // increment childkey index + nChildIndex++; + } while (HaveKey(childKey.key.GetPubKey().GetID())); + secretRet = childKey.key; + + CPubKey pubkey = secretRet.GetPubKey(); + assert(secretRet.VerifyPubKey(pubkey)); + + // store metadata + mapKeyMetadata[pubkey.GetID()] = metadata; + if (!nTimeFirstKey || metadata.nCreateTime < nTimeFirstKey) + nTimeFirstKey = metadata.nCreateTime; + + // update the chain model in the database + CHDChain hdChainCurrent; + GetHDChain(hdChainCurrent); + + if (fInternal) { + acc.nInternalChainCounter = nChildIndex; + } + else { + acc.nExternalChainCounter = nChildIndex; + } + + if (!hdChainCurrent.SetAccount(nAccountIndex, acc)) + throw std::runtime_error(std::string(__func__) + ": SetAccount failed"); + + if (IsCrypted()) { + if (!SetCryptedHDChain(hdChainCurrent, false)) + throw std::runtime_error(std::string(__func__) + ": SetCryptedHDChain failed"); + } + else { + if (!SetHDChain(hdChainCurrent, false, walletDB)) + throw std::runtime_error(std::string(__func__) + ": SetHDChain failed"); + } + + if (!AddHDPubKey(childKey.Neuter(), fInternal)) + throw std::runtime_error(std::string(__func__) + ": AddHDPubKey failed"); +} + +bool CWallet::GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const +{ + LOCK(cs_wallet); + std::map::const_iterator mi = mapHdPubKeys.find(address); + if (mi != mapHdPubKeys.end()) + { + const CHDPubKey &hdPubKey = (*mi).second; + vchPubKeyOut = hdPubKey.extPubKey.pubkey; + return true; + } + else + return CCryptoKeyStore::GetPubKey(address, vchPubKeyOut); +} + +bool CWallet::GetKey(const CKeyID &address, CKey& keyOut) const +{ + LOCK(cs_wallet); + std::map::const_iterator mi = mapHdPubKeys.find(address); + if (mi != mapHdPubKeys.end()) + { + // if the key has been found in mapHdPubKeys, derive it on the fly + const CHDPubKey &hdPubKey = (*mi).second; + CHDChain hdChainCurrent; + if (!GetHDChain(hdChainCurrent)) + throw std::runtime_error(std::string(__func__) + ": GetHDChain failed"); + if (!DecryptHDChain(hdChainCurrent)) + throw std::runtime_error(std::string(__func__) + ": DecryptHDChainSeed failed"); + // make sure seed matches this chain + if (hdChainCurrent.GetID() != hdChainCurrent.GetSeedHash()) + throw std::runtime_error(std::string(__func__) + ": Wrong HD chain!"); + + CExtKey extkey; + hdChainCurrent.DeriveChildExtKey(hdPubKey.nAccountIndex, hdPubKey.nChangeIndex != 0, hdPubKey.extPubKey.nChild, extkey); + keyOut = extkey.key; + + return true; + } + else { + return CCryptoKeyStore::GetKey(address, keyOut); + } +} + +bool CWallet::HaveKey(const CKeyID &address) const +{ + LOCK(cs_wallet); + if (mapHdPubKeys.count(address) > 0) + return true; + return CCryptoKeyStore::HaveKey(address); +} + +bool CWallet::LoadHDPubKey(const CHDPubKey &hdPubKey) +{ + AssertLockHeld(cs_wallet); + + mapHdPubKeys[hdPubKey.extPubKey.pubkey.GetID()] = hdPubKey; + return true; +} + +bool CWallet::AddHDPubKey(const CExtPubKey &extPubKey, bool fInternal) +{ + AssertLockHeld(cs_wallet); + + CHDChain hdChainCurrent; + GetHDChain(hdChainCurrent); + + CHDPubKey hdPubKey; + hdPubKey.extPubKey = extPubKey; + hdPubKey.hdchainID = hdChainCurrent.GetID(); + hdPubKey.nChangeIndex = fInternal ? 1 : 0; + mapHdPubKeys[extPubKey.pubkey.GetID()] = hdPubKey; + + // check if we need to remove from watch-only + CScript script; + script = GetScriptForDestination(extPubKey.pubkey.GetID()); + if (HaveWatchOnly(script)) + RemoveWatchOnly(script); + script = GetScriptForRawPubKey(extPubKey.pubkey); + if (HaveWatchOnly(script)) + RemoveWatchOnly(script); + + if (!fFileBacked) + return true; + + return CWalletDB(strWalletFile).WriteHDPubKey(hdPubKey, mapKeyMetadata[extPubKey.pubkey.GetID()]); +} + + +bool CWallet::AddKeyPubKey(const CKey& key, const CPubKey& pubkey) +{ + return AddKeyPubKeyWithDB(key, pubkey, nullptr); +} + +bool CWallet::AddKeyPubKeyWithDB(const CKey& key, const CPubKey &pubkey, CWalletDB * walletDB) { AssertLockHeld(cs_wallet); // mapKeyMetadata - if (!CCryptoKeyStore::AddKeyPubKey(secret, pubkey)) + if (!CCryptoKeyStore::AddKeyPubKey(key, pubkey)) return false; // check if we need to remove from watch-only @@ -145,7 +309,12 @@ bool CWallet::AddKeyPubKey(const CKey& secret, const CPubKey& pubkey) if (!fFileBacked) return true; if (!IsCrypted()) { - return CWalletDB(strWalletFile).WriteKey(pubkey, secret.GetPrivKey(), mapKeyMetadata[pubkey.GetID()]); + if(walletDB == nullptr) { + return CWalletDB(strWalletFile).WriteKey(pubkey, key.GetPrivKey(), mapKeyMetadata[pubkey.GetID()]); + } + else { + return walletDB->WriteKey(pubkey, key.GetPrivKey(), mapKeyMetadata[pubkey.GetID()]); + } } return true; } @@ -268,6 +437,50 @@ bool CWallet::LoadMultiSig(const CScript& dest) return CCryptoKeyStore::AddMultiSig(dest); } +bool CWallet::UpgradeHdChainEncrypted(const SecureString& strWalletPassphrase, const CHDChain& chain) +{ + SecureString strWalletPassphraseFinal; + + strWalletPassphraseFinal = strWalletPassphrase; + + // must get current HD chain before EncryptKeys + CHDChain hdChainCurrent; + hdChainCurrent = chain; + + CCrypter crypter; + CKeyingMaterial vMasterKey; + + { + LOCK(cs_wallet); + for (const MasterKeyMap::value_type& pMasterKey : mapMasterKeys) { + if (!crypter.SetKeyFromPassphrase(strWalletPassphraseFinal, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod)) + return false; + if (!crypter.Decrypt(pMasterKey.second.vchCryptedKey, vMasterKey)) { + continue; // try another master key + } + + + assert(EncryptHDChainUpgrade(vMasterKey, hdChainCurrent)); + + CHDChain hdChainCrypted; + assert(GetHDChain(hdChainCrypted)); + + + LogPrintf("EncryptWallet -- current seed: '%s'\n", HexStr(hdChainCurrent.GetSeed()).c_str()); + LogPrintf("EncryptWallet -- crypted seed: '%s'\n", HexStr(hdChainCrypted.GetSeed()).c_str()); + + // ids should match, seed hashes should not + assert(hdChainCurrent.GetID() == hdChainCrypted.GetID()); + assert(hdChainCurrent.GetSeedHash() != hdChainCrypted.GetSeedHash()); + + if (SetCryptedHDChain(hdChainCrypted, false)) { + return true; + } + } + } + return false; +} + bool CWallet::Unlock(const SecureString& strWalletPassphrase, bool anonymizeOnly) { SecureString strWalletPassphraseFinal; @@ -279,7 +492,6 @@ bool CWallet::Unlock(const SecureString& strWalletPassphrase, bool anonymizeOnly strWalletPassphraseFinal = strWalletPassphrase; - CCrypter crypter; CKeyingMaterial vMasterKey; @@ -482,6 +694,15 @@ void CWallet::AddToSpends(const uint256& wtxid) AddToSpends(txin.prevout, wtxid); } +void CWallet::FinishEncryptWallet() { + { + LOCK(cs_wallet); + pwalletdbEncryption->TxnCommit(); + Lock(); + } + +} + bool CWallet::GetKarmanodeVinAndKeys(CTxIn& txinRet, CPubKey& pubKeyRet, CKey& keyRet, std::string strTxHash, std::string strOutputIndex) { // wait for reindex and/or import to finish @@ -593,6 +814,10 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase) pwalletdbEncryption->WriteMasterKey(nMasterKeyMaxID, kMasterKey); } + // must get current HD chain before EncryptKeys + CHDChain hdChainCurrent; + GetHDChain(hdChainCurrent); + if (!EncryptKeys(vMasterKey)) { if (fFileBacked) { pwalletdbEncryption->TxnAbort(); @@ -602,7 +827,23 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase) // die and let the user reload their unencrypted wallet. assert(false); } + if (!hdChainCurrent.IsNull()) { + assert(EncryptHDChain(vMasterKey)); + + CHDChain hdChainCrypted; + assert(GetHDChain(hdChainCrypted)); + + + LogPrintf("EncryptWallet -- current seed: '%s'\n", HexStr(hdChainCurrent.GetSeed()).c_str()); + LogPrintf("EncryptWallet -- crypted seed: '%s'\n", HexStr(hdChainCrypted.GetSeed()).c_str()); + + // ids should match, seed hashes should not + assert(hdChainCurrent.GetID() == hdChainCrypted.GetID()); + assert(hdChainCurrent.GetSeedHash() != hdChainCrypted.GetSeedHash()); + + assert(SetCryptedHDChain(hdChainCrypted, false)); + } // Encryption was introduced in version 0.4.0 SetMinVersion(FEATURE_WALLETCRYPT, pwalletdbEncryption, true); @@ -620,7 +861,13 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase) Lock(); Unlock(strWalletPassphrase); - NewKeyPool(); + // if we are not using HD, generate new keypool + if(IsHDEnabled()) { + TopUpKeyPool(); + } + else { + NewKeyPool(); + } Lock(); // Need to completely rewrite the wallet file; if we don't, bdb might keep @@ -632,6 +879,142 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase) return true; } +void CWallet::GenerateNewHDChain(const std::string& words, const SecureString& strWalletPassphrase) +{ + CHDChain newHdChain; + + std::string strSeed = GetArg("-hdseed", "not hex"); + + if(mapArgs.count("-hdseed") && IsHex(strSeed)) { + std::vector vchSeed = ParseHex(strSeed); + if (!newHdChain.SetSeed(SecureVector(vchSeed.begin(), vchSeed.end()), true)) + throw std::runtime_error(std::string(__func__) + ": SetSeed failed"); + } + else { + if (mapArgs.count("-hdseed") && !IsHex(strSeed)) + LogPrintf("CWallet::GenerateNewHDChain -- Incorrect seed, generating random one instead\n"); + + // NOTE: empty mnemonic means "generate a new one for me" + //std::string strMnemonic = GetArg("-mnemonic", ""); + // if this is true words would already be a string now + std::string strMnemonic; + std::vector vectorWords; + if (words.size() !=0) { + strMnemonic = words; + } else { + strMnemonic = GetArg("-mnemonic", ""); + if(strMnemonic.empty()){ + vectorWords = CMnemonic::Generate(256); + strMnemonic = join(vectorWords," "); + std::string notice = "This is your seed phrase, please write it down to recover wallet \n\"" + join(vectorWords," ")+"\"\n" + + "NEVER SHARE THIS SEQUENCE WITH ANYONE TO PROTECT YOUR FUNDS"; + ShowSeedPhrase(notice); + } + } + + // NOTE: default mnemonic passphrase is an empty string + std::string strMnemonicPassphrase = GetArg("-mnemonicpassphrase", ""); + + SecureVector vchMnemonic(strMnemonic.begin(), strMnemonic.end()); + SecureVector vchMnemonicPassphrase(strMnemonicPassphrase.begin(), strMnemonicPassphrase.end()); + + if (!newHdChain.SetMnemonic(vchMnemonic, vchMnemonicPassphrase, true)) + throw std::runtime_error(std::string(__func__) + ": SetMnemonic failed"); + } + newHdChain.Debug(__func__); + + if (IsCrypted()) { + if (!UpgradeHdChainEncrypted(strWalletPassphrase, newHdChain)) + throw std::runtime_error(std::string(__func__) + ": SetCryptedHDChain failed"); + } + else { + if (!SetHDChain(newHdChain, false)) + throw std::runtime_error(std::string(__func__) + ": SetHDChain failed"); + } + + + // clean up + mapArgs.erase("-hdseed"); + mapArgs.erase("-mnemonic"); + mapArgs.erase("-mnemonicpassphrase"); +} + +void CWallet::GenerateNewHDChain(const std::vector& words, const SecureString& strWalletPassphrase) +{ + std::string strMnemonic; + strMnemonic = join(words," "); + return GenerateNewHDChain(strMnemonic, strWalletPassphrase); +} +bool CWallet::SetHDChain(const CHDChain& chain, bool memonly, CWalletDB * walletDB) +{ + LOCK(cs_wallet); + + if (!CCryptoKeyStore::SetHDChain(chain)) + return false; + + if (!memonly) { + if(walletDB != nullptr && !walletDB->WriteHDChain(chain)) { + throw std::runtime_error(std::string(__func__) + ": WriteHDChain failed"); + } + else if(!CWalletDB(strWalletFile).WriteHDChain(chain)) { + throw std::runtime_error(std::string(__func__) + ": WriteHDChain failed"); + } + } + + return true; +} + +bool CWallet::SetCryptedHDChain(const CHDChain& chain, bool memonly) +{ + LOCK(cs_wallet); + + if (!CCryptoKeyStore::SetCryptedHDChain(chain)) + return false; + + if (!memonly) { + if (!fFileBacked) + return false; + if (pwalletdbEncryption) { + + if (!pwalletdbEncryption->WriteCryptedHDChain(chain)) + throw std::runtime_error(std::string(__func__) + ": WriteCryptedHDChain failed"); + } else { + + if (!CWalletDB(strWalletFile).WriteCryptedHDChain(chain)) + throw std::runtime_error(std::string(__func__) + ": WriteCryptedHDChain failed"); + } + } + + return true; +} + +bool CWallet::GetDecryptedHDChain(CHDChain& hdChainRet) +{ + LOCK(cs_wallet); + + CHDChain hdChainTmp; + if (!GetHDChain(hdChainTmp)) { + return false; + } + + if (!DecryptHDChain(hdChainTmp)) + return false; + + // make sure seed matches this chain + if (hdChainTmp.GetID() != hdChainTmp.GetSeedHash()) + return false; + + hdChainRet = hdChainTmp; + + return true; +} + +bool CWallet::IsHDEnabled() +{ + CHDChain hdChainCurrent; + return GetHDChain(hdChainCurrent); +} + int64_t CWallet::IncOrderPosNext(CWalletDB* pwalletdb) { AssertLockHeld(cs_wallet); // nOrderPosNext @@ -2596,7 +2979,7 @@ bool CWallet::CreateCollateralTransaction(CMutableTransaction& txCollateral, std // make our change address CScript scriptChange; CPubKey vchPubKey; - assert(reservekey.GetReservedKey(vchPubKey)); // should never fail, as we just unlocked + assert(reservekey.GetReservedKey(vchPubKey, false)); // should never fail, as we just unlocked scriptChange = GetScriptForDestination(vchPubKey.GetID()); reservekey.KeepKey(); @@ -2891,7 +3274,7 @@ bool CWallet::CreateTransactionHelper(const std::vector nStakeSetUpdateTime) { setStakeCoins.clear(); - if (!SelectStakeCoins(setStakeCoins, nBalance - nReserveBalance)) + if (!SelectStakeCoins(setStakeCoins, nBalance - nReserveBalance)) { + LogPrint("staking", "CreateCoinStake(): selectStakeCoins failed\n"); return false; - + } nLastStakeSetUpdate = GetTime(); } - if (setStakeCoins.empty()) + if (setStakeCoins.empty()) { + LogPrint("staking", "CreateCoinStake(): listInputs empty\n"); return false; + } vector vwtxPrev; @@ -3364,7 +3750,7 @@ string CWallet::PrepareObfuscationDenominate(int minRounds, int maxRounds) CScript scriptChange; CPubKey vchPubKey; // use a unique change address - assert(reservekey.GetReservedKey(vchPubKey)); // should never fail, as we just unlocked + assert(reservekey.GetReservedKey(vchPubKey, true)); // should never fail, as we just unlocked scriptChange = GetScriptForDestination(vchPubKey.GetID()); reservekey.KeepKey(); @@ -3421,8 +3807,8 @@ DBErrors CWallet::LoadWallet(bool& fFirstRunRet) if (nLoadWalletRet == DB_NEED_REWRITE) { if (CDB::Rewrite(strWalletFile, "\x04pool")) { LOCK(cs_wallet); - setKeyPool.clear(); - // Note: can't top-up keypool here, because wallet is locked. + setInternalKeyPool.clear(); + setExternalKeyPool.clear(); // Note: can't top-up keypool here, because wallet is locked. // User will be prompted to unlock wallet the next operation // the requires a new key. } @@ -3446,8 +3832,8 @@ DBErrors CWallet::ZapWalletTx(std::vector& vWtx) if (nZapWalletTxRet == DB_NEED_REWRITE) { if (CDB::Rewrite(strWalletFile, "\x04pool")) { LOCK(cs_wallet); - setKeyPool.clear(); - // Note: can't top-up keypool here, because wallet is locked. + setInternalKeyPool.clear(); + setExternalKeyPool.clear(); // Note: can't top-up keypool here, because wallet is locked. // User will be prompted to unlock wallet the next operation // that requires a new key. } @@ -3521,24 +3907,41 @@ bool CWallet::NewKeyPool() { LOCK(cs_wallet); CWalletDB walletdb(strWalletFile); - for (int64_t nIndex : setKeyPool) - walletdb.ErasePool(nIndex); - setKeyPool.clear(); + for (int64_t nIndex : setInternalKeyPool){ + walletdb.ErasePool(nIndex); + } + setInternalKeyPool.clear(); + for (int64_t nIndex : setExternalKeyPool){ + walletdb.ErasePool(nIndex); + } + setExternalKeyPool.clear(); - if (IsLocked()) + for (int64_t nIndex : set_pre_split_keypool) { + walletdb.ErasePool(nIndex); + } + set_pre_split_keypool.clear(); + + if (!TopUpKeyPool()) return false; - int64_t nKeys = max(GetArg("-keypool", 1000), (int64_t)0); - for (int i = 0; i < nKeys; i++) { - int64_t nIndex = i + 1; - walletdb.WritePool(nIndex, CKeyPool(GenerateNewKey())); - setKeyPool.insert(nIndex); - } - LogPrintf("CWallet::NewKeyPool wrote %d new keys\n", nKeys); + + LogPrintf("CWallet::NewKeyPool rewrote keypool\n"); } return true; } +size_t CWallet::KeypoolCountExternalKeys() +{ + AssertLockHeld(cs_wallet); // setExternalKeyPool + return setExternalKeyPool.size() + set_pre_split_keypool.size(); +} + +size_t CWallet::KeypoolCountInternalKeys() +{ + AssertLockHeld(cs_wallet); // setInternalKeyPool + return setInternalKeyPool.size(); +} + bool CWallet::TopUpKeyPool(unsigned int kpSize) { { @@ -3547,7 +3950,6 @@ bool CWallet::TopUpKeyPool(unsigned int kpSize) if (IsLocked()) return false; - CWalletDB walletdb(strWalletFile); // Top up key pool unsigned int nTargetSize; @@ -3556,14 +3958,42 @@ bool CWallet::TopUpKeyPool(unsigned int kpSize) else nTargetSize = max(GetArg("-keypool", 1000), (int64_t)0); - while (setKeyPool.size() < (nTargetSize + 1)) { + // count amount of available keys (internal, external) + // make sure the keypool of external and internal keys fits the user selected target (-keypool) + int64_t amountExternal = setExternalKeyPool.size(); + int64_t amountInternal = setInternalKeyPool.size(); + int64_t missingExternal = std::max(std::max((int64_t) nTargetSize, (int64_t) 1) - amountExternal, (int64_t) 0); + int64_t missingInternal = std::max(std::max((int64_t) nTargetSize, (int64_t) 1) - amountInternal, (int64_t) 0); + + if (!IsHDEnabled()) + { + // don't create extra internal keys + missingInternal = 0; + } else { + nTargetSize *= 2; + } + bool fInternal = false; + CWalletDB walletdb(strWalletFile); + for (int64_t i = missingInternal + missingExternal; i--;) { int64_t nEnd = 1; - if (!setKeyPool.empty()) - nEnd = *(--setKeyPool.end()) + 1; - if (!walletdb.WritePool(nEnd, CKeyPool(GenerateNewKey()))) + if (i < missingInternal) { + fInternal = true; + } + if (!setInternalKeyPool.empty()) { + nEnd = *(--setInternalKeyPool.end()) + 1; + } + if (!setExternalKeyPool.empty()) { + nEnd = std::max(nEnd, *(--setExternalKeyPool.end()) + 1); + } + // TODO: implement keypools for all accounts? + if (!walletdb.WritePool(nEnd, CKeyPool(GenerateNewKey(0, fInternal, &walletdb), fInternal))) throw runtime_error("TopUpKeyPool() : writing generated key failed"); - setKeyPool.insert(nEnd); - LogPrintf("keypool added key %d, size=%u\n", nEnd, setKeyPool.size()); + if (fInternal) { + setInternalKeyPool.insert(nEnd); + } else { + setExternalKeyPool.insert(nEnd); + } + LogPrintf("keypool added key %d, size=%u, internal=%d\n", nEnd, setInternalKeyPool.size() + setExternalKeyPool.size() + set_pre_split_keypool.size(), fInternal); double dProgress = 100.f * nEnd / (nTargetSize + 1); std::string strMsg = strprintf(_("Loading wallet... (%3.2f %%)"), dProgress); uiInterface.InitMessage(strMsg); @@ -3572,7 +4002,7 @@ bool CWallet::TopUpKeyPool(unsigned int kpSize) return true; } -void CWallet::ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& keypool) +void CWallet::ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& keypool, bool fInternal) { nIndex = -1; keypool.vchPubKey = CPubKey(); @@ -3582,23 +4012,32 @@ void CWallet::ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& keypool) if (!IsLocked()) TopUpKeyPool(); + fInternal = fInternal && IsHDEnabled(); + std::set& setKeyPool = set_pre_split_keypool.empty() ? (fInternal ? setInternalKeyPool : setExternalKeyPool) : set_pre_split_keypool; // Get the oldest key if (setKeyPool.empty()) return; CWalletDB walletdb(strWalletFile); - nIndex = *(setKeyPool.begin()); - setKeyPool.erase(setKeyPool.begin()); - if (!walletdb.ReadPool(nIndex, keypool)) - throw runtime_error("ReserveKeyFromKeyPool() : read failed"); - if (!HaveKey(keypool.vchPubKey.GetID())) - throw runtime_error("ReserveKeyFromKeyPool() : unknown key in key pool"); + nIndex = *setKeyPool.begin(); + setKeyPool.erase(nIndex); + if (!walletdb.ReadPool(nIndex, keypool)) { + throw std::runtime_error(std::string(__func__) + ": read failed"); + } + if (!HaveKey(keypool.vchPubKey.GetID())) { + throw std::runtime_error(std::string(__func__) + ": unknown key in key pool"); + } + // If the key was pre-split keypool, we don't care about what type it is + if (set_pre_split_keypool.size() == 0 && keypool.fInternal != fInternal) { + throw std::runtime_error(std::string(__func__) + ": keypool entry misclassified"); + } assert(keypool.vchPubKey.IsValid()); LogPrintf("keypool reserve %d\n", nIndex); } } + void CWallet::KeepKey(int64_t nIndex) { // Remove from key pool @@ -3609,26 +4048,34 @@ void CWallet::KeepKey(int64_t nIndex) LogPrintf("keypool keep %d\n", nIndex); } -void CWallet::ReturnKey(int64_t nIndex) +void CWallet::ReturnKey(int64_t nIndex, bool fInternal) { // Return to key pool { LOCK(cs_wallet); - setKeyPool.insert(nIndex); + if (fInternal) { + setInternalKeyPool.insert(nIndex); + } else if (!set_pre_split_keypool.empty()) { + set_pre_split_keypool.insert(nIndex); + } else { + setExternalKeyPool.insert(nIndex); + } } LogPrintf("keypool return %d\n", nIndex); } -bool CWallet::GetKeyFromPool(CPubKey& result) +bool CWallet::GetKeyFromPool(CPubKey& result, bool fInternal) { int64_t nIndex = 0; CKeyPool keypool; { LOCK(cs_wallet); - ReserveKeyFromKeyPool(nIndex, keypool); + ReserveKeyFromKeyPool(nIndex, keypool, fInternal); if (nIndex == -1) { if (IsLocked()) return false; - result = GenerateNewKey(); + // TODO: implement keypool for all accouts? + CWalletDB walletDB(strWalletFile); + result = GenerateNewKey(0, fInternal, &walletDB); return true; } KeepKey(nIndex); @@ -3636,16 +4083,33 @@ bool CWallet::GetKeyFromPool(CPubKey& result) } return true; } +static int64_t GetOldestKeyInPool(const std::set& setKeyPool, CWalletDB& walletdb) { + CKeyPool keypool; + int64_t nIndex = *(setKeyPool.begin()); + if (!walletdb.ReadPool(nIndex, keypool)) { + throw std::runtime_error(std::string(__func__) + ": read oldest key in keypool failed"); + } + assert(keypool.vchPubKey.IsValid()); + return keypool.nTime; +} int64_t CWallet::GetOldestKeyPoolTime() { - int64_t nIndex = 0; - CKeyPool keypool; - ReserveKeyFromKeyPool(nIndex, keypool); - if (nIndex == -1) - return GetTime(); - ReturnKey(nIndex); - return keypool.nTime; + LOCK(cs_wallet); + + CWalletDB walletdb(strWalletFile); + + // test this + // load oldest key from keypool, get time and return + int64_t oldestKey = GetOldestKeyInPool(setExternalKeyPool, walletdb); + if (!setInternalKeyPool.empty()) { + oldestKey = std::max(GetOldestKeyInPool(setInternalKeyPool, walletdb), oldestKey); + if (!set_pre_split_keypool.empty()) { + oldestKey = std::max(GetOldestKeyInPool(set_pre_split_keypool, walletdb), oldestKey); + } + } + + return oldestKey; } std::map CWallet::GetAddressBalances() @@ -3782,16 +4246,17 @@ set CWallet::GetAccountAddresses(string strAccount) const return result; } -bool CReserveKey::GetReservedKey(CPubKey& pubkey) +bool CReserveKey::GetReservedKey(CPubKey& pubkey, bool fInternalIn) { if (nIndex == -1) { CKeyPool keypool; - pwallet->ReserveKeyFromKeyPool(nIndex, keypool); - if (nIndex != -1) - vchPubKey = keypool.vchPubKey; + pwallet->ReserveKeyFromKeyPool(nIndex, keypool, fInternalIn); + if (nIndex != -1) { + vchPubKey = keypool.vchPubKey;} else { return false; } + fInternal = keypool.fInternal; } assert(vchPubKey.IsValid()); pubkey = vchPubKey; @@ -3809,29 +4274,38 @@ void CReserveKey::KeepKey() void CReserveKey::ReturnKey() { if (nIndex != -1) - pwallet->ReturnKey(nIndex); + pwallet->ReturnKey(nIndex, fInternal); nIndex = -1; vchPubKey = CPubKey(); } -void CWallet::GetAllReserveKeys(set& setAddress) const +static void LoadReserveKeysToSet(std::set& setAddress, const std::set& setKeyPool, CWalletDB& walletdb) { - setAddress.clear(); - CWalletDB walletdb(strWalletFile); - - LOCK2(cs_main, cs_wallet); for (const int64_t& id : setKeyPool) { CKeyPool keypool; if (!walletdb.ReadPool(id, keypool)) 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"); setAddress.insert(keyID); } } +void CWallet::GetAllReserveKeys(std::set& setAddress) const +{ + setAddress.clear(); + + CWalletDB walletdb(strWalletFile); + + LOCK2(cs_main, cs_wallet); + LoadReserveKeysToSet(setAddress, setInternalKeyPool, walletdb); + LoadReserveKeysToSet(setAddress, setExternalKeyPool, walletdb); + for (const CKeyID& keyID : setAddress) { + if (!HaveKey(keyID)) { + throw std::runtime_error(std::string(__func__) + ": unknown key in key pool"); + } + } +} bool CWallet::UpdatedTransaction(const uint256& hashTx) { @@ -4075,6 +4549,24 @@ bool CWallet::GetDestData(const CTxDestination& dest, const std::string& key, st return false; } +void CWallet::MarkPreSplitKeys() +{ + CWalletDB walletdb(strWalletFile); + for (auto it = setExternalKeyPool.begin(); it != setExternalKeyPool.end();) { + int64_t index = *it; + CKeyPool keypool; + if (!walletdb.ReadPool(index, keypool)) { + throw std::runtime_error(std::string(__func__) + ": read keypool entry failed"); + } + keypool.m_pre_split = true; + if (!walletdb.WritePool(index, keypool)) { + throw std::runtime_error(std::string(__func__) + ": writing modified keypool entry failed"); + } + set_pre_split_keypool.insert(index); + it = setExternalKeyPool.erase(it); + } +} + // CWallet::AutoZeromint() gets called with each new incoming block void CWallet::AutoZeromint() { @@ -4389,12 +4881,15 @@ bool CWallet::MultiSend() CKeyPool::CKeyPool() { nTime = GetTime(); + m_pre_split = false; } -CKeyPool::CKeyPool(const CPubKey& vchPubKeyIn) +CKeyPool::CKeyPool(const CPubKey& vchPubKeyIn, bool fInternalIn) { nTime = GetTime(); vchPubKey = vchPubKeyIn; + fInternal = fInternalIn; + m_pre_split = false; } CWalletKey::CWalletKey(int64_t nExpires) @@ -4944,7 +5439,7 @@ bool CWallet::CreateZerocoinSpendTransaction(CAmount nValue, int nSecurityLevel, vSelectedMints.emplace_back(mint); } } else { - for (const CZerocoinMint mint : vSelectedMints) + for (const CZerocoinMint& mint : vSelectedMints) nValueSelected += ZerocoinDenominationToAmount(mint.GetDenomination()); } @@ -5045,13 +5540,13 @@ bool CWallet::CreateZerocoinSpendTransaction(CAmount nValue, int nSecurityLevel, if (nChange) { // Reserve a new key pair from key pool CPubKey vchPubKey; - assert(reserveKey.GetReservedKey(vchPubKey)); // should never fail + assert(reserveKey.GetReservedKey(vchPubKey, false)); // should never fail scriptChange = GetScriptForDestination(vchPubKey.GetID()); } } else { // Reserve a new key pair from key pool CPubKey vchPubKey; - assert(reserveKey.GetReservedKey(vchPubKey)); // should never fail + assert(reserveKey.GetReservedKey(vchPubKey, false)); // should never fail scriptZerocoinSpend = GetScriptForDestination(vchPubKey.GetID()); } diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 936f79a..2e31a7d 100755 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -10,7 +10,7 @@ #include "amount.h" #include "base58.h" -#include "crypter.h" +#include "wallet/crypter.h" #include "kernel.h" #include "key.h" #include "keystore.h" @@ -25,6 +25,7 @@ #include "wallet/walletdb.h" #include "zohmctracker.h" #include "zohmcwallet.h" +#include "bip39.h" #include #include @@ -35,6 +36,7 @@ #include #include + /** * Settings */ @@ -56,8 +58,14 @@ static const CAmount DEFAULT_TRANSACTION_MAXFEE = 1 * COIN; static const CAmount nHighTransactionMaxFeeWarning = 100 * nHighTransactionFeeWarning; //! Largest (in bytes) free transaction we're willing to create static const unsigned int MAX_FREE_TRANSACTION_CREATE_SIZE = 1000; +static const bool DEFAULT_DISABLE_WALLET = false; + //! -custombackupthreshold default static const int DEFAULT_CUSTOMBACKUPTHRESHOLD = 1; +//! if set, all keys will be derived by using BIP32 +static const bool DEFAULT_USE_HD_WALLET = false; +//! if set,will show warning if the wallet is a hd wallet and is unencrypted +static const bool DEFAULT_ENABLE_WARN_ENCRYPTHD = false; // Zerocoin denomination which creates exactly one of each denominations: // 6666 = 1*5000 + 1*1000 + 1*500 + 1*100 + 1*50 + 1*10 + 1*5 + 1 @@ -77,8 +85,10 @@ enum WalletFeature { FEATURE_WALLETCRYPT = 40000, // wallet encryption FEATURE_COMPRPUBKEY = 60000, // compressed public keys - FEATURE_LATEST = 61000 -}; + FEATURE_HD = 130000, // Hierarchical key derivation after BIP32 (HD Wallet) + FEATURE_PRE_SPLIT_KEYPOOL = 169900, // Upgraded to HD SPLIT and can have a pre-split keypool + + FEATURE_LATEST = FEATURE_PRE_SPLIT_KEYPOOL}; enum AvailableCoinsType { ALL_COINS = 1, @@ -139,9 +149,11 @@ class CKeyPool public: int64_t nTime; CPubKey vchPubKey; + bool fInternal; // for change outputs + bool m_pre_split; // For keys generated before keypool split upgrade CKeyPool(); - CKeyPool(const CPubKey& vchPubKeyIn); + CKeyPool(const CPubKey& vchPubKeyIn, bool fInternalIn); ADD_SERIALIZE_METHODS; @@ -152,6 +164,28 @@ class CKeyPool READWRITE(nVersion); READWRITE(nTime); READWRITE(vchPubKey); + if (ser_action.ForRead()) { + try { + READWRITE(fInternal); + } + catch (std::ios_base::failure&) { + /* flag as external address if we can't read the internal boolean + (this will be the case for any wallet before the HD chain split version) */ + fInternal = false; + } + try { + READWRITE(m_pre_split); + } + catch (std::ios_base::failure&) { + /* flag as postsplit address if we can't read the m_pre_split boolean + (this will be the case for any wallet that upgrades to HD chain split)*/ + m_pre_split = false; + } + } + else { + READWRITE(fInternal); + READWRITE(m_pre_split); + } } }; @@ -177,10 +211,16 @@ class CAddressBookData */ class CWallet : public CCryptoKeyStore, public CValidationInterface { +public: + enum class CoinSelectStrategy + { + random, + descentByAmount, + }; + private: // ParamForCreateTransaction is introduced to control how CreateTransaction works. struct ParamForCreateTransaction; - enum class CoinSelectStrategy; bool CreateTransactionHelper(const std::vector >& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, @@ -218,8 +258,14 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface void AddToSpends(const uint256& wtxid); void SyncMetaData(std::pair); + /* HD derive new child key (on internal or external chain) */ + void DeriveNewChildKey(const CKeyMetadata& metadata, CKey& secretRet, uint32_t nAccountIndex, bool fInternal /*= false*/, CWalletDB * walletDB); public: + + //TODO move to private after createwalletfromfile has been backported + void MarkPreSplitKeys(); + bool MintableCoins(); bool SelectStakeCoins(std::set >& setCoins, CAmount nTargetAmount) const; bool SelectCoinsDark(CAmount nValueMin, CAmount nValueMax, std::vector& setCoinsRet, CAmount& nValueRet, int nObfuscationRoundsMin, int nObfuscationRoundsMax) const; @@ -272,7 +318,25 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface bool fBackupMints; std::unique_ptr zohmcTracker; - std::set setKeyPool; + void LoadKeyPool(int nIndex, const CKeyPool &keypool) + { + if (keypool.fInternal) { + setInternalKeyPool.insert(nIndex); + } else { + setExternalKeyPool.insert(nIndex); + } + + // If no metadata exists yet, create a default with the pool key's + // creation time. Note that this may be overwritten by actually + // stored metadata for that key later, which is fine. + CKeyID keyid = keypool.vchPubKey.GetID(); + if (mapKeyMetadata.count(keyid) == 0) + mapKeyMetadata[keyid] = CKeyMetadata(keypool.nTime); + } + + std::set setInternalKeyPool; + std::set setExternalKeyPool; + std::set set_pre_split_keypool; std::map mapKeyMetadata; typedef std::map MasterKeyMap; @@ -403,6 +467,8 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface int64_t nTimeFirstKey; + std::map mapHdPubKeys; // getWalletTxs(); @@ -433,12 +499,26 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface void ListLockedCoins(std::vector& vOutpts); CAmount GetTotalValue(std::vector vCoins); - // keystore implementation - // Generate a new key - CPubKey GenerateNewKey(); + /** + * keystore implementation + * Generate a new key + */ + CPubKey GenerateNewKey(uint32_t nAccountIndex, bool fInternal /*= false*/, CWalletDB * walletDB); + //! HaveKey implementation that also checks the mapHdPubKeys + bool HaveKey(const CKeyID &address) const; + //! GetPubKey implementation that also checks the mapHdPubKeys + bool GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const; + //! GetKey implementation that can derive a HD private key on the fly + bool GetKey(const CKeyID &address, CKey& keyOut) const; + //! Adds a HDPubKey into the wallet(database) + bool AddHDPubKey(const CExtPubKey &extPubKey, bool fInternal); + //! loads a HDPubKey into the wallets memory + bool LoadHDPubKey(const CHDPubKey &hdPubKey); + //! Adds a key to the store, and saves it to disk. bool AddKeyPubKey(const CKey& key, const CPubKey& pubkey); + bool AddKeyPubKeyWithDB(const CKey& key, const CPubKey &pubkey, CWalletDB * walletDB); //! Adds a key to the store, without saving it to disk (used by LoadWallet) bool LoadKey(const CKey& key, const CPubKey& pubkey) { return CCryptoKeyStore::AddKeyPubKey(key, pubkey); } //! Load metadata (used by LoadWallet) @@ -483,7 +563,8 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface bool Unlock(const SecureString& strWalletPassphrase, bool anonimizeOnly = false); bool ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, const SecureString& strNewWalletPassphrase); bool EncryptWallet(const SecureString& strWalletPassphrase); - + void FinishEncryptWallet(); + std::tuple GetHDChains(); void GetKeyBirthTimes(std::map& mapKeyBirth) const; unsigned int ComputeTimeSmart(const CWalletTx& wtx) const; @@ -564,12 +645,13 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface static CFeeRate minTxFee; static CAmount GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarget, const CTxMemPool& pool); - bool NewKeyPool(); + size_t KeypoolCountExternalKeys(); + size_t KeypoolCountInternalKeys(); bool TopUpKeyPool(unsigned int kpSize = 0); - void ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& keypool); + void ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& keypool, bool fInternal); void KeepKey(int64_t nIndex); - void ReturnKey(int64_t nIndex); - bool GetKeyFromPool(CPubKey& key); + void ReturnKey(int64_t nIndex, bool fInternal); + bool GetKeyFromPool(CPubKey &key, bool fInternal /*= false*/); int64_t GetOldestKeyPoolTime(); void GetAllReserveKeys(std::set& setAddress) const; @@ -661,7 +743,7 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface bool SetAddressBook(const CTxDestination& address, const std::string& strName, const std::string& purpose); bool DelAddressBook(const CTxDestination& address); - + bool NewKeyPool(); bool UpdatedTransaction(const uint256& hashTx); void Inventory(const uint256& hash) @@ -674,10 +756,9 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface } } - unsigned int GetKeyPoolSize() - { - AssertLockHeld(cs_wallet); // setKeyPool - return setKeyPool.size(); + unsigned int GetKeyPoolSize() { + AssertLockHeld(cs_wallet); // set{Ex,In}ternalKeyPool + return setInternalKeyPool.size() + setExternalKeyPool.size(); } bool SetDefaultKey(const CPubKey& vchPubKey); @@ -695,6 +776,21 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface return nWalletVersion; } + /** + * HD Wallet Functions + */ + + /* Returns true if HD is enabled */ + bool IsHDEnabled(); + /* Generates a new HD chain */ + void GenerateNewHDChain(const std::string& words, const SecureString& strWalletPassphrase = std::string().c_str()); + void GenerateNewHDChain(const std::vector& words, const SecureString& strWalletPassphrase = std::string().c_str()); + /* Set the HD chain model (chain child index counters) */ + bool SetHDChain(const CHDChain& chain, bool memonly, CWalletDB * walletDB = nullptr); + bool UpgradeHdChainEncrypted(const SecureString& strWalletPassphrase, const CHDChain& chain); + bool SetCryptedHDChain(const CHDChain& chain, bool memonly); + bool GetDecryptedHDChain(CHDChain& hdChainRet); + //! Get wallet transactions that conflict with given transaction (spend same outputs) std::set GetConflicts(const uint256& txid) const; @@ -731,12 +827,14 @@ class CReserveKey CWallet* pwallet; int64_t nIndex; CPubKey vchPubKey; + bool fInternal; public: CReserveKey(CWallet* pwalletIn) { nIndex = -1; pwallet = pwalletIn; + fInternal = false; } ~CReserveKey() @@ -745,7 +843,7 @@ class CReserveKey } void ReturnKey(); - bool GetReservedKey(CPubKey& pubkey); + bool GetReservedKey(CPubKey &pubkey, bool fInternalIn = false); void KeepKey(); }; diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index 414b420..70ea549 100755 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -16,7 +16,7 @@ #include "txdb.h" #include "util.h" #include "utiltime.h" -#include "wallet.h" +#include "wallet/wallet.h" #include "primitives/deterministicmint.h" #include @@ -599,14 +599,7 @@ bool ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, CW ssKey >> nIndex; CKeyPool keypool; ssValue >> keypool; - pwallet->setKeyPool.insert(nIndex); - - // If no metadata exists yet, create a default with the pool key's - // creation time. Note that this may be overwritten by actually - // stored metadata for that key later, which is fine. - CKeyID keyid = keypool.vchPubKey.GetID(); - if (pwallet->mapKeyMetadata.count(keyid) == 0) - pwallet->mapKeyMetadata[keyid] = CKeyMetadata(keypool.nTime); + pwallet->LoadKeyPool(nIndex, keypool); } else if (strType == "version") { ssValue >> wss.nFileVersion; if (wss.nFileVersion == 10300) @@ -661,6 +654,45 @@ bool ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, CW return false; } } + else if (strType == "hdchain") + { + CHDChain chain; + ssValue >> chain; + if (!pwallet->SetHDChain(chain, true)) + { + strErr = "Error reading wallet database: SetHDChain failed"; + return false; + } + } + else if (strType == "chdchain") + { + CHDChain chain; + ssValue >> chain; + if (!pwallet->SetCryptedHDChain(chain, true)) + { + strErr = "Error reading wallet database: SetHDCryptedChain failed"; + return false; + } + } + else if (strType == "hdpubkey") + { + CPubKey vchPubKey; + ssKey >> vchPubKey; + + CHDPubKey hdPubKey; + ssValue >> hdPubKey; + + if(vchPubKey != hdPubKey.extPubKey.pubkey) + { + strErr = "Error reading wallet database: CHDPubKey corrupt"; + return false; + } + if (!pwallet->LoadHDPubKey(hdPubKey)) + { + strErr = "Error reading wallet database: LoadHDPubKey failed"; + return false; + } + } } catch (...) { return false; } @@ -669,8 +701,8 @@ bool ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, CW static bool IsKeyType(string strType) { - return (strType == "key" || strType == "wkey" || - strType == "mkey" || strType == "ckey"); + return (strType == "mkey" || strType == "ckey" || + strType == "hdchain" || strType == "chdchain"); } DBErrors CWalletDB::LoadWallet(CWallet* pwallet) @@ -1097,7 +1129,7 @@ bool CWalletDB::Recover(CDBEnv& dbenv, std::string filename, bool fOnlyKeys) string strType, strErr; bool fReadOK = ReadKeyValue(&dummyWallet, ssKey, ssValue, wss, strType, strErr); - if (!IsKeyType(strType)) + if (!IsKeyType(strType) && strType != "hdpubkey") continue; if (!fReadOK) { LogPrintf("WARNING: CWalletDB::Recover skipping %s: %s\n", strType, strErr); @@ -1133,6 +1165,35 @@ bool CWalletDB::EraseDestData(const std::string& address, const std::string& key return Erase(std::make_pair(std::string("destdata"), std::make_pair(address, key))); } + +bool CWalletDB::WriteHDChain(const CHDChain& chain) +{ + nWalletDBUpdated++; + return Write(std::string("hdchain"), chain); +} + +bool CWalletDB::WriteCryptedHDChain(const CHDChain& chain) +{ + nWalletDBUpdated++; + + if (!Write(std::string("chdchain"), chain)) + return false; + + Erase(std::string("hdchain")); + + return true; +} + +bool CWalletDB::WriteHDPubKey(const CHDPubKey& hdPubKey, const CKeyMetadata& keyMeta) +{ + nWalletDBUpdated++; + + if (!Write(std::make_pair(std::string("keymeta"), hdPubKey.extPubKey.pubkey), keyMeta, false)) + return false; + + return Write(std::make_pair(std::string("hdpubkey"), hdPubKey.extPubKey.pubkey), hdPubKey, false); +} + bool CWalletDB::WriteZerocoinSpendSerialEntry(const CZerocoinSpend& zerocoinSpend) { return Write(make_pair(string("zcserial"), zerocoinSpend.GetSerial()), zerocoinSpend, true); diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h index 5dd0907..42adcca 100755 --- a/src/wallet/walletdb.h +++ b/src/wallet/walletdb.h @@ -11,6 +11,7 @@ #include "amount.h" #include "primitives/transaction.h" #include "wallet/db.h" +#include "wallet/hdchain.h" #include "key.h" #include "keystore.h" #include "primitives/zerocoin.h" @@ -155,6 +156,12 @@ class CWalletDB : public CDB static bool Recover(CDBEnv& dbenv, std::string filename, bool fOnlyKeys); static bool Recover(CDBEnv& dbenv, std::string filename); + //! write the hdchain model (external chain child index counter) + bool WriteHDChain(const CHDChain& chain); + bool WriteCryptedHDChain(const CHDChain& chain); + bool WriteHDPubKey(const CHDPubKey& hdPubKey, const CKeyMetadata& keyMeta); + + bool WriteDeterministicMint(const CDeterministicMint& dMint); bool ReadDeterministicMint(const uint256& hashPubcoin, CDeterministicMint& dMint); bool EraseDeterministicMint(const uint256& hashPubcoin); diff --git a/test/config.ini.in b/test/config.ini.in new file mode 100644 index 0000000..a1119dc --- /dev/null +++ b/test/config.ini.in @@ -0,0 +1,19 @@ +# Copyright (c) 2013-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +# These environment variables are set by the build process and read by +# test/functional/test_runner.py and test/util/bitcoin-util-test.py + +[environment] +SRCDIR=@abs_top_srcdir@ +BUILDDIR=@abs_top_builddir@ +EXEEXT=@EXEEXT@ +RPCAUTH=@abs_top_srcdir@/share/rpcauth/rpcauth.py + +[components] +# Which components are enabled. These are commented out by `configure` if they were disabled when running config. +@ENABLE_WALLET_TRUE@ENABLE_WALLET=true +@BUILD_BITCOIN_UTILS_TRUE@ENABLE_UTILS=true +@BUILD_BITCOIND_TRUE@ENABLE_BITCOIND=true +@ENABLE_ZMQ_TRUE@ENABLE_ZMQ=true diff --git a/test/test_framework/__init__.py b/test/functional/__init__.py similarity index 100% rename from test/test_framework/__init__.py rename to test/functional/__init__.py diff --git a/test/decodetx.py b/test/functional/decodetx.py similarity index 99% rename from test/decodetx.py rename to test/functional/decodetx.py index 31e829e..a2f390f 100644 --- a/test/decodetx.py +++ b/test/functional/decodetx.py @@ -3,7 +3,6 @@ WITNESS = 1 -from test_framework.script import * class RawTransaction: def __init__(self, tx_data): diff --git a/test/listtransactions.py b/test/functional/listtransactions.py similarity index 96% rename from test/listtransactions.py rename to test/functional/listtransactions.py index bc1a365..7dcd859 100644 --- a/test/listtransactions.py +++ b/test/functional/listtransactions.py @@ -5,9 +5,6 @@ # Exercise the listtransactions API -from test_framework.test_framework import BitcoinTestFramework -from test_framework.authproxy import AuthServiceProxy, JSONRPCException -from test_framework.util import * from test_case_base import TestCaseBase diff --git a/test/segwit.py b/test/functional/segwit.py similarity index 98% rename from test/segwit.py rename to test/functional/segwit.py index fad6956..77aad1c 100644 --- a/test/segwit.py +++ b/test/functional/segwit.py @@ -7,13 +7,12 @@ # Test the SegWit changeover logic # -from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import * -from test_framework.mininode import sha256, ripemd160, CTransaction, CTxIn, COutPoint, CTxOut -from test_framework.address import script_to_p2sh, key_to_p2pkh -from test_framework.script import CScript, OP_HASH160, OP_CHECKSIG, OP_0, hash160, OP_EQUAL, OP_DUP, OP_EQUALVERIFY, OP_1, OP_2, OP_CHECKMULTISIG +from test.functional.test_framework import BitcoinTestFramework +from test.functional.test_framework.mininode import sha256, ripemd160, CTransaction, CTxIn, COutPoint, CTxOut +from test.functional.test_framework.address import key_to_p2pkh +from test.functional.test_framework import CScript, OP_HASH160, OP_CHECKSIG, OP_0, hash160, OP_EQUAL from io import BytesIO -from test_framework.mininode import FromHex +from test.functional.test_framework.mininode import FromHex import time NODE_0 = 0 diff --git a/test/test_case_base.py b/test/functional/test_case_base.py similarity index 92% rename from test/test_case_base.py rename to test/functional/test_case_base.py index c20d891..31894bf 100644 --- a/test/test_case_base.py +++ b/test/functional/test_case_base.py @@ -1,4 +1,4 @@ -from test_framework.test_framework import BitcoinTestFramework +from test.functional.test_framework import BitcoinTestFramework class TestCaseBase(BitcoinTestFramework) : def set_test_params(self) : diff --git a/test/functional/test_framework/__init__.py b/test/functional/test_framework/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/test/test_framework/address.py b/test/functional/test_framework/address.py similarity index 100% rename from test/test_framework/address.py rename to test/functional/test_framework/address.py diff --git a/test/test_framework/authproxy.py b/test/functional/test_framework/authproxy.py similarity index 100% rename from test/test_framework/authproxy.py rename to test/functional/test_framework/authproxy.py diff --git a/test/test_framework/bignum.py b/test/functional/test_framework/bignum.py similarity index 100% rename from test/test_framework/bignum.py rename to test/functional/test_framework/bignum.py diff --git a/test/test_framework/blockstore.py b/test/functional/test_framework/blockstore.py similarity index 100% rename from test/test_framework/blockstore.py rename to test/functional/test_framework/blockstore.py diff --git a/test/test_framework/blocktools.py b/test/functional/test_framework/blocktools.py similarity index 100% rename from test/test_framework/blocktools.py rename to test/functional/test_framework/blocktools.py diff --git a/test/test_framework/comptool.py b/test/functional/test_framework/comptool.py similarity index 100% rename from test/test_framework/comptool.py rename to test/functional/test_framework/comptool.py diff --git a/test/test_framework/coverage.py b/test/functional/test_framework/coverage.py similarity index 100% rename from test/test_framework/coverage.py rename to test/functional/test_framework/coverage.py diff --git a/test/test_framework/key.py b/test/functional/test_framework/key.py similarity index 100% rename from test/test_framework/key.py rename to test/functional/test_framework/key.py diff --git a/test/test_framework/messages.py b/test/functional/test_framework/messages.py similarity index 100% rename from test/test_framework/messages.py rename to test/functional/test_framework/messages.py diff --git a/test/test_framework/mininode.py b/test/functional/test_framework/mininode.py similarity index 100% rename from test/test_framework/mininode.py rename to test/functional/test_framework/mininode.py diff --git a/test/test_framework/netutil.py b/test/functional/test_framework/netutil.py similarity index 100% rename from test/test_framework/netutil.py rename to test/functional/test_framework/netutil.py diff --git a/test/test_framework/script.py b/test/functional/test_framework/script.py similarity index 100% rename from test/test_framework/script.py rename to test/functional/test_framework/script.py diff --git a/test/test_framework/segwit_addr.py b/test/functional/test_framework/segwit_addr.py similarity index 100% rename from test/test_framework/segwit_addr.py rename to test/functional/test_framework/segwit_addr.py diff --git a/test/test_framework/siphash.py b/test/functional/test_framework/siphash.py similarity index 100% rename from test/test_framework/siphash.py rename to test/functional/test_framework/siphash.py diff --git a/test/test_framework/socks5.py b/test/functional/test_framework/socks5.py similarity index 100% rename from test/test_framework/socks5.py rename to test/functional/test_framework/socks5.py diff --git a/test/test_framework/test_framework.py b/test/functional/test_framework/test_framework.py similarity index 100% rename from test/test_framework/test_framework.py rename to test/functional/test_framework/test_framework.py diff --git a/test/test_framework/test_node.py b/test/functional/test_framework/test_node.py similarity index 100% rename from test/test_framework/test_node.py rename to test/functional/test_framework/test_node.py diff --git a/test/test_framework/util.py b/test/functional/test_framework/util.py similarity index 100% rename from test/test_framework/util.py rename to test/functional/test_framework/util.py diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py new file mode 100644 index 0000000..876f00e --- /dev/null +++ b/test/functional/test_runner.py @@ -0,0 +1,482 @@ +#!/usr/bin/env python3 +# Copyright (c) 2014-2017 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. +"""Run regression test suite. +This module calls down into individual test cases via subprocess. It will +forward all unrecognized arguments onto the individual test scripts. +Functional tests are disabled on Windows by default. Use --force to run them anyway. +For a description of arguments recognized by test scripts, see +`test/functional/test_framework/test_framework.py:BitcoinTestFramework.main`. +""" + +import argparse +from collections import deque +import configparser +import datetime +import os +import time +import shutil +import signal +import sys +import subprocess +import tempfile +import re +import logging + +# Formatting. Default colors to empty strings. +BOLD, BLUE, RED, GREY = ("", ""), ("", ""), ("", ""), ("", "") +try: + # Make sure python thinks it can write unicode to its stdout + "\u2713".encode("utf_8").decode(sys.stdout.encoding) + TICK = "✓ " + CROSS = "✖ " + CIRCLE = "○ " +except UnicodeDecodeError: + TICK = "P " + CROSS = "x " + CIRCLE = "o " + +if os.name == 'posix': + # primitive formatting on supported + # terminal via ANSI escape sequences: + BOLD = ('\033[0m', '\033[1m') + BLUE = ('\033[0m', '\033[0;34m') + RED = ('\033[0m', '\033[0;31m') + GREY = ('\033[0m', '\033[1;30m') + +TEST_EXIT_PASSED = 0 +TEST_EXIT_SKIPPED = 77 + +BASE_SCRIPTS= [ + # Scripts that are run by the travis build process. + # Longest test should go first, to favor running tests in parallel + 'wallet.py', + 'wallet_hd.py', + 'decodetx.py', + 'listtransaction.py', + 'segwit.py', + 'test_case_base.py', + 'zerocoin.py', + + # Don't append tests at the end to avoid merge conflicts + # Put them in a random line within the section that fits their approximate run-time +] + +EXTENDED_SCRIPTS = [ + # These tests are not run by the travis build process. + # Longest test should go first, to favor running tests in parallel + # vv Tests less than 20m vv + #'feature_fee_estimation.py', + # vv Tests less than 5m vv + # vv Tests less than 2m vv + #'p2p_timeouts.py', +] + +# Place EXTENDED_SCRIPTS first since it has the 3 longest running tests +ALL_SCRIPTS = EXTENDED_SCRIPTS + BASE_SCRIPTS + +NON_SCRIPTS = [ + # These are python files that live in the functional tests directory, but are not test scripts. + "test_runner.py", +] + +def main(): + # Parse arguments and pass through unrecognised args + parser = argparse.ArgumentParser(add_help=False, + usage='%(prog)s [test_runner.py options] [script options] [scripts]', + description=__doc__, + epilog=''' + Help text and arguments for individual test script:''', + formatter_class=argparse.RawTextHelpFormatter) + parser.add_argument('--combinedlogslen', '-c', type=int, default=0, help='print a combined log (of length n lines) from all test nodes and test framework to the console on failure.') + parser.add_argument('--coverage', action='store_true', help='generate a basic coverage report for the RPC interface') + parser.add_argument('--exclude', '-x', help='specify a comma-separated-list of scripts to exclude.') + parser.add_argument('--extended', action='store_true', help='run the extended test suite in addition to the basic tests') + parser.add_argument('--force', '-f', action='store_true', help='run tests even on platforms where they are disabled by default (e.g. windows).') + parser.add_argument('--help', '-h', '-?', action='store_true', help='print help text and exit') + parser.add_argument('--jobs', '-j', type=int, default=4, help='how many test scripts to run in parallel. Default=4.') + parser.add_argument('--keepcache', '-k', action='store_true', help='the default behavior is to flush the cache directory on startup. --keepcache retains the cache from the previous testrun.') + parser.add_argument('--quiet', '-q', action='store_true', help='only print dots, results summary and failure logs') + parser.add_argument('--tmpdirprefix', '-t', default=tempfile.gettempdir(), help="Root directory for datadirs") + args, unknown_args = parser.parse_known_args() + + # args to be passed on always start with two dashes; tests are the remaining unknown args + tests = [arg for arg in unknown_args if arg[:2] != "--"] + passon_args = [arg for arg in unknown_args if arg[:2] == "--"] + + # Read config generated by configure. + config = configparser.ConfigParser() + configfile = os.path.abspath(os.path.dirname(__file__)) + "/../config.ini" + config.read_file(open(configfile)) + + passon_args.append("--configfile=%s" % configfile) + + # Set up logging + logging_level = logging.INFO if args.quiet else logging.DEBUG + logging.basicConfig(format='%(message)s', level=logging_level) + + # Create base test directory + tmpdir = "%s/pivx_test_runner_%s" % (args.tmpdirprefix, datetime.datetime.now().strftime("%Y%m%d_%H%M%S")) + os.makedirs(tmpdir) + + logging.debug("Temporary test directory at %s" % tmpdir) + + enable_wallet = config["components"].getboolean("ENABLE_WALLET") + enable_utils = config["components"].getboolean("ENABLE_UTILS") + enable_bitcoind = config["components"].getboolean("ENABLE_BITCOIND") + + if config["environment"]["EXEEXT"] == ".exe" and not args.force: + # https://github.com/bitcoin/bitcoin/commit/d52802551752140cf41f0d9a225a43e84404d3e9 + # https://github.com/bitcoin/bitcoin/pull/5677#issuecomment-136646964 + print("Tests currently disabled on Windows by default. Use --force option to enable") + sys.exit(0) + + if not (enable_wallet and enable_utils and enable_bitcoind): + print("No functional tests to run. Wallet, utils, and pivxd must all be enabled") + print("Rerun `configure` with -enable-wallet, -with-utils and -with-daemon and rerun make") + sys.exit(0) + + # Build list of tests + if tests: + # Individual tests have been specified. Run specified tests that exist + # in the ALL_SCRIPTS list. Accept the name with or without .py extension. + tests = [re.sub("\.py$", "", t) + ".py" for t in tests] + test_list = [] + for t in tests: + if t in ALL_SCRIPTS: + test_list.append(t) + else: + print("{}WARNING!{} Test '{}' not found in full test list.".format(BOLD[1], BOLD[0], t)) + else: + # No individual tests have been specified. + # Run all base tests, and optionally run extended tests. + test_list = BASE_SCRIPTS + if args.extended: + # place the EXTENDED_SCRIPTS first since the three longest ones + # are there and the list is shorter + test_list = EXTENDED_SCRIPTS + test_list + + # Remove the test cases that the user has explicitly asked to exclude. + if args.exclude: + tests_excl = [re.sub("\.py$", "", t) + ".py" for t in args.exclude.split(',')] + for exclude_test in tests_excl: + if exclude_test in test_list: + test_list.remove(exclude_test) + else: + print("{}WARNING!{} Test '{}' not found in current test list.".format(BOLD[1], BOLD[0], exclude_test)) + + if not test_list: + print("No valid test scripts specified. Check that your test is in one " + "of the test lists in test_runner.py, or run test_runner.py with no arguments to run all tests") + sys.exit(0) + + if args.help: + # Print help for test_runner.py, then print help of the first script (with args removed) and exit. + parser.print_help() + subprocess.check_call([(config["environment"]["SRCDIR"] + '/test/functional/' + test_list[0].split()[0])] + ['-h']) + sys.exit(0) + + check_script_list(config["environment"]["SRCDIR"]) + check_script_prefixes() + + if not args.keepcache: + shutil.rmtree("%s/test/cache" % config["environment"]["BUILDDIR"], ignore_errors=True) + + run_tests(test_list, config["environment"]["SRCDIR"], config["environment"]["BUILDDIR"], config["environment"]["EXEEXT"], tmpdir, args.jobs, args.coverage, passon_args, args.combinedlogslen) + +def run_tests(test_list, src_dir, build_dir, exeext, tmpdir, jobs=1, enable_coverage=False, args=[], combined_logs_len=0): + # Warn if bitcoind is already running (unix only) + try: + if subprocess.check_output(["pidof", "pivxd"]) is not None: + print("%sWARNING!%s There is already a pivxd process running on this system. Tests may fail unexpectedly due to resource contention!" % (BOLD[1], BOLD[0])) + except (OSError, subprocess.SubprocessError): + pass + + # Warn if there is a cache directory + cache_dir = "%s/test/cache" % build_dir + if os.path.isdir(cache_dir): + print("%sWARNING!%s There is a cache directory here: %s. If tests fail unexpectedly, try deleting the cache directory." % (BOLD[1], BOLD[0], cache_dir)) + + #Set env vars + if "BITCOIND" not in os.environ: + os.environ["BITCOIND"] = build_dir + '/src/pivxd' + exeext + os.environ["BITCOINCLI"] = build_dir + '/src/pivx-cli' + exeext + + tests_dir = src_dir + '/test/functional/' + + flags = ["--srcdir={}/src".format(build_dir)] + args + flags.append("--cachedir=%s" % cache_dir) + + if enable_coverage: + coverage = RPCCoverage() + flags.append(coverage.flag) + logging.debug("Initializing coverage directory at %s" % coverage.dir) + else: + coverage = None + + if len(test_list) > 1 and jobs > 1: + # Populate cache + try: + subprocess.check_output([tests_dir + 'create_cache.py'] + flags + ["--tmpdir=%s/cache" % tmpdir]) + except subprocess.CalledProcessError as e: + sys.stdout.buffer.write(e.output) + raise + + #Run Tests + job_queue = TestHandler(jobs, tests_dir, tmpdir, test_list, flags) + time0 = time.time() + test_results = [] + + max_len_name = len(max(test_list, key=len)) + test_count = len(test_list) + for i in range(test_count): + test_result, testdir, stdout, stderr = job_queue.get_next() + test_results.append(test_result) + done_str = "{}/{} - {}{}{}".format(i + 1, test_count, BOLD[1], test_result.name, BOLD[0]) + if test_result.status == "Passed": + logging.debug("%s passed, Duration: %s s" % (done_str, test_result.time)) + elif test_result.status == "Skipped": + logging.debug("%s skipped" % (done_str)) + else: + print("%s failed, Duration: %s s\n" % (done_str, test_result.time)) + print(BOLD[1] + 'stdout:\n' + BOLD[0] + stdout + '\n') + print(BOLD[1] + 'stderr:\n' + BOLD[0] + stderr + '\n') + if combined_logs_len and os.path.isdir(testdir): + # Print the final `combinedlogslen` lines of the combined logs + print('{}Combine the logs and print the last {} lines ...{}'.format(BOLD[1], combined_logs_len, BOLD[0])) + print('\n============') + print('{}Combined log for {}:{}'.format(BOLD[1], testdir, BOLD[0])) + print('============\n') + combined_logs, _ = subprocess.Popen([os.path.join(tests_dir, 'combine_logs.py'), '-c', testdir], universal_newlines=True, stdout=subprocess.PIPE).communicate() + print("\n".join(deque(combined_logs.splitlines(), combined_logs_len))) + + print_results(test_results, max_len_name, (int(time.time() - time0))) + + if coverage: + coverage.report_rpc_coverage() + + logging.debug("Cleaning up coverage data") + coverage.cleanup() + + # Clear up the temp directory if all subdirectories are gone + if not os.listdir(tmpdir): + os.rmdir(tmpdir) + + all_passed = all(map(lambda test_result: test_result.was_successful, test_results)) + + sys.exit(not all_passed) + +def print_results(test_results, max_len_name, runtime): + results = "\n" + BOLD[1] + "%s | %s | %s\n\n" % ("TEST".ljust(max_len_name), "STATUS ", "DURATION") + BOLD[0] + + test_results.sort(key=lambda result: result.name.lower()) + all_passed = True + time_sum = 0 + + for test_result in test_results: + all_passed = all_passed and test_result.was_successful + time_sum += test_result.time + test_result.padding = max_len_name + results += str(test_result) + + status = TICK + "Passed" if all_passed else CROSS + "Failed" + results += BOLD[1] + "\n%s | %s | %s s (accumulated) \n" % ("ALL".ljust(max_len_name), status.ljust(9), time_sum) + BOLD[0] + results += "Runtime: %s s\n" % (runtime) + print(results) + +class TestHandler: + """ + Trigger the test scripts passed in via the list. + """ + + def __init__(self, num_tests_parallel, tests_dir, tmpdir, test_list=None, flags=None): + assert(num_tests_parallel >= 1) + self.num_jobs = num_tests_parallel + self.tests_dir = tests_dir + self.tmpdir = tmpdir + self.test_list = test_list + self.flags = flags + self.num_running = 0 + # In case there is a graveyard of zombie pivxds, we can apply a + # pseudorandom offset to hopefully jump over them. + # (625 is PORT_RANGE/MAX_NODES) + self.portseed_offset = int(time.time() * 1000) % 625 + self.jobs = [] + + def get_next(self): + while self.num_running < self.num_jobs and self.test_list: + # Add tests + self.num_running += 1 + t = self.test_list.pop(0) + portseed = len(self.test_list) + self.portseed_offset + portseed_arg = ["--portseed={}".format(portseed)] + log_stdout = tempfile.SpooledTemporaryFile(max_size=2**16) + log_stderr = tempfile.SpooledTemporaryFile(max_size=2**16) + test_argv = t.split() + testdir = "{}/{}_{}".format(self.tmpdir, re.sub(".py$", "", test_argv[0]), portseed) + tmpdir_arg = ["--tmpdir={}".format(testdir)] + self.jobs.append((t, + time.time(), + subprocess.Popen([self.tests_dir + test_argv[0]] + test_argv[1:] + self.flags + portseed_arg + tmpdir_arg, + universal_newlines=True, + stdout=log_stdout, + stderr=log_stderr), + testdir, + log_stdout, + log_stderr)) + if not self.jobs: + raise IndexError('pop from empty list') + + # Print remaining running jobs when all jobs have been started. + if not self.test_list: + print("Remaining jobs: [{}]".format(", ".join(j[0] for j in self.jobs))) + + dot_count = 0 + while True: + # Return first proc that finishes + time.sleep(.5) + for j in self.jobs: + (name, time0, proc, testdir, log_out, log_err) = j + if os.getenv('TRAVIS') == 'true' and int(time.time() - time0) > 20 * 60: + # In travis, timeout individual tests after 20 minutes (to stop tests hanging and not + # providing useful output. + proc.send_signal(signal.SIGINT) + if proc.poll() is not None: + log_out.seek(0), log_err.seek(0) + [stdout, stderr] = [l.read().decode('utf-8') for l in (log_out, log_err)] + log_out.close(), log_err.close() + if proc.returncode == TEST_EXIT_PASSED and stderr == "": + status = "Passed" + elif proc.returncode == TEST_EXIT_SKIPPED: + status = "Skipped" + else: + status = "Failed" + self.num_running -= 1 + self.jobs.remove(j) + clearline = '\r' + (' ' * dot_count) + '\r' + print(clearline, end='', flush=True) + dot_count = 0 + return TestResult(name, status, int(time.time() - time0)), testdir, stdout, stderr + print('.', end='', flush=True) + dot_count += 1 + +class TestResult(): + def __init__(self, name, status, time): + self.name = name + self.status = status + self.time = time + self.padding = 0 + + def __repr__(self): + if self.status == "Passed": + color = BLUE + glyph = TICK + elif self.status == "Failed": + color = RED + glyph = CROSS + elif self.status == "Skipped": + color = GREY + glyph = CIRCLE + + return color[1] + "%s | %s%s | %s s\n" % (self.name.ljust(self.padding), glyph, self.status.ljust(7), self.time) + color[0] + + @property + def was_successful(self): + return self.status != "Failed" + + +def check_script_prefixes(): + """Check that at most a handful of the + test scripts don't start with one of the allowed name prefixes.""" + + # LEEWAY is provided as a transition measure, so that pull-requests + # that introduce new tests that don't conform with the naming + # convention don't immediately cause the tests to fail. + LEEWAY = 10 + + good_prefixes_re = re.compile("(example|feature|interface|mempool|mining|p2p|rpc|wallet|zerocoin)_") + bad_script_names = [script for script in ALL_SCRIPTS if good_prefixes_re.match(script) is None] + + if len(bad_script_names) > 0: + print("INFO: %d tests not meeting naming conventions:" % (len(bad_script_names))) + print(" %s" % ("\n ".join(sorted(bad_script_names)))) + assert len(bad_script_names) <= LEEWAY, "Too many tests not following naming convention! (%d found, maximum: %d)" % (len(bad_script_names), LEEWAY) + + +def check_script_list(src_dir): + """Check scripts directory. + Check that there are no scripts in the functional tests directory which are + not being run by pull-tester.py.""" + script_dir = src_dir + '/test/functional/' + python_files = set([t for t in os.listdir(script_dir) if t[-3:] == ".py"]) + missed_tests = list(python_files - set(map(lambda x: x.split()[0], ALL_SCRIPTS + NON_SCRIPTS))) + if len(missed_tests) != 0: + print("%sWARNING!%s The following scripts are not being run: %s. Check the test lists in test_runner.py." % (BOLD[1], BOLD[0], str(missed_tests))) + if os.getenv('TRAVIS') == 'true': + # On travis this warning is an error to prevent merging incomplete commits into master + sys.exit(1) + +class RPCCoverage(): + """ + Coverage reporting utilities for test_runner. + Coverage calculation works by having each test script subprocess write + coverage files into a particular directory. These files contain the RPC + commands invoked during testing, as well as a complete listing of RPC + commands per `pivx-cli help` (`rpc_interface.txt`). + After all tests complete, the commands run are combined and diff'd against + the complete list to calculate uncovered RPC commands. + See also: test/functional/test_framework/coverage.py + """ + def __init__(self): + self.dir = tempfile.mkdtemp(prefix="coverage") + self.flag = '--coveragedir=%s' % self.dir + + def report_rpc_coverage(self): + """ + Print out RPC commands that were unexercised by tests. + """ + uncovered = self._get_uncovered_rpc_commands() + + if uncovered: + print("Uncovered RPC commands:") + print("".join((" - %s\n" % i) for i in sorted(uncovered))) + else: + print("All RPC commands covered.") + + def cleanup(self): + return shutil.rmtree(self.dir) + + def _get_uncovered_rpc_commands(self): + """ + Return a set of currently untested RPC commands. + """ + # This is shared from `test/functional/test-framework/coverage.py` + reference_filename = 'rpc_interface.txt' + coverage_file_prefix = 'coverage.' + + coverage_ref_filename = os.path.join(self.dir, reference_filename) + coverage_filenames = set() + all_cmds = set() + covered_cmds = set() + + if not os.path.isfile(coverage_ref_filename): + raise RuntimeError("No coverage reference found") + + with open(coverage_ref_filename, 'r') as f: + all_cmds.update([i.strip() for i in f.readlines()]) + + for root, dirs, files in os.walk(self.dir): + for filename in files: + if filename.startswith(coverage_file_prefix): + coverage_filenames.add(os.path.join(root, filename)) + + for filename in coverage_filenames: + with open(filename, 'r') as f: + covered_cmds.update([i.strip() for i in f.readlines()]) + + return all_cmds - covered_cmds + + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/test/wallet.py b/test/functional/wallet.py similarity index 99% rename from test/wallet.py rename to test/functional/wallet.py index e27a6d5..b477ff5 100644 --- a/test/wallet.py +++ b/test/functional/wallet.py @@ -18,7 +18,6 @@ # j) check balances - node0 should have 0, node2 should have 100 # -from test_framework.util import * from test_case_base import TestCaseBase class WalletTest(TestCaseBase): diff --git a/test/functional/wallet_hd.py b/test/functional/wallet_hd.py new file mode 100644 index 0000000..8ad3b9e --- /dev/null +++ b/test/functional/wallet_hd.py @@ -0,0 +1,109 @@ +#!/usr/bin/env python3 +# Copyright (c) 2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. +"""Test Hierarchical Deterministic wallet function.""" + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import * +import shutil +class WalletHDTest(BitcoinTestFramework): + + def set_test_params(self): + self.setup_clean_chain = True + self.num_nodes = 2 + self.extra_args = [['-usehd=0'],['-usehd=1', '-keypool=0']] + + def setup_network(self): + self.add_nodes(self.num_nodes, self.extra_args) + self.start_node(0) + self.start_node(1) + self.is_network_split = False + connect_nodes_bi(self.nodes, 0, 1) + self.sync_all() + + + def run_test (self): + tmpdir = self.options.tmpdir + + # Make sure can't switch off usehd after wallet creation + self.stop_node(1) + self.start_node(1) + # self.assert_start_raises_init_error(1, self.options.tmpdir, ['-usehd=0'], 'already existing HD wallet') + connect_nodes_bi(self.nodes, 0, 1) + + # Make sure we use hd, keep chainid + chainid = self.nodes[1].getwalletinfo()['hdchainid'] + assert_equal(len(chainid), 64) + + # create an internal key + change_addr = self.nodes[1].getrawchangeaddress() + change_addrV= self.nodes[1].validateaddress(change_addr); + assert_equal(change_addrV["hdkeypath"], "m/44'/1'/0'/1/0") #first internal child key + + # Import a non-HD private key in the HD wallet + non_hd_add = self.nodes[0].getnewaddress() + self.nodes[1].importprivkey(self.nodes[0].dumpprivkey(non_hd_add)) + + # This should be enough to keep the master key and the non-HD key + self.nodes[1].backupwallet(tmpdir + "/hd.bak") + #self.nodes[1].dumpwallet(tmpdir + "/hd.dump") + + # Derive some HD addresses and remember the last + # Also send funds to each add + self.nodes[0].generate(120) + hd_add = None + num_hd_adds = 300 + for i in range(num_hd_adds): + hd_add = self.nodes[1].getnewaddress() + hd_info = self.nodes[1].validateaddress(hd_add) + assert_equal(hd_info["hdkeypath"], "m/44'/1'/0'/0/"+str(i+1)) + assert_equal(hd_info["hdchainid"], chainid) + self.nodes[0].sendtoaddress(hd_add, 1) + print("balance: " + str(self.nodes[0].getbalance())) + + self.nodes[0].sendtoaddress(non_hd_add, 1) + self.nodes[0].generate(6) + + # create an internal key (again) + change_addr = self.nodes[1].getrawchangeaddress() + change_addrV= self.nodes[1].validateaddress(change_addr); + assert_equal(change_addrV["hdkeypath"], "m/44'/1'/0'/1/1") #second internal child key + + self.sync_all() + assert_equal(self.nodes[1].getbalance(), num_hd_adds + 1) + + self.log.info("Restore backup ...") + self.stop_node(1) + os.remove(self.options.tmpdir + "/node1/regtest/wallet.dat") + shutil.copyfile(tmpdir + "/hd.bak", tmpdir + "/node1/regtest/wallet.dat") + self.start_node(1,['-usehd=1', '-keypool=0']) + connect_nodes_bi(self.nodes, 0, 1) + + # Assert that derivation is deterministic + hd_add_2 = None + for _ in range(num_hd_adds): + hd_add_2 = self.nodes[1].getnewaddress() + hd_info_2 = self.nodes[1].validateaddress(hd_add_2) + assert_equal(hd_info_2["hdkeypath"], "m/44'/1'/0'/0/"+str(_+1)) + assert_equal(hd_info_2["hdchainid"], chainid) + assert_equal(hd_add, hd_add_2) + + # Needs rescan + self.stop_node(1) + self.start_node(1,['-usehd=1', '-keypool=0', '-rescan']) + connect_nodes_bi(self.nodes, 0, 1) + assert_equal(self.nodes[1].getbalance(), num_hd_adds + 1) + + # send a tx and make sure its using the internal chain for the changeoutput + txid = self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), 1) + outs = self.nodes[1].decoderawtransaction(self.nodes[1].gettransaction(txid)['hex'])['vout']; + keypath = "" + for out in outs: + if out['value'] != 1: + keypath = self.nodes[1].validateaddress(out['scriptPubKey']['addresses'][0])['hdkeypath'] + + assert_equal(keypath[0:13], "m/44'/1'/0'/1") + +if __name__ == '__main__': + WalletHDTest().main () \ No newline at end of file diff --git a/test/zerocoin.py b/test/functional/zerocoin.py similarity index 98% rename from test/zerocoin.py rename to test/functional/zerocoin.py index 9b66d83..c3dc044 100644 --- a/test/zerocoin.py +++ b/test/functional/zerocoin.py @@ -18,7 +18,6 @@ # j) check balances - node0 should have 0, node2 should have 100 # -from test_framework.util import * from test_case_base import TestCaseBase class ZerocoinTest(TestCaseBase):