From e55621dbd2633ae4137a7aa71b2af43881f01b6d Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sat, 17 Nov 2018 13:15:03 +0000 Subject: [PATCH 01/40] Remove -Werror It is an annoying piece of garbage --- CMakeLists.txt | 3 --- contrib/CMakeLists.txt | 5 ----- contrib/epee/tests/src/CMakeLists.txt | 4 ++-- src/CMakeLists.txt | 5 ----- 4 files changed, 2 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5e7791f0a..dc7f1467e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -601,9 +601,6 @@ else() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ARCH_FLAG}") set(WARNINGS "-Wall -Wextra -Wpointer-arith -Wundef -Wvla -Wwrite-strings -Wno-error=extra -Wno-error=deprecated-declarations -Wno-unused-parameter -Wno-unused-variable -Wno-error=unused-variable -Wno-error=undef -Wno-error=uninitialized") - if(NOT MINGW) - set(WARNINGS_AS_ERRORS_FLAG "-Werror") - endif() if(CMAKE_C_COMPILER_ID STREQUAL "Clang") if(ARM) set(WARNINGS "${WARNINGS} -Wno-error=inline-asm") diff --git a/contrib/CMakeLists.txt b/contrib/CMakeLists.txt index 990a05c08..3bebbe0d2 100644 --- a/contrib/CMakeLists.txt +++ b/contrib/CMakeLists.txt @@ -26,10 +26,5 @@ # 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. -# warnings are cleared only for GCC on Linux -if (NOT (MINGW OR APPLE OR FREEBSD OR OPENBSD OR DRAGONFLY)) - add_compile_options("${WARNINGS_AS_ERRORS_FLAG}") # applies only to targets that follow -endif() - add_subdirectory(epee) diff --git a/contrib/epee/tests/src/CMakeLists.txt b/contrib/epee/tests/src/CMakeLists.txt index c7d31735b..4807fa7ea 100644 --- a/contrib/epee/tests/src/CMakeLists.txt +++ b/contrib/epee/tests/src/CMakeLists.txt @@ -14,8 +14,8 @@ IF (MSVC) include_directories(SYSTEM platform/msvc) ELSE() # set stuff for other systems - SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11 -Wall -Werror") - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Werror -Wno-reorder") + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11 -Wall") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Wno-reorder") ENDIF() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6ee7effdd..a0b62da77 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -34,11 +34,6 @@ if (WIN32 OR STATIC) add_definitions(-DMINIUPNP_STATICLIB) endif () -# warnings are cleared only for GCC on Linux -if (NOT (MINGW OR APPLE OR FREEBSD OR OPENBSD OR DRAGONFLY)) - add_compile_options("${WARNINGS_AS_ERRORS_FLAG}") # applies only to targets that follow -endif() - function (monero_private_headers group) source_group("${group}\\Private" FILES From 636ffdc7a13ac5bd9f463be88979c10cf97888ba Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sun, 2 Dec 2018 13:06:41 +0000 Subject: [PATCH 02/40] blockchain: fix race between two external mining threads --- src/cryptonote_core/blockchain.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index 42bc9652d..76a9d0cb0 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -1270,7 +1270,9 @@ bool Blockchain::create_block_template(block& b, const account_public_address& m uint64_t already_generated_coins; uint64_t pool_cookie; - CRITICAL_REGION_BEGIN(m_blockchain_lock); + m_tx_pool.lock(); + const auto unlock_guard = epee::misc_utils::create_scope_leave_handler([&]() { m_tx_pool.unlock(); }); + CRITICAL_REGION_LOCAL(m_blockchain_lock); height = m_db->height(); if (m_btc_valid) { // The pool cookie is atomic. The lack of locking is OK, as if it changes @@ -1306,8 +1308,6 @@ bool Blockchain::create_block_template(block& b, const account_public_address& m median_weight = m_current_block_cumul_weight_limit / 2; already_generated_coins = m_db->get_block_already_generated_coins(height - 1); - CRITICAL_REGION_END(); - size_t txs_weight; uint64_t fee; if (!m_tx_pool.fill_block_template(b, median_weight, already_generated_coins, txs_weight, fee, expected_reward, m_hardfork->get_current_version())) @@ -1318,7 +1318,6 @@ bool Blockchain::create_block_template(block& b, const account_public_address& m #if defined(DEBUG_CREATE_BLOCK_TEMPLATE) size_t real_txs_weight = 0; uint64_t real_fee = 0; - CRITICAL_REGION_BEGIN(m_tx_pool.m_transactions_lock); for(crypto::hash &cur_hash: b.tx_hashes) { auto cur_res = m_tx_pool.m_transactions.find(cur_hash); @@ -1362,7 +1361,6 @@ bool Blockchain::create_block_template(block& b, const account_public_address& m { LOG_ERROR("Creating block template: error: wrongly calculated fee"); } - CRITICAL_REGION_END(); MDEBUG("Creating block template: height " << height << ", median weight " << median_weight << ", already generated coins " << already_generated_coins << From 0ad65833297cbe3061bb1162affbe9601bca6ed4 Mon Sep 17 00:00:00 2001 From: TheCharlatan Date: Sat, 13 Oct 2018 17:07:56 +0200 Subject: [PATCH 03/40] Add glibc back compat code To ensure that the binaries compiled by gitian run across many linux distributions, enforce 2.17 as the minimum libc version supported. --- CMakeLists.txt | 9 +- contrib/gitian/gitian-linux.yml | 2 +- contrib/gitian/symbol-check.py | 163 ----------------------------- src/common/CMakeLists.txt | 4 + src/common/compat/glibc_compat.cpp | 98 +++++++++++++++++ 5 files changed, 111 insertions(+), 165 deletions(-) delete mode 100755 contrib/gitian/symbol-check.py create mode 100644 src/common/compat/glibc_compat.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index dc7f1467e..1168c4666 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -695,6 +695,13 @@ else() set(LD_SECURITY_FLAGS "${LD_SECURITY_FLAGS} -Wl,-z,noexecheap") endif() + if(BACKCOMPAT) + add_definitions(-DFDELT_TYPE=long\ int) + add_linker_flag_if_supported(-Wl,--wrap=__divmoddi4 LD_BACKCOMPAT_FLAGS) + add_linker_flag_if_supported(-Wl,--wrap=glob LD_BACKCOMPAT_FLAGS) + message(STATUS "Using Lib C back compat flags: ${LD_BACKCOMPAT_FLAGS}") + endif() + # some windows linker bits if (WIN32) add_linker_flag_if_supported(-Wl,--dynamicbase LD_SECURITY_FLAGS) @@ -707,7 +714,7 @@ else() set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11 -D_GNU_SOURCE ${MINGW_FLAG} ${STATIC_ASSERT_FLAG} ${WARNINGS} ${C_WARNINGS} ${COVERAGE_FLAGS} ${PIC_FLAG} ${C_SECURITY_FLAGS}") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -D_GNU_SOURCE ${MINGW_FLAG} ${STATIC_ASSERT_CPP_FLAG} ${WARNINGS} ${CXX_WARNINGS} ${COVERAGE_FLAGS} ${PIC_FLAG} ${CXX_SECURITY_FLAGS}") - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${LD_SECURITY_FLAGS}") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${LD_SECURITY_FLAGS} ${LD_BACKCOMPAT_FLAGS}") # With GCC 6.1.1 the compiled binary malfunctions due to aliasing. Until that # is fixed in the code (Issue #847), force compiler to be conservative. diff --git a/contrib/gitian/gitian-linux.yml b/contrib/gitian/gitian-linux.yml index 473a7720d..3bb25c314 100644 --- a/contrib/gitian/gitian-linux.yml +++ b/contrib/gitian/gitian-linux.yml @@ -152,7 +152,7 @@ script: | for i in ${HOSTS}; do export PATH=${BASEPREFIX}/${i}/native/bin:${ORIGPATH} mkdir build && cd build - cmake .. -DCMAKE_TOOLCHAIN_FILE=${BASEPREFIX}/${i}/share/toolchain.cmake + cmake .. -DCMAKE_TOOLCHAIN_FILE=${BASEPREFIX}/${i}/share/toolchain.cmake -DBACKCOMPAT=ON make DISTNAME=monero-${i} mv bin ${DISTNAME} diff --git a/contrib/gitian/symbol-check.py b/contrib/gitian/symbol-check.py deleted file mode 100755 index 6808e77da..000000000 --- a/contrib/gitian/symbol-check.py +++ /dev/null @@ -1,163 +0,0 @@ -#!/usr/bin/env python3 -# Copyright (c) 2014 Wladimir J. van der Laan -# Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. -''' -A script to check that the (Linux) executables produced by gitian only contain -allowed gcc, glibc and libstdc++ version symbols. This makes sure they are -still compatible with the minimum supported Linux distribution versions. - -Example usage: - - find ../gitian-builder/build -type f -executable | xargs python contrib/devtools/symbol-check.py -''' -import subprocess -import re -import sys -import os - -# Debian 6.0.9 (Squeeze) has: -# -# - g++ version 4.4.5 (https://packages.debian.org/search?suite=default§ion=all&arch=any&searchon=names&keywords=g%2B%2B) -# - libc version 2.11.3 (https://packages.debian.org/search?suite=default§ion=all&arch=any&searchon=names&keywords=libc6) -# - libstdc++ version 4.4.5 (https://packages.debian.org/search?suite=default§ion=all&arch=any&searchon=names&keywords=libstdc%2B%2B6) -# -# Ubuntu 10.04.4 (Lucid Lynx) has: -# -# - g++ version 4.4.3 (http://packages.ubuntu.com/search?keywords=g%2B%2B&searchon=names&suite=lucid§ion=all) -# - libc version 2.11.1 (http://packages.ubuntu.com/search?keywords=libc6&searchon=names&suite=lucid§ion=all) -# - libstdc++ version 4.4.3 (http://packages.ubuntu.com/search?suite=lucid§ion=all&arch=any&keywords=libstdc%2B%2B&searchon=names) -# -# Taking the minimum of these as our target. -# -# According to GNU ABI document (http://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html) this corresponds to: -# GCC 4.4.0: GCC_4.4.0 -# GCC 4.4.2: GLIBCXX_3.4.13, CXXABI_1.3.3 -# (glibc) GLIBC_2_11 -# -MAX_VERSIONS = { -'GCC': (4,4,0), -'CXXABI': (1,3,3), -'GLIBCXX': (3,4,13), -'GLIBC': (2,11) -} -# See here for a description of _IO_stdin_used: -# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=634261#109 - -# Ignore symbols that are exported as part of every executable -IGNORE_EXPORTS = { -'_edata', '_end', '_init', '__bss_start', '_fini', '_IO_stdin_used', 'stdin', 'stdout', 'stderr' -} -READELF_CMD = os.getenv('READELF', '/usr/bin/readelf') -CPPFILT_CMD = os.getenv('CPPFILT', '/usr/bin/c++filt') -# Allowed NEEDED libraries -ALLOWED_LIBRARIES = { -# bitcoind and bitcoin-qt -'libgcc_s.so.1', # GCC base support -'libc.so.6', # C library -'libpthread.so.0', # threading -'libanl.so.1', # DNS resolve -'libm.so.6', # math library -'librt.so.1', # real-time (clock) -'ld-linux-x86-64.so.2', # 64-bit dynamic linker -'ld-linux.so.2', # 32-bit dynamic linker -# bitcoin-qt only -'libX11-xcb.so.1', # part of X11 -'libX11.so.6', # part of X11 -'libxcb.so.1', # part of X11 -'libfontconfig.so.1', # font support -'libfreetype.so.6', # font parsing -'libdl.so.2' # programming interface to dynamic linker -} - -class CPPFilt(object): - ''' - Demangle C++ symbol names. - - Use a pipe to the 'c++filt' command. - ''' - def __init__(self): - self.proc = subprocess.Popen(CPPFILT_CMD, stdin=subprocess.PIPE, stdout=subprocess.PIPE, universal_newlines=True) - - def __call__(self, mangled): - self.proc.stdin.write(mangled + '\n') - self.proc.stdin.flush() - return self.proc.stdout.readline().rstrip() - - def close(self): - self.proc.stdin.close() - self.proc.stdout.close() - self.proc.wait() - -def read_symbols(executable, imports=True): - ''' - Parse an ELF executable and return a list of (symbol,version) tuples - for dynamic, imported symbols. - ''' - p = subprocess.Popen([READELF_CMD, '--dyn-syms', '-W', executable], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, universal_newlines=True) - (stdout, stderr) = p.communicate() - if p.returncode: - raise IOError('Could not read symbols for %s: %s' % (executable, stderr.strip())) - syms = [] - for line in stdout.splitlines(): - line = line.split() - if len(line)>7 and re.match('[0-9]+:$', line[0]): - (sym, _, version) = line[7].partition('@') - is_import = line[6] == 'UND' - if version.startswith('@'): - version = version[1:] - if is_import == imports: - syms.append((sym, version)) - return syms - -def check_version(max_versions, version): - if '_' in version: - (lib, _, ver) = version.rpartition('_') - else: - lib = version - ver = '0' - ver = tuple([int(x) for x in ver.split('.')]) - if not lib in max_versions: - return False - return ver <= max_versions[lib] - -def read_libraries(filename): - p = subprocess.Popen([READELF_CMD, '-d', '-W', filename], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, universal_newlines=True) - (stdout, stderr) = p.communicate() - if p.returncode: - raise IOError('Error opening file') - libraries = [] - for line in stdout.splitlines(): - tokens = line.split() - if len(tokens)>2 and tokens[1] == '(NEEDED)': - match = re.match('^Shared library: \[(.*)\]$', ' '.join(tokens[2:])) - if match: - libraries.append(match.group(1)) - else: - raise ValueError('Unparseable (NEEDED) specification') - return libraries - -if __name__ == '__main__': - cppfilt = CPPFilt() - retval = 0 - for filename in sys.argv[1:]: - # Check imported symbols - for sym,version in read_symbols(filename, True): - if version and not check_version(MAX_VERSIONS, version): - print('%s: symbol %s from unsupported version %s' % (filename, cppfilt(sym), version)) - retval = 1 - # Check exported symbols - for sym,version in read_symbols(filename, False): - if sym in IGNORE_EXPORTS: - continue - print('%s: export of symbol %s not allowed' % (filename, cppfilt(sym))) - retval = 1 - # Check dependency libraries - for library_name in read_libraries(filename): - if library_name not in ALLOWED_LIBRARIES: - print('%s: NEEDED library %s is not allowed' % (filename, library_name)) - retval = 1 - - sys.exit(retval) - - diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 5da23c944..3b1eb6d23 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -50,6 +50,10 @@ if (STACK_TRACE) list(APPEND common_sources stack_trace.cpp) endif() +if (BACKCOMPAT) + list(APPEND common_sources compat/glibc_compat.cpp) +endif() + set(common_headers) set(common_private_headers diff --git a/src/common/compat/glibc_compat.cpp b/src/common/compat/glibc_compat.cpp new file mode 100644 index 000000000..bf567987d --- /dev/null +++ b/src/common/compat/glibc_compat.cpp @@ -0,0 +1,98 @@ +#include +#include +#include +#include +#include +#include +#include + +#if defined(HAVE_SYS_SELECT_H) +#include +#endif + +// Prior to GLIBC_2.14, memcpy was aliased to memmove. +extern "C" void* memmove(void* a, const void* b, size_t c); +//extern "C" void* memset(void* a, int b, long unsigned int c); +extern "C" void* memcpy(void* a, const void* b, size_t c) +{ + return memmove(a, b, c); +} + +extern "C" void __chk_fail(void) __attribute__((__noreturn__)); + +#if defined(__i386__) || defined(__arm__) + +extern "C" int64_t __udivmoddi4(uint64_t u, uint64_t v, uint64_t* rp); + +extern "C" int64_t __wrap___divmoddi4(int64_t u, int64_t v, int64_t* rp) +{ + int32_t c1 = 0, c2 = 0; + int64_t uu = u, vv = v; + int64_t w; + int64_t r; + + if (uu < 0) { + c1 = ~c1, c2 = ~c2, uu = -uu; + } + if (vv < 0) { + c1 = ~c1, vv = -vv; + } + + w = __udivmoddi4(uu, vv, (uint64_t*)&r); + if (c1) + w = -w; + if (c2) + r = -r; + + *rp = r; + return w; +} +#endif + +/* glibc-internal users use __explicit_bzero_chk, and explicit_bzero + redirects to that. */ +#undef explicit_bzero +/* Set LEN bytes of S to 0. The compiler will not delete a call to + this function, even if S is dead after the call. */ +void +explicit_bzero (void *s, size_t len) +{ + memset (s, '\0', len); + /* Compiler barrier. */ + asm volatile ("" ::: "memory"); +} + +// Redefine explicit_bzero_chk +void +__explicit_bzero_chk (void *dst, size_t len, size_t dstlen) +{ + /* Inline __memset_chk to avoid a PLT reference to __memset_chk. */ + if (__glibc_unlikely (dstlen < len)) + __chk_fail (); + memset (dst, '\0', len); + /* Compiler barrier. */ + asm volatile ("" ::: "memory"); +} +/* libc-internal references use the hidden + __explicit_bzero_chk_internal symbol. This is necessary if + __explicit_bzero_chk is implemented as an IFUNC because some + targets do not support hidden references to IFUNC symbols. */ +#define strong_alias (__explicit_bzero_chk, __explicit_bzero_chk_internal) + +#undef glob +extern "C" int glob_old(const char * pattern, int flags, int (*errfunc) (const char *epath, int eerrno), glob_t *pglob); +#ifdef __i386__ +__asm__(".symver glob_old,glob@GLIBC_2.1"); +#elif defined(__amd64__) +__asm__(".symver glob_old,glob@GLIBC_2.2.5"); +#elif defined(__arm__) +__asm(".symver glob_old,glob@GLIBC_2.4"); +#elif defined(__aarch64__) +__asm__(".symver glob_old,glob@GLIBC_2.17"); +#endif + +extern "C" int __wrap_glob(const char * pattern, int flags, int (*errfunc) (const char *epath, int eerrno), glob_t *pglob) +{ + return glob_old(pattern, flags, errfunc, pglob); +} + From 9736a0a8b92f31c768586f31afd51c0e21af54d6 Mon Sep 17 00:00:00 2001 From: Norman Moeschter Date: Tue, 4 Dec 2018 07:27:08 +0100 Subject: [PATCH 04/40] Changed RECIEVED to RECEIVED in log messages. --- contrib/epee/include/net/levin_client_async.h | 2 +- contrib/epee/include/net/levin_protocol_handler_async.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/contrib/epee/include/net/levin_client_async.h b/contrib/epee/include/net/levin_client_async.h index b3a46465b..ed92f4b95 100644 --- a/contrib/epee/include/net/levin_client_async.h +++ b/contrib/epee/include/net/levin_client_async.h @@ -431,7 +431,7 @@ namespace levin } CRITICAL_REGION_END(); - LOG_PRINT_L4("LEVIN_PACKET_RECIEVED. [len=" << head.m_cb << ", flags=" << head.m_flags << ", is_cmd=" << head.m_have_to_return_data <<", cmd_id = " << head.m_command << ", pr_v=" << head.m_protocol_version << ", uid=" << string_tools::get_str_from_guid_a(head.m_id) << "]"); + LOG_PRINT_L4("LEVIN_PACKET_RECEIVED. [len=" << head.m_cb << ", flags=" << head.m_flags << ", is_cmd=" << head.m_have_to_return_data <<", cmd_id = " << head.m_command << ", pr_v=" << head.m_protocol_version << ", uid=" << string_tools::get_str_from_guid_a(head.m_id) << "]"); if(is_request) { diff --git a/contrib/epee/include/net/levin_protocol_handler_async.h b/contrib/epee/include/net/levin_protocol_handler_async.h index 6b1528caf..11649febe 100644 --- a/contrib/epee/include/net/levin_protocol_handler_async.h +++ b/contrib/epee/include/net/levin_protocol_handler_async.h @@ -416,7 +416,7 @@ public: bool is_response = (m_oponent_protocol_ver == LEVIN_PROTOCOL_VER_1 && m_current_head.m_flags&LEVIN_PACKET_RESPONSE); - MDEBUG(m_connection_context << "LEVIN_PACKET_RECIEVED. [len=" << m_current_head.m_cb + MDEBUG(m_connection_context << "LEVIN_PACKET_RECEIVED. [len=" << m_current_head.m_cb << ", flags" << m_current_head.m_flags << ", r?=" << m_current_head.m_have_to_return_data <<", cmd = " << m_current_head.m_command From 10d79d1848a19adcae4ab99042670bf45bde25f3 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Mon, 3 Dec 2018 19:07:59 +0000 Subject: [PATCH 05/40] CONTRIBUTING: mention not changing spelling/typoes in code --- CONTRIBUTING.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3de9cd5ce..883d366aa 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -19,7 +19,8 @@ posted to #monero-dev on irc.freenode.net). Patches should be self contained. A good rule of thumb is to have one patch per separate issue, feature, or logical change. Also, no -other changes, such as random whitespace changes or reindentation. +other changes, such as random whitespace changes, reindentation, +or fixing typoes, spelling, or wording, unless user visible. Following the code style of the particular chunk of code you're modifying is encouraged. Proper squashing should be done (eg, if you're making a buggy patch, then a later patch to fix the bug, From a121320fc9873e44fd1651a1e1a86de8270d03ff Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Mon, 3 Dec 2018 21:33:49 +0000 Subject: [PATCH 06/40] easylogging++: avoid uneeded temporary std::string object --- external/easylogging++/easylogging++.cc | 15 +++++++-------- external/easylogging++/easylogging++.h | 2 +- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/external/easylogging++/easylogging++.cc b/external/easylogging++/easylogging++.cc index aec4a150d..ab4ee49c3 100644 --- a/external/easylogging++/easylogging++.cc +++ b/external/easylogging++/easylogging++.cc @@ -2130,24 +2130,23 @@ static int priority(Level level) { return 7; } -bool VRegistry::allowed(Level level, const char* category) { +bool VRegistry::allowed(Level level, const std::string &category) { base::threading::ScopedLock scopedLock(lock()); - const std::string scategory = category; - const std::map::const_iterator it = m_cached_allowed_categories.find(scategory); + const std::map::const_iterator it = m_cached_allowed_categories.find(category); if (it != m_cached_allowed_categories.end()) return priority(level) <= it->second; - if (m_categories.empty() || category == nullptr) { + if (m_categories.empty()) { return false; } else { std::vector>::const_reverse_iterator it = m_categories.rbegin(); for (; it != m_categories.rend(); ++it) { - if (base::utils::Str::wildCardMatch(category, it->first.c_str())) { + if (base::utils::Str::wildCardMatch(category.c_str(), it->first.c_str())) { const int p = priority(it->second); - m_cached_allowed_categories.insert(std::make_pair(std::move(scategory), p)); + m_cached_allowed_categories.insert(std::make_pair(category, p)); return priority(level) <= p; } } - m_cached_allowed_categories.insert(std::make_pair(std::move(scategory), -1)); + m_cached_allowed_categories.insert(std::make_pair(category, -1)); return false; } } @@ -2715,7 +2714,7 @@ void Writer::initializeLogger(const std::string& loggerId, bool lookup, bool nee } if (ELPP->hasFlag(LoggingFlag::HierarchicalLogging)) { m_proceed = m_level == Level::Verbose ? m_logger->enabled(m_level) : - ELPP->vRegistry()->allowed(m_level, loggerId.c_str()); + ELPP->vRegistry()->allowed(m_level, loggerId); } else { m_proceed = m_logger->enabled(m_level); } diff --git a/external/easylogging++/easylogging++.h b/external/easylogging++/easylogging++.h index acf2a7674..1e27f62a6 100644 --- a/external/easylogging++/easylogging++.h +++ b/external/easylogging++/easylogging++.h @@ -2463,7 +2463,7 @@ class VRegistry : base::NoCopy, public base::threading::ThreadSafe { void setModules(const char* modules); - bool allowed(Level level, const char* category); + bool allowed(Level level, const std::string &category); bool allowed(base::type::VerboseLevel vlevel, const char* file); From 4bd63dab9db35f29abe97167489814aedc5fb3e1 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Wed, 5 Dec 2018 00:12:29 +0000 Subject: [PATCH 07/40] blockchain: call deinit in dtor This ensures the io service that runs in another thread cannot access data after it's deleted --- src/cryptonote_core/blockchain.cpp | 17 ++++++++++------- src/cryptonote_core/blockchain.h | 5 +++++ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index 76a9d0cb0..528fef2ae 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -128,6 +128,11 @@ Blockchain::Blockchain(tx_memory_pool& tx_pool) : LOG_PRINT_L3("Blockchain::" << __func__); } //------------------------------------------------------------------ +Blockchain::~Blockchain() +{ + deinit(); +} +//------------------------------------------------------------------ bool Blockchain::have_tx(const crypto::hash &id) const { LOG_PRINT_L3("Blockchain::" << __func__); @@ -507,15 +512,13 @@ bool Blockchain::deinit() // as this should be called if handling a SIGSEGV, need to check // if m_db is a NULL pointer (and thus may have caused the illegal // memory operation), otherwise we may cause a loop. - if (m_db == NULL) - { - throw DB_ERROR("The db pointer is null in Blockchain, the blockchain may be corrupt!"); - } - try { - m_db->close(); - MTRACE("Local blockchain read/write activity stopped successfully"); + if (m_db) + { + m_db->close(); + MTRACE("Local blockchain read/write activity stopped successfully"); + } } catch (const std::exception& e) { diff --git a/src/cryptonote_core/blockchain.h b/src/cryptonote_core/blockchain.h index 877828f81..67bccc6c6 100644 --- a/src/cryptonote_core/blockchain.h +++ b/src/cryptonote_core/blockchain.h @@ -120,6 +120,11 @@ namespace cryptonote */ Blockchain(tx_memory_pool& tx_pool); + /** + * @brief Blockchain destructor + */ + ~Blockchain(); + /** * @brief Initialize the Blockchain state * From be871722378974c5b87d627d4ac5fdf9144dd8ad Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Wed, 5 Dec 2018 00:30:39 +0000 Subject: [PATCH 08/40] unit_tests: strengthen notify test against OS scheduling --- tests/unit_tests/notify.cpp | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/tests/unit_tests/notify.cpp b/tests/unit_tests/notify.cpp index 105d21ca8..cd70b7739 100644 --- a/tests/unit_tests/notify.cpp +++ b/tests/unit_tests/notify.cpp @@ -69,11 +69,22 @@ TEST(notify, works) tools::Notify notify(spec.c_str()); notify.notify("1111111111111111111111111111111111111111111111111111111111111111"); - epee::misc_utils::sleep_no_w(100); - - std::string s; - ASSERT_TRUE(epee::file_io_utils::load_file_to_string(name_template, s)); - ASSERT_TRUE(s == "1111111111111111111111111111111111111111111111111111111111111111"); + bool ok = false; + for (int i = 0; i < 10; ++i) + { + epee::misc_utils::sleep_no_w(100); + std::string s; + if (epee::file_io_utils::load_file_to_string(name_template, s)) + { + if (s == "1111111111111111111111111111111111111111111111111111111111111111") + { + ok = true; + break; + } + std::cout << "got: [" << s << "]" << std::endl; + } + } boost::filesystem::remove(name_template); + ASSERT_TRUE(ok); } From a44d54645ec0b44c991435cb85b39d2c4c224e97 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Wed, 5 Dec 2018 14:07:45 +0000 Subject: [PATCH 09/40] util: set MONERO_DEFAULT_LOG_CATEGORY Otherwise it'd end up with whatever was included last --- src/common/util.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/common/util.cpp b/src/common/util.cpp index 448f792ff..ec7d8b70c 100644 --- a/src/common/util.cpp +++ b/src/common/util.cpp @@ -82,6 +82,9 @@ using namespace epee; #include #include +#undef MONERO_DEFAULT_LOG_CATEGORY +#define MONERO_DEFAULT_LOG_CATEGORY "util" + namespace tools { std::function signal_handler::m_handler; From e1355ecd3e13238e2fd8b63b5a19a607e7c4a936 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Wed, 5 Dec 2018 14:52:43 +0000 Subject: [PATCH 10/40] util: use fcntl instead of flock, for compatibility in particular with NFS --- src/common/util.cpp | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/src/common/util.cpp b/src/common/util.cpp index ec7d8b70c..28745eea4 100644 --- a/src/common/util.cpp +++ b/src/common/util.cpp @@ -85,6 +85,29 @@ using namespace epee; #undef MONERO_DEFAULT_LOG_CATEGORY #define MONERO_DEFAULT_LOG_CATEGORY "util" +namespace +{ + +#ifndef _WIN32 +static int flock_exnb(int fd) +{ + struct flock fl; + int ret; + + memset(&fl, 0, sizeof(fl)); + fl.l_type = F_WRLCK; + fl.l_whence = SEEK_SET; + fl.l_start = 0; + fl.l_len = 0; + ret = fcntl(fd, F_SETLK, &fl); + if (ret < 0) + MERROR("Error locking fd " << fd << ": " << errno << " (" << strerror(errno) << ")"); + return ret; +} +#endif + +} + namespace tools { std::function signal_handler::m_handler; @@ -185,7 +208,7 @@ namespace tools struct stat wstats = {}; if (fstat(fdw, std::addressof(wstats)) == 0 && rstats.st_dev == wstats.st_dev && rstats.st_ino == wstats.st_ino && - flock(fdw, (LOCK_EX | LOCK_NB)) == 0 && ftruncate(fdw, 0) == 0) + flock_exnb(fdw) == 0 && ftruncate(fdw, 0) == 0) { std::FILE* file = fdopen(fdw, "w"); if (file) return {file, std::move(name)}; @@ -238,10 +261,10 @@ namespace tools MERROR("Failed to open " << filename << ": " << std::error_code(GetLastError(), std::system_category())); } #else - m_fd = open(filename.c_str(), O_RDONLY | O_CREAT | O_CLOEXEC, 0666); + m_fd = open(filename.c_str(), O_RDWR | O_CREAT | O_CLOEXEC, 0666); if (m_fd != -1) { - if (flock(m_fd, LOCK_EX | LOCK_NB) == -1) + if (flock_exnb(m_fd) == -1) { MERROR("Failed to lock " << filename << ": " << std::strerror(errno)); close(m_fd); From 8f7add0a05dc3e3d4eb2e6972483e0535efed829 Mon Sep 17 00:00:00 2001 From: Dusan Klinec Date: Tue, 4 Dec 2018 22:01:03 +0100 Subject: [PATCH 11/40] build: protobuf dependency fixes, libusb build - docker protobuf dependencies, cross-compilation - device/trezor protobuf build fixes, try_compile - libusb built under all platforms, used by trezor for direct connect --- .travis.yml | 7 +- Dockerfile | 17 +++- cmake/CheckTrezor.cmake | 95 ++++++++++++++++++++- cmake/test-protobuf.cpp | 43 ++++++++++ cmake/test-protobuf.proto | 7 ++ contrib/depends/README.md | 10 +++ contrib/depends/packages/libusb.mk | 20 +++-- contrib/depends/packages/native_protobuf.mk | 28 ++++++ contrib/depends/packages/packages.mk | 6 +- contrib/depends/toolchain.cmake.in | 6 ++ src/device_trezor/CMakeLists.txt | 8 -- src/wallet/CMakeLists.txt | 6 ++ 12 files changed, 228 insertions(+), 25 deletions(-) create mode 100644 cmake/test-protobuf.cpp create mode 100644 cmake/test-protobuf.proto create mode 100644 contrib/depends/packages/native_protobuf.mk diff --git a/.travis.yml b/.travis.yml index ca3a24ae8..ffb31fc08 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,9 +23,9 @@ env: - DOCKER_PACKAGES="build-essential libtool cmake autotools-dev automake pkg-config bsdmainutils curl git ca-certificates ccache" matrix: # ARM v7 - - HOST=arm-linux-gnueabihf PACKAGES="gperf g++-arm-linux-gnueabihf" + - HOST=arm-linux-gnueabihf PACKAGES="python3 gperf g++-arm-linux-gnueabihf" # ARM v8 - - HOST=aarch64-linux-gnu PACKAGES="gperf g++-aarch64-linux-gnu" + - HOST=aarch64-linux-gnu PACKAGES="python3 gperf g++-aarch64-linux-gnu" # i686 Win - HOST=i686-w64-mingw32 PACKAGES="python3 nsis g++-mingw-w64-i686" # i686 Linux @@ -33,7 +33,7 @@ env: # Win64 - HOST=x86_64-w64-mingw32 PACKAGES="cmake python3 nsis g++-mingw-w64-x86-64 wine-binfmt wine64 bc" RUN_TESTS=true # x86_64 Linux - - HOST=x86_64-unknown-linux-gnu PACKAGES="gperf cmake python3-zmq protobuf-compiler libdbus-1-dev libharfbuzz-dev libprotobuf-dev" RUN_TESTS=true + - HOST=x86_64-unknown-linux-gnu PACKAGES="gperf cmake python3-zmq libdbus-1-dev libharfbuzz-dev" RUN_TESTS=true # Cross-Mac - HOST=x86_64-apple-darwin11 PACKAGES="cmake imagemagick libcap-dev librsvg2-bin libz-dev libbz2-dev libtiff-tools python-dev python3-setuptools-git" OSX_SDK=10.11 @@ -52,6 +52,7 @@ before_script: - if [ -n "$OSX_SDK" -a ! -f contrib/depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz ]; then curl --location --fail $SDK_URL/MacOSX${OSX_SDK}.sdk.tar.gz -o contrib/depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz; fi - if [ -n "$OSX_SDK" -a -f contrib/depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz ]; then tar -C contrib/depends/SDKs -xf contrib/depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz; fi - if [[ $HOST = *-mingw32 ]]; then $DOCKER_EXEC bash -c "update-alternatives --set $HOST-g++ \$(which $HOST-g++-posix)"; fi + - if [[ $HOST = *-mingw32 ]]; then $DOCKER_EXEC bash -c "update-alternatives --set $HOST-gcc \$(which $HOST-gcc-posix)"; fi - if [ -z "$NO_DEPENDS" ]; then $DOCKER_EXEC bash -c "CONFIG_SHELL= make $MAKEJOBS -C contrib/depends HOST=$HOST $DEP_OPTS"; fi script: - git submodule init && git submodule update diff --git a/Dockerfile b/Dockerfile index 0728c6ce8..9fe7cfb8f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -20,7 +20,8 @@ RUN set -ex && \ automake \ bzip2 \ xsltproc \ - gperf + gperf \ + unzip WORKDIR /usr/local @@ -147,6 +148,20 @@ RUN set -ex \ && make \ && make install +# Protobuf +ARG PROTOBUF_VERSION=v3.6.1 +ARG PROTOBUF_HASH=48cb18e5c419ddd23d9badcfe4e9df7bde1979b2 +RUN set -ex \ + && git clone https://github.com/protocolbuffers/protobuf -b ${PROTOBUF_VERSION} \ + && cd protobuf \ + && test `git rev-parse HEAD` = ${PROTOBUF_HASH} || exit 1 \ + && git submodule update --init --recursive \ + && ./autogen.sh \ + && CFLAGS="-fPIC" CXXFLAGS="-fPIC" ./configure --enable-static --disable-shared \ + && make \ + && make install \ + && ldconfig + WORKDIR /src COPY . . diff --git a/cmake/CheckTrezor.cmake b/cmake/CheckTrezor.cmake index bcd3cfc2c..71214363d 100644 --- a/cmake/CheckTrezor.cmake +++ b/cmake/CheckTrezor.cmake @@ -2,13 +2,55 @@ OPTION(USE_DEVICE_TREZOR "Trezor support compilation" ON) OPTION(USE_DEVICE_TREZOR_LIBUSB "Trezor LibUSB compilation" ON) OPTION(USE_DEVICE_TREZOR_UDP_RELEASE "Trezor UdpTransport in release mode" OFF) +# Helper function to fix cmake < 3.6.0 FindProtobuf variables +function(_trezor_protobuf_fix_vars) + if(${CMAKE_VERSION} VERSION_LESS "3.6.0") + foreach(UPPER + PROTOBUF_SRC_ROOT_FOLDER + PROTOBUF_IMPORT_DIRS + PROTOBUF_DEBUG + PROTOBUF_LIBRARY + PROTOBUF_PROTOC_LIBRARY + PROTOBUF_INCLUDE_DIR + PROTOBUF_PROTOC_EXECUTABLE + PROTOBUF_LIBRARY_DEBUG + PROTOBUF_PROTOC_LIBRARY_DEBUG + PROTOBUF_LITE_LIBRARY + PROTOBUF_LITE_LIBRARY_DEBUG + ) + if (DEFINED ${UPPER}) + string(REPLACE "PROTOBUF_" "Protobuf_" Camel ${UPPER}) + if (NOT DEFINED ${Camel}) + set(${Camel} ${${UPPER}} PARENT_SCOPE) + endif() + endif() + endforeach() + endif() +endfunction() + # Use Trezor master switch if (USE_DEVICE_TREZOR) # Protobuf is required to build protobuf messages for Trezor include(FindProtobuf OPTIONAL) find_package(Protobuf) - if(NOT Protobuf_FOUND) + _trezor_protobuf_fix_vars() + + # Protobuf handling the cache variables set in docker. + if(NOT Protobuf_FOUND AND NOT Protobuf_LIBRARY AND NOT Protobuf_PROTOC_EXECUTABLE AND NOT Protobuf_INCLUDE_DIR) message(STATUS "Could not find Protobuf") + elseif(NOT Protobuf_LIBRARY OR NOT EXISTS "${Protobuf_LIBRARY}") + message(STATUS "Protobuf library not found: ${Protobuf_LIBRARY}") + unset(Protobuf_FOUND) + elseif(NOT Protobuf_PROTOC_EXECUTABLE OR NOT EXISTS "${Protobuf_PROTOC_EXECUTABLE}") + message(STATUS "Protobuf executable not found: ${Protobuf_PROTOC_EXECUTABLE}") + unset(Protobuf_FOUND) + elseif(NOT Protobuf_INCLUDE_DIR OR NOT EXISTS "${Protobuf_INCLUDE_DIR}") + message(STATUS "Protobuf include dir not found: ${Protobuf_INCLUDE_DIR}") + unset(Protobuf_FOUND) + else() + message(STATUS "Protobuf lib: ${Protobuf_LIBRARY}, inc: ${Protobuf_INCLUDE_DIR}, protoc: ${Protobuf_PROTOC_EXECUTABLE}") + set(Protobuf_INCLUDE_DIRS ${Protobuf_INCLUDE_DIR}) + set(Protobuf_FOUND 1) # override found if all rquired info was provided by variables endif() else() @@ -37,9 +79,32 @@ if(Protobuf_FOUND AND USE_DEVICE_TREZOR) endif() endif() -# Try to build protobuf messages +# Protobuf compilation test if(Protobuf_FOUND AND USE_DEVICE_TREZOR AND TREZOR_PYTHON) - set(ENV{PROTOBUF_INCLUDE_DIRS} "${Protobuf_INCLUDE_DIRS}") + execute_process(COMMAND ${Protobuf_PROTOC_EXECUTABLE} -I "${CMAKE_SOURCE_DIR}/cmake" -I "${Protobuf_INCLUDE_DIR}" "${CMAKE_SOURCE_DIR}/cmake/test-protobuf.proto" --cpp_out ${CMAKE_BINARY_DIR} RESULT_VARIABLE RET OUTPUT_VARIABLE OUT ERROR_VARIABLE ERR) + if(RET) + message(STATUS "Protobuf test generation failed: ${OUT} ${ERR}") + endif() + + try_compile(Protobuf_COMPILE_TEST_PASSED + "${CMAKE_BINARY_DIR}" + SOURCES + "${CMAKE_BINARY_DIR}/test-protobuf.pb.cc" + "${CMAKE_SOURCE_DIR}/cmake/test-protobuf.cpp" + CMAKE_FLAGS + "-DINCLUDE_DIRECTORIES=${Protobuf_INCLUDE_DIR};${CMAKE_BINARY_DIR}" + "-DCMAKE_CXX_STANDARD=11" + LINK_LIBRARIES ${Protobuf_LIBRARY} + OUTPUT_VARIABLE OUTPUT + ) + if(NOT Protobuf_COMPILE_TEST_PASSED) + message(STATUS "Protobuf Compilation test failed: ${OUTPUT}.") + endif() +endif() + +# Try to build protobuf messages +if(Protobuf_FOUND AND USE_DEVICE_TREZOR AND TREZOR_PYTHON AND Protobuf_COMPILE_TEST_PASSED) + set(ENV{PROTOBUF_INCLUDE_DIRS} "${Protobuf_INCLUDE_DIR}") set(ENV{PROTOBUF_PROTOC_EXECUTABLE} "${Protobuf_PROTOC_EXECUTABLE}") execute_process(COMMAND ${TREZOR_PYTHON} tools/build_protob.py WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/../src/device_trezor/trezor RESULT_VARIABLE RET OUTPUT_VARIABLE OUT ERROR_VARIABLE ERR) if(RET) @@ -47,9 +112,10 @@ if(Protobuf_FOUND AND USE_DEVICE_TREZOR AND TREZOR_PYTHON) "OUT: ${OUT}, ERR: ${ERR}." "Please read src/device_trezor/trezor/tools/README.md") else() - message(STATUS "Trezor protobuf messages regenerated ${OUT}") + message(STATUS "Trezor protobuf messages regenerated out: \"${OUT}.\"") set(DEVICE_TREZOR_READY 1) add_definitions(-DDEVICE_TREZOR_READY=1) + add_definitions(-DPROTOBUF_INLINE_NOT_IN_HEADERS=0) if(CMAKE_BUILD_TYPE STREQUAL "Debug") add_definitions(-DTREZOR_DEBUG=1) @@ -75,5 +141,26 @@ if(Protobuf_FOUND AND USE_DEVICE_TREZOR AND TREZOR_PYTHON) include_directories(${LibUSB_INCLUDE_DIRS}) endif() endif() + + set(TREZOR_LIBUSB_LIBRARIES "") + if(LibUSB_COMPILE_TEST_PASSED) + list(APPEND TREZOR_LIBUSB_LIBRARIES ${LibUSB_LIBRARIES}) + message(STATUS "Trezor compatible LibUSB found at: ${LibUSB_INCLUDE_DIRS}") + endif() + + if (BUILD_GUI_DEPS) + set(TREZOR_DEP_LIBS "") + set(TREZOR_DEP_LINKER "") + + if (Protobuf_LIBRARY) + list(APPEND TREZOR_DEP_LIBS ${Protobuf_LIBRARY}) + string(APPEND TREZOR_DEP_LINKER " -lprotobuf") + endif() + + if (TREZOR_LIBUSB_LIBRARIES) + list(APPEND TREZOR_DEP_LIBS ${TREZOR_LIBUSB_LIBRARIES}) + string(APPEND TREZOR_DEP_LINKER " -lusb-1.0") + endif() + endif() endif() endif() diff --git a/cmake/test-protobuf.cpp b/cmake/test-protobuf.cpp new file mode 100644 index 000000000..532df7cbe --- /dev/null +++ b/cmake/test-protobuf.cpp @@ -0,0 +1,43 @@ +// Copyright (c) 2014-2018, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. 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. +// +// 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 +// THE COPYRIGHT HOLDER 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. + +#include +#include +#include +#include +#include "test-protobuf.pb.h" + +int main(int argc, char *argv[]) { + google::protobuf::UnknownFieldSet ufs; + ufs.ClearAndFreeMemory(); + + Success sc; + sc.set_message("test"); + sc.SerializeToOstream(&std::cerr); + return 0; +} diff --git a/cmake/test-protobuf.proto b/cmake/test-protobuf.proto new file mode 100644 index 000000000..5300aea35 --- /dev/null +++ b/cmake/test-protobuf.proto @@ -0,0 +1,7 @@ +syntax = "proto2"; + +import "google/protobuf/descriptor.proto"; + +message Success { + optional string message = 1; +} diff --git a/contrib/depends/README.md b/contrib/depends/README.md index 597398369..c9f8b0783 100644 --- a/contrib/depends/README.md +++ b/contrib/depends/README.md @@ -53,6 +53,16 @@ Download it from apple, or search for it on github. Create a new directoty calle directory and place the entire MacOSX10.11.sdk folder in it. The depends build will then pick it up automatically (without requiring SDK_PATH). + +#Mingw builds + +Building for 32/64bit mingw requires switching alternatives to a posix mode + +```bash +update-alternatives --set x86_64-w64-mingw32-g++ x86_64-w64-mingw32-g++-posix +update-alternatives --set x86_64-w64-mingw32-gcc x86_64-w64-mingw32-gcc-posix +``` + ### Other documentation - [description.md](description.md): General description of the depends system diff --git a/contrib/depends/packages/libusb.mk b/contrib/depends/packages/libusb.mk index 6d60cce26..d865d2a17 100644 --- a/contrib/depends/packages/libusb.mk +++ b/contrib/depends/packages/libusb.mk @@ -11,13 +11,21 @@ endef define $(package)_set_vars $(package)_config_opts=--disable-shared $(package)_config_opts_linux=--with-pic --disable-udev + $(package)_config_opts_mingw32=--disable-udev + $(package)_config_opts_darwin=--disable-udev endef -define $(package)_config_cmds - cp -f $(BASEDIR)/config.guess config.guess &&\ - cp -f $(BASEDIR)/config.sub config.sub &&\ - $($(package)_autoconf) -endef +ifneq ($(host_os),darwin) + define $(package)_config_cmds + cp -f $(BASEDIR)/config.guess config.guess &&\ + cp -f $(BASEDIR)/config.sub config.sub &&\ + $($(package)_autoconf) + endef +else + define $(package)_config_cmds + $($(package)_autoconf) + endef +endif define $(package)_build_cmd $(MAKE) @@ -27,5 +35,5 @@ define $(package)_stage_cmds $(MAKE) DESTDIR=$($(package)_staging_dir) install endef -define $(package)_postprocess_cmds cp -f lib/libusb-1.0.a lib/libusb.a +define $(package)_postprocess_cmds cp -f lib/libusb-1.0.a lib/libusb.a endef diff --git a/contrib/depends/packages/native_protobuf.mk b/contrib/depends/packages/native_protobuf.mk new file mode 100644 index 000000000..83e602341 --- /dev/null +++ b/contrib/depends/packages/native_protobuf.mk @@ -0,0 +1,28 @@ +package=protobuf3 +$(package)_version=3.6.1 +$(package)_download_path=https://github.com/protocolbuffers/protobuf/releases/download/v$($(package)_version)/ +$(package)_file_name=protobuf-cpp-$($(package)_version).tar.gz +$(package)_sha256_hash=b3732e471a9bb7950f090fd0457ebd2536a9ba0891b7f3785919c654fe2a2529 +$(package)_cxxflags=-std=c++11 + +define $(package)_set_vars + $(package)_config_opts=--disable-shared --prefix=$(build_prefix) + $(package)_config_opts_linux=--with-pic +endef + +define $(package)_config_cmds + $($(package)_autoconf) +endef + +define $(package)_build_cmds + $(MAKE) -C src libprotobuf.la all +endef + +define $(package)_stage_cmds + $(MAKE) DESTDIR=$($(package)_staging_dir) -C src install install-libLTLIBRARIES install-nobase_includeHEADERS &&\ + $(MAKE) DESTDIR=$($(package)_staging_dir) install-pkgconfigDATA +endef + +define $(package)_postprocess_cmds + rm lib/libprotoc.a +endef diff --git a/contrib/depends/packages/packages.mk b/contrib/depends/packages/packages.mk index 234adbdd4..b3a5992d0 100644 --- a/contrib/depends/packages/packages.mk +++ b/contrib/depends/packages/packages.mk @@ -1,10 +1,10 @@ -packages:=boost openssl libevent zeromq cppzmq zlib expat ldns cppzmq readline libiconv qt hidapi -native_packages := native_ccache +packages:=boost openssl libevent zeromq cppzmq zlib expat ldns cppzmq readline libiconv qt hidapi protobuf libusb +native_packages := native_ccache native_protobuf darwin_native_packages = native_biplist native_ds_store native_mac_alias darwin_packages = sodium-darwin -linux_packages = eudev libusb +linux_packages = eudev ifeq ($(host_os),linux) packages += unwind diff --git a/contrib/depends/toolchain.cmake.in b/contrib/depends/toolchain.cmake.in index f59b7b5ee..547b59108 100644 --- a/contrib/depends/toolchain.cmake.in +++ b/contrib/depends/toolchain.cmake.in @@ -21,6 +21,12 @@ SET(LIBUNWIND_LIBRARY_DIRS @prefix@/lib) SET(LIBUSB-1.0_LIBRARY @prefix@/lib/libusb-1.0.a) SET(LIBUDEV_LIBRARY @prefix@/lib/libudev.a) +SET(Protobuf_FOUND 1) +SET(Protobuf_PROTOC_EXECUTABLE @prefix@/native/bin/protoc CACHE FILEPATH "Path to the native protoc") +SET(Protobuf_INCLUDE_DIR @prefix@/include CACHE PATH "Protobuf include dir") +SET(Protobuf_INCLUDE_DIRS @prefix@/include CACHE PATH "Protobuf include dir") +SET(Protobuf_LIBRARY @prefix@/lib/libprotobuf.a CACHE FILEPATH "Protobuf library") + SET(ZMQ_INCLUDE_PATH @prefix@/include) SET(ZMQ_LIB @prefix@/lib/libzmq.a) diff --git a/src/device_trezor/CMakeLists.txt b/src/device_trezor/CMakeLists.txt index b27c843b6..7f979389a 100644 --- a/src/device_trezor/CMakeLists.txt +++ b/src/device_trezor/CMakeLists.txt @@ -67,14 +67,6 @@ set(trezor_private_headers) if(DEVICE_TREZOR_READY) message(STATUS "Trezor support enabled") - add_definitions(-DPROTOBUF_INLINE_NOT_IN_HEADERS=0) - - set(TREZOR_LIBUSB_LIBRARIES "") - if(LibUSB_COMPILE_TEST_PASSED) - list(APPEND TREZOR_LIBUSB_LIBRARIES ${LibUSB_LIBRARIES}) - message(STATUS "Trezor compatible LibUSB found at: ${LibUSB_INCLUDE_DIRS}") - endif() - monero_private_headers(device_trezor ${device_private_headers}) diff --git a/src/wallet/CMakeLists.txt b/src/wallet/CMakeLists.txt index 69b7c4ffb..2cbfa2478 100644 --- a/src/wallet/CMakeLists.txt +++ b/src/wallet/CMakeLists.txt @@ -139,6 +139,12 @@ if (BUILD_GUI_DEPS) endif() install(TARGETS wallet_merged ARCHIVE DESTINATION ${lib_folder}) + + install(FILES ${TREZOR_DEP_LIBS} + DESTINATION ${lib_folder}) + file(WRITE "trezor_link_flags.txt" ${TREZOR_DEP_LINKER}) + install(FILES "trezor_link_flags.txt" + DESTINATION ${lib_folder}) endif() add_subdirectory(api) From 442b30eee9fc0b5b03cae11bbf8ec16ad116e2f9 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Wed, 5 Dec 2018 19:20:19 +0000 Subject: [PATCH 12/40] blockchain_db: remove a couple unused functions --- src/blockchain_db/berkeleydb/db_bdb.cpp | 23 ----------------------- src/blockchain_db/berkeleydb/db_bdb.h | 18 ------------------ src/blockchain_db/lmdb/db_lmdb.cpp | 23 ----------------------- src/blockchain_db/lmdb/db_lmdb.h | 18 ------------------ 4 files changed, 82 deletions(-) diff --git a/src/blockchain_db/berkeleydb/db_bdb.cpp b/src/blockchain_db/berkeleydb/db_bdb.cpp index 6c79120e8..b27a00a69 100644 --- a/src/blockchain_db/berkeleydb/db_bdb.cpp +++ b/src/blockchain_db/berkeleydb/db_bdb.cpp @@ -714,29 +714,6 @@ bool BlockchainBDB::for_all_outputs(std::function ba(ss); - tx_out o; - - if (!(::serialization::serialize(ba, o))) - throw1(DB_ERROR("Error deserializing tx output blob")); - - return o; -} - uint64_t BlockchainBDB::get_output_global_index(const uint64_t& amount, const uint64_t& index) { LOG_PRINT_L3("BlockchainBDB::" << __func__); diff --git a/src/blockchain_db/berkeleydb/db_bdb.h b/src/blockchain_db/berkeleydb/db_bdb.h index 76d0a0517..e80adae9e 100644 --- a/src/blockchain_db/berkeleydb/db_bdb.h +++ b/src/blockchain_db/berkeleydb/db_bdb.h @@ -391,24 +391,6 @@ private: virtual void check_hard_fork_info(); virtual void drop_hard_fork_info(); - /** - * @brief convert a tx output to a blob for storage - * - * @param output the output to convert - * - * @return the resultant blob - */ - blobdata output_to_blob(const tx_out& output) const; - - /** - * @brief convert a tx output blob to a tx output - * - * @param blob the blob to convert - * - * @return the resultant tx output - */ - tx_out output_from_blob(const blobdata& blob) const; - /** * @brief get the global index of the index-th output of the given amount * diff --git a/src/blockchain_db/lmdb/db_lmdb.cpp b/src/blockchain_db/lmdb/db_lmdb.cpp index 4b1fa5ac3..dfeab4c6f 100644 --- a/src/blockchain_db/lmdb/db_lmdb.cpp +++ b/src/blockchain_db/lmdb/db_lmdb.cpp @@ -1166,29 +1166,6 @@ void BlockchainLMDB::remove_spent_key(const crypto::key_image& k_image) } } -blobdata BlockchainLMDB::output_to_blob(const tx_out& output) const -{ - LOG_PRINT_L3("BlockchainLMDB::" << __func__); - blobdata b; - if (!t_serializable_object_to_blob(output, b)) - throw1(DB_ERROR("Error serializing output to blob")); - return b; -} - -tx_out BlockchainLMDB::output_from_blob(const blobdata& blob) const -{ - LOG_PRINT_L3("BlockchainLMDB::" << __func__); - std::stringstream ss; - ss << blob; - binary_archive ba(ss); - tx_out o; - - if (!(::serialization::serialize(ba, o))) - throw1(DB_ERROR("Error deserializing tx output blob")); - - return o; -} - void BlockchainLMDB::check_open() const { // LOG_PRINT_L3("BlockchainLMDB::" << __func__); diff --git a/src/blockchain_db/lmdb/db_lmdb.h b/src/blockchain_db/lmdb/db_lmdb.h index 6db241240..93f037c60 100644 --- a/src/blockchain_db/lmdb/db_lmdb.h +++ b/src/blockchain_db/lmdb/db_lmdb.h @@ -359,24 +359,6 @@ private: virtual void check_hard_fork_info(); virtual void drop_hard_fork_info(); - /** - * @brief convert a tx output to a blob for storage - * - * @param output the output to convert - * - * @return the resultant blob - */ - blobdata output_to_blob(const tx_out& output) const; - - /** - * @brief convert a tx output blob to a tx output - * - * @param blob the blob to convert - * - * @return the resultant tx output - */ - tx_out output_from_blob(const blobdata& blob) const; - void check_open() const; virtual bool is_read_only() const; From c3fae517a429a0e963a7dedc463f2e96f70e981a Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Wed, 5 Dec 2018 19:21:43 +0000 Subject: [PATCH 13/40] blockchain_db: allocate known size vector only once --- src/blockchain_db/blockchain_db.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/blockchain_db/blockchain_db.cpp b/src/blockchain_db/blockchain_db.cpp index db0124cd4..6ce59421e 100644 --- a/src/blockchain_db/blockchain_db.cpp +++ b/src/blockchain_db/blockchain_db.cpp @@ -170,7 +170,7 @@ void BlockchainDB::add_transaction(const crypto::hash& blk_hash, const transacti uint64_t tx_id = add_transaction_data(blk_hash, tx, tx_hash, tx_prunable_hash); - std::vector amount_output_indices; + std::vector amount_output_indices(tx.vout.size()); // iterate tx.vout using indices instead of C++11 foreach syntax because // we need the index @@ -183,13 +183,13 @@ void BlockchainDB::add_transaction(const crypto::hash& blk_hash, const transacti cryptonote::tx_out vout = tx.vout[i]; rct::key commitment = rct::zeroCommit(vout.amount); vout.amount = 0; - amount_output_indices.push_back(add_output(tx_hash, vout, i, tx.unlock_time, - &commitment)); + amount_output_indices[i] = add_output(tx_hash, vout, i, tx.unlock_time, + &commitment); } else { - amount_output_indices.push_back(add_output(tx_hash, tx.vout[i], i, tx.unlock_time, - tx.version > 1 ? &tx.rct_signatures.outPk[i].mask : NULL)); + amount_output_indices[i] = add_output(tx_hash, tx.vout[i], i, tx.unlock_time, + tx.version > 1 ? &tx.rct_signatures.outPk[i].mask : NULL); } } add_tx_amount_output_indices(tx_id, amount_output_indices); From 1b0fe29ee3e7a6f396cb965677bac5d6f609f3d7 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Wed, 5 Dec 2018 19:26:49 +0000 Subject: [PATCH 14/40] db_lmdb: inline check_open, it's trivial and called everywhere --- src/blockchain_db/lmdb/db_lmdb.cpp | 13 ++++++------- src/blockchain_db/lmdb/db_lmdb.h | 2 +- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/blockchain_db/lmdb/db_lmdb.cpp b/src/blockchain_db/lmdb/db_lmdb.cpp index dfeab4c6f..fe6aef9ba 100644 --- a/src/blockchain_db/lmdb/db_lmdb.cpp +++ b/src/blockchain_db/lmdb/db_lmdb.cpp @@ -456,6 +456,12 @@ inline int lmdb_txn_renew(MDB_txn *txn) return res; } +inline void BlockchainLMDB::check_open() const +{ + if (!m_open) + throw0(DB_ERROR("DB operation attempted on a not-open DB instance")); +} + void BlockchainLMDB::do_resize(uint64_t increase_size) { LOG_PRINT_L3("BlockchainLMDB::" << __func__); @@ -1166,13 +1172,6 @@ void BlockchainLMDB::remove_spent_key(const crypto::key_image& k_image) } } -void BlockchainLMDB::check_open() const -{ -// LOG_PRINT_L3("BlockchainLMDB::" << __func__); - if (!m_open) - throw0(DB_ERROR("DB operation attempted on a not-open DB instance")); -} - BlockchainLMDB::~BlockchainLMDB() { LOG_PRINT_L3("BlockchainLMDB::" << __func__); diff --git a/src/blockchain_db/lmdb/db_lmdb.h b/src/blockchain_db/lmdb/db_lmdb.h index 93f037c60..b7b1b04d5 100644 --- a/src/blockchain_db/lmdb/db_lmdb.h +++ b/src/blockchain_db/lmdb/db_lmdb.h @@ -359,7 +359,7 @@ private: virtual void check_hard_fork_info(); virtual void drop_hard_fork_info(); - void check_open() const; + inline void check_open() const; virtual bool is_read_only() const; From f97b2edb3ce7fbcbb8425aab5d6ead9c57b3aa10 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Wed, 5 Dec 2018 19:27:39 +0000 Subject: [PATCH 15/40] db_lmdb: avoid pointless division --- src/blockchain_db/lmdb/db_lmdb.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/blockchain_db/lmdb/db_lmdb.cpp b/src/blockchain_db/lmdb/db_lmdb.cpp index fe6aef9ba..6e03b86c1 100644 --- a/src/blockchain_db/lmdb/db_lmdb.cpp +++ b/src/blockchain_db/lmdb/db_lmdb.cpp @@ -3168,7 +3168,7 @@ uint64_t BlockchainLMDB::add_block(const block& blk, size_t block_weight, const check_open(); uint64_t m_height = height(); - if (m_height % 1000 == 0) + if (m_height % 1024 == 0) { // for batch mode, DB resize check is done at start of batch transaction if (! m_batch_active && need_resize()) From 7bb6c00b5ee9c7ff1f833682e9e56190d73323f7 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Wed, 5 Dec 2018 20:34:10 +0000 Subject: [PATCH 16/40] cryptonote: set tx hash on newly parsed txes when known --- src/cryptonote_basic/cryptonote_basic.h | 2 ++ src/cryptonote_basic/cryptonote_format_utils.cpp | 1 + src/cryptonote_core/tx_pool.cpp | 16 +++++++++++----- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/cryptonote_basic/cryptonote_basic.h b/src/cryptonote_basic/cryptonote_basic.h index 645e99f91..196b20e2a 100644 --- a/src/cryptonote_basic/cryptonote_basic.h +++ b/src/cryptonote_basic/cryptonote_basic.h @@ -211,6 +211,8 @@ namespace cryptonote void set_hash_valid(bool v) const { hash_valid.store(v,std::memory_order_release); } bool is_blob_size_valid() const { return blob_size_valid.load(std::memory_order_acquire); } void set_blob_size_valid(bool v) const { blob_size_valid.store(v,std::memory_order_release); } + void set_hash(const crypto::hash &h) { hash = h; set_hash_valid(true); } + void set_blob_size(size_t sz) { blob_size = sz; set_blob_size_valid(true); } BEGIN_SERIALIZE_OBJECT() if (!typename Archive::is_saving()) diff --git a/src/cryptonote_basic/cryptonote_format_utils.cpp b/src/cryptonote_basic/cryptonote_format_utils.cpp index 9dc77c05c..e8deb3b1b 100644 --- a/src/cryptonote_basic/cryptonote_format_utils.cpp +++ b/src/cryptonote_basic/cryptonote_format_utils.cpp @@ -204,6 +204,7 @@ namespace cryptonote CHECK_AND_ASSERT_MES(r, false, "Failed to parse transaction from blob"); CHECK_AND_ASSERT_MES(expand_transaction_1(tx, false), false, "Failed to expand transaction data"); tx.invalidate_hashes(); + tx.set_blob_size(tx_blob.size()); return true; } //--------------------------------------------------------------- diff --git a/src/cryptonote_core/tx_pool.cpp b/src/cryptonote_core/tx_pool.cpp index a078274c1..6ce00339a 100644 --- a/src/cryptonote_core/tx_pool.cpp +++ b/src/cryptonote_core/tx_pool.cpp @@ -480,6 +480,10 @@ namespace cryptonote MERROR("Failed to parse tx from txpool"); return false; } + else + { + tx.set_hash(id); + } tx_weight = meta.weight; fee = meta.fee; relayed = meta.relayed; @@ -782,6 +786,7 @@ namespace cryptonote // continue return true; } + tx.set_hash(txid); txi.tx_json = obj_to_json_str(tx); txi.blob_size = bd->size(); txi.weight = meta.weight; @@ -847,14 +852,13 @@ namespace cryptonote m_blockchain.for_all_txpool_txes([&tx_infos, key_image_infos](const crypto::hash &txid, const txpool_tx_meta_t &meta, const cryptonote::blobdata *bd){ cryptonote::rpc::tx_in_pool txi; txi.tx_hash = txid; - transaction tx; - if (!parse_and_validate_tx_from_blob(*bd, tx)) + if (!parse_and_validate_tx_from_blob(*bd, txi.tx)) { MERROR("Failed to parse tx from txpool"); // continue return true; } - txi.tx = tx; + txi.tx.set_hash(txid); txi.blob_size = bd->size(); txi.weight = meta.weight; txi.fee = meta.fee; @@ -990,21 +994,23 @@ namespace cryptonote { struct transction_parser { - transction_parser(const cryptonote::blobdata &txblob, transaction &tx): txblob(txblob), tx(tx), parsed(false) {} + transction_parser(const cryptonote::blobdata &txblob, const crypto::hash &txid, transaction &tx): txblob(txblob), txid(txid), tx(tx), parsed(false) {} cryptonote::transaction &operator()() { if (!parsed) { if (!parse_and_validate_tx_from_blob(txblob, tx)) throw std::runtime_error("failed to parse transaction blob"); + tx.set_hash(txid); parsed = true; } return tx; } const cryptonote::blobdata &txblob; + const crypto::hash &txid; transaction &tx; bool parsed; - } lazy_tx(txblob, tx); + } lazy_tx(txblob, txid, tx); //not the best implementation at this time, sorry :( //check is ring_signature already checked ? From 36da8397f86af0c280bb5002c3f4aebbdc21b96f Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Wed, 5 Dec 2018 20:34:35 +0000 Subject: [PATCH 17/40] tx_pool: add a few std::move where it can make a difference --- src/cryptonote_core/tx_pool.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/cryptonote_core/tx_pool.cpp b/src/cryptonote_core/tx_pool.cpp index 6ce00339a..c2ddcee52 100644 --- a/src/cryptonote_core/tx_pool.cpp +++ b/src/cryptonote_core/tx_pool.cpp @@ -663,7 +663,8 @@ namespace cryptonote // continue return true; } - txs.push_back(tx); + tx.set_hash(txid); + txs.push_back(std::move(tx)); return true; }, true, include_unrelayed_txes); } @@ -803,7 +804,7 @@ namespace cryptonote txi.last_relayed_time = include_sensitive_data ? meta.last_relayed_time : 0; txi.do_not_relay = meta.do_not_relay; txi.double_spend_seen = meta.double_spend_seen; - tx_infos.push_back(txi); + tx_infos.push_back(std::move(txi)); return true; }, true, include_sensitive_data); @@ -885,7 +886,7 @@ namespace cryptonote } const crypto::key_image& k_image = kee.first; - key_image_infos[k_image] = tx_hashes; + key_image_infos[k_image] = std::move(tx_hashes); } return true; } From d40acef20b2b7fb4722cea1ba33c3cb63764b77f Mon Sep 17 00:00:00 2001 From: selsta Date: Fri, 7 Dec 2018 13:37:23 +0100 Subject: [PATCH 18/40] simplewallet: donate command validate amount --- src/simplewallet/simplewallet.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index ee3f1f744..e615b174f 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -6256,8 +6256,18 @@ bool simple_wallet::donate(const std::vector &args_) local_args.pop_back(); } // get amount and pop - amount_str = local_args.back(); - local_args.pop_back(); + uint64_t amount; + bool ok = cryptonote::parse_amount(amount, local_args.back()); + if (ok && amount != 0) + { + amount_str = local_args.back(); + local_args.pop_back(); + } + else + { + fail_msg_writer() << tr("amount is wrong: ") << local_args.back() << ", " << tr("expected number from 0 to ") << print_money(std::numeric_limits::max()); + return true; + } // push back address, amount, payment id std::string address_str; if (m_wallet->nettype() != cryptonote::MAINNET) From b494943a10bea4af3c3861afcc6401f9a87f28ef Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Thu, 29 Nov 2018 22:01:48 +0000 Subject: [PATCH 19/40] cryptonote: don't serialize for blob size if already known --- .../cryptonote_format_utils.cpp | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/cryptonote_basic/cryptonote_format_utils.cpp b/src/cryptonote_basic/cryptonote_format_utils.cpp index e8deb3b1b..a08b1fb3e 100644 --- a/src/cryptonote_basic/cryptonote_format_utils.cpp +++ b/src/cryptonote_basic/cryptonote_format_utils.cpp @@ -402,11 +402,19 @@ namespace cryptonote //--------------------------------------------------------------- uint64_t get_transaction_weight(const transaction &tx) { - std::ostringstream s; - binary_archive a(s); - ::serialization::serialize(a, const_cast(tx)); - const cryptonote::blobdata blob = s.str(); - return get_transaction_weight(tx, blob.size()); + size_t blob_size; + if (tx.is_blob_size_valid()) + { + blob_size = tx.blob_size; + } + else + { + std::ostringstream s; + binary_archive a(s); + ::serialization::serialize(a, const_cast(tx)); + blob_size = s.str().size(); + } + return get_transaction_weight(tx, blob_size); } //--------------------------------------------------------------- bool get_tx_fee(const transaction& tx, uint64_t & fee) From e2095e00ba9a823b32ad03665716be82bb69847c Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Fri, 7 Dec 2018 16:34:56 +0000 Subject: [PATCH 20/40] singleton: fix missing *this return value in operator= while there, disable both operator= and copy ctor, since they are not supposed to be around for a singleton --- src/mnemonics/singleton.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mnemonics/singleton.h b/src/mnemonics/singleton.h index a15c2b9ae..d317a2d8d 100644 --- a/src/mnemonics/singleton.h +++ b/src/mnemonics/singleton.h @@ -50,8 +50,8 @@ namespace Language class Singleton { Singleton() {} - Singleton(Singleton &s) {} - Singleton& operator=(const Singleton&) {} + Singleton(Singleton &s) = delete; + Singleton& operator=(const Singleton&) = delete; public: static T* instance() { From 8ef2437e5d314be63779fa00c67d8a2360516301 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sat, 8 Dec 2018 10:52:25 +0000 Subject: [PATCH 21/40] perf_timer: make all logs Info level and make them not default at log level 1 --- contrib/epee/src/mlog.cpp | 2 +- src/common/perf_timer.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/contrib/epee/src/mlog.cpp b/contrib/epee/src/mlog.cpp index 00d848388..9b6b832d1 100644 --- a/contrib/epee/src/mlog.cpp +++ b/contrib/epee/src/mlog.cpp @@ -103,7 +103,7 @@ static const char *get_default_categories(int level) categories = "*:WARNING,net:FATAL,net.http:FATAL,net.p2p:FATAL,net.cn:FATAL,global:INFO,verify:FATAL,stacktrace:INFO,logging:INFO,msgwriter:INFO"; break; case 1: - categories = "*:INFO,global:INFO,stacktrace:INFO,logging:INFO,msgwriter:INFO"; + categories = "*:INFO,global:INFO,stacktrace:INFO,logging:INFO,msgwriter:INFO,perf.*:DEBUG"; break; case 2: categories = "*:DEBUG"; diff --git a/src/common/perf_timer.h b/src/common/perf_timer.h index 584434a0d..267f94161 100644 --- a/src/common/perf_timer.h +++ b/src/common/perf_timer.h @@ -63,7 +63,7 @@ protected: class LoggingPerformanceTimer: public PerformanceTimer { public: - LoggingPerformanceTimer(const std::string &s, const std::string &cat, uint64_t unit, el::Level l = el::Level::Debug); + LoggingPerformanceTimer(const std::string &s, const std::string &cat, uint64_t unit, el::Level l = el::Level::Info); ~LoggingPerformanceTimer(); private: From 9eedf5f08771ff04a51765c5cd81b65d62794060 Mon Sep 17 00:00:00 2001 From: Jethro Grassie Date: Sat, 8 Dec 2018 20:52:54 -0500 Subject: [PATCH 22/40] ignore child process when exec --- src/common/spawn.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/common/spawn.cpp b/src/common/spawn.cpp index 0a2ce8387..b2d03f62f 100644 --- a/src/common/spawn.cpp +++ b/src/common/spawn.cpp @@ -35,6 +35,7 @@ #include #else #include +#include #endif #include "misc_log_ex.h" @@ -114,7 +115,10 @@ int spawn(const char *filename, const std::vector& args, bool wait) if (pid > 0) { if (!wait) + { + signal(SIGCHLD, SIG_IGN); return 0; + } while (1) { From ed5b588ca36f0e59f67600a5c48d736a6e323795 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Mon, 3 Dec 2018 15:32:14 +0000 Subject: [PATCH 23/40] wallet: optionally keep track of owned outputs uses --- src/simplewallet/simplewallet.cpp | 87 +++++++++++++++++++++++++------ src/simplewallet/simplewallet.h | 2 + src/wallet/wallet2.cpp | 27 +++++++++- src/wallet/wallet2.h | 10 +++- 4 files changed, 108 insertions(+), 18 deletions(-) diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index e615b174f..b3dfc5dea 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -2399,6 +2399,19 @@ bool simple_wallet::set_ignore_fractional_outputs(const std::vector return true; } +bool simple_wallet::set_track_uses(const std::vector &args/* = std::vector()*/) +{ + const auto pwd_container = get_and_verify_password(); + if (pwd_container) + { + parse_bool_and_use(args[1], [&](bool r) { + m_wallet->track_uses(r); + m_wallet->rewrite(m_wallet_file, pwd_container->password()); + }); + } + return true; +} + bool simple_wallet::set_device_name(const std::vector &args/* = std::vector()*/) { const auto pwd_container = get_and_verify_password(); @@ -2947,6 +2960,7 @@ bool simple_wallet::set_variable(const std::vector &args) success_msg_writer() << "subaddress-lookahead = " << lookahead.first << ":" << lookahead.second; success_msg_writer() << "segregation-height = " << m_wallet->segregation_height(); success_msg_writer() << "ignore-fractional-outputs = " << m_wallet->ignore_fractional_outputs(); + success_msg_writer() << "track-uses = " << m_wallet->track_uses(); success_msg_writer() << "device_name = " << m_wallet->device_name(); return true; } @@ -3003,6 +3017,7 @@ bool simple_wallet::set_variable(const std::vector &args) CHECK_SIMPLE_VARIABLE("subaddress-lookahead", set_subaddress_lookahead, tr(":")); CHECK_SIMPLE_VARIABLE("segregation-height", set_segregation_height, tr("unsigned integer")); CHECK_SIMPLE_VARIABLE("ignore-fractional-outputs", set_ignore_fractional_outputs, tr("0 or 1")); + CHECK_SIMPLE_VARIABLE("track-uses", set_track_uses, tr("0 or 1")); CHECK_SIMPLE_VARIABLE("device-name", set_device_name, tr("")); } fail_msg_writer() << tr("set: unrecognized argument(s)"); @@ -4728,6 +4743,7 @@ bool simple_wallet::show_incoming_transfers(const std::vector& args bool filter = false; bool available = false; bool verbose = false; + bool uses = false; if (local_args.size() > 0) { if (local_args[0] == "available") @@ -4743,12 +4759,22 @@ bool simple_wallet::show_incoming_transfers(const std::vector& args local_args.erase(local_args.begin()); } } - if (local_args.size() > 0 && local_args[0] == "verbose") + while (local_args.size() > 0) { - verbose = true; + if (local_args[0] == "verbose") + verbose = true; + else if (local_args[0] == "uses") + uses = true; + else + { + fail_msg_writer() << tr("Invalid keyword: ") << local_args.front(); + break; + } local_args.erase(local_args.begin()); } + const uint64_t blockchain_height = m_wallet->get_blockchain_current_height(); + PAUSE_READLINE(); std::set subaddr_indices; @@ -4782,9 +4808,16 @@ bool simple_wallet::show_incoming_transfers(const std::vector& args verbose_string = (boost::format("%68s%68s") % tr("pubkey") % tr("key image")).str(); message_writer() << boost::format("%21s%8s%12s%8s%16s%68s%16s%s") % tr("amount") % tr("spent") % tr("unlocked") % tr("ringct") % tr("global index") % tr("tx id") % tr("addr index") % verbose_string; } - std::string verbose_string; + std::string extra_string; if (verbose) - verbose_string = (boost::format("%68s%68s") % td.get_public_key() % (td.m_key_image_known ? epee::string_tools::pod_to_hex(td.m_key_image) : td.m_key_image_partial ? (epee::string_tools::pod_to_hex(td.m_key_image) + "/p") : std::string(64, '?'))).str(); + extra_string += (boost::format("%68s%68s") % td.get_public_key() % (td.m_key_image_known ? epee::string_tools::pod_to_hex(td.m_key_image) : td.m_key_image_partial ? (epee::string_tools::pod_to_hex(td.m_key_image) + "/p") : std::string(64, '?'))).str(); + if (uses) + { + std::vector heights; + for (const auto &e: td.m_uses) heights.push_back(e.first); + const std::pair line = show_outputs_line(heights, blockchain_height, td.m_spent_height); + extra_string += tr("Heights: ") + line.first + "\n" + line.second; + } message_writer(td.m_spent ? console_color_magenta : console_color_green, false) << boost::format("%21s%8s%12s%8s%16u%68s%16u%s") % print_money(td.amount()) % @@ -4794,7 +4827,7 @@ bool simple_wallet::show_incoming_transfers(const std::vector& args td.m_global_output_index % td.m_txid % td.m_subaddr_index.minor % - verbose_string; + extra_string; ++transfers_found; } } @@ -4946,6 +4979,33 @@ bool simple_wallet::rescan_spent(const std::vector &args) return true; } //---------------------------------------------------------------------------------------------------- +std::pair simple_wallet::show_outputs_line(const std::vector &heights, uint64_t blockchain_height, uint64_t highlight_height) const +{ + std::stringstream ostr; + + for (uint64_t h: heights) + blockchain_height = std::max(blockchain_height, h); + + for (size_t j = 0; j < heights.size(); ++j) + ostr << (heights[j] == highlight_height ? " *" : " ") << heights[j]; + + // visualize the distribution, using the code by moneroexamples onion-monero-viewer + const uint64_t resolution = 79; + std::string ring_str(resolution, '_'); + for (size_t j = 0; j < heights.size(); ++j) + { + uint64_t pos = (heights[j] * resolution) / blockchain_height; + ring_str[pos] = 'o'; + } + if (highlight_height < blockchain_height) + { + uint64_t pos = (highlight_height * resolution) / blockchain_height; + ring_str[pos] = '*'; + } + + return std::make_pair(ostr.str(), ring_str); +} +//---------------------------------------------------------------------------------------------------- bool simple_wallet::print_ring_members(const std::vector& ptx_vector, std::ostream& ostr) { uint32_t version; @@ -5016,21 +5076,18 @@ bool simple_wallet::print_ring_members(const std::vector heights(absolute_offsets.size(), 0); + uint64_t highlight_height = std::numeric_limits::max(); for (size_t j = 0; j < absolute_offsets.size(); ++j) { - uint64_t pos = (res.outs[j].height * resolution) / blockchain_height; - ring_str[pos] = 'o'; + heights[j] = res.outs[j].height; + if (j == source.real_output) + highlight_height = heights[j]; } - uint64_t pos = (res.outs[source.real_output].height * resolution) / blockchain_height; - ring_str[pos] = '*'; - ostr << tr("\n|") << ring_str << tr("|\n"); + std::pair ring_str = show_outputs_line(heights, highlight_height); + ostr << ring_str.first << tr("\n|") << ring_str.second << tr("|\n"); } // warn if rings contain keys originating from the same tx or temporally very close block heights bool are_keys_from_same_tx = false; diff --git a/src/simplewallet/simplewallet.h b/src/simplewallet/simplewallet.h index 5010e3adc..e49da8c18 100644 --- a/src/simplewallet/simplewallet.h +++ b/src/simplewallet/simplewallet.h @@ -142,6 +142,7 @@ namespace cryptonote bool set_subaddress_lookahead(const std::vector &args = std::vector()); bool set_segregation_height(const std::vector &args = std::vector()); bool set_ignore_fractional_outputs(const std::vector &args = std::vector()); + bool set_track_uses(const std::vector &args = std::vector()); bool set_device_name(const std::vector &args = std::vector()); bool help(const std::vector &args = std::vector()); bool start_mining(const std::vector &args); @@ -251,6 +252,7 @@ namespace cryptonote bool print_seed(bool encrypted); void key_images_sync_intern(); void on_refresh_finished(uint64_t start_height, uint64_t fetched_blocks, bool is_init, bool received_money); + std::pair show_outputs_line(const std::vector &heights, uint64_t blockchain_height, uint64_t highlight_height = std::numeric_limits::max()) const; struct transfer_view { diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 1a93c513b..64fd742f5 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -894,6 +894,7 @@ wallet2::wallet2(network_type nettype, uint64_t kdf_rounds, bool unattended): m_key_reuse_mitigation2(false), m_segregation_height(0), m_ignore_fractional_outputs(true), + m_track_uses(false), m_is_initialized(false), m_kdf_rounds(kdf_rounds), is_old_file_format(false), @@ -1450,6 +1451,7 @@ void wallet2::cache_tx_data(const cryptonote::transaction& tx, const crypto::has //---------------------------------------------------------------------------------------------------- void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote::transaction& tx, const std::vector &o_indices, uint64_t height, uint64_t ts, bool miner_tx, bool pool, bool double_spend_seen, const tx_cache_data &tx_cache_data) { + PERF_TIMER(process_new_transaction); // In this function, tx (probably) only contains the base information // (that is, the prunable stuff may or may not be included) if (!miner_tx && !pool) @@ -1782,11 +1784,12 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote { if(in.type() != typeid(cryptonote::txin_to_key)) continue; - auto it = m_key_images.find(boost::get(in).k_image); + const cryptonote::txin_to_key &in_to_key = boost::get(in); + auto it = m_key_images.find(in_to_key.k_image); if(it != m_key_images.end()) { transfer_details& td = m_transfers[it->second]; - uint64_t amount = boost::get(in).amount; + uint64_t amount = in_to_key.amount; if (amount > 0) { if(amount != td.amount()) @@ -1817,6 +1820,20 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote m_callback->on_money_spent(height, txid, tx, amount, tx, td.m_subaddr_index); } } + + if (!pool && m_track_uses) + { + PERF_TIMER(track_uses); + std::vector offsets = cryptonote::relative_output_offsets_to_absolute(in_to_key.key_offsets); + for (transfer_details &td: m_transfers) + { + if ((td.is_rct() ? 0 : td.amount()) != in_to_key.amount) + continue; + for (uint64_t offset: offsets) + if (offset == td.m_global_output_index) + td.m_uses.push_back(std::make_pair(height, txid)); + } + } } uint64_t fee = miner_tx ? 0 : tx.version == 1 ? tx_money_spent_in_ins - get_outs_money_amount(tx) : tx.rct_signatures.txnFee; @@ -3182,6 +3199,9 @@ bool wallet2::store_keys(const std::string& keys_file_name, const epee::wipeable value2.SetInt(m_ignore_fractional_outputs ? 1 : 0); json.AddMember("ignore_fractional_outputs", value2, json.GetAllocator()); + value2.SetInt(m_track_uses ? 1 : 0); + json.AddMember("track_uses", value2, json.GetAllocator()); + value2.SetUint(m_subaddress_lookahead_major); json.AddMember("subaddress_lookahead_major", value2, json.GetAllocator()); @@ -3328,6 +3348,7 @@ bool wallet2::load_keys(const std::string& keys_file_name, const epee::wipeable_ m_key_reuse_mitigation2 = true; m_segregation_height = 0; m_ignore_fractional_outputs = true; + m_track_uses = false; m_subaddress_lookahead_major = SUBADDRESS_LOOKAHEAD_MAJOR; m_subaddress_lookahead_minor = SUBADDRESS_LOOKAHEAD_MINOR; m_original_keys_available = false; @@ -3480,6 +3501,8 @@ bool wallet2::load_keys(const std::string& keys_file_name, const epee::wipeable_ m_segregation_height = field_segregation_height; GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, ignore_fractional_outputs, int, Int, false, true); m_ignore_fractional_outputs = field_ignore_fractional_outputs; + GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, track_uses, int, Int, false, false); + m_track_uses = field_track_uses; GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, subaddress_lookahead_major, uint32_t, Uint, false, SUBADDRESS_LOOKAHEAD_MAJOR); m_subaddress_lookahead_major = field_subaddress_lookahead_major; GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, subaddress_lookahead_minor, uint32_t, Uint, false, SUBADDRESS_LOOKAHEAD_MINOR); diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index ace01a235..52579376f 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -273,6 +273,7 @@ namespace tools bool m_key_image_partial; std::vector m_multisig_k; std::vector m_multisig_info; // one per other participant + std::vector> m_uses; bool is_rct() const { return m_rct; } uint64_t amount() const { return m_amount; } @@ -297,6 +298,7 @@ namespace tools FIELD(m_key_image_partial) FIELD(m_multisig_k) FIELD(m_multisig_info) + FIELD(m_uses) END_SERIALIZE() }; @@ -984,6 +986,8 @@ namespace tools void ignore_fractional_outputs(bool value) { m_ignore_fractional_outputs = value; } bool confirm_non_default_ring_size() const { return m_confirm_non_default_ring_size; } void confirm_non_default_ring_size(bool always) { m_confirm_non_default_ring_size = always; } + bool track_uses() const { return m_track_uses; } + void track_uses(bool value) { m_track_uses = value; } const std::string & device_name() const { return m_device_name; } void device_name(const std::string & device_name) { m_device_name = device_name; } const std::string & device_derivation_path() const { return m_device_derivation_path; } @@ -1395,6 +1399,7 @@ namespace tools bool m_key_reuse_mitigation2; uint64_t m_segregation_height; bool m_ignore_fractional_outputs; + bool m_track_uses; bool m_is_initialized; NodeRPCProxy m_node_rpc_proxy; std::unordered_set m_scanned_pool_txs[2]; @@ -1444,7 +1449,7 @@ namespace tools }; } BOOST_CLASS_VERSION(tools::wallet2, 27) -BOOST_CLASS_VERSION(tools::wallet2::transfer_details, 10) +BOOST_CLASS_VERSION(tools::wallet2::transfer_details, 11) BOOST_CLASS_VERSION(tools::wallet2::multisig_info, 1) BOOST_CLASS_VERSION(tools::wallet2::multisig_info::LR, 0) BOOST_CLASS_VERSION(tools::wallet2::multisig_tx_set, 1) @@ -1593,6 +1598,9 @@ namespace boost return; } a & x.m_key_image_requested; + if (ver < 11) + return; + a & x.m_uses; } template From aad10a6cb056e1370e88962e77a024bb86311bed Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Mon, 3 Dec 2018 17:45:18 +0000 Subject: [PATCH 24/40] wallet2: speedup output tracking It can get heavy for large wallets --- src/wallet/wallet2.cpp | 55 ++++++++++++++++++++++++++++++++++-------- src/wallet/wallet2.h | 7 +++--- 2 files changed, 49 insertions(+), 13 deletions(-) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 64fd742f5..777a177db 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -1449,7 +1449,7 @@ void wallet2::cache_tx_data(const cryptonote::transaction& tx, const crypto::has } } //---------------------------------------------------------------------------------------------------- -void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote::transaction& tx, const std::vector &o_indices, uint64_t height, uint64_t ts, bool miner_tx, bool pool, bool double_spend_seen, const tx_cache_data &tx_cache_data) +void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote::transaction& tx, const std::vector &o_indices, uint64_t height, uint64_t ts, bool miner_tx, bool pool, bool double_spend_seen, const tx_cache_data &tx_cache_data, std::map, size_t> *output_tracker_cache) { PERF_TIMER(process_new_transaction); // In this function, tx (probably) only contains the base information @@ -1688,6 +1688,8 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote if (!m_multisig && !m_watch_only) m_key_images[td.m_key_image] = m_transfers.size()-1; m_pub_keys[tx_scan_info[o].in_ephemeral.pub] = m_transfers.size()-1; + if (output_tracker_cache) + (*output_tracker_cache)[std::make_pair(tx.vout[o].amount, td.m_global_output_index)] = m_transfers.size() - 1; if (m_multisig) { THROW_WALLET_EXCEPTION_IF(!m_multisig_rescan_k && m_multisig_rescan_info, @@ -1753,6 +1755,8 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote td.m_mask = rct::identity(); td.m_rct = false; } + if (output_tracker_cache) + (*output_tracker_cache)[std::make_pair(tx.vout[o].amount, td.m_global_output_index)] = kit->second; if (m_multisig) { THROW_WALLET_EXCEPTION_IF(!m_multisig_rescan_k && m_multisig_rescan_info, @@ -1824,10 +1828,24 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote if (!pool && m_track_uses) { PERF_TIMER(track_uses); + const uint64_t amount = in_to_key.amount; std::vector offsets = cryptonote::relative_output_offsets_to_absolute(in_to_key.key_offsets); - for (transfer_details &td: m_transfers) + if (output_tracker_cache) { - if ((td.is_rct() ? 0 : td.amount()) != in_to_key.amount) + for (uint64_t offset: offsets) + { + const std::map, size_t>::const_iterator i = output_tracker_cache->find(std::make_pair(amount, offset)); + if (i != output_tracker_cache->end()) + { + size_t idx = i->second; + THROW_WALLET_EXCEPTION_IF(idx >= m_transfers.size(), error::wallet_internal_error, "Output tracker cache index out of range"); + m_transfers[idx].m_uses.push_back(std::make_pair(height, txid)); + } + } + } + else for (transfer_details &td: m_transfers) + { + if (amount != in_to_key.amount) continue; for (uint64_t offset: offsets) if (offset == td.m_global_output_index) @@ -2016,7 +2034,7 @@ void wallet2::process_outgoing(const crypto::hash &txid, const cryptonote::trans add_rings(tx); } //---------------------------------------------------------------------------------------------------- -void wallet2::process_new_blockchain_entry(const cryptonote::block& b, const cryptonote::block_complete_entry& bche, const parsed_block &parsed_block, const crypto::hash& bl_id, uint64_t height, const std::vector &tx_cache_data, size_t tx_cache_data_offset) +void wallet2::process_new_blockchain_entry(const cryptonote::block& b, const cryptonote::block_complete_entry& bche, const parsed_block &parsed_block, const crypto::hash& bl_id, uint64_t height, const std::vector &tx_cache_data, size_t tx_cache_data_offset, std::map, size_t> *output_tracker_cache) { THROW_WALLET_EXCEPTION_IF(bche.txs.size() + 1 != parsed_block.o_indices.indices.size(), error::wallet_internal_error, "block transactions=" + std::to_string(bche.txs.size()) + @@ -2029,7 +2047,7 @@ void wallet2::process_new_blockchain_entry(const cryptonote::block& b, const cry { TIME_MEASURE_START(miner_tx_handle_time); if (m_refresh_type != RefreshNoCoinbase) - process_new_transaction(get_transaction_hash(b.miner_tx), b.miner_tx, parsed_block.o_indices.indices[0].indices, height, b.timestamp, true, false, false, tx_cache_data[tx_cache_data_offset]); + process_new_transaction(get_transaction_hash(b.miner_tx), b.miner_tx, parsed_block.o_indices.indices[0].indices, height, b.timestamp, true, false, false, tx_cache_data[tx_cache_data_offset], output_tracker_cache); ++tx_cache_data_offset; TIME_MEASURE_FINISH(miner_tx_handle_time); @@ -2038,7 +2056,7 @@ void wallet2::process_new_blockchain_entry(const cryptonote::block& b, const cry THROW_WALLET_EXCEPTION_IF(bche.txs.size() != parsed_block.txes.size(), error::wallet_internal_error, "Wrong amount of transactions for block"); for (size_t idx = 0; idx < b.tx_hashes.size(); ++idx) { - process_new_transaction(b.tx_hashes[idx], parsed_block.txes[idx], parsed_block.o_indices.indices[idx+1].indices, height, b.timestamp, false, false, false, tx_cache_data[tx_cache_data_offset++]); + process_new_transaction(b.tx_hashes[idx], parsed_block.txes[idx], parsed_block.o_indices.indices[idx+1].indices, height, b.timestamp, false, false, false, tx_cache_data[tx_cache_data_offset++], output_tracker_cache); } TIME_MEASURE_FINISH(txs_handle_time); m_last_block_reward = cryptonote::get_outs_money_amount(b.miner_tx); @@ -2136,7 +2154,7 @@ void wallet2::pull_hashes(uint64_t start_height, uint64_t &blocks_start_height, hashes = std::move(res.m_block_ids); } //---------------------------------------------------------------------------------------------------- -void wallet2::process_parsed_blocks(uint64_t start_height, const std::vector &blocks, const std::vector &parsed_blocks, uint64_t& blocks_added) +void wallet2::process_parsed_blocks(uint64_t start_height, const std::vector &blocks, const std::vector &parsed_blocks, uint64_t& blocks_added, std::map, size_t> *output_tracker_cache) { size_t current_index = start_height; blocks_added = 0; @@ -2243,7 +2261,7 @@ void wallet2::process_parsed_blocks(uint64_t start_height, const std::vector= m_blockchain.size()) { - process_new_blockchain_entry(bl, blocks[i], parsed_blocks[i], bl_id, current_index, tx_cache_data, tx_cache_data_offset); + process_new_blockchain_entry(bl, blocks[i], parsed_blocks[i], bl_id, current_index, tx_cache_data, tx_cache_data_offset, output_tracker_cache); ++blocks_added; } else if(bl_id != m_blockchain[current_index]) @@ -2255,7 +2273,7 @@ void wallet2::process_parsed_blocks(uint64_t start_height, const std::vector, size_t>> wallet2::create_output_tracker_cache() const +{ + std::shared_ptr, size_t>> cache{new std::map, size_t>()}; + for (size_t i = 0; i < m_transfers.size(); ++i) + { + const transfer_details &td = m_transfers[i]; + (*cache)[std::make_pair(td.is_rct() ? 0 : td.amount(), td.m_global_output_index)] = i; + } + return cache; +} //---------------------------------------------------------------------------------------------------- void wallet2::refresh(bool trusted_daemon, uint64_t start_height, uint64_t & blocks_fetched, bool& received_money) { @@ -2734,6 +2763,7 @@ void wallet2::refresh(bool trusted_daemon, uint64_t start_height, uint64_t & blo std::vector blocks; std::vector parsed_blocks; bool refreshed = false; + std::shared_ptr, size_t>> output_tracker_cache; // pull the first set of blocks get_short_chain_history(short_chain_history, (m_first_refresh_done || trusted_daemon) ? 1 : FIRST_REFRESH_GRANULARITY); @@ -2787,7 +2817,7 @@ void wallet2::refresh(bool trusted_daemon, uint64_t start_height, uint64_t & blo { try { - process_parsed_blocks(blocks_start_height, blocks, parsed_blocks, added_blocks); + process_parsed_blocks(blocks_start_height, blocks, parsed_blocks, added_blocks, output_tracker_cache.get()); } catch (const tools::error::out_of_hashchain_bounds_error&) { @@ -2830,6 +2860,11 @@ void wallet2::refresh(bool trusted_daemon, uint64_t start_height, uint64_t & blo throw std::runtime_error("proxy exception in refresh thread"); } + // if we've got at least 10 blocks to refresh, assume we're starting + // a long refresh, and setup a tracking output cache if we need to + if (m_track_uses && !output_tracker_cache && next_blocks.size() >= 10) + output_tracker_cache = create_output_tracker_cache(); + // switch to the new blocks from the daemon blocks_start_height = next_blocks_start_height; blocks = std::move(next_blocks); diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 52579376f..5b1988080 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -1253,8 +1253,8 @@ namespace tools * \param password Password of wallet file */ bool load_keys(const std::string& keys_file_name, const epee::wipeable_string& password); - void process_new_transaction(const crypto::hash &txid, const cryptonote::transaction& tx, const std::vector &o_indices, uint64_t height, uint64_t ts, bool miner_tx, bool pool, bool double_spend_seen, const tx_cache_data &tx_cache_data); - void process_new_blockchain_entry(const cryptonote::block& b, const cryptonote::block_complete_entry& bche, const parsed_block &parsed_block, const crypto::hash& bl_id, uint64_t height, const std::vector &tx_cache_data, size_t tx_cache_data_offset); + void process_new_transaction(const crypto::hash &txid, const cryptonote::transaction& tx, const std::vector &o_indices, uint64_t height, uint64_t ts, bool miner_tx, bool pool, bool double_spend_seen, const tx_cache_data &tx_cache_data, std::map, size_t> *output_tracker_cache = NULL); + void process_new_blockchain_entry(const cryptonote::block& b, const cryptonote::block_complete_entry& bche, const parsed_block &parsed_block, const crypto::hash& bl_id, uint64_t height, const std::vector &tx_cache_data, size_t tx_cache_data_offset, std::map, size_t> *output_tracker_cache = NULL); void detach_blockchain(uint64_t height); void get_short_chain_history(std::list& ids, uint64_t granularity = 1) const; bool clear(); @@ -1262,7 +1262,7 @@ namespace tools void pull_hashes(uint64_t start_height, uint64_t& blocks_start_height, const std::list &short_chain_history, std::vector &hashes); void fast_refresh(uint64_t stop_height, uint64_t &blocks_start_height, std::list &short_chain_history, bool force = false); void pull_and_parse_next_blocks(uint64_t start_height, uint64_t &blocks_start_height, std::list &short_chain_history, const std::vector &prev_blocks, const std::vector &prev_parsed_blocks, std::vector &blocks, std::vector &parsed_blocks, bool &error); - void process_parsed_blocks(uint64_t start_height, const std::vector &blocks, const std::vector &parsed_blocks, uint64_t& blocks_added); + void process_parsed_blocks(uint64_t start_height, const std::vector &blocks, const std::vector &parsed_blocks, uint64_t& blocks_added, std::map, size_t> *output_tracker_cache = NULL); uint64_t select_transfers(uint64_t needed_money, std::vector unused_transfers_indices, std::vector& selected_transfers) const; bool prepare_file_names(const std::string& file_path); void process_unconfirmed(const crypto::hash &txid, const cryptonote::transaction& tx, uint64_t height); @@ -1316,6 +1316,7 @@ namespace tools std::unordered_set &pkeys) const; void cache_tx_data(const cryptonote::transaction& tx, const crypto::hash &txid, tx_cache_data &tx_cache_data) const; + std::shared_ptr, size_t>> create_output_tracker_cache() const; void setup_new_blockchain(); void create_keys_file(const std::string &wallet_, bool watch_only, const epee::wipeable_string &password, bool create_address_file); From 4422b14ac06965f8844d722ceb38e383a6d3240a Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Mon, 26 Nov 2018 00:19:10 +0000 Subject: [PATCH 25/40] epee: avoid string allocation when parsing a pod from string --- contrib/epee/include/string_tools.h | 48 ++++++++--------------------- src/checkpoints/checkpoints.cpp | 4 +-- 2 files changed, 14 insertions(+), 38 deletions(-) diff --git a/contrib/epee/include/string_tools.h b/contrib/epee/include/string_tools.h index 6a063cc36..0d8eca727 100644 --- a/contrib/epee/include/string_tools.h +++ b/contrib/epee/include/string_tools.h @@ -117,16 +117,12 @@ namespace string_tools return to_hex::string(to_byte_span(to_span(src))); } //---------------------------------------------------------------------------- - template - bool parse_hexstr_to_binbuff(const std::basic_string& s, std::basic_string& res) + inline bool parse_hexstr_to_binbuff(const epee::span s, epee::span& res) { - res.clear(); - if (s.size() & 1) - return false; - try - { - res.resize(s.size() / 2); - unsigned char *dst = (unsigned char *)res.data(); + if (s.size() != res.size() * 2) + return false; + + unsigned char *dst = (unsigned char *)&res[0]; const unsigned char *src = (const unsigned char *)s.data(); for(size_t i = 0; i < s.size(); i += 2) { @@ -140,28 +136,15 @@ namespace string_tools } return true; - } - catch(...) - { - return false; - } } //---------------------------------------------------------------------------- - template - bool parse_tpod_from_hex_string(const std::string& str_hash, t_pod_type& t_pod) + inline bool parse_hexstr_to_binbuff(const std::string& s, std::string& res) { - static_assert(std::is_pod::value, "expected pod type"); - std::string buf; - bool res = epee::string_tools::parse_hexstr_to_binbuff(str_hash, buf); - if (!res || buf.size() != sizeof(t_pod_type)) - { + if (s.size() & 1) return false; - } - else - { - buf.copy(reinterpret_cast(&t_pod), sizeof(t_pod_type)); - return true; - } + res.resize(s.size() / 2); + epee::span rspan((char*)&res[0], res.size()); + return parse_hexstr_to_binbuff(epee::to_span(s), rspan); } //---------------------------------------------------------------------------- PUSH_WARNINGS @@ -360,17 +343,10 @@ POP_WARNINGS bool hex_to_pod(const std::string& hex_str, t_pod_type& s) { static_assert(std::is_pod::value, "expected pod type"); - std::string hex_str_tr = trim(hex_str); if(sizeof(s)*2 != hex_str.size()) return false; - std::string bin_buff; - if(!parse_hexstr_to_binbuff(hex_str_tr, bin_buff)) - return false; - if(bin_buff.size()!=sizeof(s)) - return false; - - s = *(t_pod_type*)bin_buff.data(); - return true; + epee::span rspan((char*)&s, sizeof(s)); + return parse_hexstr_to_binbuff(epee::to_span(hex_str), rspan); } //---------------------------------------------------------------------------- template diff --git a/src/checkpoints/checkpoints.cpp b/src/checkpoints/checkpoints.cpp index 467b2174d..541c098a6 100644 --- a/src/checkpoints/checkpoints.cpp +++ b/src/checkpoints/checkpoints.cpp @@ -74,7 +74,7 @@ namespace cryptonote bool checkpoints::add_checkpoint(uint64_t height, const std::string& hash_str) { crypto::hash h = crypto::null_hash; - bool r = epee::string_tools::parse_tpod_from_hex_string(hash_str, h); + bool r = epee::string_tools::hex_to_pod(hash_str, h); CHECK_AND_ASSERT_MES(r, false, "Failed to parse checkpoint hash string into binary representation!"); // return false if adding at a height we already have AND the hash is different @@ -283,7 +283,7 @@ namespace cryptonote // parse the second part as crypto::hash, // if this fails move on to the next record std::string hashStr = record.substr(pos + 1); - if (!epee::string_tools::parse_tpod_from_hex_string(hashStr, hash)) + if (!epee::string_tools::hex_to_pod(hashStr, hash)) { continue; } From 76c97e4dbc9772d531a38c737c91a30a181840e4 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Mon, 26 Nov 2018 15:49:17 +0000 Subject: [PATCH 26/40] epee: speed up string matching a bit --- contrib/epee/include/storages/parserse_base_utils.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/contrib/epee/include/storages/parserse_base_utils.h b/contrib/epee/include/storages/parserse_base_utils.h index 31495ae13..d73fbde3a 100644 --- a/contrib/epee/include/storages/parserse_base_utils.h +++ b/contrib/epee/include/storages/parserse_base_utils.h @@ -91,11 +91,15 @@ namespace misc_utils */ inline void match_string2(std::string::const_iterator& star_end_string, std::string::const_iterator buf_end, std::string& val) { - val.clear(); - val.reserve(std::distance(star_end_string, buf_end)); bool escape_mode = false; std::string::const_iterator it = star_end_string; ++it; + std::string::const_iterator fi = it; + while (fi != buf_end && *fi != '\\' && *fi != '\"') + ++fi; + val.assign(it, fi); + val.reserve(std::distance(star_end_string, buf_end)); + it = fi; for(;it != buf_end;it++) { if(escape_mode/*prev_ch == '\\'*/) From 70d90326a7f48b462d421e2a5a8454e05d11e795 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Fri, 7 Dec 2018 12:32:32 +0000 Subject: [PATCH 27/40] add a once_a_time_milliseconds class --- contrib/epee/include/math_helper.h | 39 +++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/contrib/epee/include/math_helper.h b/contrib/epee/include/math_helper.h index ef839f609..e22e8ee6e 100644 --- a/contrib/epee/include/math_helper.h +++ b/contrib/epee/include/math_helper.h @@ -230,35 +230,56 @@ namespace math_helper } } - template - class once_a_time_seconds + template + class once_a_time { + uint64_t get_time() const + { +#ifdef _WIN32 + FILETIME fileTime; + GetSystemTimeAsFileTime(&fileTime); + unsigned __int64 present = 0; + present |= fileTime.dwHighDateTime; + present = present << 32; + present |= fileTime.dwLowDateTime; + present /= 10; // mic-sec +#else + struct timeval tv; + gettimeofday(&tv, NULL); + return tv.tv_sec * 1000000 + tv.tv_usec; +#endif + } + public: - once_a_time_seconds():m_interval(default_interval) + once_a_time():m_interval(default_interval * scale) { m_last_worked_time = 0; if(!start_immediate) - time(&m_last_worked_time); + m_last_worked_time = get_time(); } template bool do_call(functor_t functr) { - time_t current_time = 0; - time(¤t_time); + uint64_t current_time = get_time(); if(current_time - m_last_worked_time > m_interval) { bool res = functr(); - time(&m_last_worked_time); + m_last_worked_time = get_time(); return res; } return true; } private: - time_t m_last_worked_time; - time_t m_interval; + uint64_t m_last_worked_time; + uint64_t m_interval; }; + + template + class once_a_time_seconds: public once_a_time<1000000, default_interval, start_immediate> {}; + template + class once_a_time_milliseconds: public once_a_time<1000, default_interval, start_immediate> {}; } } From 0c87b55670d92931fc3946bef715472e644010d7 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Fri, 7 Dec 2018 12:32:50 +0000 Subject: [PATCH 28/40] protocol: change standby mode to not wait sleeping --- .../cryptonote_protocol_handler.h | 2 ++ .../cryptonote_protocol_handler.inl | 34 ++++++++++++------- 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/src/cryptonote_protocol/cryptonote_protocol_handler.h b/src/cryptonote_protocol/cryptonote_protocol_handler.h index d7b74c06d..618b635cc 100644 --- a/src/cryptonote_protocol/cryptonote_protocol_handler.h +++ b/src/cryptonote_protocol/cryptonote_protocol_handler.h @@ -131,6 +131,7 @@ namespace cryptonote bool should_download_next_span(cryptonote_connection_context& context) const; void drop_connection(cryptonote_connection_context &context, bool add_fail, bool flush_all_spans); bool kick_idle_peers(); + bool check_standby_peers(); int try_add_next_blocks(cryptonote_connection_context &context); t_core& m_core; @@ -143,6 +144,7 @@ namespace cryptonote boost::mutex m_sync_lock; block_queue m_block_queue; epee::math_helper::once_a_time_seconds<30> m_idle_peer_kicker; + epee::math_helper::once_a_time_milliseconds<100> m_standby_checker; boost::mutex m_buffer_mutex; double get_avg_block_size(); diff --git a/src/cryptonote_protocol/cryptonote_protocol_handler.inl b/src/cryptonote_protocol/cryptonote_protocol_handler.inl index 617d98352..fbbdd965f 100644 --- a/src/cryptonote_protocol/cryptonote_protocol_handler.inl +++ b/src/cryptonote_protocol/cryptonote_protocol_handler.inl @@ -1208,6 +1208,7 @@ skip: bool t_cryptonote_protocol_handler::on_idle() { m_idle_peer_kicker.do_call(boost::bind(&t_cryptonote_protocol_handler::kick_idle_peers, this)); + m_standby_checker.do_call(boost::bind(&t_cryptonote_protocol_handler::check_standby_peers, this)); return m_core.on_idle(); } //------------------------------------------------------------------------------------------------------------------------ @@ -1243,6 +1244,22 @@ skip: } //------------------------------------------------------------------------------------------------------------------------ template + bool t_cryptonote_protocol_handler::check_standby_peers() + { + m_p2p->for_each_connection([&](cryptonote_connection_context& context, nodetool::peerid_type peer_id, uint32_t support_flags)->bool + { + if (context.m_state == cryptonote_connection_context::state_standby) + { + LOG_PRINT_CCONTEXT_L2("requesting callback"); + ++context.m_callback_request_count; + m_p2p->request_callback(context); + } + return true; + }); + return true; + } + //------------------------------------------------------------------------------------------------------------------------ + template int t_cryptonote_protocol_handler::handle_request_chain(int command, NOTIFY_REQUEST_CHAIN::request& arg, cryptonote_connection_context& context) { MLOG_P2P_MESSAGE("Received NOTIFY_REQUEST_CHAIN (" << arg.block_ids.size() << " blocks"); @@ -1336,14 +1353,13 @@ skip: bool start_from_current_chain = false; if (!force_next_span) { - bool first = true; - while (1) + do { size_t nblocks = m_block_queue.get_num_filled_spans(); size_t size = m_block_queue.get_data_size(); if (nblocks < BLOCK_QUEUE_NBLOCKS_THRESHOLD || size < BLOCK_QUEUE_SIZE_THRESHOLD) { - if (!first) + if (context.m_state != cryptonote_connection_context::state_standby) { LOG_DEBUG_CC(context, "Block queue is " << nblocks << " and " << size << ", resuming"); } @@ -1366,10 +1382,9 @@ skip: break; } - if (first) + if (context.m_state != cryptonote_connection_context::state_standby) { LOG_DEBUG_CC(context, "Block queue is " << nblocks << " and " << size << ", pausing"); - first = false; context.m_state = cryptonote_connection_context::state_standby; } @@ -1383,13 +1398,8 @@ skip: return true; } - for (size_t n = 0; n < 50; ++n) - { - if (m_stopping) - return true; - boost::this_thread::sleep_for(boost::chrono::milliseconds(100)); - } - } + return true; + } while(0); context.m_state = cryptonote_connection_context::state_synchronizing; } From 0030100645e4938c176b3a35374ed7cfd45adb1f Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Thu, 6 Dec 2018 00:38:24 +0000 Subject: [PATCH 29/40] easylogging++: check allowed categories before logging --- contrib/epee/include/misc_log_ex.h | 23 +++++++++++++++-------- external/easylogging++/easylogging++.cc | 19 +++++++++++++++++++ external/easylogging++/easylogging++.h | 2 ++ 3 files changed, 36 insertions(+), 8 deletions(-) diff --git a/contrib/epee/include/misc_log_ex.h b/contrib/epee/include/misc_log_ex.h index 9100a8db3..1ff9da3a7 100644 --- a/contrib/epee/include/misc_log_ex.h +++ b/contrib/epee/include/misc_log_ex.h @@ -38,14 +38,21 @@ #define MAX_LOG_FILE_SIZE 104850000 // 100 MB - 7600 bytes #define MAX_LOG_FILES 50 -#define MCFATAL(cat,x) CLOG(FATAL,cat) << x -#define MCERROR(cat,x) CLOG(ERROR,cat) << x -#define MCWARNING(cat,x) CLOG(WARNING,cat) << x -#define MCINFO(cat,x) CLOG(INFO,cat) << x -#define MCDEBUG(cat,x) CLOG(DEBUG,cat) << x -#define MCTRACE(cat,x) CLOG(TRACE,cat) << x -#define MCLOG(level,cat,x) ELPP_WRITE_LOG(el::base::Writer, level, el::base::DispatchAction::NormalLog, cat) << x -#define MCLOG_FILE(level,cat,x) ELPP_WRITE_LOG(el::base::Writer, level, el::base::DispatchAction::FileOnlyLog, cat) << x +#define MCLOG_TYPE(level, cat, type, x) do { \ + if (ELPP->vRegistry()->allowed(level, cat)) { \ + el::base::Writer(level, __FILE__, __LINE__, ELPP_FUNC, type).construct(cat) << x; \ + } \ + } while (0) + +#define MCLOG(level, cat, x) MCLOG_TYPE(level, cat, el::base::DispatchAction::NormalLog, x) +#define MCLOG_FILE(level, cat, x) MCLOG_TYPE(level, cat, el::base::DispatchAction::FileOnlyLog, x) + +#define MCFATAL(cat,x) MCLOG(el::Level::Fatal,cat, x) +#define MCERROR(cat,x) MCLOG(el::Level::Error,cat, x) +#define MCWARNING(cat,x) MCLOG(el::Level::Warning,cat, x) +#define MCINFO(cat,x) MCLOG(el::Level::Info,cat, x) +#define MCDEBUG(cat,x) MCLOG(el::Level::Debug,cat, x) +#define MCTRACE(cat,x) MCLOG(el::Level::Trace,cat, x) #define MCLOG_COLOR(level,cat,color,x) MCLOG(level,cat,"\033[1;" color "m" << x << "\033[0m") #define MCLOG_RED(level,cat,x) MCLOG_COLOR(level,cat,"31",x) diff --git a/external/easylogging++/easylogging++.cc b/external/easylogging++/easylogging++.cc index ab4ee49c3..f5f7481f8 100644 --- a/external/easylogging++/easylogging++.cc +++ b/external/easylogging++/easylogging++.cc @@ -2693,6 +2693,12 @@ Writer& Writer::construct(int count, const char* loggerIds, ...) { return *this; } +Writer& Writer::construct(const char *loggerId) { + initializeLogger(ELPP->registeredLoggers()->get(loggerId, ELPP->hasFlag(LoggingFlag::CreateLoggerAutomatically))); + m_messageBuilder.initialize(m_logger); + return *this; +} + void Writer::initializeLogger(const std::string& loggerId, bool lookup, bool needLock) { if (lookup) { m_logger = ELPP->registeredLoggers()->get(loggerId, ELPP->hasFlag(LoggingFlag::CreateLoggerAutomatically)); @@ -2721,6 +2727,19 @@ void Writer::initializeLogger(const std::string& loggerId, bool lookup, bool nee } } +void Writer::initializeLogger(Logger *logger, bool needLock) { + m_logger = logger; + if (m_logger == nullptr) { + m_proceed = false; + } else { + if (needLock) { + m_logger->acquireLock(); // This should not be unlocked by checking m_proceed because + // m_proceed can be changed by lines below + } + m_proceed = true; + } +} + void Writer::processDispatch() { #if ELPP_LOGGING_ENABLED if (ELPP->hasFlag(LoggingFlag::MultiLoggerSupport)) { diff --git a/external/easylogging++/easylogging++.h b/external/easylogging++/easylogging++.h index 1e27f62a6..d9a2dc3d1 100644 --- a/external/easylogging++/easylogging++.h +++ b/external/easylogging++/easylogging++.h @@ -3290,6 +3290,7 @@ class Writer : base::NoCopy { Writer& construct(Logger* logger, bool needLock = true); Writer& construct(int count, const char* loggerIds, ...); + Writer& construct(const char *loggerId); protected: LogMessage* m_msg; Level m_level; @@ -3305,6 +3306,7 @@ class Writer : base::NoCopy { friend class el::Helpers; void initializeLogger(const std::string& loggerId, bool lookup = true, bool needLock = true); + void initializeLogger(Logger *logger, bool needLock = true); void processDispatch(); void triggerDispatch(void); }; From f875a0312e4763e595adca81446abc750bd4b5cd Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Fri, 7 Dec 2018 13:13:24 +0000 Subject: [PATCH 30/40] mlocker: set default log category --- contrib/epee/src/mlocker.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/contrib/epee/src/mlocker.cpp b/contrib/epee/src/mlocker.cpp index 078a84ce3..446fa3315 100644 --- a/contrib/epee/src/mlocker.cpp +++ b/contrib/epee/src/mlocker.cpp @@ -40,6 +40,9 @@ #include +#undef MONERO_DEFAULT_LOG_CATEGORY +#define MONERO_DEFAULT_LOG_CATEGORY "mlocker" + // did an mlock operation previously fail? we only // want to log an error once and be done with it static std::atomic previously_failed{ false }; From 28477c75a30ac411287329ad17f74b91433a1e2d Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Wed, 5 Dec 2018 22:25:27 +0000 Subject: [PATCH 31/40] p2p: use vector instead of list for peer lists --- src/p2p/net_node.h | 6 +++--- src/p2p/net_node.inl | 10 +++++----- src/p2p/net_peerlist.h | 15 +++++++++------ src/p2p/p2p_protocol_defs.h | 20 ++++++++++---------- src/rpc/core_rpc_server.cpp | 7 ++++--- tests/unit_tests/test_peerlist.cpp | 6 +++--- 6 files changed, 34 insertions(+), 30 deletions(-) diff --git a/src/p2p/net_node.h b/src/p2p/net_node.h index 1e52a013e..2b9abfd5f 100644 --- a/src/p2p/net_node.h +++ b/src/p2p/net_node.h @@ -194,12 +194,12 @@ namespace nodetool const boost::program_options::variables_map& vm ); bool idle_worker(); - bool handle_remote_peerlist(const std::list& peerlist, time_t local_time, const epee::net_utils::connection_context_base& context); + bool handle_remote_peerlist(const std::vector& peerlist, time_t local_time, const epee::net_utils::connection_context_base& context); bool get_local_node_data(basic_node_data& node_data); //bool get_local_handshake_data(handshake_data& hshd); - bool merge_peerlist_with_local(const std::list& bs); - bool fix_time_delta(std::list& local_peerlist, time_t local_time, int64_t& delta); + bool merge_peerlist_with_local(const std::vector& bs); + bool fix_time_delta(std::vector& local_peerlist, time_t local_time, int64_t& delta); bool connections_maker(); bool peer_sync_idle_maker(); diff --git a/src/p2p/net_node.inl b/src/p2p/net_node.inl index e75e2878b..608e7d2ac 100644 --- a/src/p2p/net_node.inl +++ b/src/p2p/net_node.inl @@ -1365,7 +1365,7 @@ namespace nodetool } //----------------------------------------------------------------------------------- template - bool node_server::fix_time_delta(std::list& local_peerlist, time_t local_time, int64_t& delta) + bool node_server::fix_time_delta(std::vector& local_peerlist, time_t local_time, int64_t& delta) { //fix time delta time_t now = 0; @@ -1385,10 +1385,10 @@ namespace nodetool } //----------------------------------------------------------------------------------- template - bool node_server::handle_remote_peerlist(const std::list& peerlist, time_t local_time, const epee::net_utils::connection_context_base& context) + bool node_server::handle_remote_peerlist(const std::vector& peerlist, time_t local_time, const epee::net_utils::connection_context_base& context) { int64_t delta = 0; - std::list peerlist_ = peerlist; + std::vector peerlist_ = peerlist; if(!fix_time_delta(peerlist_, local_time, delta)) return false; LOG_DEBUG_CC(context, "REMOTE PEERLIST: TIME_DELTA: " << delta << ", remote peerlist size=" << peerlist_.size()); @@ -1770,8 +1770,8 @@ namespace nodetool template bool node_server::log_peerlist() { - std::list pl_white; - std::list pl_gray; + std::vector pl_white; + std::vector pl_gray; m_peerlist.get_peerlist_full(pl_gray, pl_white); MINFO(ENDL << "Peerlist white:" << ENDL << print_peerlist_to_string(pl_white) << ENDL << "Peerlist gray:" << ENDL << print_peerlist_to_string(pl_gray) ); return true; diff --git a/src/p2p/net_peerlist.h b/src/p2p/net_peerlist.h index 1d609a37e..e7aad5abe 100644 --- a/src/p2p/net_peerlist.h +++ b/src/p2p/net_peerlist.h @@ -68,9 +68,9 @@ namespace nodetool bool deinit(); size_t get_white_peers_count(){CRITICAL_REGION_LOCAL(m_peerlist_lock); return m_peers_white.size();} size_t get_gray_peers_count(){CRITICAL_REGION_LOCAL(m_peerlist_lock); return m_peers_gray.size();} - bool merge_peerlist(const std::list& outer_bs); - bool get_peerlist_head(std::list& bs_head, uint32_t depth = P2P_DEFAULT_PEERS_IN_HANDSHAKE); - bool get_peerlist_full(std::list& pl_gray, std::list& pl_white); + bool merge_peerlist(const std::vector& outer_bs); + bool get_peerlist_head(std::vector& bs_head, uint32_t depth = P2P_DEFAULT_PEERS_IN_HANDSHAKE); + bool get_peerlist_full(std::vector& pl_gray, std::vector& pl_white); bool get_white_peer_by_index(peerlist_entry& p, size_t i); bool get_gray_peer_by_index(peerlist_entry& p, size_t i); bool append_with_peer_white(const peerlist_entry& pr); @@ -265,7 +265,7 @@ namespace nodetool } //-------------------------------------------------------------------------------------------------- inline - bool peerlist_manager::merge_peerlist(const std::list& outer_bs) + bool peerlist_manager::merge_peerlist(const std::vector& outer_bs) { CRITICAL_REGION_LOCAL(m_peerlist_lock); for(const peerlist_entry& be: outer_bs) @@ -315,12 +315,13 @@ namespace nodetool } //-------------------------------------------------------------------------------------------------- inline - bool peerlist_manager::get_peerlist_head(std::list& bs_head, uint32_t depth) + bool peerlist_manager::get_peerlist_head(std::vector& bs_head, uint32_t depth) { CRITICAL_REGION_LOCAL(m_peerlist_lock); peers_indexed::index::type& by_time_index=m_peers_white.get(); uint32_t cnt = 0; + bs_head.reserve(depth); for(const peers_indexed::value_type& vl: boost::adaptors::reverse(by_time_index)) { if(!vl.last_seen) @@ -335,16 +336,18 @@ namespace nodetool } //-------------------------------------------------------------------------------------------------- inline - bool peerlist_manager::get_peerlist_full(std::list& pl_gray, std::list& pl_white) + bool peerlist_manager::get_peerlist_full(std::vector& pl_gray, std::vector& pl_white) { CRITICAL_REGION_LOCAL(m_peerlist_lock); peers_indexed::index::type& by_time_index_gr=m_peers_gray.get(); + pl_gray.resize(pl_gray.size() + by_time_index_gr.size()); for(const peers_indexed::value_type& vl: boost::adaptors::reverse(by_time_index_gr)) { pl_gray.push_back(vl); } peers_indexed::index::type& by_time_index_wt=m_peers_white.get(); + pl_white.resize(pl_white.size() + by_time_index_wt.size()); for(const peers_indexed::value_type& vl: boost::adaptors::reverse(by_time_index_wt)) { pl_white.push_back(vl); diff --git a/src/p2p/p2p_protocol_defs.h b/src/p2p/p2p_protocol_defs.h index e793e19b6..bb9d2635c 100644 --- a/src/p2p/p2p_protocol_defs.h +++ b/src/p2p/p2p_protocol_defs.h @@ -114,7 +114,7 @@ namespace nodetool #pragma pack(pop) inline - std::string print_peerlist_to_string(const std::list& pl) + std::string print_peerlist_to_string(const std::vector& pl) { time_t now_time = 0; time(&now_time); @@ -189,7 +189,7 @@ namespace nodetool { basic_node_data node_data; t_playload_type payload_data; - std::list local_peerlist_new; + std::vector local_peerlist_new; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(node_data) @@ -198,7 +198,7 @@ namespace nodetool { // saving: save both, so old and new peers can understand it KV_SERIALIZE(local_peerlist_new) - std::list> local_peerlist; + std::vector> local_peerlist; for (const auto &p: this_ref.local_peerlist_new) { if (p.adr.get_type_id() == epee::net_utils::ipv4_network_address::ID) @@ -217,7 +217,7 @@ namespace nodetool // loading: load old list only if there is no new one if (!epee::serialization::selector::serialize(this_ref.local_peerlist_new, stg, hparent_section, "local_peerlist_new")) { - std::list> local_peerlist; + std::vector> local_peerlist; epee::serialization::selector::serialize_stl_container_pod_val_as_blob(local_peerlist, stg, hparent_section, "local_peerlist"); for (const auto &p: local_peerlist) ((response&)this_ref).local_peerlist_new.push_back(peerlist_entry({epee::net_utils::ipv4_network_address(p.adr.ip, p.adr.port), p.id, p.last_seen})); @@ -248,7 +248,7 @@ namespace nodetool { uint64_t local_time; t_playload_type payload_data; - std::list local_peerlist_new; + std::vector local_peerlist_new; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(local_time) @@ -257,7 +257,7 @@ namespace nodetool { // saving: save both, so old and new peers can understand it KV_SERIALIZE(local_peerlist_new) - std::list> local_peerlist; + std::vector> local_peerlist; for (const auto &p: this_ref.local_peerlist_new) { if (p.adr.get_type_id() == epee::net_utils::ipv4_network_address::ID) @@ -276,7 +276,7 @@ namespace nodetool // loading: load old list only if there is no new one if (!epee::serialization::selector::serialize(this_ref.local_peerlist_new, stg, hparent_section, "local_peerlist_new")) { - std::list> local_peerlist; + std::vector> local_peerlist; epee::serialization::selector::serialize_stl_container_pod_val_as_blob(local_peerlist, stg, hparent_section, "local_peerlist"); for (const auto &p: local_peerlist) ((response&)this_ref).local_peerlist_new.push_back(peerlist_entry({epee::net_utils::ipv4_network_address(p.adr.ip, p.adr.port), p.id, p.last_seen})); @@ -389,9 +389,9 @@ namespace nodetool struct response { - std::list local_peerlist_white; - std::list local_peerlist_gray; - std::list connections_list; + std::vector local_peerlist_white; + std::vector local_peerlist_gray; + std::vector connections_list; peerid_type my_id; uint64_t local_time; BEGIN_KV_SERIALIZE_MAP() diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index 990bfc5b4..af7548060 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -857,11 +857,11 @@ namespace cryptonote bool core_rpc_server::on_get_peer_list(const COMMAND_RPC_GET_PEER_LIST::request& req, COMMAND_RPC_GET_PEER_LIST::response& res) { PERF_TIMER(on_get_peer_list); - std::list white_list; - std::list gray_list; + std::vector white_list; + std::vector gray_list; m_p2p.get_peerlist_manager().get_peerlist_full(gray_list, white_list); - + res.white_list.reserve(white_list.size()); for (auto & entry : white_list) { if (entry.adr.get_type_id() == epee::net_utils::ipv4_network_address::ID) @@ -871,6 +871,7 @@ namespace cryptonote res.white_list.emplace_back(entry.id, entry.adr.str(), entry.last_seen); } + res.gray_list.reserve(gray_list.size()); for (auto & entry : gray_list) { if (entry.adr.get_type_id() == epee::net_utils::ipv4_network_address::ID) diff --git a/tests/unit_tests/test_peerlist.cpp b/tests/unit_tests/test_peerlist.cpp index c6572c6c2..f638c6251 100644 --- a/tests/unit_tests/test_peerlist.cpp +++ b/tests/unit_tests/test_peerlist.cpp @@ -42,7 +42,7 @@ TEST(peer_list, peer_list_general) #define ADD_GRAY_NODE(addr_, id_, last_seen_) { nodetool::peerlist_entry ple; ple.last_seen=last_seen_;ple.adr = addr_; ple.id = id_;plm.append_with_peer_gray(ple);} #define ADD_WHITE_NODE(addr_, id_, last_seen_) { nodetool::peerlist_entry ple;ple.last_seen=last_seen_; ple.adr = addr_; ple.id = id_;plm.append_with_peer_white(ple);} -#define PRINT_HEAD(step) {std::list bs_head; bool r = plm.get_peerlist_head(bs_head, 100);std::cout << "step " << step << ": " << bs_head.size() << std::endl;} +#define PRINT_HEAD(step) {std::vector bs_head; bool r = plm.get_peerlist_head(bs_head, 100);std::cout << "step " << step << ": " << bs_head.size() << std::endl;} ADD_GRAY_NODE(MAKE_IPV4_ADDRESS(123,43,12,1, 8080), 121241, 34345); ADD_GRAY_NODE(MAKE_IPV4_ADDRESS(123,43,12,2, 8080), 121241, 34345); @@ -58,7 +58,7 @@ TEST(peer_list, peer_list_general) size_t gray_list_size = plm.get_gray_peers_count(); ASSERT_EQ(gray_list_size, 1); - std::list bs_head; + std::vector bs_head; bool r = plm.get_peerlist_head(bs_head, 100); std::cout << bs_head.size() << std::endl; ASSERT_TRUE(r); @@ -78,7 +78,7 @@ TEST(peer_list, merge_peer_lists) //ADD_NODE_TO_PL("\2", \3, 0x\1, (1353346618 -(\4*60*60*24+\5*60*60+\6*60+\7 )));\n nodetool::peerlist_manager plm; plm.init(false); - std::list outer_bs; + std::vector outer_bs; #define ADD_NODE_TO_PL(ip_, port_, id_, timestamp_) { nodetool::peerlist_entry ple; epee::string_tools::get_ip_int32_from_string(ple.adr.ip, ip_); ple.last_seen = timestamp_; ple.adr.port = port_; ple.id = id_;outer_bs.push_back(ple);} From af2d19cf700623ffc315e405d1f5d6ac486eaa6b Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Wed, 31 Oct 2018 13:26:54 +0000 Subject: [PATCH 32/40] perf_timer: only log to file --- src/common/perf_timer.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/common/perf_timer.cpp b/src/common/perf_timer.cpp index d9f1f65c1..d287949ba 100644 --- a/src/common/perf_timer.cpp +++ b/src/common/perf_timer.cpp @@ -33,6 +33,9 @@ #undef MONERO_DEFAULT_LOG_CATEGORY #define MONERO_DEFAULT_LOG_CATEGORY "perf" +#define PERF_LOG(level, cat, x) \ + ELPP_WRITE_LOG(el::base::Writer, level, el::base::DispatchAction::FileOnlyLog, cat) << x + namespace tools { uint64_t get_tick_count() @@ -108,7 +111,7 @@ LoggingPerformanceTimer::LoggingPerformanceTimer(const std::string &s, const std { if (!performance_timers) { - MCLOG(level, cat.c_str(), "PERF ----------"); + PERF_LOG(level, cat.c_str(), "PERF ----------"); performance_timers = new std::vector(); performance_timers->reserve(16); // how deep before realloc } @@ -118,7 +121,7 @@ LoggingPerformanceTimer::LoggingPerformanceTimer(const std::string &s, const std if (!pt->started && !pt->paused) { size_t size = 0; for (const auto *tmp: *performance_timers) if (!tmp->paused) ++size; - MCLOG(pt->level, cat.c_str(), "PERF " << std::string((size-1) * 2, ' ') << " " << pt->name); + PERF_LOG(pt->level, cat.c_str(), "PERF " << std::string((size-1) * 2, ' ') << " " << pt->name); pt->started = true; } } @@ -138,7 +141,7 @@ LoggingPerformanceTimer::~LoggingPerformanceTimer() char s[12]; snprintf(s, sizeof(s), "%8llu ", (unsigned long long)(ticks_to_ns(ticks) / (1000000000 / unit))); size_t size = 0; for (const auto *tmp: *performance_timers) if (!tmp->paused || tmp==this) ++size; - MCLOG(level, cat.c_str(), "PERF " << s << std::string(size * 2, ' ') << " " << name); + PERF_LOG(level, cat.c_str(), "PERF " << s << std::string(size * 2, ' ') << " " << name); if (performance_timers->empty()) { delete performance_timers; From 70e4e4382e4a9dba90c555cf6612c727aee99c4b Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sun, 11 Mar 2018 11:17:29 +0000 Subject: [PATCH 33/40] perf_timer: add a way to get and reset the current time --- src/common/perf_timer.cpp | 16 ++++++++++++++++ src/common/perf_timer.h | 4 ++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/common/perf_timer.cpp b/src/common/perf_timer.cpp index d287949ba..fc51dc7f7 100644 --- a/src/common/perf_timer.cpp +++ b/src/common/perf_timer.cpp @@ -165,4 +165,20 @@ void PerformanceTimer::resume() paused = false; } +void PerformanceTimer::reset() +{ + if (paused) + ticks = 0; + else + ticks = get_tick_count(); +} + +uint64_t PerformanceTimer::value() const +{ + uint64_t v = ticks; + if (!paused) + v = get_tick_count() - v; + return ticks_to_ns(v); +} + } diff --git a/src/common/perf_timer.h b/src/common/perf_timer.h index 267f94161..d859cf576 100644 --- a/src/common/perf_timer.h +++ b/src/common/perf_timer.h @@ -51,8 +51,8 @@ public: ~PerformanceTimer(); void pause(); void resume(); - - uint64_t value() const { return ticks; } + void reset(); + uint64_t value() const; protected: uint64_t ticks; From 34daa571e3ffe00dfdb06fea8745b705265e681b Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Thu, 6 Dec 2018 01:07:34 +0000 Subject: [PATCH 34/40] perf_timer: check allowed categories before logging --- src/common/perf_timer.cpp | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/src/common/perf_timer.cpp b/src/common/perf_timer.cpp index fc51dc7f7..3e1357833 100644 --- a/src/common/perf_timer.cpp +++ b/src/common/perf_timer.cpp @@ -33,8 +33,12 @@ #undef MONERO_DEFAULT_LOG_CATEGORY #define MONERO_DEFAULT_LOG_CATEGORY "perf" +#define PERF_LOG_ALWAYS(level, cat, x) \ + el::base::Writer(level, __FILE__, __LINE__, ELPP_FUNC, el::base::DispatchAction::FileOnlyLog).construct(cat) << x #define PERF_LOG(level, cat, x) \ - ELPP_WRITE_LOG(el::base::Writer, level, el::base::DispatchAction::FileOnlyLog, cat) << x + do { \ + if (ELPP->vRegistry()->allowed(level, cat)) PERF_LOG_ALWAYS(level, cat, x); \ + } while(0) namespace tools { @@ -109,9 +113,11 @@ PerformanceTimer::PerformanceTimer(bool paused): started(true), paused(paused) LoggingPerformanceTimer::LoggingPerformanceTimer(const std::string &s, const std::string &cat, uint64_t unit, el::Level l): PerformanceTimer(), name(s), cat(cat), unit(unit), level(l) { + const bool log = ELPP->vRegistry()->allowed(level, cat.c_str()); if (!performance_timers) { - PERF_LOG(level, cat.c_str(), "PERF ----------"); + if (log) + PERF_LOG_ALWAYS(level, cat.c_str(), "PERF ----------"); performance_timers = new std::vector(); performance_timers->reserve(16); // how deep before realloc } @@ -120,8 +126,11 @@ LoggingPerformanceTimer::LoggingPerformanceTimer(const std::string &s, const std LoggingPerformanceTimer *pt = performance_timers->back(); if (!pt->started && !pt->paused) { - size_t size = 0; for (const auto *tmp: *performance_timers) if (!tmp->paused) ++size; - PERF_LOG(pt->level, cat.c_str(), "PERF " << std::string((size-1) * 2, ' ') << " " << pt->name); + if (log) + { + size_t size = 0; for (const auto *tmp: *performance_timers) if (!tmp->paused) ++size; + PERF_LOG_ALWAYS(pt->level, cat.c_str(), "PERF " << std::string((size-1) * 2, ' ') << " " << pt->name); + } pt->started = true; } } @@ -138,10 +147,14 @@ LoggingPerformanceTimer::~LoggingPerformanceTimer() { pause(); performance_timers->pop_back(); - char s[12]; - snprintf(s, sizeof(s), "%8llu ", (unsigned long long)(ticks_to_ns(ticks) / (1000000000 / unit))); - size_t size = 0; for (const auto *tmp: *performance_timers) if (!tmp->paused || tmp==this) ++size; - PERF_LOG(level, cat.c_str(), "PERF " << s << std::string(size * 2, ' ') << " " << name); + const bool log = ELPP->vRegistry()->allowed(level, cat.c_str()); + if (log) + { + char s[12]; + snprintf(s, sizeof(s), "%8llu ", (unsigned long long)(ticks_to_ns(ticks) / (1000000000 / unit))); + size_t size = 0; for (const auto *tmp: *performance_timers) if (!tmp->paused || tmp==this) ++size; + PERF_LOG_ALWAYS(level, cat.c_str(), "PERF " << s << std::string(size * 2, ' ') << " " << name); + } if (performance_timers->empty()) { delete performance_timers; From 6c76c778e7e5be8ad944d51bbe8abd124d1f34e8 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Fri, 7 Dec 2018 18:23:01 +0000 Subject: [PATCH 35/40] wallet2: clear all payments on soft rescan_bc They'll get duplicated otherwise --- src/wallet/wallet2.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 777a177db..e1a817859 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -5324,6 +5324,10 @@ void wallet2::rescan_blockchain(bool hard, bool refresh) m_transfers.clear(); m_key_images.clear(); m_pub_keys.clear(); + m_unconfirmed_txs.clear(); + m_payments.clear(); + m_confirmed_txs.clear(); + m_unconfirmed_payments.clear(); m_scanned_pool_txs[0].clear(); m_scanned_pool_txs[1].clear(); From c7d4338765af625162e8196b9c4ee677f56d64f6 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Tue, 11 Dec 2018 20:30:42 +0000 Subject: [PATCH 36/40] update expiry date for both signing and encryption keys --- utils/gpg_keys/moneromooo.asc | 50 +++++++++++++++++------------------ 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/utils/gpg_keys/moneromooo.asc b/utils/gpg_keys/moneromooo.asc index cce180937..4275b6c0e 100644 --- a/utils/gpg_keys/moneromooo.asc +++ b/utils/gpg_keys/moneromooo.asc @@ -13,18 +13,18 @@ p7gDvxXOGxzq0sqfPTWTBdCj1OPfunHbbeH8ypwBlNpwVG40fJdya+Dqjwu25qX6 Xh5vxLzeJTBmlawa97MCliPvzzJgW9qHRVCa9lLloGVYLiUOS0N+dZ/r/QARAQAB tD5tb25lcm9tb29vLW1vbmVybyA8bW9uZXJvbW9vby1tb25lcm9AdXNlcnMubm9y ZXBseS5naXRodWIuY29tPokCPwQTAQIAKQIbAwcLCQgHAwIBBhUIAgkKCwQWAgMB -Ah4BAheABQJbof8TBQkLMcqRAAoJEGhvB0VNbO/DOrcP/1eG3gkIgq+lXKlv/lta -ZFl8jS5iQUwxTHv8s+O7pbL2mwKt5oM8QmXVMFLlaanENmH0y/DhWRYIYuKTifDN -tXOxENCZhxgjlVxAtnMdD2J8MJANzV2MYGLbGQeFAuZHIL2LMfvUENLYx/jJpe7f -93kXZoQio7rIolnlbM1QoJLxi/7HlOt/VsopJlV2wAmOmlpyWDnOZtUtZgiCGV6a -apFzTs2m3n2GP7+8PG/W01/jVyFqixGW8cWVZORBMhjro2JqrRvw7U+Ypk2o7Em4 -SAnAJyzqpTDh9zf0QWkQXN83YThB3dk1M1FXOyKtZ8G+YVNfs5Ldr7tHNbqKi2v8 -lPaPIDQ7UmxZhy9vraKss0/3AEXaiE2eSvLc4eCcLiS4yVQ2KJpK5TUvz3cP1D5C -USsjxUZvolUELBtNaRVAsxX6OAyA8FjwJ8AKCqyR0NHvrbYhj54N1Js8PWtb+qqk -5sBLKOwEPaWM1uG6SJabrY1xu2VNLOGdJA9bRfyyzfpXksD0lFgwLKki6ReqqoMS -QiVdymhcp55J4tFwsDkzJX7296d1x3r7GAIQMLNc7YizukWfNtvUkSUsAwp+RKUx -TTwkwL1ztzSRpt3hGMJ9SfULTaQD7YAYfz4kitMBNpm90CLFa4CeINu98gE9Ogmc -R+CGQOHLUC3rXubgRCiQg5wfuQINBFQym34BEADHtTHduZFdu76RAzqTjT94F92L +Ah4BAheABQJcEB4SBQkLn+mRAAoJEGhvB0VNbO/DzSIQALXk6ST5Uoxh5+NLBJgI +GR2NOCFwsU+97VOkZWZnzpk+JdUrq/I9JmWWTegGKu3it5YvM8xY1zD1l+RXlnmY +Bg7oT6N63lL8hBhxGm9Hk2A1VJlEjtgtvjbg5yLSdvjxJL1vrmchWGwFWoHT9uIh +oefemb3TQ1U+ADVsW42jXca650/rqvsUMpmQbDfHxUBIfpbxgTWz8sHuMfhFB3R0 +nzSuZ1E1Pbg5jWYxd6sXpb1VFZ7TaQNVGB+4wMe8AH8/0qziLVTXvSkoer6qxU+r +e9M9/Rgue1FJSzZogUekIqyNLsvAeATSCYzi8NoywkUbAq6AqazJtdcOD+7M2/Vl +pdQEnIKSO/9xrziUQifRsPx4LOjf2d2Hvor/rBJYwoI1cFgR5pmH30Mi7OY0mMmm +2TMUPPz7YiVY+RPPpY3Mg5oPRe6sHVAdFYBmc0PTR4v92iYgfQXzoCd5HOJI9QB3 +SwrKz7cNLQwob2za1AXZ3sUp+yok6QMt8Tk6xIbMAjeR4jVeP8iQHhiVS1zx5z/g +lCAfb0hJnykoANgIZvJR/L+tuZjVStqnXjHgreY3IjlWTaNjZ/X5uMvd6zivqI9a +aEmqw/ZDCXRMAtjUCpUvpNlqAgqqbQsx6MFDnMbd4BuKQONeAFLm/Rp31nIvt1vb ++Iu3vkXBbbjb5yMu/dcpgSRUuQINBFQym34BEADHtTHduZFdu76RAzqTjT94F92L xSSopLSk7/sdLWTc2ERmjDId7dKmqrL1Kh2kqAtHY3Rq8Y839LGmbJCzI1kJyOHF o9jkEI93sqXcztLjizPVukqClOZNt3NV/nvefH6JSdqWcnC4V1mQr2Ztl0j+51i+ NYVwGjlsOMlBER+LW/s7egRqAQonrcEB5vsSAzd8mOlNKjRAnDCV+C21GDKxzb80 @@ -35,17 +35,17 @@ xRFfhoiiPyjjPRmJ+/iG3KXLzEiMfbyTFzGkX3Z9BJTxemUx8JOSVQXa++t4w39J UwzwBKNItDhtQqJpCaF43fJ4ykLMJi5gRpgqtb+T3CF0abXNII1IfS8a0fSpd48d 6hzoCVqpvWsI1fOY5Ui0BIgubNhkr4OJDCWBT5zhxjCJ3QiUSKyyqjfw1Fpuf/0Y CSA9Q9FSCq9qTppJs5ITHVjhWw2zxrJEG+P2+dvryBhV9l4T2xx1oHqlKX8zzLBG -kS8NmnxoRFQs5rZYvQARAQABiQIlBBgBAgAPAhsMBQJX3tl5BQkHbqT4AAoJEGhv -B0VNbO/DrN4QAJVTg2l91LSxb2dTikXbkRCPev1Eiqjd3d4TZIyE7yeYreHUyfcz -sytEsMUpd5nqqL/QMOwgC8Dm+77Yp480atI/c0wQh30EfJq1YP4q/gwv8EtriFo6 -ZaqYNzajmB8otz6yyb5RD9S6ocZX5b22nnNM/ihiTQJiqJKC2XHPQH3/grniU9if -WXUlY7Fo+8lRn/aRPMjYT2elsugru8GoplDMyfPRymnMJmTwNPYkg0Dnm2JUXYhH -VLO6Ebh7fUChsiGNmSp+siv7fcZIf20+LvoymgyT+49LrrQMvRleOqaJc1LBKaK6 -1yU+jLk1f9bFCMORQoTxvIVaSnjMWAeKDxi8nwuVfUJpQYXmbOOqMZgoFi6t+U7/ -T6Cz1CGKv3JgEveWyHeOvsjopej3a4Hmk7QGM/xJrd83roUjypjx5lTeMDvcPlPs -IQOy33qWguR1xoEnwAp9ov/meS7HtUOoC0m9ROZqWT6ArN+1ONplFP4GTsuW91Qz -pacQMl09F0KF1MacAdpauCOKj+wy9XPUW8v3kWZufUSgNtOLHS+kVumkqdJuJ0aB -7Ezc1yYY6DwRFOdlUpTJkRMozyPRvS15Lz/vPEhcbxMHRAg611CS2CqTEIbk2chJ -QBlj77a45lDTXGQHFVYXlbXx/HWb5zOGpNji0QhY1hOABRo78DT5yda+ -=ksQj +kS8NmnxoRFQs5rZYvQARAQABiQIlBBgBAgAPAhsMBQJcEB4eBQkLn+meAAoJEGhv +B0VNbO/DjzYP/2A6HtpvPkD+s/0+Ghmp5Rw7HIvZz0RnCsvM3qVQqVn3JTqHXyhD +5GmZrCxhliW1nRBITaKSRHXSGeE/O1BtK6eW/Z1P6bWJVd+R9vhaZlLU2sswiFzu +q3s7bL/Fo9VRc0SX6j6JDh1FZ3JcebUfY59sixHLqZuAk9m97z6H1NjS+f4pB5Tp +n1nnRgdvYk4tjlk4mmluIAwjq8Ll6gw6ntwjX9Gq9OblutTr2MZDyTIOxcG54ZN2 +2t5JA7Syh0He6dn/NLlb//bPPnic3GuYfkgKht8M1XCJfnDKju+I9qRGf1DYIjP7 +m24IDC0MM9Fo7KIUY+vcV0J/BIkkZtZ9xh0iEEnR/KqYXmClym+EiWCwPhLloKL3 +6cZr5MaiYJsodYa73x35pSGvioUrBDb78v8nCNhoTUXzZv8E0s/0YI2UZSGhVEC6 +ANNXPvKeOdibGNDM4JOwETabkEng38UE6Oa7Qonra2MWsPegh+mnZ7/sqrktQRMB +T/Xne6vapDONeLeY2hVcT0j9f/S8rgpHPjP4/hmYE9d38Euwa7TZ0lHWcmJzQy6F +7HfGR3oYAYAwRnvl+kYUGZ46u9Nodi4+wycFc4+IpwFtnlUzRBOcOilnR2X6KFJW +SiVss1i7ECcWaKCBNN1MrpwGWeuSbCQ00c3bxe6ZN6goB1t2u1KAZqMK +=HFHX -----END PGP PUBLIC KEY BLOCK----- From 41e12d4d2958d0142038e75fe983128b5f2e1d8e Mon Sep 17 00:00:00 2001 From: moneroexamples Date: Tue, 11 Dec 2018 16:50:27 +0800 Subject: [PATCH 37/40] Make get_output_key method const get_output_key method is commonly used when working with txs and their key images. Because the method is not const, passing blockchain object though const& or pointers to const is not possible in this context. This is especially problematic in external projects (e.g., projects in moneroexamples) that use monero C++ api to operate on the blockchain and txs. Thus, having get_output_key method will simplify moving blockchain object around through const references and pointers to const objects. --- src/blockchain_db/berkeleydb/db_bdb.cpp | 4 ++-- src/blockchain_db/blockchain_db.h | 4 ++-- src/blockchain_db/lmdb/db_lmdb.cpp | 4 ++-- src/blockchain_db/lmdb/db_lmdb.h | 4 ++-- tests/unit_tests/testdb.h | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/blockchain_db/berkeleydb/db_bdb.cpp b/src/blockchain_db/berkeleydb/db_bdb.cpp index b27a00a69..60a7326f8 100644 --- a/src/blockchain_db/berkeleydb/db_bdb.cpp +++ b/src/blockchain_db/berkeleydb/db_bdb.cpp @@ -1632,7 +1632,7 @@ output_data_t BlockchainBDB::get_output_key(const uint64_t& global_index) const return v; } -output_data_t BlockchainBDB::get_output_key(const uint64_t& amount, const uint64_t& index) +output_data_t BlockchainBDB::get_output_key(const uint64_t& amount, const uint64_t& index) const { LOG_PRINT_L3("BlockchainBDB::" << __func__); check_open(); @@ -1641,7 +1641,7 @@ output_data_t BlockchainBDB::get_output_key(const uint64_t& amount, const uint64 return get_output_key(glob_index); } -tx_out_index BlockchainBDB::get_output_tx_and_index(const uint64_t& amount, const uint64_t& index) +tx_out_index BlockchainBDB::get_output_tx_and_index(const uint64_t& amount, const uint64_t& index) const { LOG_PRINT_L3("BlockchainBDB::" << __func__); std::vector < uint64_t > offsets; diff --git a/src/blockchain_db/blockchain_db.h b/src/blockchain_db/blockchain_db.h index f13aa0cae..9d4f59b3c 100644 --- a/src/blockchain_db/blockchain_db.h +++ b/src/blockchain_db/blockchain_db.h @@ -1258,7 +1258,7 @@ public: * * @return the requested output data */ - virtual output_data_t get_output_key(const uint64_t& amount, const uint64_t& index) = 0; + virtual output_data_t get_output_key(const uint64_t& amount, const uint64_t& index) const = 0; /** * @brief gets an output's tx hash and index @@ -1310,7 +1310,7 @@ public: * @param offsets a list of amount-specific output indices * @param outputs return-by-reference a list of outputs' metadata */ - virtual void get_output_key(const epee::span &amounts, const std::vector &offsets, std::vector &outputs, bool allow_partial = false) = 0; + virtual void get_output_key(const epee::span &amounts, const std::vector &offsets, std::vector &outputs, bool allow_partial = false) const = 0; /* * FIXME: Need to check with git blame and ask what this does to diff --git a/src/blockchain_db/lmdb/db_lmdb.cpp b/src/blockchain_db/lmdb/db_lmdb.cpp index 6e03b86c1..89e02ce89 100644 --- a/src/blockchain_db/lmdb/db_lmdb.cpp +++ b/src/blockchain_db/lmdb/db_lmdb.cpp @@ -2535,7 +2535,7 @@ uint64_t BlockchainLMDB::get_num_outputs(const uint64_t& amount) const return num_elems; } -output_data_t BlockchainLMDB::get_output_key(const uint64_t& amount, const uint64_t& index) +output_data_t BlockchainLMDB::get_output_key(const uint64_t& amount, const uint64_t& index) const { LOG_PRINT_L3("BlockchainLMDB::" << __func__); check_open(); @@ -3242,7 +3242,7 @@ void BlockchainLMDB::get_output_tx_and_index_from_global(const std::vector &amounts, const std::vector &offsets, std::vector &outputs, bool allow_partial) +void BlockchainLMDB::get_output_key(const epee::span &amounts, const std::vector &offsets, std::vector &outputs, bool allow_partial) const { if (amounts.size() != 1 && amounts.size() != offsets.size()) throw0(DB_ERROR("Invalid sizes of amounts and offets")); diff --git a/src/blockchain_db/lmdb/db_lmdb.h b/src/blockchain_db/lmdb/db_lmdb.h index b7b1b04d5..60797a076 100644 --- a/src/blockchain_db/lmdb/db_lmdb.h +++ b/src/blockchain_db/lmdb/db_lmdb.h @@ -242,8 +242,8 @@ public: virtual uint64_t get_num_outputs(const uint64_t& amount) const; - virtual output_data_t get_output_key(const uint64_t& amount, const uint64_t& index); - virtual void get_output_key(const epee::span &amounts, const std::vector &offsets, std::vector &outputs, bool allow_partial = false); + virtual output_data_t get_output_key(const uint64_t& amount, const uint64_t& index) const; + virtual void get_output_key(const epee::span &amounts, const std::vector &offsets, std::vector &outputs, bool allow_partial = false) const; virtual tx_out_index get_output_tx_and_index_from_global(const uint64_t& index) const; virtual void get_output_tx_and_index_from_global(const std::vector &global_indices, diff --git a/tests/unit_tests/testdb.h b/tests/unit_tests/testdb.h index 5d9ba5833..709ab40b7 100644 --- a/tests/unit_tests/testdb.h +++ b/tests/unit_tests/testdb.h @@ -89,11 +89,11 @@ public: virtual uint64_t get_tx_block_height(const crypto::hash& h) const { return 0; } virtual uint64_t get_num_outputs(const uint64_t& amount) const { return 1; } virtual uint64_t get_indexing_base() const { return 0; } - virtual cryptonote::output_data_t get_output_key(const uint64_t& amount, const uint64_t& index) { return cryptonote::output_data_t(); } + virtual cryptonote::output_data_t get_output_key(const uint64_t& amount, const uint64_t& index) const { return cryptonote::output_data_t(); } virtual cryptonote::tx_out_index get_output_tx_and_index_from_global(const uint64_t& index) const { return cryptonote::tx_out_index(); } virtual cryptonote::tx_out_index get_output_tx_and_index(const uint64_t& amount, const uint64_t& index) const { return cryptonote::tx_out_index(); } virtual void get_output_tx_and_index(const uint64_t& amount, const std::vector &offsets, std::vector &indices) const {} - virtual void get_output_key(const epee::span &amounts, const std::vector &offsets, std::vector &outputs, bool allow_partial = false) {} + virtual void get_output_key(const epee::span &amounts, const std::vector &offsets, std::vector &outputs, bool allow_partial = false) const {} virtual bool can_thread_bulk_indices() const { return false; } virtual std::vector get_tx_output_indices(const crypto::hash& h) const { return std::vector(); } virtual std::vector get_tx_amount_output_indices(const uint64_t tx_index) const { return std::vector(); } From c946a359859d0fbeb6700f9bf3560b6c76207135 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sat, 22 Dec 2018 15:51:33 +0000 Subject: [PATCH 38/40] message_store: fix error message adding const char * with offset --- src/wallet/message_store.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/wallet/message_store.cpp b/src/wallet/message_store.cpp index 9dcc40774..685766cf6 100644 --- a/src/wallet/message_store.cpp +++ b/src/wallet/message_store.cpp @@ -125,7 +125,7 @@ void message_store::set_signer(const multisig_wallet_state &state, const boost::optional &transport_address, const boost::optional monero_address) { - THROW_WALLET_EXCEPTION_IF(index >= m_num_authorized_signers, tools::error::wallet_internal_error, "Invalid signer index " + index); + THROW_WALLET_EXCEPTION_IF(index >= m_num_authorized_signers, tools::error::wallet_internal_error, "Invalid signer index " + std::to_string(index)); authorized_signer &m = m_signers[index]; if (label) { @@ -146,7 +146,7 @@ void message_store::set_signer(const multisig_wallet_state &state, const authorized_signer &message_store::get_signer(uint32_t index) const { - THROW_WALLET_EXCEPTION_IF(index >= m_num_authorized_signers, tools::error::wallet_internal_error, "Invalid signer index " + index); + THROW_WALLET_EXCEPTION_IF(index >= m_num_authorized_signers, tools::error::wallet_internal_error, "Invalid signer index " + std::to_string(index)); return m_signers[index]; } @@ -201,7 +201,7 @@ void message_store::unpack_signer_config(const multisig_wallet_state &state, con THROW_WALLET_EXCEPTION_IF(true, tools::error::wallet_internal_error, "Invalid structure of signer config"); } uint32_t num_signers = (uint32_t)signers.size(); - THROW_WALLET_EXCEPTION_IF(num_signers != m_num_authorized_signers, tools::error::wallet_internal_error, "Wrong number of signers in config: " + num_signers); + THROW_WALLET_EXCEPTION_IF(num_signers != m_num_authorized_signers, tools::error::wallet_internal_error, "Wrong number of signers in config: " + std::to_string(num_signers)); } void message_store::process_signer_config(const multisig_wallet_state &state, const std::string &signer_config) @@ -424,7 +424,7 @@ void message_store::setup_signer_for_auto_config(uint32_t index, const std::stri // auto-config parameters. In the wallet of somebody using the token to send auto-config // data the auto-config parameters are stored in the "me" signer and taken from there // to send that data. - THROW_WALLET_EXCEPTION_IF(index >= m_num_authorized_signers, tools::error::wallet_internal_error, "Invalid signer index " + index); + THROW_WALLET_EXCEPTION_IF(index >= m_num_authorized_signers, tools::error::wallet_internal_error, "Invalid signer index " + std::to_string(index)); authorized_signer &m = m_signers[index]; m.auto_config_token = token; crypto::hash_to_scalar(token.data(), token.size(), m.auto_config_secret_key); @@ -506,7 +506,7 @@ void message_store::process_wallet_created_data(const multisig_wallet_state &sta break; default: - THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, "Illegal message type " + (uint32_t)type); + THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, "Illegal message type " + std::to_string((uint32_t)type)); break; } } @@ -573,7 +573,7 @@ size_t message_store::get_message_index_by_id(uint32_t id) const { size_t index; bool found = get_message_index_by_id(id, index); - THROW_WALLET_EXCEPTION_IF(!found, tools::error::wallet_internal_error, "Invalid message id " + id); + THROW_WALLET_EXCEPTION_IF(!found, tools::error::wallet_internal_error, "Invalid message id " + std::to_string(id)); return index; } @@ -601,7 +601,7 @@ message message_store::get_message_by_id(uint32_t id) const { message m; bool found = get_message_by_id(id, m); - THROW_WALLET_EXCEPTION_IF(!found, tools::error::wallet_internal_error, "Invalid message id " + id); + THROW_WALLET_EXCEPTION_IF(!found, tools::error::wallet_internal_error, "Invalid message id " + std::to_string(id)); return m; } From 842bcffbb8d5d434aae9514d34b9d4fecb25a30c Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Tue, 25 Dec 2018 19:10:37 +0000 Subject: [PATCH 39/40] blocks: fix checkpoint code generation on OpenBSD Its od outputs small decimals with leading 0, which means octal in C --- src/blocks/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/blocks/CMakeLists.txt b/src/blocks/CMakeLists.txt index 30d85adbf..ff48af6dc 100644 --- a/src/blocks/CMakeLists.txt +++ b/src/blocks/CMakeLists.txt @@ -39,7 +39,7 @@ foreach(BLOB_NAME checkpoints testnet_blocks stagenet_blocks) cd ${CMAKE_CURRENT_BINARY_DIR} && echo "'#include\t'" > ${OUTPUT_C_SOURCE} && echo "'const\tunsigned\tchar\t${BLOB_NAME}[]={'" >> ${OUTPUT_C_SOURCE} && - od -v -An -tu1 ${CMAKE_CURRENT_SOURCE_DIR}/${INPUT_DAT_FILE} | sed -e "'s/[0-9]\\{1,\\}/&,/g'" -e "'$$s/.$$//'" >> ${OUTPUT_C_SOURCE} && + od -v -An -tx1 ${CMAKE_CURRENT_SOURCE_DIR}/${INPUT_DAT_FILE} | sed -e "'s/[0-9a-fA-F]\\{1,\\}/0x&,/g'" -e "'$$s/.$$//'" >> ${OUTPUT_C_SOURCE} && echo "'};'" >> ${OUTPUT_C_SOURCE} && echo "'const\tsize_t\t${BLOB_NAME}_len\t=\tsizeof(${BLOB_NAME});'" >> ${OUTPUT_C_SOURCE} ) From 6cbafa9dd945325e6731cadcbe6a79a3f080f54f Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Mon, 7 Jan 2019 11:56:50 +0000 Subject: [PATCH 40/40] wallet_api: fix usage of LOG_ERROR --- src/wallet/api/wallet.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp index c320ad76f..d206d0517 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp @@ -1149,7 +1149,7 @@ std::string WalletImpl::getSubaddressLabel(uint32_t accountIndex, uint32_t addre } catch (const std::exception &e) { - LOG_ERROR("Error getting subaddress label: ") << e.what(); + LOG_ERROR("Error getting subaddress label: " << e.what()); setStatusError(string(tr("Failed to get subaddress label: ")) + e.what()); return ""; } @@ -1162,7 +1162,7 @@ void WalletImpl::setSubaddressLabel(uint32_t accountIndex, uint32_t addressIndex } catch (const std::exception &e) { - LOG_ERROR("Error setting subaddress label: ") << e.what(); + LOG_ERROR("Error setting subaddress label: " << e.what()); setStatusError(string(tr("Failed to set subaddress label: ")) + e.what()); } } @@ -1179,7 +1179,7 @@ string WalletImpl::getMultisigInfo() const { clearStatus(); return m_wallet->get_multisig_info(); } catch (const exception& e) { - LOG_ERROR("Error on generating multisig info: ") << e.what(); + LOG_ERROR("Error on generating multisig info: " << e.what()); setStatusError(string(tr("Failed to get multisig info: ")) + e.what()); } @@ -1196,7 +1196,7 @@ string WalletImpl::makeMultisig(const vector& info, uint32_t threshold) return m_wallet->make_multisig(epee::wipeable_string(m_password), info, threshold); } catch (const exception& e) { - LOG_ERROR("Error on making multisig wallet: ") << e.what(); + LOG_ERROR("Error on making multisig wallet: " << e.what()); setStatusError(string(tr("Failed to make multisig: ")) + e.what()); } @@ -1210,7 +1210,7 @@ std::string WalletImpl::exchangeMultisigKeys(const std::vector &inf return m_wallet->exchange_multisig_keys(epee::wipeable_string(m_password), info); } catch (const exception& e) { - LOG_ERROR("Error on exchanging multisig keys: ") << e.what(); + LOG_ERROR("Error on exchanging multisig keys: " << e.what()); setStatusError(string(tr("Failed to make multisig: ")) + e.what()); } @@ -1228,7 +1228,7 @@ bool WalletImpl::finalizeMultisig(const vector& extraMultisigInfo) { setStatusError(tr("Failed to finalize multisig wallet creation")); } catch (const exception& e) { - LOG_ERROR("Error on finalizing multisig wallet creation: ") << e.what(); + LOG_ERROR("Error on finalizing multisig wallet creation: " << e.what()); setStatusError(string(tr("Failed to finalize multisig wallet creation: ")) + e.what()); } @@ -1244,7 +1244,7 @@ bool WalletImpl::exportMultisigImages(string& images) { images = epee::string_tools::buff_to_hex_nodelimer(blob); return true; } catch (const exception& e) { - LOG_ERROR("Error on exporting multisig images: ") << e.what(); + LOG_ERROR("Error on exporting multisig images: " << e.what()); setStatusError(string(tr("Failed to export multisig images: ")) + e.what()); } @@ -1272,7 +1272,7 @@ size_t WalletImpl::importMultisigImages(const vector& images) { return m_wallet->import_multisig(blobs); } catch (const exception& e) { - LOG_ERROR("Error on importing multisig images: ") << e.what(); + LOG_ERROR("Error on importing multisig images: " << e.what()); setStatusError(string(tr("Failed to import multisig images: ")) + e.what()); } @@ -1286,7 +1286,7 @@ bool WalletImpl::hasMultisigPartialKeyImages() const { return m_wallet->has_multisig_partial_key_images(); } catch (const exception& e) { - LOG_ERROR("Error on checking for partial multisig key images: ") << e.what(); + LOG_ERROR("Error on checking for partial multisig key images: " << e.what()); setStatusError(string(tr("Failed to check for partial multisig key images: ")) + e.what()); } @@ -1314,7 +1314,7 @@ PendingTransaction* WalletImpl::restoreMultisigTransaction(const string& signDat return ptx; } catch (exception& e) { - LOG_ERROR("Error on restoring multisig transaction: ") << e.what(); + LOG_ERROR("Error on restoring multisig transaction: " << e.what()); setStatusError(string(tr("Failed to restore multisig transaction: ")) + e.what()); }