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..b13dd0c 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,11 @@ BITCOIN_CORE_H = \ script/script_error.h \ serialize.h \ support/allocators/zeroafterfree.h \ - support/cleanse.h \ spork.h \ sporkdb.h \ + stakeinput.h \ streams.h \ + support/cleanse.h \ sync.h \ threadsafety.h \ timedata.h \ @@ -195,12 +195,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 +278,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 +287,19 @@ 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 \ + stakeinput.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 +308,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 +378,7 @@ libbitcoin_common_a_SOURCES = \ amount.cpp \ base58.cpp \ bech32.cpp \ + wallet/bip39.cpp \ bip38.cpp \ chainparams.cpp \ coins.cpp \ @@ -391,7 +405,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 +424,7 @@ libbitcoin_util_a_SOURCES = \ clientversion.cpp \ random.cpp \ rpc/protocol.cpp \ + support/cleanse.cpp \ sync.cpp \ uint256.cpp \ util.cpp \ @@ -573,3 +588,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..d928198 100755 --- a/src/chain.h +++ b/src/chain.h @@ -7,6 +7,7 @@ #ifndef BITCOIN_CHAIN_H #define BITCOIN_CHAIN_H +#include "chainparams.h" #include "pow.h" #include "primitives/block.h" #include "tinyformat.h" @@ -165,6 +166,7 @@ class CBlockIndex uint256 hashProofOfStake; int64_t nMint; int64_t nMoneySupply; + uint256 nStakeModifierV2; //! block header int nVersion; @@ -200,6 +202,7 @@ class CBlockIndex nMoneySupply = 0; nFlags = 0; nStakeModifier = 0; + nStakeModifierV2 = uint256(); nStakeModifierChecksum = 0; prevoutStake.SetNull(); nStakeTime = 0; @@ -234,22 +237,10 @@ class CBlockIndex if(block.nVersion > 5) nAccumulatorCheckpoint = block.nAccumulatorCheckpoint; - //Proof of Stake - bnChainTrust = uint256(); - nMint = 0; - nMoneySupply = 0; - nFlags = 0; - nStakeModifier = 0; - nStakeModifierChecksum = 0; - hashProofOfStake = uint256(); - if (block.IsProofOfStake()) { SetProofOfStake(); prevoutStake = block.vtx[1].vin[0].prevout; nStakeTime = block.nTime; - } else { - prevoutStake.SetNull(); - nStakeTime = 0; } } @@ -430,7 +421,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()); } @@ -457,7 +448,14 @@ class CDiskBlockIndex : public CBlockIndex READWRITE(nMint); READWRITE(nMoneySupply); READWRITE(nFlags); - READWRITE(nStakeModifier); + + // v1/v2 modifier selection. + if (!Params().IsStakeModifierV2(nHeight)) { + READWRITE(nStakeModifier); + } else { + READWRITE(nStakeModifierV2); + } + if (IsProofOfStake()) { READWRITE(prevoutStake); READWRITE(nStakeTime); diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 3f873a5..975081c 100755 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -20,6 +20,7 @@ #include #include #include +#include static const int SCRYPT_SCRATCHPAD_SIZE = 131072 + 63; @@ -379,6 +380,20 @@ libzerocoin::ZerocoinParams* CChainParams::OldZerocoin_Params() const return &ZCParams; } +bool CChainParams::HasStakeMinAgeOrDepth(const int contextHeight, const uint32_t contextTime, + const int utxoFromBlockHeight, const uint32_t utxoFromBlockTime) const +{ + // before stake modifier V2, the age required was 3 * 60 * 60 (3 hour) / not required on regtest + if (!IsStakeModifierV2(contextHeight)) { + return true; + //return (NetworkID() == CBaseChainParams::REGTEST || (utxoFromBlockTime + 10800 <= contextTime)); + } + + // after stake modifier V2, we require the utxo to be nStakeMinDepth deep in the chain + return (contextHeight - utxoFromBlockHeight >= nStakeMinDepth); +} + + class CMainParams : public CChainParams { public: @@ -404,15 +419,18 @@ class CMainParams : public CChainParams nRejectBlockOutdatedMajority = 2850; nToCheckBlockUpgradeMajority = 3000; // 24 hours (legacy) nMinerThreads = 0; - nMaturity = 4; - nKarmanodeCountDrift = 20; - nMaxMoneyOut = 30000000 * COIN; /* Legacy Blocktime */ nTargetTimespanLegacy = 1 * 60 * 40; // OHMC: 40 Minutes nTargetSpacingLegacy = 1 * 30; // OHMC: 30 Seconds /* New Blocktime */ nTargetTimespan = 1 * 60 * 60 * 2; // OHMC New: 120 Minutes nTargetSpacing = 1 * 60 * 4; // OHMC New: 240 Seconds + nStakeMinDepth = 600; + nFutureTimeDriftPoW = 7200; + nFutureTimeDriftPoS = 180; + nMaturity = 4; + nKarmanodeCountDrift = 20; + nMaxMoneyOut = 30000000 * COIN; /** Height or Time Based Activations **/ nLastPOWBlock = 1001; @@ -458,8 +476,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"; @@ -478,6 +495,8 @@ class CMainParams : public CChainParams strSporkKey = "04dcb6cbd18fdecce2aac1f795aa650a25749fb58eb5afc796655cce5c728a2eb38ec0ce85d67555ddde6530cd04e6fd1f7c5f818ba483ad6f098e402803225074"; strObfuscationPoolDummyAddress = "D87q2gC9j6nNrnzCsg4aY6bHMLsT9nUhEw"; + nBlockStakeModifierlV2 = 99999999; // this will be set at a later date + /** Zerocoin */ zerocoinModulus = "25195908475657893494027183240048398571429282126204032027777137836043662020707595556264018525880784" "4069182906412495150821892985591491761845028084891200728449926873928072877767359714183472702618963750149718246911" @@ -554,8 +573,8 @@ class CTestNetParams : public CMainParams /* New Blocktime */ nTargetTimespan = 1 * 60 * 60 * 1; // OHMC New: 60 Minutes nTargetSpacing = 1 * 60 * 2; // OHMC New: 120 Seconds - nMaturity = 15; + nStakeMinDepth = 100; nKarmanodeCountDrift = 4; nModifierUpdateBlock = 51197; //approx Mon, 17 Apr 2017 04:00:00 GMT nMaxMoneyOut = 43199500 * COIN; @@ -581,8 +600,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"; @@ -598,6 +617,7 @@ class CTestNetParams : public CMainParams nPoolMaxTransactions = 2; strSporkKey = "0491826db990788ac61af9f74556c07bbf049b36a2b6942a6df11011643c4076f0cb05b360de70822728dfb929bd3467336366ba7351c5772c504641b8310e4a91"; strObfuscationPoolDummyAddress = "y57cqfGRkekRyDRNeJiLtYVEbvhXrNbmox"; + nBlockStakeModifierlV2 = 9999999; // this will be set at a later date nBudgetFeeConfirmations = 3; // Number of confirmations for the finalization fee. We have to make this very short // here because we only have a 8 block finalization window on testnet @@ -650,10 +670,13 @@ class CRegTestParams : public CTestNetParams genesis.nBits = 0x207fffff; genesis.nNonce = 12345; nMaturity = 0; + nStakeMinDepth = 0; nLastPOWBlock = 999999999; // PoS complicates Regtest because of timing issues nZerocoinLastOldParams = 499; nZerocoinStartHeight = 100; + nBlockStakeModifierlV2 = std::numeric_limits::max(); // max integer value (never switch on regtest) + hashGenesisBlock = genesis.GetHash(); nDefaultPort = 51476; //assert(hashGenesisBlock == uint256("0x2b1a0f66712aad59ad283662d5b919415a25921ce89511d73019107e380485bf")); @@ -717,6 +740,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..2e643c0 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 }; @@ -83,6 +82,15 @@ class CChainParams int64_t Interval() const { return nTargetTimespan / nTargetSpacing; } /** Majurity Checks */ int COINBASE_MATURITY() const { return nMaturity; } + + /** returns the coinstake maturity (min depth required) **/ + int COINSTAKE_MIN_DEPTH() const { return nStakeMinDepth; } + bool HasStakeMinAgeOrDepth(const int contextHeight, const uint32_t contextTime, const int utxoFromBlockHeight, const uint32_t utxoFromBlockTime) const; + + /** returns the max future time (and drift in seconds) allowed for a block in the future **/ + int FutureBlockTimeDrift(const bool isPoS) const { return isPoS ? nFutureTimeDriftPoS : nFutureTimeDriftPoW; } + uint32_t MaxFutureBlockTime(uint32_t time, const bool isPoS) const { return time + FutureBlockTimeDrift(isPoS); } + unsigned int StakeMaturity() const { return nStakeMaturity; } /** Max Money Checks */ CAmount MaxMoneyOut() const { return nMaxMoneyOut; } @@ -97,6 +105,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; } @@ -122,6 +131,7 @@ class CChainParams int LAST_POW_BLOCK() const { return nLastPOWBlock; } int Zerocoin_StartHeight() const { return nZerocoinStartHeight; } int Zerocoin_LastOldParams() const { return nZerocoinLastOldParams; } + bool IsStakeModifierV2(const int nHeight) const { return nHeight >= nBlockStakeModifierlV2; } protected: CChainParams() {} @@ -143,6 +153,10 @@ class CChainParams int nLastPOWBlock; int nKarmanodeCountDrift; int nMaturity; + int nStakeMinDepth; + int nFutureTimeDriftPoW; + int nFutureTimeDriftPoS; + unsigned int nStakeMaturity; int nModifierUpdateBlock; CAmount nMaxMoneyOut; @@ -150,6 +164,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; @@ -177,6 +192,7 @@ class CChainParams int64_t nBudgetFeeConfirmations; int nZerocoinStartHeight; int nZerocoinLastOldParams; + int nBlockStakeModifierlV2; }; /** 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/karmanode-payments.cpp b/src/karmanode-payments.cpp index c0bebe0..5eab3e2 100755 --- a/src/karmanode-payments.cpp +++ b/src/karmanode-payments.cpp @@ -330,20 +330,20 @@ void CKarmanodePayments::FillBlockPayee(CMutableTransaction& txNew, int64_t nFee txNew.vout[i].nValue = karmanodePayment; //subtract mn payment from the stake reward - if (i == 2) { - // Majority of cases; do it quick and move on - txNew.vout[i - 1].nValue -= karmanodePayment; - } else if (i > 2) { - // special case, stake is split between (i-1) outputs - unsigned int outputs = i-1; - CAmount knPaymentSplit = karmanodePayment / outputs; - CAmount knPaymentRemainder = karmanodePayment - (knPaymentSplit * outputs); - for (unsigned int j=1; j<=outputs; j++) { - txNew.vout[j].nValue -= knPaymentSplit; - } - // in case it's not an even division, take the last bit of dust from the last one - txNew.vout[outputs].nValue -= knPaymentRemainder; - } + if (i == 2) { + // Majority of cases; do it quick and move on + txNew.vout[i - 1].nValue -= karmanodePayment; + } else if (i > 2) { + // special case, stake is split between (i-1) outputs + unsigned int outputs = i-1; + CAmount knPaymentSplit = karmanodePayment / outputs; + CAmount knPaymentRemainder = karmanodePayment - (knPaymentSplit * outputs); + for (unsigned int j=1; j<=outputs; j++) { + txNew.vout[j].nValue -= knPaymentSplit; + } + // in case it's not an even division, take the last bit of dust from the last one + txNew.vout[outputs].nValue -= knPaymentRemainder; + } } else { txNew.vout.resize(2); txNew.vout[1].scriptPubKey = payee; diff --git a/src/kernel.cpp b/src/kernel.cpp index 0c6040a..befca22 100755 --- a/src/kernel.cpp +++ b/src/kernel.cpp @@ -6,38 +6,24 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include +#include #include "db.h" #include "kernel.h" #include "script/interpreter.h" #include "timedata.h" #include "util.h" +#include "stakeinput.h" +#include "spork.h" using namespace std; -bool fTestNet = false; //Params().NetworkID() == CBaseChainParams::TESTNET; - -// Modifier interval: time to elapse before new modifier is computed -// Set to 3-hour for production network and 20-minute for test network -unsigned int nModifierInterval; -int nStakeTargetSpacing = 60; -unsigned int getIntervalVersion(bool fTestNet) -{ - if (fTestNet) - return MODIFIER_INTERVAL_TESTNET; - else - return MODIFIER_INTERVAL; -} +// v1 modifier interval. +static const int64_t OLD_MODIFIER_INTERVAL = 2087; // Hard checkpoints of stake modifiers to ensure they are deterministic static std::map mapStakeModifierCheckpoints = - boost::assign::map_list_of(0, 0xe0f05322); - -// Get time weight -int64_t GetWeight(int64_t nIntervalBeginning, int64_t nIntervalEnd) -{ - return nIntervalEnd - nIntervalBeginning - nStakeMinAge; -} + boost::assign::map_list_of(0, 0xe0f05322); // Get the last stake modifier and its generation time from a given block static bool GetLastStakeModifier(const CBlockIndex* pindex, uint64_t& nStakeModifier, int64_t& nModifierTime) @@ -57,29 +43,19 @@ static bool GetLastStakeModifier(const CBlockIndex* pindex, uint64_t& nStakeModi static int64_t GetStakeModifierSelectionIntervalSection(int nSection) { assert(nSection >= 0 && nSection < 64); - int64_t a = getIntervalVersion(fTestNet) * 63 / (63 + ((63 - nSection) * (MODIFIER_INTERVAL_RATIO - 1))); + int64_t a = MODIFIER_INTERVAL * 63 / (63 + ((63 - nSection) * (MODIFIER_INTERVAL_RATIO - 1))); return a; } -// Get stake modifier selection interval (in seconds) -static int64_t GetStakeModifierSelectionInterval() -{ - int64_t nSelectionInterval = 0; - for (int nSection = 0; nSection < 64; nSection++) { - nSelectionInterval += GetStakeModifierSelectionIntervalSection(nSection); - } - return nSelectionInterval; -} - // select a block from the candidate blocks in vSortedByTimestamp, excluding // already selected blocks in vSelectedBlocks, and with timestamp up to // nSelectionIntervalStop. static bool SelectBlockFromCandidates( - vector >& vSortedByTimestamp, - map& mapSelectedBlocks, - int64_t nSelectionIntervalStop, - uint64_t nStakeModifierPrev, - const CBlockIndex** pindexSelected) + vector >& vSortedByTimestamp, + map& mapSelectedBlocks, + int64_t nSelectionIntervalStop, + uint64_t nStakeModifierPrev, + const CBlockIndex** pindexSelected) { bool fModifierV2 = false; bool fFirstRun = true; @@ -134,6 +110,30 @@ static bool SelectBlockFromCandidates( return fSelected; } +/* NEW MODIFIER */ + +// Stake Modifier (hash modifier of proof-of-stake): +// The purpose of stake modifier is to prevent a txout (coin) owner from +// computing future proof-of-stake generated by this txout at the time +// of transaction confirmation. To meet kernel protocol, the txout +// must hash with a future stake modifier to generate the proof. +uint256 ComputeStakeModifier(const CBlockIndex* pindexPrev, const uint256& kernel) +{ + if (!pindexPrev) + return uint256(); // genesis block's modifier is 0 + + CHashWriter ss(SER_GETHASH, 0); + ss << kernel; + + // switch with old modifier on upgrade block + if (!Params().IsStakeModifierV2(pindexPrev->nHeight + 1)) + ss << pindexPrev->nStakeModifier; + else + ss << pindexPrev->nStakeModifierV2; + + return ss.GetHash(); +} + // Stake Modifier (hash modifier of proof-of-stake): // The purpose of stake modifier is to prevent a txout (coin) owner from // computing future proof-of-stake generated by this txout at the time @@ -169,17 +169,15 @@ bool ComputeNextStakeModifier(const CBlockIndex* pindexPrev, uint64_t& nStakeMod return error("ComputeNextStakeModifier: unable to get last modifier"); if (GetBoolArg("-printstakemodifier", false)) - LogPrintf("ComputeNextStakeModifier: prev modifier= %s time=%s\n", std::to_string(nStakeModifier).c_str(), DateTimeStrFormat("%Y-%m-%d %H:%M:%S", nModifierTime).c_str()); + LogPrintf("ComputeNextStakeModifier: prev modifier= %s time=%s\n", boost::lexical_cast(nStakeModifier).c_str(), DateTimeStrFormat("%Y-%m-%d %H:%M:%S", nModifierTime).c_str()); - if (nModifierTime / getIntervalVersion(fTestNet) >= pindexPrev->GetBlockTime() / getIntervalVersion(fTestNet)) + if (nModifierTime / MODIFIER_INTERVAL >= pindexPrev->GetBlockTime() / MODIFIER_INTERVAL) return true; // Sort candidate blocks by timestamp vector > vSortedByTimestamp; - vSortedByTimestamp.reserve(64 * getIntervalVersion(fTestNet) / nStakeTargetSpacing); - int64_t nSelectionInterval = GetStakeModifierSelectionInterval(); - int64_t nSelectionIntervalStart = (pindexPrev->GetBlockTime() / getIntervalVersion(fTestNet)) * getIntervalVersion(fTestNet) - nSelectionInterval; - const CBlockIndex* pindex = pindexPrev; + vSortedByTimestamp.reserve(64 * MODIFIER_INTERVAL / Params().TargetSpacing()); + int64_t nSelectionIntervalStart = (pindexPrev->GetBlockTime() / MODIFIER_INTERVAL ) * MODIFIER_INTERVAL - OLD_MODIFIER_INTERVAL; const CBlockIndex* pindex = pindexPrev; while (pindex && pindex->GetBlockTime() >= nSelectionIntervalStart) { vSortedByTimestamp.push_back(make_pair(pindex->GetBlockTime(), pindex->GetBlockHash())); @@ -209,7 +207,7 @@ bool ComputeNextStakeModifier(const CBlockIndex* pindexPrev, uint64_t& nStakeMod mapSelectedBlocks.insert(make_pair(pindex->GetBlockHash(), pindex)); if (fDebug || GetBoolArg("-printstakemodifier", false)) LogPrintf("ComputeNextStakeModifier: selected round %d stop=%s height=%d bit=%d\n", - nRound, DateTimeStrFormat("%Y-%m-%d %H:%M:%S", nSelectionIntervalStop).c_str(), pindex->nHeight, pindex->GetStakeEntropyBit()); + nRound, DateTimeStrFormat("%Y-%m-%d %H:%M:%S", nSelectionIntervalStop).c_str(), pindex->nHeight, pindex->GetStakeEntropyBit()); } // Print selection map for visualization of the selected blocks @@ -232,7 +230,7 @@ bool ComputeNextStakeModifier(const CBlockIndex* pindexPrev, uint64_t& nStakeMod LogPrintf("ComputeNextStakeModifier: selection height [%d, %d] map %s\n", nHeightFirstCandidate, pindexPrev->nHeight, strSelectionMap.c_str()); } if (fDebug || GetBoolArg("-printstakemodifier", false)) { - LogPrintf("ComputeNextStakeModifier: new modifier=%s time=%s\n", std::to_string(nStakeModifierNew).c_str(), DateTimeStrFormat("%Y-%m-%d %H:%M:%S", pindexPrev->GetBlockTime()).c_str()); + LogPrintf("ComputeNextStakeModifier: new modifier=%s time=%s\n", boost::lexical_cast(nStakeModifierNew).c_str(), DateTimeStrFormat("%Y-%m-%d %H:%M:%S", pindexPrev->GetBlockTime()).c_str()); } nStakeModifier = nStakeModifierNew; @@ -242,7 +240,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)) @@ -250,110 +248,137 @@ bool GetKernelStakeModifier(uint256 hashBlockFrom, uint64_t& nStakeModifier, int const CBlockIndex* pindexFrom = mapBlockIndex[hashBlockFrom]; nStakeModifierHeight = pindexFrom->nHeight; nStakeModifierTime = pindexFrom->GetBlockTime(); - int64_t nStakeModifierSelectionInterval = GetStakeModifierSelectionInterval(); const CBlockIndex* pindex = pindexFrom; - CBlockIndex* pindexNext = chainActive[pindexFrom->nHeight + 1]; + CBlockIndex* pindexNext = chainActive[pindex->nHeight + 1]; // loop to find the stake modifier later by a selection interval - while (nStakeModifierTime < pindexFrom->GetBlockTime() + nStakeModifierSelectionInterval) { + do { if (!pindexNext) { // Should never happen - return error("Null pindexNext\n"); + return error("%s : Null pindexNext, current block %s ", __func__, pindex->phashBlock->GetHex()); } pindex = pindexNext; - pindexNext = chainActive[pindexNext->nHeight + 1]; if (pindex->GeneratedStakeModifier()) { nStakeModifierHeight = pindex->nHeight; nStakeModifierTime = pindex->GetBlockTime(); } - } + pindexNext = chainActive[pindex->nHeight + 1]; + } while (nStakeModifierTime < pindexFrom->GetBlockTime() + OLD_MODIFIER_INTERVAL); + nStakeModifier = pindex->nStakeModifier; return true; } -uint256 stakeHash(unsigned int nTimeTx, CDataStream ss, unsigned int prevoutIndex, uint256 prevoutHash, unsigned int nTimeBlockFrom) +bool CheckStakeKernelHash(const CBlockIndex* pindexPrev, const unsigned int nBits, CStakeInput* stake, const unsigned int nTimeTx, uint256& hashProofOfStake, const bool fVerify) { - //Ohmcoin will hash in the transaction hash and the index number in order to make sure each hash is unique - ss << nTimeBlockFrom << prevoutIndex << prevoutHash << nTimeTx; - return Hash(ss.begin(), ss.end()); + // Calculate the proof of stake hash + if (!GetHashProofOfStake(pindexPrev, stake, nTimeTx, fVerify, hashProofOfStake)) { + return error("%s : Failed to calculate the proof of stake hash", __func__); + } + + const CAmount& nValueIn = stake->GetValue(); + const CDataStream& ssUniqueID = stake->GetUniqueness(); + + // Base target + uint256 bnTarget; + bnTarget.SetCompact(nBits); + + // Weighted target + uint256 bnWeight = uint256(nValueIn) / 100; + bnTarget *= bnWeight; + + // Check if proof-of-stake hash meets target protocol + const bool res = (hashProofOfStake < bnTarget); + + if (fVerify || res) { + LogPrint("staking", "%s : Proof Of Stake:" + "\nssUniqueID=%s" + "\nnTimeTx=%d" + "\nhashProofOfStake=%s" + "\nnBits=%d" + "\nweight=%d" + "\nbnTarget=%s (res: %d)\n\n", + __func__, HexStr(ssUniqueID), nTimeTx, hashProofOfStake.GetHex(), + nBits, nValueIn, bnTarget.GetHex(), res); + } + return res; } -//test hash vs target -bool stakeTargetHit(uint256 hashProofOfStake, int64_t nValueIn, uint256 bnTargetPerCoinDay) -{ - //get the stake weight - weight is equal to coin amount - uint256 bnCoinDayWeight = uint256(nValueIn) / 100; +bool GetHashProofOfStake(const CBlockIndex* pindexPrev, CStakeInput* stake, const unsigned int nTimeTx, const bool fVerify, uint256& hashProofOfStakeRet) { + // Grab the stake data + CBlockIndex* pindexfrom = stake->GetIndexFrom(); + if (!pindexfrom) return error("%s : Failed to find the block index for stake origin", __func__); + const CDataStream& ssUniqueID = stake->GetUniqueness(); + const unsigned int nTimeBlockFrom = pindexfrom->nTime; + CDataStream modifier_ss(SER_GETHASH, 0); + + // Hash the modifier + if (!Params().IsStakeModifierV2(pindexPrev->nHeight + 1)) { + // Modifier v1 + uint64_t nStakeModifier = 0; + if (!stake->GetModifier(nStakeModifier)) + return error("%s : Failed to get kernel stake modifier", __func__); + modifier_ss << nStakeModifier; + } else { + // Modifier v2 + modifier_ss << pindexPrev->nStakeModifierV2; + } - // Now check if proof-of-stake hash meets target protocol - return (uint256(hashProofOfStake) < bnCoinDayWeight * bnTargetPerCoinDay); + CDataStream ss(modifier_ss); + // Calculate hash + ss << nTimeBlockFrom << ssUniqueID << nTimeTx; + hashProofOfStakeRet = Hash(ss.begin(), ss.end()); + + if (fVerify) { + LogPrint("staking", "%s :{ nStakeModifier=%s\n" + "nStakeModifierHeight=%s\n" + "}\n", + __func__, HexStr(modifier_ss), std::to_string(stake->getStakeModifierHeight())); + } + return true; } -//instead of looping outside and reinitializing variables many times, we will give a nTimeTx and also search interval so that we can do all the hashing here -bool CheckStakeKernelHash(unsigned int nBits, const CBlock blockFrom, const CTransaction txPrev, const COutPoint prevout, unsigned int& nTimeTx, unsigned int nHashDrift, bool fCheck, uint256& hashProofOfStake, bool fPrintProofOfStake) +bool Stake(const CBlockIndex* pindexPrev, CStakeInput* stakeInput, unsigned int nBits, unsigned int& nTimeTx, uint256& hashProofOfStake) { - //assign new variables to make it easier to read - int64_t nValueIn = txPrev.vout[prevout.n].nValue; - unsigned int nTimeBlockFrom = blockFrom.GetBlockTime(); - - if (nTimeTx < nTimeBlockFrom) // Transaction timestamp violation - return error("CheckStakeKernelHash() : nTime violation"); - - //if (nTimeBlockFrom + nStakeMinAge > nTimeTx) // Min age requirement - //return error("CheckStakeKernelHash() : min age violation - nTimeBlockFrom=%d nStakeMinAge=%d nTimeTx=%d", nTimeBlockFrom, nStakeMinAge, nTimeTx); - - //grab difficulty - uint256 bnTargetPerCoinDay; - bnTargetPerCoinDay.SetCompact(nBits); - - //grab stake modifier - uint64_t nStakeModifier = 0; - int nStakeModifierHeight = 0; - int64_t nStakeModifierTime = 0; - if (!GetKernelStakeModifier(blockFrom.GetHash(), nStakeModifier, nStakeModifierHeight, nStakeModifierTime, fPrintProofOfStake)) { - LogPrintf("CheckStakeKernelHash(): failed to get kernel stake modifier \n"); - return false; - } + int prevHeight = pindexPrev->nHeight; - //create data stream once instead of repeating it in the loop - CDataStream ss(SER_GETHASH, 0); - ss << nStakeModifier; + // get stake input pindex + CBlockIndex* pindexFrom = stakeInput->GetIndexFrom(); + if (!pindexFrom || pindexFrom->nHeight < 1) return error("%s : no pindexfrom", __func__); - //if wallet is simply checking to make sure a hash is valid - if (fCheck) { - hashProofOfStake = stakeHash(nTimeTx, ss, prevout.n, prevout.hash, nTimeBlockFrom); - return stakeTargetHit(hashProofOfStake, nValueIn, bnTargetPerCoinDay); - } + const uint32_t nTimeBlockFrom = pindexFrom->nTime; + const int nHeightBlockFrom = pindexFrom->nHeight; + // check for maturity (min age/depth) requirements + if (!Params().HasStakeMinAgeOrDepth(prevHeight + 1, nTimeTx, nHeightBlockFrom, nTimeBlockFrom)) + return error("%s : min age violation - height=%d - nTimeTx=%d, nTimeBlockFrom=%d, nHeightBlockFrom=%d", + __func__, prevHeight + 1, nTimeTx, nTimeBlockFrom, nHeightBlockFrom); + + // iterate the hashing bool fSuccess = false; - unsigned int nTryTime = 0; - unsigned int i; - for (i = 0; i < (nHashDrift); i++) //iterate the hashing + const unsigned int nHashDrift = 60; + unsigned int nTryTime = nTimeTx - 1; + // iterate from nTimeTx up to nTimeTx + nHashDrift + // but not after the max allowed future blocktime drift (3 minutes for PoS) + const unsigned int maxTime = std::min(nTimeTx + nHashDrift, Params().MaxFutureBlockTime(GetAdjustedTime(), true)); + + while (nTryTime < maxTime) { + //new block came in, move on + if (chainActive.Height() != prevHeight) + break; - //hash this iteration - nTryTime = nTimeTx + nHashDrift - i; - hashProofOfStake = stakeHash(nTryTime, ss, prevout.n, prevout.hash, nTimeBlockFrom); + ++nTryTime; // if stake hash does not meet the target then continue to next iteration - if (!stakeTargetHit(hashProofOfStake, nValueIn, bnTargetPerCoinDay)) + uint256 hashProofOfStake = 0; + if (!CheckStakeKernelHash(pindexPrev, nBits, stakeInput, nTryTime, hashProofOfStake)) continue; - fSuccess = true; // if we make it this far then we have successfully created a stake hash + // if we made it this far, then we have successfully found a valid kernel hash + fSuccess = true; nTimeTx = nTryTime; - - if (fDebug || fPrintProofOfStake) { - LogPrintf("CheckStakeKernelHash() : using modifier %s at height=%d timestamp=%s for block from height=%d timestamp=%s\n", - std::to_string(nStakeModifier).c_str(), nStakeModifierHeight, - DateTimeStrFormat("%Y-%m-%d %H:%M:%S", nStakeModifierTime).c_str(), - mapBlockIndex[blockFrom.GetHash()]->nHeight, - DateTimeStrFormat("%Y-%m-%d %H:%M:%S", blockFrom.GetBlockTime()).c_str()); - LogPrintf("CheckStakeKernelHash() : pass protocol=%s modifier=%s nTimeBlockFrom=%u prevoutHash=%s nTimeTxPrev=%u nPrevout=%u nTimeTx=%u hashProof=%s\n", - "0.3", - std::to_string(nStakeModifier).c_str(), - nTimeBlockFrom, prevout.hash.ToString().c_str(), nTimeBlockFrom, prevout.n, nTryTime, - hashProofOfStake.ToString().c_str()); - } break; } @@ -363,42 +388,106 @@ 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 initStakeInput(const CBlock block, std::unique_ptr& stake, int nPreviousBlockHeight) { const CTransaction tx = block.vtx[1]; if (!tx.IsCoinStake()) - return error("CheckProofOfStake() : called on non-coinstake %s", tx.GetHash().ToString().c_str()); + return error("initStakeInput() : called on non-coinstake %s", tx.GetHash().ToString().c_str()); // Kernel (input 0) must match the stake hash target per coin age (nBits) const CTxIn& txin = tx.vin[0]; + //Construct the stakeinput object // First try finding the previous transaction in database uint256 hashBlock; CTransaction txPrev; if (!GetTransaction(txin.prevout.hash, txPrev, hashBlock, true)) - return error("CheckProofOfStake() : INFO: read txPrev failed"); + return error("initStakeInput() : INFO: read txPrev failed"); //verify signature and script - if (!VerifyScript(txin.scriptSig, txPrev.vout[txin.prevout.n].scriptPubKey, - tx.wit.vtxinwit.size() > 0 ? &tx.wit.vtxinwit[0].scriptWitness : NULL, STANDARD_SCRIPT_VERIFY_FLAGS, TransactionSignatureChecker(&tx, 0, txPrev.vout[txin.prevout.n].nValue))) - return error("CheckProofOfStake() : VerifySignature failed on coinstake %s", tx.GetHash().ToString().c_str()); - - CBlockIndex* pindex = NULL; - BlockMap::iterator it = mapBlockIndex.find(hashBlock); - if (it != mapBlockIndex.end()) - pindex = it->second; - else - return error("CheckProofOfStake() : read block failed"); + if (!VerifyScript(txin.scriptSig, txPrev.vout[txin.prevout.n].scriptPubKey, NULL, STANDARD_SCRIPT_VERIFY_FLAGS, TransactionSignatureChecker(&tx, 0, txPrev.vout[txin.prevout.n].nValue))) + return error("initStakeInput() : VerifySignature failed on coinstake %s", tx.GetHash().ToString().c_str()); + + COhmStake* ohmInput = new COhmStake(); + ohmInput->SetInput(txPrev, txin.prevout.n); + stake = std::unique_ptr(ohmInput); + + return true; +} + +bool CheckKernelExtraInputs(const CTransaction & tx, const CScript& scriptKernel) +{ + if (!tx.IsCoinStake()) { + return true; + } + + const auto& vin = tx.vin; + for (size_t i = 0; i < vin.size(); ++i) { + const auto& in = vin[i]; + uint256 hashBlock; + CTransaction txPrev; + + if (!GetTransaction(in.prevout.hash, txPrev, hashBlock, true)) { + return error("CheckKernelExtraInputs() : INFO: read txPrev failed"); + } + + const auto& prevOut = txPrev.vout[in.prevout.n]; + if (scriptKernel != prevOut.scriptPubKey) { + return error("CheckKernelExtraInputs() : invalid input at position %d for coinstake %s", i, tx.GetHash().ToString().c_str()); + } + } + + if (tx.vin.size() > 1) { + return error("CheckKernelExtraInputs() : invalid multi-inputs coinstake"); + } + + // Prevent multi-empty-outputs + for (size_t i = 1; i < tx.vout.size(); i++ ) { + if (tx.vout[i].IsEmpty()) { + return error("CheckKernelExtraInputs() : bad-txns-vout-empty"); + } + } + + return true; +} + +// Check kernel hash target and coinstake signature +bool CheckProofOfStake(const CBlock block, uint256& hashProofOfStake, std::unique_ptr& stake, int nPreviousBlockHeight) +{ + // Initialize the stake object + if(!initStakeInput(block, stake, nPreviousBlockHeight)) + return error("%s : stake input object initialization failed", __func__); + + const CTransaction tx = block.vtx[1]; + CBlockIndex* pindexPrev = mapBlockIndex[block.hashPrevBlock]; + CBlockIndex* pindexfrom = stake->GetIndexFrom(); + if (!pindexfrom) + return error("%s: Failed to find the block index for stake origin", __func__); + + if(GetSporkValue(SPORK_24_KERNEL_EXTRA_STAKING_CHECK) >= pindexfrom->nHeight) { + const CTxIn& txin = tx.vin[0]; + uint256 hashBlock; + CTransaction txPrev; + if (!GetTransaction(txin.prevout.hash, txPrev, hashBlock, true)) + return error("CheckProofOfStake() : INFO: read txPrev failed"); + CTxOut prevTxOut = txPrev.vout[txin.prevout.n]; + // any coinstake transaction has to have scripts only from kernel. + if (!CheckKernelExtraInputs(tx, prevTxOut.scriptPubKey)) { + return error("CheckProofOfStake() : extra inputs check failed"); + } + } + + unsigned int nBlockFromTime = pindexfrom->nTime; + unsigned int nTxTime = block.nTime; + const int nBlockFromHeight = pindexfrom->nHeight; - // Read block header - CBlock blockprev; - if (!ReadBlockFromDisk(blockprev, pindex->GetBlockPos())) - return error("CheckProofOfStake(): INFO: failed to find block"); + // Check for maturity (min age/depth) requirements + if (!Params().HasStakeMinAgeOrDepth(nPreviousBlockHeight+1, nTxTime, nBlockFromHeight, nBlockFromTime)) + return error("%s : min age violation - height=%d - nTimeTx=%d, nTimeBlockFrom=%d, nHeightBlockFrom=%d", + __func__, nPreviousBlockHeight, nTxTime, nBlockFromTime, nBlockFromHeight); - unsigned int nInterval = 0; - unsigned int nTime = block.nTime; - if (!CheckStakeKernelHash(block.nBits, blockprev, txPrev, txin.prevout, nTime, nInterval, true, hashProofOfStake, fDebug)) - return error("CheckProofOfStake() : INFO: check kernel failed on coinstake %s, hashProof=%s \n", tx.GetHash().ToString().c_str(), hashProofOfStake.ToString().c_str()); // may occur during initial download or if behind on block chain sync + if (!CheckStakeKernelHash(pindexPrev, block.nBits, stake.get(), nTxTime, hashProofOfStake, true) && (nTxTime > 1505247602)) + return error("%s : INFO: check kernel failed on coinstake %s, hashProof=%s", __func__, + tx.GetHash().GetHex(), hashProofOfStake.GetHex()); return true; } @@ -427,7 +516,7 @@ unsigned int GetStakeModifierChecksum(const CBlockIndex* pindex) // Check stake modifier hard checkpoints bool CheckStakeModifierCheckpoints(int nHeight, unsigned int nStakeModifierChecksum) { - if (fTestNet) return true; // Testnet has no checkpoints + if (Params().NetworkID() != CBaseChainParams::MAIN) return true; // Testnet has no checkpoints if (mapStakeModifierCheckpoints.count(nHeight)) { return nStakeModifierChecksum == mapStakeModifierCheckpoints[nHeight]; } diff --git a/src/kernel.h b/src/kernel.h index 32173ff..d6eabe7 100755 --- a/src/kernel.h +++ b/src/kernel.h @@ -6,33 +6,32 @@ #define BITCOIN_KERNEL_H #include "main.h" +#include "stakeinput.h" // MODIFIER_INTERVAL: time to elapse before new modifier is computed static const unsigned int MODIFIER_INTERVAL = 60; -static const unsigned int MODIFIER_INTERVAL_TESTNET = 60; -extern unsigned int nModifierInterval; -extern unsigned int getIntervalVersion(bool fTestNet); // MODIFIER_INTERVAL_RATIO: // ratio of group interval length between the last group and the first group static const int MODIFIER_INTERVAL_RATIO = 3; // Compute the hash modifier for proof-of-stake +bool GetKernelStakeModifier(const uint256 & hashBlockFrom, uint64_t& nStakeModifier, int& nStakeModifierHeight, int64_t& nStakeModifierTime, bool fPrintProofOfStake); bool ComputeNextStakeModifier(const CBlockIndex* pindexPrev, uint64_t& nStakeModifier, bool& fGeneratedStakeModifier); +uint256 ComputeStakeModifier(const CBlockIndex* pindexPrev, const uint256& kernel); +bool Stake(const CBlockIndex* pindexPrev, CStakeInput* stakeInput, unsigned int nBits, unsigned int& nTimeTx, uint256& hashProofOfStake); -// Check whether stake kernel meets hash target -// Sets hashProofOfStake on success return -uint256 stakeHash(unsigned int nTimeTx, CDataStream ss, unsigned int prevoutIndex, uint256 prevoutHash, unsigned int nTimeBlockFrom); -bool stakeTargetHit(uint256 hashProofOfStake, int64_t nValueIn, uint256 bnTargetPerCoinDay); -bool CheckStakeKernelHash(unsigned int nBits, const CBlock blockFrom, const CTransaction txPrev, const COutPoint prevout, unsigned int& nTimeTx, unsigned int nHashDrift, bool fCheck, uint256& hashProofOfStake, bool fPrintProofOfStake = false); +// Initialize the stake input object +bool initStakeInput(const CBlock block, std::unique_ptr& stake, int nPreviousBlockHeight); // 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, std::unique_ptr& stake, int nPreviousBlockHeight); -// Check whether the coinstake timestamp meets protocol -bool CheckCoinStakeTimestamp(int64_t nTimeBlock, int64_t nTimeTx); +bool CheckStakeKernelHash(const CBlockIndex* pindexPrev, const unsigned int nBits, CStakeInput* stake, const unsigned int nTimeTx, uint256& hashProofOfStake, const bool fVerify = false); +// Returns the proof of stake hash +bool GetHashProofOfStake(const CBlockIndex* pindexPrev, CStakeInput* stake, const unsigned int nTimeTx, const bool fVerify, uint256& hashProofOfStakeRet); // Get stake modifier checksum unsigned int GetStakeModifierChecksum(const CBlockIndex* pindex); @@ -40,7 +39,4 @@ unsigned int GetStakeModifierChecksum(const CBlockIndex* pindex); // Check stake modifier hard checkpoints bool CheckStakeModifierCheckpoints(int nHeight, unsigned int nStakeModifierChecksum); -// Get time weight using supplied timestamps -int64_t GetWeight(int64_t nIntervalBeginning, int64_t nIntervalEnd); - #endif // BITCOIN_KERNEL_H 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..8305f03 --- 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,23 @@ #include "ui_interface.h" #include "util.h" #include "utilmoneystr.h" -#include "versionbits.h" #include "validationinterface.h" +#include "primitives/block.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 +103,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 +136,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 +217,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 +229,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; + + 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; - // 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. + 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 +603,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 +757,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 +1130,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 +1146,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 +1171,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 +1196,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 +1223,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 +1261,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 +1307,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 +1318,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 +1386,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 +1401,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 +1442,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 +1451,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 +1542,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 +1562,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 +1588,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 +1653,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 +1662,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 +1698,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 +1729,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,9 +1737,19 @@ 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); + + // As zero fee transactions are not going to be accepted in the near future (4.0) and the code will be fully refactored soon. + // This is just a quick inline towards that goal, the mempool by default will not accept them. Blocking + // any subsequent network relay. + if ((Params().NetworkID() != CBaseChainParams::REGTEST) && + nFees == 0) { + return error("%s: zero fees not accepted %s, %d > %d", + __func__, hash.ToString(), nFees, ::minRelayTxFee.GetFee(nSize) * 10000); - + } unsigned int scriptVerifyFlags = STANDARD_SCRIPT_VERIFY_FLAGS; if (!Params().RequireStandard()) { @@ -1739,12 +1758,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 +1779,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 +1846,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 +1867,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 +1929,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 +1971,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 +1999,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 +2007,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()); } @@ -2143,7 +2162,7 @@ bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex) if (!ReadBlockFromDisk(block, pindex->GetBlockPos())) return false; if (block.GetHash() != pindex->GetBlockHash()) { - LogPrintf("%s : block=%s index=%s\n", __func__, block.GetHash().ToString().c_str(), pindex->GetBlockHash().ToString().c_str()); + LogPrintf("%s : block=%s index=%s\n", __func__, block.GetHash().GetHex(), pindex->GetBlockHash().GetHex());; return error("ReadBlockFromDisk(CBlock&, CBlockIndex*) : GetHash() doesn't match index"); } return true; @@ -2155,7 +2174,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 +2190,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 +2254,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 +2324,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 +2379,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 +2390,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 +2422,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 +2463,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 +2476,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 +2491,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 +2545,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 +2588,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 +2660,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 +2769,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; @@ -3085,7 +2864,7 @@ bool UpdateZOHMCSupply(const CBlock& block, CBlockIndex* pindex) 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); } @@ -3182,7 +2961,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin // verify that the view's current state corresponds to the previous block uint256 hashPrevBlock = pindex->pprev == NULL ? uint256(0) : pindex->pprev->GetBlockHash(); if (hashPrevBlock != view.GetBestBlock()) - LogPrintf("%s: hashPrev=%s view=%s\n", __func__, hashPrevBlock.ToString().c_str(), view.GetBestBlock().ToString().c_str()); + LogPrintf("%s: hashPrev=%s view=%s\n", __func__, hashPrevBlock.GetHex(), view.GetBestBlock().GetHex());; assert(hashPrevBlock == view.GetBestBlock()); // Special case for the genesis block, skipping connection of its transactions @@ -3194,11 +2973,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 +2995,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 +3028,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 +3068,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 +3089,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 +3121,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,7 +3147,7 @@ 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); @@ -3398,7 +3161,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin 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 +3177,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 +3263,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) { @@ -3570,24 +3333,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 +3385,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 +3736,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 +3813,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 +3826,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); } } @@ -4193,15 +3955,19 @@ CBlockIndex* AddToBlockIndex(const CBlock& block) pindexNew->hashProofOfStake = mapProofOfStake[hash]; } - // ppcoin: compute stake modifier - uint64_t nStakeModifier = 0; - bool fGeneratedStakeModifier = false; - if (!ComputeNextStakeModifier(pindexNew->pprev, nStakeModifier, fGeneratedStakeModifier)) - LogPrintf("AddToBlockIndex() : ComputeNextStakeModifier() failed \n"); - pindexNew->SetStakeModifier(nStakeModifier, fGeneratedStakeModifier); - pindexNew->nStakeModifierChecksum = GetStakeModifierChecksum(pindexNew); - if (!CheckStakeModifierCheckpoints(pindexNew->nHeight, pindexNew->nStakeModifierChecksum)) - LogPrintf("AddToBlockIndex() : Rejected by stake modifier checkpoint height=%d, modifier=%s \n", pindexNew->nHeight, std::to_string(nStakeModifier)); + if (!Params().IsStakeModifierV2(pindexNew->nHeight)) { + uint64_t nStakeModifier = 0; + bool fGeneratedStakeModifier = false; + if (!ComputeNextStakeModifier(pindexNew->pprev, nStakeModifier, fGeneratedStakeModifier)) + LogPrintf("AddToBlockIndex() : ComputeNextStakeModifier() failed \n"); + pindexNew->SetStakeModifier(nStakeModifier, fGeneratedStakeModifier); + pindexNew->nStakeModifierChecksum = GetStakeModifierChecksum(pindexNew); + if (!CheckStakeModifierCheckpoints(pindexNew->nHeight, pindexNew->nStakeModifierChecksum)) + LogPrintf("AddToBlockIndex() : Rejected by stake modifier checkpoint height=%d, modifier=%s \n", pindexNew->nHeight, std::to_string(nStakeModifier)); + } else { + // compute v2 stake modifier + pindexNew->nStakeModifierV2 = ComputeStakeModifier(pindexNew->pprev, block.vtx[1].vin[0].prevout.hash); + } } pindexNew->nChainWork = (pindexNew->pprev ? pindexNew->pprev->nChainWork : 0) + GetBlockProof(*pindexNew); pindexNew->RaiseValidity(BLOCK_VALID_TREE); @@ -4347,7 +4113,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; } @@ -4356,17 +4122,22 @@ static int GetWitnessCommitmentIndex(const CBlock& block); bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bool fCheckMerkleRoot, bool fCheckSig) { // These are checks that are independent of context. + const bool IsPoS = block.IsProofOfStake(); + LogPrint("debug", "%s: block=%s is proof of stake=%d\n", __func__, block.GetHash().ToString().c_str(), IsPoS); // Check that the header is valid (particularly PoW). This is mostly // 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); + if (!CheckBlockHeader(block, state, !IsPoS)) + return state.DoS(100, error("%s : CheckBlockHeader failed", __func__), REJECT_INVALID, "bad-header", true); + + // All potential-corruption validation must be done before we do any + // transaction validation, as otherwise we may mark the header as invalid + // because we receive the wrong transactions for it. // 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"), + if (Params().NetworkID() != CBaseChainParams::REGTEST && + block.GetBlockTime() > Params().MaxFutureBlockTime(GetAdjustedTime(), IsPoS)) // 3 minute future drift for PoS + return state.Invalid(error("%s : block timestamp too far in the future", __func__), REJECT_INVALID, "time-too-new"); // Check the merkle root. @@ -4374,38 +4145,32 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo bool mutated; uint256 hashMerkleRoot2 = block.BuildMerkleTree(&mutated); if (block.hashMerkleRoot != hashMerkleRoot2) - return state.DoS(100, error("CheckBlock() : hashMerkleRoot mismatch"), - REJECT_INVALID, "bad-txnmrklroot", true); + return state.DoS(100, error("%s : hashMerkleRoot mismatch", __func__), + 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); + return state.DoS(100, error("%s : duplicate transaction", __func__), + REJECT_INVALID, "bad-txns-duplicate", true); } - // All potential-corruption validation must be done before we do any - // transaction validation, as otherwise we may mark the header as invalid - // because we receive the wrong transactions for it. - // Note that witness malleability is checked in ContextualCheckBlock, so no - // checks that use witness data may be performed here. - // 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"); + return state.DoS(100, error("%s : size limits failed", __func__), + 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"); + return state.DoS(100, error("%s : first tx is not coinbase", __func__), + 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"); + return state.DoS(100, error("%s : more than one coinbase", __func__), + REJECT_INVALID, "bad-cb-multiple"); - if (block.IsProofOfStake()) { + if (IsPoS) { int commitpos = GetWitnessCommitmentIndex(block); if (commitpos >= 0) { if (IsSporkActive(SPORK_21_SEGWIT_ON_COINBASE)) { @@ -4424,14 +4189,14 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo } // Coinbase output should be empty if proof-of-stake block if (!block.vtx[0].vout[0].IsEmpty()) - return state.DoS(100, error("CheckBlock() : coinbase output not empty for proof-of-stake block")); + return state.DoS(100, error("%s : coinbase output not empty for proof-of-stake block", __func__)); // Second transaction must be coinstake, the rest must not be if (block.vtx.empty() || !block.vtx[1].IsCoinStake()) - return state.DoS(100, error("CheckBlock() : second tx is not coinstake")); + return state.DoS(100, error("%s : second tx is not coinstake", __func__)); for (unsigned int i = 2; i < block.vtx.size(); i++) if (block.vtx[i].IsCoinStake()) - return state.DoS(100, error("CheckBlock() : more than one coinstake")); + return state.DoS(100, error("%s : more than one coinstake", __func__)); } // ----------- swiftTX transaction scanning ----------- @@ -4443,16 +4208,17 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo if (mapLockedInputs.count(in.prevout)) { if (mapLockedInputs[in.prevout] != tx.GetHash()) { 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"); + LogPrintf("%s : found conflicting transaction with transaction lock %s %s\n", __func__, + mapLockedInputs[in.prevout].ToString(), tx.GetHash().GetHex()); + return state.DoS(0, error("%s : found conflicting transaction with transaction lock", __func__), + REJECT_INVALID, "conflicting-tx-ix"); } } } } } } else { - LogPrintf("CheckBlock() : skipping transaction locking checks\n"); + LogPrintf("%s : skipping transaction locking checks\n", __func__); } // karmanode payments / budgets @@ -4476,12 +4242,12 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo if (nHeight != 0 && !IsInitialBlockDownload()) { 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"); + return state.DoS(0, error("%s : Couldn't find karmanode/budget payment", __func__), + REJECT_INVALID, "bad-cb-payee"); } } else { if (fDebug) - LogPrintf("CheckBlock(): Karmanode payment check skipped on sync - skipping IsBlockPayeeValid()\n"); + LogPrintf("%s: karmanode payment check skipped on sync - skipping IsBlockPayeeValid()\n", __func__); } } @@ -4491,8 +4257,8 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo nSigOps += GetLegacySigOpCount(tx); } 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); + return state.DoS(100, error("%s : out-of-bounds SigOpCount", __func__), + REJECT_INVALID, "bad-blk-sigops", true); return true; } @@ -4512,23 +4278,10 @@ bool CheckWork(const CBlock block, CBlockIndex* const pindexPrev) if (block.nBits != nBitsRequired) return error("%s: incorrect proof of work at %d", __func__, pindexPrev->nHeight + 1); - if (block.IsProofOfStake()) { - uint256 hashProofOfStake; - uint256 hash = block.GetHash(); - - if(!CheckProofOfStake(block, hashProofOfStake)) { - LogPrintf("WARNING: ProcessBlock(): check proof-of-stake failed for block %s\n", hash.ToString().c_str()); - return false; - } - if(!mapProofOfStake.count(hash)) // add to mapProofOfStake - mapProofOfStake.insert(make_pair(hash, hashProofOfStake)); - } return true; } -bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex* const pindexPrev) -{ - const Consensus::Params& consensus = Params().GetConsensus(); +bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex* const pindexPrev) { uint256 hash = block.GetHash(); if (hash == Params().HashGenesisBlock()) @@ -4541,14 +4294,12 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta //If this is a reorg, check that it is not too deep int nMaxReorgDepth = GetArg("-maxreorg", Params().MaxReorganizationDepth()); if (chainActive.Height() - nHeight >= nMaxReorgDepth) - return state.DoS(1, error("%s: forked chain older than max reorganization depth (height %d)", __func__, nHeight)); + return state.DoS(1, + error("%s: forked chain older than max reorganization depth (height %d)", __func__, nHeight)); - // Check timestamp against prev - 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"); - } + // Check blocktime against prev (WANT: blk_time > MedianTimePast) + if (Params().NetworkID() != CBaseChainParams::REGTEST && block.GetBlockTime() <= pindexPrev->GetMedianTimePast()) + return state.DoS(50, error("%s : block timestamp too old", __func__), REJECT_INVALID, "time-too-old"); // Check that the block chain matches the known block chain up to a checkpoint if (!Checkpoints::CheckBlock(nHeight, hash)) @@ -4556,35 +4307,15 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta REJECT_CHECKPOINT, "checkpoint mismatch"); // Don't accept any forks from the main chain prior to last checkpoint - CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint(); + CBlockIndex *pcheckpoint = Checkpoints::GetLastCheckpoint(); if (pcheckpoint && nHeight < pcheckpoint->nHeight) 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())) { - return state.Invalid(error("%s : rejected nVersion=1 block", __func__), - REJECT_OBSOLETE, "bad-version"); - } - - // Reject block.nVersion=2 blocks when 95% (75% on testnet) of the network has upgraded: - if (block.nVersion < 3 && 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 block.nVersion=1, ..., CURRENT_VERSION-1 blocks when 95% (75% on testnet) of the network has upgraded: + for (int version = 2; version <= CBlockHeader::CURRENT_VERSION; version++) { + if (block.nVersion < version && CBlockIndex::IsSuperMajority(version, pindexPrev, Params().RejectBlockOutdatedMajority())) { + return state.Invalid(error("%s : rejected nVersion=%d block", __func__, block.nVersion), REJECT_OBSOLETE, "bad-version"); + } } return true; @@ -4679,16 +4410,16 @@ 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) { if (!CheckTransaction(tx, true, chainActive.Height() + 1 >= Params().Zerocoin_StartHeight(), state, GetSporkValue(SPORK_20_SEGWIT_ACTIVATION) < block.nTime)) - return error("CheckBlock() : CheckTransaction failed"); + return error("%s : CheckTransaction failed", __func__); // double check that there are no double spent zOHMC spends in this block if (tx.IsZerocoinSpend()) { @@ -4706,14 +4437,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 +4466,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)) { @@ -4813,7 +4544,7 @@ bool AcceptBlockHeader(const CBlock& block, CValidationState& state, CBlockIndex if (hash != Params().HashGenesisBlock()) { BlockMap::iterator mi = mapBlockIndex.find(block.hashPrevBlock); if (mi == mapBlockIndex.end()) - return state.DoS(0, error("%s : prev block %s not found", __func__, block.hashPrevBlock.ToString().c_str()), 0, "bad-prevblk"); + return state.DoS(0, error("%s : prev block %s not found", __func__, block.hashPrevBlock.GetHex()), 0, "bad-prevblk"); pindexPrev = (*mi).second; if (pindexPrev->nStatus & BLOCK_FAILED_MASK) { //If this "invalid" block is an exact match from the checkpoints, then reconsider it @@ -4856,7 +4587,7 @@ bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex** ppindex, if (block.GetHash() != Params().HashGenesisBlock()) { BlockMap::iterator mi = mapBlockIndex.find(block.hashPrevBlock); if (mi == mapBlockIndex.end()) - return state.DoS(0, error("%s : prev block %s not found", __func__, block.hashPrevBlock.ToString().c_str()), 0, "bad-prevblk"); + return state.DoS(0, error("%s : prev block %s not found", __func__, block.hashPrevBlock.GetHex()), 0, "bad-prevblk"); pindexPrev = (*mi).second; if (pindexPrev->nStatus & BLOCK_FAILED_MASK) { //If this "invalid" block is an exact match from the checkpoints, then reconsider it @@ -4877,12 +4608,30 @@ bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex** ppindex, if (block.GetHash() != Params().HashGenesisBlock() && !CheckWork(block, pindexPrev)) return false; + bool isPoS = false; + if (block.IsProofOfStake()) { + isPoS = true; + uint256 hashProofOfStake = 0; + std::unique_ptr stake; + + if (!CheckProofOfStake(block, hashProofOfStake, stake, pindexPrev->nHeight)) + return state.DoS(100, error("%s: proof of stake check failed", __func__)); + + if (!stake) + return error("%s: null stake ptr", __func__); + + uint256 hash = block.GetHash(); + if(!mapProofOfStake.count(hash)) // add to mapProofOfStake + mapProofOfStake.insert(std::make_pair(hash, hashProofOfStake)); + } + if (!AcceptBlockHeader(block, state, &pindex)) return false; if (pindex->nStatus & BLOCK_HAVE_DATA) { // TODO: deal better with duplicate blocks. // return state.DoS(20, error("AcceptBlock() : already have block %d %s", pindex->nHeight, pindex->GetBlockHash().ToString()), REJECT_DUPLICATE, "duplicate"); + LogPrintf("AcceptBlock() : already have block %d %s", pindex->nHeight, pindex->GetBlockHash().ToString()); return true; } @@ -4896,50 +4645,71 @@ bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex** ppindex, int nHeight = pindex->nHeight; - if (block.IsProofOfStake()) { + if (isPoS) { LOCK(cs_main); - CCoinsViewCache coins(pcoinsTip); + // Blocks arrives in order, so if prev block is not the tip then we are on a fork. + // Extra info: duplicated blocks are skipping this checks, so we don't have to worry about those here. + bool isBlockFromFork = pindexPrev != nullptr && chainActive.Tip() != pindexPrev; - if (!coins.HaveInputs(block.vtx[1])) { - // the inputs are spent at the chain tip so we should look at the recently spent outputs + // Coin stake + CTransaction &stakeTxIn = block.vtx[1]; - for (CTxIn in : block.vtx[1].vin) { - auto it = mapStakeSpent.find(in.prevout); - if (it == mapStakeSpent.end()) { - return false; - } - if (it->second < pindexPrev->nHeight) { - return false; - } - } + // Inputs + std::vector phrInputs; + + for (const CTxIn& stakeIn : stakeTxIn.vin) { + phrInputs.push_back(stakeIn); } + const bool hasPHRInputs = !phrInputs.empty(); + + // Check whether is a fork or not + if (isBlockFromFork) { + + // Start at the block we're adding on to + CBlockIndex *prev = pindexPrev; + + CBlock bl; + if (!ReadBlockFromDisk(bl, prev)) + return error("%s: previous block %s not on disk", __func__, prev->GetBlockHash().GetHex()); + + std::vector vBlockSerials; + int readBlock = 0; + // Go backwards on the forked chain up to the split + while (!chainActive.Contains(prev)) { - // if this is on a fork - if (!chainActive.Contains(pindexPrev) && pindexPrev != NULL) { - // start at the block we're adding on to - CBlockIndex *last = pindexPrev; - - // while that block is not on the main chain - while (!chainActive.Contains(last) && last != NULL) { - CBlock bl; - ReadBlockFromDisk(bl, last); - // loop through every spent input from said block - for (CTransaction t : bl.vtx) { - for (CTxIn in: t.vin) { - // loop through every spent input in the staking transaction of the new block - for (CTxIn stakeIn : block.vtx[1].vin) { - // if they spend the same input - if (stakeIn.prevout == in.prevout) { - // reject the block - return false; + // Increase amount of read blocks + readBlock++; + // Check if the forked chain is longer than the max reorg limit + if (readBlock == Params().MaxReorganizationDepth()) { + // TODO: Remove this chain from disk. + return error("%s: forked chain longer than maximum reorg limit", __func__); + } + + // Loop through every input from said block + for (const CTransaction &t : bl.vtx) { + for (const CTxIn &in: t.vin) { + // Loop through every input of the staking tx + for (const CTxIn &stakeIn : phrInputs) { + // if it's already spent + + // First regular staking check + if (hasPHRInputs) { + if (stakeIn.prevout == in.prevout) { + return state.DoS(100, error("%s: input already spent on a previous block", + __func__)); + } } } } } - // go to the parent block - last = last->pprev; + // Prev block + prev = prev->pprev; + if (!ReadBlockFromDisk(bl, prev)) + // Previous block not on disk + return error("%s: previous block %s not on disk", __func__, prev->GetBlockHash().GetHex()); + } } } @@ -5027,36 +4797,6 @@ void CBlockIndex::BuildSkip() bool ProcessNewBlock(CValidationState& state, CNode* pfrom, CBlock* pblock, CDiskBlockPos* dbp) { - // Preliminary checks - int64_t nStartTime = GetTimeMillis(); - bool checked = CheckBlock(*pblock, state); - - int nMints = 0; - int nSpends = 0; - for (const CTransaction tx : pblock->vtx) { - if (tx.ContainsZerocoins()) { - for (const CTxIn in : tx.vin) { - if (in.scriptSig.IsZerocoinSpend()) - nSpends++; - } - for (const CTxOut out : tx.vout) { - if (out.IsZerocoinMint()) - nMints++; - } - } - } - if (nMints || nSpends) - LogPrintf("%s : block contains %d zOHMC mints and %d zOHMC spends\n", __func__, nMints, nSpends); - - // ppcoin: check proof-of-stake - // Limited duplicity on stake: prevents block flood attack - // Duplicate stake allowed only when there is orphan child block - //if (pblock->IsProofOfStake() && setStakeSeen.count(pblock->GetProofOfStake())/* && !mapOrphanBlocksByPrev.count(hash)*/) - // return error("ProcessNewBlock() : duplicate proof-of-stake (%s, %d) for block %s", pblock->GetProofOfStake().first.ToString().c_str(), pblock->GetProofOfStake().second, pblock->GetHash().ToString().c_str()); - - // NovaCoin: check proof-of-stake block signature - if (!pblock->CheckBlockSignature()) - return error("ProcessNewBlock() : bad proof-of-stake block signature"); if (pblock->GetHash() != Params().HashGenesisBlock() && pfrom != NULL) { //if we get this far, check if the prev block is our prev block, if not then request sync and return false @@ -5067,17 +4807,26 @@ bool ProcessNewBlock(CValidationState& state, CNode* pfrom, CBlock* pblock, CDis } } + // Preliminary checks + int64_t nStartTime = GetTimeMillis(); + + // check block + bool checked = CheckBlock(*pblock, state); + + if (!pblock->CheckBlockSignature()) + return error("ProcessNewBlock() : bad proof-of-stake block signature"); + { - LOCK(cs_main); // Replaces the former TRY_LOCK loop because busy waiting wastes too much resources + LOCK(cs_main); - MarkBlockAsReceived (pblock->GetHash ()); + MarkBlockAsReceived(pblock->GetHash()); if (!checked) { return error ("%s : CheckBlock FAILED for block %s", __func__, pblock->GetHash().GetHex()); } // Store to disk CBlockIndex* pindex = NULL; - bool ret = AcceptBlock (*pblock, state, &pindex, dbp, checked); + bool ret = AcceptBlock(*pblock, state, &pindex, dbp, checked); if (pindex && pfrom) { mapBlockSource[pindex->GetBlockHash ()] = pfrom->GetId (); } @@ -5109,7 +4858,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 +4866,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 +4888,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 +4972,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 +5022,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 +5064,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 +5296,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 +5315,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 +5336,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 +5364,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 +5564,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 +5591,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 +5712,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 +5929,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 +5975,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 +6015,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 +6026,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 +6163,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 +6438,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 +6537,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 +6552,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 +6652,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 +6676,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 +6692,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 +6789,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 +6863,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 +6999,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 +7082,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 +7100,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..03bb231 100755 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin developers -// Copyright (c) 2012-2013 The PPCoin developers // Copyright (c) 2014-2015 The Dash developers +// Copyright (c) 2012-2013 The PPCoin developers // Copyright (c) 2015-2017 The PIVX developers // Copyright (c) 2017 The Ohmcoin developers // Distributed under the MIT/X11 software license, see the accompanying @@ -32,7 +32,6 @@ #include #include -using namespace std; ////////////////////////////////////////////////////////////////////////////// // @@ -51,7 +50,7 @@ class COrphan { public: const CTransaction* ptx; - set setDependsOn; + std::set setDependsOn; CFeeRate feeRate; double dPriority; @@ -102,15 +101,32 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn, CWallet* pwallet, CReserveKey reservekey(pwallet); // Create new block - unique_ptr pblocktemplate(new CBlockTemplate()); + std::unique_ptr pblocktemplate(new CBlockTemplate()); if (!pblocktemplate.get()) return NULL; CBlock* pblock = &pblocktemplate->block; // pointer for convenience + CBlockIndex* pindexPrev = chainActive.Tip(); + + // Make sure to create the correct block version after zerocoin is enabled + bool fZerocoinActive = chainActive.Height() >= Params().Zerocoin_StartHeight(); + if(Params().IsStakeModifierV2(pindexPrev->nHeight + 1)) { + pblock->nVersion = 5; //!> Supports V2 Stake Modifiers. + } else if (fZerocoinActive) { + pblock->nVersion = 4; + } else { + pblock->nVersion = 3; + } + // -regtest only: allow overriding block.nVersion with // -blockversion=N to test forking scenarios - if (Params().MineBlocksOnDemand()) + if (Params().MineBlocksOnDemand()) { + if (fZerocoinActive) + pblock->nVersion = 4; + else + pblock->nVersion = 3; pblock->nVersion = GetArg("-blockversion", pblock->nVersion); + } // Decide whether to include witness transactions // This is only needed in case the witness softfork activation is reverted @@ -120,18 +136,8 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn, CWallet* pwallet, // transaction (which in most cases can be a no-op). bool fIncludeWitness = IsSporkActive(SPORK_20_SEGWIT_ACTIVATION); - // Blocktime and Reward update. - bool fEnforceBlockTimeUpdate = IsSporkActive(SPORK_23_NEW_BLOCKTIME_ENFORCEMENT); - bool fUpgradeActiveV3 = Params().GetConsensus().NetworkUpgradeActive(chainActive.Tip()->nHeight, Consensus::UPGRADE_V3_0_BLOCKTIME); - bool fZerocoinActive = false; // we don't have zerocoin... TODO: Remove! - if (!fUpgradeActiveV3) { - pblock->nVersion = 5; - } else { - if (!fEnforceBlockTimeUpdate) { - pblock->nVersion = 6; - } - } + // Create coinbase tx CMutableTransaction txNew; @@ -149,7 +155,6 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn, CWallet* pwallet, if (fProofOfStake) { boost::this_thread::interruption_point(); pblock->nTime = GetAdjustedTime(); - CBlockIndex* pindexPrev = chainActive.Tip(); pblock->nBits = GetNextWorkRequired(pindexPrev, pblock); CMutableTransaction txCoinStake; int64_t nSearchTime = pblock->nTime; // search to current time @@ -166,8 +171,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 @@ -216,16 +223,16 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn, CWallet* pwallet, CCoinsViewCache view(pcoinsTip); // Priority order to process transactions - list vOrphan; // list memory doesn't move - map > mapDependers; + std::list vOrphan; // list memory doesn't move + std::map > mapDependers; bool fPrintPriority = GetBoolArg("-printpriority", false); int64_t nBlockSigOpsCost = 400; // This vector will be sorted into a priority queue: - vector vecPriority; + std::vector vecPriority; vecPriority.reserve(mempool.mapTx.size()); - for (map::iterator mi = mempool.mapTx.begin(); + for (std::map::iterator mi = mempool.mapTx.begin(); mi != mempool.mapTx.end(); ++mi) { const CTransaction& tx = mi->second.GetTx(); if (tx.IsCoinBase() || tx.IsCoinStake() || !IsFinalTx(tx, nHeight)){ @@ -255,8 +262,8 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn, CWallet* pwallet, nTotalIn = tx.GetZerocoinSpent(); //Give a high priority to zerocoinspends to get into the next block - //Priority = (age^6+100000)*amount - gives higher priority to zphrs that have been in mempool long - //and higher priority to zphrs that are large in value + //Priority = (age^6+100000)*amount - gives higher priority to zOHMCs that have been in mempool long + //and higher priority to zOHMCs that are large in value int64_t nTimeSeen = GetAdjustedTime(); double nConfs = 100000; @@ -343,8 +350,8 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn, CWallet* pwallet, TxPriorityCompare comparer(fSortedByFee); std::make_heap(vecPriority.begin(), vecPriority.end(), comparer); - vector vBlockSerials; - vector vTxSerials; + std::vector vBlockSerials; + std::vector vTxSerials; while (!vecPriority.empty()) { // Take highest priority transaction off the priority queue: double dPriority = vecPriority.front().get<0>(); @@ -364,6 +371,14 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn, CWallet* pwallet, if (nBlockCost + nTxCost >= nBlockMaxCost) continue; + // Legacy limits on sigOps: + int64_t nTxSigOpsCost = GetLegacySigOpCount(tx); + if (nBlockSigOpsCost + nTxSigOpsCost >= MAX_BLOCK_SIGOPS_COST) + continue; + + nBlockSigOpsCost += nTxSigOpsCost; + pblocktemplate->vTxSigOpsCost.push_back(nTxSigOpsCost); + // Skip free transactions if we're past the minimum block size: const uint256& hash = tx.GetHash(); double dPriorityDelta = 0; @@ -384,22 +399,22 @@ 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; if (!spend.HasValidSerial(GetZerocoinParams(effectiveHeight))) fDoubleSerial = true; - if (count(vBlockSerials.begin(), vBlockSerials.end(), spend.getCoinSerialNumber())) + if (std::count(vBlockSerials.begin(), vBlockSerials.end(), spend.getCoinSerialNumber())) fDoubleSerial = true; - if (count(vTxSerials.begin(), vTxSerials.end(), spend.getCoinSerialNumber())) + if (std::count(vTxSerials.begin(), vTxSerials.end(), spend.getCoinSerialNumber())) fDoubleSerial = true; if (fDoubleSerial) break; @@ -416,8 +431,9 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn, CWallet* pwallet, // Note that flags: we don't want to set mempool/IsStandard() // 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 +447,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) { @@ -460,12 +476,16 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn, CWallet* pwallet, //Make payee if (txNew.vout.size() > 1) { pblock->payee = txNew.vout[1].scriptPubKey; + } else { + CAmount blockValue = nFees + GetBlockValue(pindexPrev->nHeight); + txNew.vout[0].nValue = blockValue; + txNew.vin[0].scriptSig = CScript() << nHeight << OP_0; } } nLastBlockTx = nBlockTx; nLastBlockCost = nBlockCost; - LogPrintf("CreateNewBlock(): total size %u txs: %u fees: %ld sigopscost %d\n", nBlockCost, nBlockTx, nFees, nBlockSigOpsCost); + LogPrintf("CreateNewBlock(): total size %u\n", nBlockSize); // Compute final coinbase transaction. if (!fProofOfStake) { @@ -502,14 +522,35 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn, CWallet* pwallet, } } } - pblock->nAccumulatorCheckpoint = pCheckpointCache.second.second; } + + pblock->nAccumulatorCheckpoint = pCheckpointCache.second.second; + pblocktemplate->vTxSigOpsCost[0] = WITNESS_SCALE_FACTOR * GetLegacySigOpCount(pblock->vtx[0]); + if (fProofOfStake) { + if (! IsSporkActive(SPORK_21_SEGWIT_ON_COINBASE)) { + bool fHaveWitness = false; + for (size_t t = 1; t < pblock->vtx.size(); t++) { + if (!pblock->vtx[t].wit.IsNull()) { + fHaveWitness = true; + break; + } + } + if (fHaveWitness) { + if (fDebug) { + LogPrintf("CreateNewBlock : staking-on-segwit block found but the feature is not enabled.\n"); + } + return NULL; + } + } + } + CValidationState state; if (!TestBlockValidity(state, *pblock, pindexPrev, false, false)) { + LogPrintf("CreateNewBlock() : TestBlockValidity failed\n"); mempool.clear(); - throw std::runtime_error(strprintf("%s: TestBlockValidity failed: %s", __func__, state.GetRejectReason())); + return NULL; } } @@ -545,8 +586,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); @@ -585,14 +637,13 @@ bool ProcessBlockFound(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey) node->PushInventory(CInv(MSG_BLOCK, pblock->GetHash())); } - for (CNode* node : vNodes) { - node->PushInventory(CInv(MSG_BLOCK, pblock->GetHash())); - } - return true; } 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,16 +660,28 @@ 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 +692,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 // @@ -682,7 +751,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); @@ -753,13 +822,13 @@ void static ThreadBitcoinMiner(void* parg) try { BitcoinMiner(pwallet, false); boost::this_thread::interruption_point(); - } catch (std::exception& e) { - LogPrintf("ThreadBitcoinMiner() exception"); + } catch (const std::exception& e) { + 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) @@ -798,9 +867,8 @@ void ThreadStakeMinter() try { BitcoinMiner(pwallet, true); boost::this_thread::interruption_point(); - } catch (std::exception& e) { + } catch (const std::exception& e) { LogPrintf("ThreadStakeMinter() exception \n"); - ThreadStakeMinter(); } catch (...) { LogPrintf("ThreadStakeMinter() error \n"); } 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.cpp b/src/primitives/block.cpp index 69c89b8..f28ea3f 100755 --- a/src/primitives/block.cpp +++ b/src/primitives/block.cpp @@ -140,6 +140,7 @@ void CBlock::print() const LogPrintf("%s", ToString()); } + // ppcoin: sign block bool CBlock::SignBlock(const CKeyStore& keystore) { @@ -301,7 +302,6 @@ bool CBlock::CheckBlockSignature() const return false; } - int64_t GetBlockCost(const CBlock& block) { // This implements the cost = (stripped_size * 4) + witness_size formula, diff --git a/src/primitives/block.h b/src/primitives/block.h index 6a07e08..61398bf 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 @@ -148,9 +150,6 @@ class CBlock : public CBlockHeader return !IsProofOfStake(); } - bool SignBlock(const CKeyStore& keystore); - bool CheckBlockSignature() const; - std::pair GetProofOfStake() const { return IsProofOfStake()? std::make_pair(vtx[1].vin[0].prevout, nTime) : std::make_pair(COutPoint(), (unsigned int)0); @@ -162,6 +161,9 @@ class CBlock : public CBlockHeader // merkle root). uint256 BuildMerkleTree(bool* mutated = NULL) const; + bool SignBlock(const CKeyStore& keystore); + bool CheckBlockSignature() const; + std::vector GetMerkleBranch(int nIndex) const; static uint256 CheckMerkleBranch(uint256 hash, const std::vector& vMerkleBranch, int nIndex); std::string ToString() const; 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..10b3e53 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" @@ -275,8 +275,8 @@ QString TransactionDesc::toHTML(CWallet* wallet, CWalletTx& wtx, TransactionReco } if (wtx.IsCoinBase()) { - quint32 numBlocksToMaturity = Params().COINBASE_MATURITY() + 1; - strHTML += "
" + tr("Generated coins must mature %1 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, its state will change to \"not accepted\" and it won't be spendable. This may occasionally happen if another node generates a block within a few seconds of yours.").arg(QString::number(numBlocksToMaturity)) + "
"; + //quint32 numBlocksToMaturity = Params().COINBASE_MATURITY() + 1; + //strHTML += "
" + tr("Generated coins must mature %1 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, its state will change to \"not accepted\" and it won't be spendable. This may occasionally happen if another node generates a block within a few seconds of yours.").arg(QString::number(numBlocksToMaturity)) + "
"; } // 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..9ca5fa0 100755 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -8,6 +8,7 @@ #include "base58.h" #include "checkpoints.h" #include "clientversion.h" +#include "kernel.h" #include "consensus/validation.h" #include "consensus/upgrades.h" #include "main.h" @@ -137,6 +138,7 @@ UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool tx result.push_back(Pair("modifier", strprintf("%16x", blockindex->nStakeModifier))); result.push_back(Pair("modifierchecksum", strprintf("%08x", GetStakeModifierChecksum(blockindex)))); + result.push_back(Pair("modifierV2", blockindex->nStakeModifierV2.GetHex())); result.push_back(Pair("moneysupply",ValueFromAmount(blockindex->nMoneySupply))); UniValue zohmcObj(UniValue::VOBJ); @@ -742,16 +744,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/spork.cpp b/src/spork.cpp index 978516b..ffa9191 100755 --- a/src/spork.cpp +++ b/src/spork.cpp @@ -137,6 +137,7 @@ int64_t GetSporkValue(int nSporkID) if (nSporkID == SPORK_21_SEGWIT_ON_COINBASE) r = SPORK_21_SEGWIT_ON_COINBASE_DEFAULT; if (nSporkID == SPORK_22_ZEROCOIN_MAINTENANCE_MODE) r = SPORK_22_ZEROCOIN_MAINTENANCE_MODE_DEFAULT; if (nSporkID == SPORK_23_NEW_BLOCKTIME_ENFORCEMENT) r = SPORK_23_NEW_BLOCKTIME_ENFORCEMENT_DEFAULT; + if (nSporkID == SPORK_24_KERNEL_EXTRA_STAKING_CHECK) r = SPORK_24_KERNEL_EXTRA_STAKING_CHECK_DEFAULT; if (r == -1) LogPrintf("GetSpork::Unknown Spork %d\n", nSporkID); @@ -289,6 +290,7 @@ int CSporkManager::GetSporkIDByName(std::string strName) if (strName == "SPORK_21_SEGWIT_ON_COINBASE") return SPORK_21_SEGWIT_ON_COINBASE_DEFAULT; if (strName == "SPORK_22_ZEROCOIN_MAINTENANCE_MODE") return SPORK_22_ZEROCOIN_MAINTENANCE_MODE; if (strName == "SPORK_23_NEW_BLOCKTIME_ENFORCEMENT") return SPORK_23_NEW_BLOCKTIME_ENFORCEMENT; + if (strName == "SPORK_24_KERNEL_EXTRA_STAKING_CHECK") return SPORK_24_KERNEL_EXTRA_STAKING_CHECK; return -1; } @@ -313,5 +315,7 @@ std::string CSporkManager::GetSporkNameByID(int id) if (id == SPORK_21_SEGWIT_ON_COINBASE) return "SPORK_21_SEGWIT_ON_COINBASE"; if (id == SPORK_22_ZEROCOIN_MAINTENANCE_MODE) return "SPORK_22_ZEROCOIN_MAINTENANCE_MODE"; if (id == SPORK_23_NEW_BLOCKTIME_ENFORCEMENT) return "SPORK_23_NEW_BLOCKTIME_ENFORCEMENT"; + if (id == SPORK_24_KERNEL_EXTRA_STAKING_CHECK) return "SPORK_24_KERNEL_EXTRA_STAKING_CHECK"; + return "Unknown"; } diff --git a/src/spork.h b/src/spork.h index 41fcc9a..1530f8f 100755 --- a/src/spork.h +++ b/src/spork.h @@ -27,7 +27,7 @@ using namespace boost; Sporks 11,12, and 16 to be removed with 1st zerocoin release */ #define SPORK_START 10001 -#define SPORK_END 10022 +#define SPORK_END 10023 #define SPORK_2_SWIFTTX 10001 #define SPORK_3_SWIFTTX_BLOCK_FILTERING 10002 @@ -49,6 +49,7 @@ using namespace boost; #define SPORK_21_SEGWIT_ON_COINBASE 10020 #define SPORK_22_ZEROCOIN_MAINTENANCE_MODE 10021 #define SPORK_23_NEW_BLOCKTIME_ENFORCEMENT 10022 +#define SPORK_24_KERNEL_EXTRA_STAKING_CHECK 10023 #define SPORK_2_SWIFTTX_DEFAULT 978307200 //2001-1-1 #define SPORK_3_SWIFTTX_BLOCK_FILTERING_DEFAULT 1424217600 //2015-2-18 @@ -72,6 +73,7 @@ using namespace boost; #define SPORK_22_ZEROCOIN_MAINTENANCE_MODE_DEFAULT 4070908800 //OFF // Sporks that forces new blocktime upgrade and protocol 71020 #define SPORK_23_NEW_BLOCKTIME_ENFORCEMENT_DEFAULT 4070908800 //OFF DEFAULT +#define SPORK_24_KERNEL_EXTRA_STAKING_CHECK_DEFAULT 9999999999 //OFF class CSporkMessage; class CSporkManager; diff --git a/src/stakeinput.cpp b/src/stakeinput.cpp new file mode 100644 index 0000000..0e11cb3 --- /dev/null +++ b/src/stakeinput.cpp @@ -0,0 +1,113 @@ +// Copyright (c) 2017-2019 The PIVX developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "chain.h" +#include "main.h" +#include "stakeinput.h" +#include "wallet/wallet.h" + +bool COhmStake::SetInput(CTransaction txPrev, unsigned int n) +{ + this->txFrom = txPrev; + this->nPosition = n; + return true; +} + +bool COhmStake::GetTxFrom(CTransaction& tx) +{ + tx = txFrom; + return true; +} + +bool COhmStake::CreateTxIn(CWallet* pwallet, CTxIn& txIn, uint256 hashTxOut) +{ + txIn = CTxIn(txFrom.GetHash(), nPosition); + return true; +} + +CAmount COhmStake::GetValue() +{ + return txFrom.vout[nPosition].nValue; +} + +bool COhmStake::CreateTxOuts(CWallet* pwallet, std::vector& vout, CAmount nTotal) +{ + std::vector vSolutions; + txnouttype whichType; + CScript scriptPubKeyKernel = txFrom.vout[nPosition].scriptPubKey; + if (!Solver(scriptPubKeyKernel, whichType, vSolutions)) { + LogPrintf("CreateCoinStake : failed to parse kernel\n"); + return false; + } + + if (whichType != TX_PUBKEY && whichType != TX_PUBKEYHASH) + return false; // only support pay to public key and pay to address + + CScript scriptPubKey; + if (whichType == TX_PUBKEYHASH) // pay to address type + { + //convert to pay to public key type + CKey key; + CKeyID keyID = CKeyID(uint160(vSolutions[0])); + if (!pwallet->GetKey(keyID, key)) + return false; + + scriptPubKey << key.GetPubKey() << OP_CHECKSIG; + } else + scriptPubKey = scriptPubKeyKernel; + + vout.emplace_back(CTxOut(0, scriptPubKey)); + + // Calculate if we need to split the output + if (nTotal / 2 > (CAmount)(pwallet->nStakeSplitThreshold * COIN)) + vout.emplace_back(CTxOut(0, scriptPubKey)); + + return true; +} + +bool COhmStake::GetModifier(uint64_t& nStakeModifier) +{ + if (this->nStakeModifier == 0) { + // look for the modifier + GetIndexFrom(); + if (!pindexFrom) + return error("%s: failed to get index from", __func__); + // TODO: This method must be removed from here in the short terms.. it's a call to an static method in kernel.cpp when this class method is only called from kernel.cpp, no comments.. + if (!GetKernelStakeModifier(pindexFrom->GetBlockHash(), this->nStakeModifier, this->nStakeModifierHeight, this->nStakeModifierTime, false)) + return error("CheckStakeKernelHash(): failed to get kernel stake modifier"); + } + nStakeModifier = this->nStakeModifier; + + return true; +} + +CDataStream COhmStake::GetUniqueness() +{ + //The unique identifier for a PHR stake is the outpoint + CDataStream ss(SER_NETWORK, 0); + ss << nPosition << txFrom.GetHash(); + return ss; +} + +//The block that the UTXO was added to the chain +CBlockIndex* COhmStake::GetIndexFrom() +{ + if (pindexFrom) + return pindexFrom; + + uint256 hashBlock = 0; + CTransaction tx; + if (GetTransaction(txFrom.GetHash(), tx, hashBlock, true)) { + // If the index is in the chain, then set it as the "index from" + if (mapBlockIndex.count(hashBlock)) { + CBlockIndex* pindex = mapBlockIndex.at(hashBlock); + if (chainActive.Contains(pindex)) + pindexFrom = pindex; + } + } else { + LogPrintf("%s : failed to find tx %s\n", __func__, txFrom.GetHash().GetHex()); + } + + return pindexFrom; +} diff --git a/src/stakeinput.h b/src/stakeinput.h new file mode 100644 index 0000000..ca71b7d --- /dev/null +++ b/src/stakeinput.h @@ -0,0 +1,59 @@ +// Copyright (c) 2017-2019 The PIVX developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef PHORE_STAKEINPUT_H +#define PHORE_STAKEINPUT_H + +class CKeyStore; +class CWallet; +class CWalletTx; + +class CStakeInput +{ +protected: + CBlockIndex* pindexFrom = nullptr; + +public: + virtual ~CStakeInput(){}; + virtual CBlockIndex* GetIndexFrom() = 0; + virtual bool CreateTxIn(CWallet* pwallet, CTxIn& txIn, uint256 hashTxOut = 0) = 0; + virtual bool GetTxFrom(CTransaction& tx) = 0; + virtual CAmount GetValue() = 0; + virtual bool CreateTxOuts(CWallet* pwallet, std::vector& vout, CAmount nTotal) = 0; + virtual bool GetModifier(uint64_t& nStakeModifier) = 0; + virtual CDataStream GetUniqueness() = 0; + + virtual uint64_t getStakeModifierHeight() const { + return 0; + } +}; + +class COhmStake : public CStakeInput +{ +private: + CTransaction txFrom; + unsigned int nPosition; + + // cached data + uint64_t nStakeModifier = 0; + int nStakeModifierHeight = 0; + int64_t nStakeModifierTime = 0; +public: + COhmStake(){} + + bool SetInput(CTransaction txPrev, unsigned int n); + + CBlockIndex* GetIndexFrom() override; + bool GetTxFrom(CTransaction& tx) override; + CAmount GetValue() override; + bool GetModifier(uint64_t& nStakeModifier) override; + CDataStream GetUniqueness() override; + bool CreateTxIn(CWallet* pwallet, CTxIn& txIn, uint256 hashTxOut = 0) override; + bool CreateTxOuts(CWallet* pwallet, vector& vout, CAmount nTotal) override; + + uint64_t getStakeModifierHeight() const override { return nStakeModifierHeight; } +}; + + +#endif //PHORE_STAKEINPUT_H 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..7e5fbda 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) @@ -311,7 +313,11 @@ bool CBlockTreeDB::LoadBlockIndexGuts() pindexNew->nMint = diskindex.nMint; pindexNew->nMoneySupply = diskindex.nMoneySupply; pindexNew->nFlags = diskindex.nFlags; - pindexNew->nStakeModifier = diskindex.nStakeModifier; + if (!Params().IsStakeModifierV2(pindexNew->nHeight)) { + pindexNew->nStakeModifier = diskindex.nStakeModifier; + } else { + pindexNew->nStakeModifierV2 = diskindex.nStakeModifierV2; + } pindexNew->prevoutStake = diskindex.prevoutStake; pindexNew->nStakeTime = diskindex.nStakeTime; pindexNew->hashProofOfStake = diskindex.hashProofOfStake; 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..913f071 100755 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -11,19 +11,24 @@ #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 "stakeinput.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 +78,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 +104,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); - if (!AddKeyPubKey(secret, pubkey)) - throw std::runtime_error("CWallet::GenerateNewKey() : AddKey failed"); + 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 (!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 +310,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 +438,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 +493,6 @@ bool CWallet::Unlock(const SecureString& strWalletPassphrase, bool anonymizeOnly strWalletPassphraseFinal = strWalletPassphrase; - CCrypter crypter; CKeyingMaterial vMasterKey; @@ -482,6 +695,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 +815,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 +828,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 +862,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 +880,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 @@ -2098,38 +2482,32 @@ bool less_then_denom(const COutput& out1, const COutput& out2) return (!found1 && found2); } -bool CWallet::SelectStakeCoins(std::set >& setCoins, CAmount nTargetAmount) const +bool CWallet::SelectStakeCoins(std::list >& listInputs, CAmount nTargetAmount, int blockHeight) const { LOCK(cs_main); //Add OHMC - vector vCoins; + std::vector vCoins; AvailableCoins(vCoins, true, NULL, false, STAKABLE_COINS); CAmount nAmountSelected = 0; - for (const COutput& out : vCoins) { + for (const COutput &out : vCoins) { //make sure not to outrun target amount if (nAmountSelected + out.tx->vout[out.i].nValue > nTargetAmount) continue; - //if zerocoinspend, then use the block time - int64_t nTxTime = out.tx->GetTxTime(); - if (out.tx->IsZerocoinSpend()) { - if (!out.tx->IsInMainChain()) - continue; - nTxTime = mapBlockIndex.at(out.tx->hashBlock)->GetBlockTime(); - } - - //check for min age - if (GetAdjustedTime() - nTxTime < nStakeMinAge) + if (out.tx->IsZerocoinSpend() && !out.tx->IsInMainChain()) continue; - //check that it is matured - if (out.nDepth < (out.tx->IsCoinStake() ? Params().COINBASE_MATURITY() : 10)) + CBlockIndex* utxoBlock = mapBlockIndex.at(out.tx->hashBlock); + //check for maturity (min age/depth) + if (!Params().HasStakeMinAgeOrDepth(blockHeight, GetAdjustedTime(), utxoBlock->nHeight, utxoBlock->GetBlockTime())) continue; //add to our stake set - setCoins.insert(make_pair(out.tx, out.i)); nAmountSelected += out.tx->vout[out.i].nValue; + std::unique_ptr input(new COhmStake()); + input->SetInput((CTransaction) *out.tx, out.i); + listInputs.emplace_back(std::move(input)); } return true; } @@ -2138,6 +2516,9 @@ bool CWallet::MintableCoins() { LOCK(cs_main); CAmount nBalance = GetBalance(); + + int chainHeight = chainActive.Height(); + if (mapArgs.count("-reservebalance") && !ParseMoney(mapArgs["-reservebalance"], nReserveBalance)) return error("MintableCoins() : invalid reserve balance amount"); if (nBalance <= nReserveBalance) @@ -2146,15 +2527,11 @@ bool CWallet::MintableCoins() vector vCoins; AvailableCoins(vCoins, true); + int64_t time = GetAdjustedTime(); for (const COutput& out : vCoins) { - int64_t nTxTime = out.tx->GetTxTime(); - if (out.tx->IsZerocoinSpend()) { - if (!out.tx->IsInMainChain()) - continue; - nTxTime = mapBlockIndex.at(out.tx->hashBlock)->GetBlockTime(); - } - - if (GetAdjustedTime() - nTxTime > nStakeMinAge) + CBlockIndex* utxoBlock = mapBlockIndex.at(out.tx->hashBlock); + //check for maturity (min age/depth) + if (Params().HasStakeMinAgeOrDepth(chainHeight, time, utxoBlock->nHeight, utxoBlock->nTime)) return true; } @@ -2596,7 +2973,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(); @@ -2690,7 +3067,6 @@ bool CWallet::CreateTransaction(const vector >& vecSend, AvailableCoinsType coin_type, bool useIX, CAmount nFeePay) - { ParamForCreateTransaction param = {}; @@ -2891,7 +3267,7 @@ bool CWallet::CreateTransactionHelper(const std::vector 0 && nBalance <= nReserveBalance) return false; - // presstab HyperStake - Initialize as static and don't update the set on every run of CreateCoinStake() in order to lighten resource use - static std::set > setStakeCoins; - static int nLastStakeSetUpdate = 0; - - if (GetTime() - nLastStakeSetUpdate > nStakeSetUpdateTime) { - setStakeCoins.clear(); - if (!SelectStakeCoins(setStakeCoins, nBalance - nReserveBalance)) - return false; - - nLastStakeSetUpdate = GetTime(); + // Get the list of stakable inputs + std::list > listInputs; + if (!SelectStakeCoins(listInputs, nBalance - nReserveBalance, pindexPrev->nHeight + 1)) { + LogPrintf("CreateCoinStake(): selectStakeCoins failed\n"); + return false; } - if (setStakeCoins.empty()) + if (listInputs.empty()) { + LogPrint("staking", "CreateCoinStake(): listInputs empty\n"); + MilliSleep(50000); return false; + } - vector vwtxPrev; + if (GetAdjustedTime() - chainActive.Tip()->GetBlockTime() < 60) { + if (Params().NetworkID() == CBaseChainParams::REGTEST) { + MilliSleep(1000); + } + } - CAmount nCredit = 0; + CAmount nCredit; CScript scriptPubKeyKernel; bool fKernelFound = false; + int nAttempts = 0; - //prevent staking a time that won't be accepted - if (GetAdjustedTime() <= chainActive.Tip()->nTime) - MilliSleep(10000); - - for (std::pair pcoin : setStakeCoins) { - //make sure that enough time has elapsed between - CBlockIndex* pindex = NULL; - BlockMap::iterator it = mapBlockIndex.find(pcoin.first->hashBlock); - if (it != mapBlockIndex.end()) - pindex = it->second; - else { - if (fDebug) - LogPrintf("CreateCoinStake() failed to find block index \n"); - continue; - } + // Block time. + nTxNewTime = GetAdjustedTime(); + // If the block time is in the future, then starts there. + if (pindexPrev->nTime > nTxNewTime) { + nTxNewTime = pindexPrev->nTime; + } - // Read block header - CBlockHeader block = pindex->GetBlockHeader(); + for (std::unique_ptr& stakeInput : listInputs) { + nCredit = 0; + // Make sure the wallet is unlocked and shutdown hasn't been requested + if (IsLocked() || ShutdownRequested()) + return false; uint256 hashProofOfStake = 0; - COutPoint prevoutStake = COutPoint(pcoin.first->GetHash(), pcoin.second); - nTxNewTime = GetAdjustedTime(); - + nAttempts++; //iterates each utxo inside of CheckStakeKernelHash() - if (CheckStakeKernelHash(nBits, block, *pcoin.first, prevoutStake, nTxNewTime, nHashDrift, false, hashProofOfStake, true)) { - //Double check that this will pass time requirements - if (nTxNewTime <= chainActive.Tip()->GetMedianTimePast()) { - LogPrintf("CreateCoinStake() : kernel found, but it is too far in the past \n"); - continue; - } + if (Stake(pindexPrev, stakeInput.get(), nBits, nTxNewTime, hashProofOfStake)) { // Found a kernel - if (fDebug && GetBoolArg("-printcoinstake", false)) - LogPrintf("CreateCoinStake : kernel found\n"); - - vector vSolutions; - txnouttype whichType; - CScript scriptPubKeyOut; - scriptPubKeyKernel = pcoin.first->vout[pcoin.second].scriptPubKey; - if (!Solver(scriptPubKeyKernel, whichType, vSolutions)) { - LogPrintf("CreateCoinStake : failed to parse kernel\n"); - break; - } - if (fDebug && GetBoolArg("-printcoinstake", false)) - LogPrintf("CreateCoinStake : parsed kernel type=%d\n", whichType); - if (whichType != TX_PUBKEY && whichType != TX_PUBKEYHASH && whichType != TX_WITNESS_V0_KEYHASH) { - if (fDebug && GetBoolArg("-printcoinstake", false)) - LogPrintf("CreateCoinStake : no support for kernel type=%d\n", whichType); - break; // only support pay to public key and pay to address + LogPrintf("CreateCoinStake : kernel found\n"); + nCredit += stakeInput->GetValue(); + + // Calculate reward + CAmount nReward; + nReward = GetBlockValue(chainActive.Height() + 1); + nCredit += nReward; + + // Create the output transaction(s) + std::vector vout; + if (!stakeInput->CreateTxOuts(this, vout, nCredit)) { + LogPrintf("%s : failed to get scriptPubKey\n", __func__); + continue; } - if (whichType == TX_PUBKEYHASH) // pay to address type - { - //convert to pay to public key type - CKey key; - if (!keystore.GetKey(uint160(vSolutions[0]), key)) { - if (fDebug && GetBoolArg("-printcoinstake", false)) - LogPrintf("CreateCoinStake : failed to get key for kernel type=%d\n", whichType); - break; // unable to find corresponding public key - } + txNew.vout.insert(txNew.vout.end(), vout.begin(), vout.end()); - scriptPubKeyOut << key.GetPubKey() << OP_CHECKSIG; + CAmount nMinFee = 0; + // Set output amount + if (txNew.vout.size() == 3) { + txNew.vout[1].nValue = ((nCredit - nMinFee) / 2 / CENT) * CENT; + txNew.vout[2].nValue = nCredit - nMinFee - txNew.vout[1].nValue; } else - scriptPubKeyOut = scriptPubKeyKernel; - - txNew.vin.push_back(CTxIn(pcoin.first->GetHash(), pcoin.second)); - nCredit += pcoin.first->vout[pcoin.second].nValue; - vwtxPrev.push_back(pcoin.first); - txNew.vout.push_back(CTxOut(0, scriptPubKeyOut)); + txNew.vout[1].nValue = nCredit - nMinFee; - //presstab HyperStake - calculate the total size of our new output including the stake reward so that we can use it to decide whether to split the stake outputs - const CBlockIndex* pIndex0 = chainActive.Tip(); - uint64_t nTotalSize = pcoin.first->vout[pcoin.second].nValue + GetBlockValue(pIndex0->nHeight); + // Limit size + unsigned int nBytes = ::GetSerializeSize(txNew, SER_NETWORK, PROTOCOL_VERSION); + if (nBytes >= DEFAULT_BLOCK_MAX_SIZE / 5) + return error("CreateCoinStake : exceeded coinstake size limit"); - //presstab HyperStake - if MultiSend is set to send in coinstake we will add our outputs here (values asigned further down) - if (nTotalSize / 2 > nStakeSplitThreshold * COIN) - txNew.vout.push_back(CTxOut(0, scriptPubKeyOut)); //split stake + //Masternode payment + FillBlockPayee(txNew, nMinFee, true); + + uint256 hashTxOut = txNew.GetHash(); + CTxIn in; + if (!stakeInput->CreateTxIn(this, in, hashTxOut)) { + LogPrintf("%s : failed to create TxIn\n", __func__); + txNew.vin.clear(); + txNew.vout.clear(); + continue; + } + txNew.vin.emplace_back(in); - if (fDebug && GetBoolArg("-printcoinstake", false)) - LogPrintf("CreateCoinStake : added kernel type=%d\n", whichType); fKernelFound = true; break; } - if (fKernelFound) - break; // if kernel is found stop searching } + LogPrint("staking", "%s: attempted staking %d times\n", __func__, nAttempts); + if (!fKernelFound) return false; - // Calculate reward - CAmount nReward; - const CBlockIndex* pIndex0 = chainActive.Tip(); - nReward = GetBlockValue(pIndex0->nHeight); - nCredit += nReward; - - CAmount nMinFee = 0; - while (true) { - // Set output amount - if (txNew.vout.size() == 3) { - txNew.vout[1].nValue = ((nCredit - nMinFee) / 2 / CENT) * CENT; - txNew.vout[2].nValue = nCredit - nMinFee - txNew.vout[1].nValue; - } else - txNew.vout[1].nValue = nCredit - nMinFee; - - // Limit size - unsigned int nBytes = GetTransactionCost(txNew); - if (nBytes >= MAX_STANDARD_TX_COST) - return error("CreateCoinStake : exceeded coinstake size limit"); - - CAmount nFeeNeeded = GetMinimumFee(nBytes, nTxConfirmTarget, mempool); - - // Check enough fee is paid - if (nMinFee < nFeeNeeded) { - nMinFee = nFeeNeeded; - continue; // try signing again - } else { - if (fDebug) - LogPrintf("CreateCoinStake : fee for coinstake %s\n", FormatMoney(nMinFee).c_str()); - break; - } - } - - //Karmanode payment - FillBlockPayee(txNew, nMinFee, true); - // Sign int nIn = 0; - for (const CWalletTx* pcoin : vwtxPrev) { - if (!SignSignature(*this, *pcoin, txNew, nIn++, SIGHASH_ALL)) + for(CTxIn txIn : txNew.vin) { + const CWalletTx *wtx = GetWalletTx(txIn.prevout.hash); + if(!SignSignature(*this, *wtx, txNew, nIn++, (SIGHASH_ALL | SIGHASH_ANYONECANPAY))) return error("CreateCoinStake : failed to sign coinstake"); } // Successfully generated coinstake - nLastStakeSetUpdate = 0; //this will trigger stake set to repopulate next round return true; } - /** * Call after CreateTransaction unless you want to abort */ @@ -3364,7 +3689,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 +3746,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 +3771,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 +3846,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 +3889,6 @@ bool CWallet::TopUpKeyPool(unsigned int kpSize) if (IsLocked()) return false; - CWalletDB walletdb(strWalletFile); // Top up key pool unsigned int nTargetSize; @@ -3556,14 +3897,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 +3941,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 +3951,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 +3987,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 +4022,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 +4185,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 +4213,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 +4488,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() { @@ -4183,7 +4614,8 @@ void CWallet::AutoZeromint() void CWallet::AutoCombineDust() { LOCK2(cs_main, cs_wallet); - if (chainActive.Tip()->nTime < (GetAdjustedTime() - 300) || IsLocked()) { + const CBlockIndex* tip = chainActive.Tip(); + if (tip->nTime < (GetAdjustedTime() - 300) || IsLocked()) { return; } @@ -4276,11 +4708,13 @@ bool CWallet::MultiSend() { LOCK2(cs_main, cs_wallet); // Stop the old blocks from sending multisends - if (chainActive.Tip()->nTime < (GetAdjustedTime() - 300) || IsLocked()) { + const CBlockIndex* tip = chainActive.Tip(); + int chainTipHeight = tip->nHeight; + if (tip->nTime < (GetAdjustedTime() - 300) || IsLocked()) { return false; } - if (chainActive.Tip()->nHeight <= nLastMultiSendHeight) { + if (chainTipHeight <= nLastMultiSendHeight) { LogPrintf("Multisend: lastmultisendheight is higher than current best height\n"); return false; } @@ -4389,12 +4823,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) @@ -4414,7 +4851,7 @@ int CMerkleTx::SetMerkleBranch(const CBlock& block) // Locate the transaction for (nIndex = 0; nIndex < (int)block.vtx.size(); nIndex++) if (block.vtx[nIndex] == *(CTransaction*)this) - break; + break; if (nIndex == (int)block.vtx.size()) { vMerkleBranch.clear(); nIndex = -1; @@ -4944,7 +5381,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 +5482,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..28a30f1 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,10 +258,16 @@ 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 SelectStakeCoins(std::list >& listInputs, CAmount nTargetAmount, int blockHeight) const; bool SelectCoinsDark(CAmount nValueMin, CAmount nValueMax, std::vector& setCoinsRet, CAmount& nValueRet, int nObfuscationRoundsMin, int nObfuscationRoundsMax) const; bool SelectCoinsByDenominations(int nDenom, CAmount nValueMin, CAmount nValueMax, std::vector& vCoinsRet, std::vector& vCoinsRet2, CAmount& nValueRet, int nObfuscationRoundsMin, int nObfuscationRoundsMax); bool SelectCoinsDarkDenominated(CAmount nTargetValue, std::vector& setCoinsRet, CAmount& nValueRet) 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):