diff --git a/CMakeLists.txt b/CMakeLists.txt index 4a38a381..05c64002 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -55,7 +55,7 @@ if(APPLE) set(CMAKE_OSX_DEPLOYMENT_TARGET 10.10.5) endif() -set(USE_PCH FALSE CACHE BOOL "Use shared precompiled headers for MSVC") +set(USE_PCH FALSE CACHE BOOL "Use shared precompiled headers") include_directories(src contrib/eos_portable_archive contrib contrib/epee/include "${CMAKE_BINARY_DIR}/version" "${CMAKE_BINARY_DIR}/contrib/zlib") @@ -153,7 +153,8 @@ else() set(DEBUG_FLAGS "-g3 -O0") endif() set(RELEASE_FLAGS "-Ofast -DNDEBUG -Wno-unused-variable") - if(NOT APPLE) + + if(NOT APPLE AND NOT (CMAKE_SYSTEM_NAME STREQUAL "Android")) set(RELEASE_FLAGS "${RELEASE_FLAGS} -flto") endif() #if(CMAKE_C_COMPILER_ID STREQUAL "GNU" AND NOT MINGW) diff --git a/README.md b/README.md index 8f9a5ad5..6af4daa1 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ Be sure to properly clone the repository: |--|--|--|--| | gcc (Linux) | 5.4.0 | 7.2.0 | 8.3.0 | | llvm/clang (Linux) | UNKNOWN | 7.0.1 | 8.0.0 | -| [MSVC](https://visualstudio.microsoft.com/downloads/) (Windows) | 2015 (14.0 update 1) | 2015 (14.0 update 3) | 2017 (15.5.7) | +| [MSVC](https://visualstudio.microsoft.com/downloads/) (Windows) | 2015 (14.0 update 1) | 2017 (15.5.7) | 2019 | | [XCode](https://developer.apple.com/downloads/) (macOS) | 7.3.1 | 9.2 | 9.2 | | [CMake](https://cmake.org/download/) | 2.8.6 | 3.15.5 | 3.15.5 | | [Boost](https://www.boost.org/users/download/) | 1.56 | 1.68 | 1.68 | diff --git a/contrib/epee/include/misc_log_ex.h b/contrib/epee/include/misc_log_ex.h index 37b2400f..e0a58617 100644 --- a/contrib/epee/include/misc_log_ex.h +++ b/contrib/epee/include/misc_log_ex.h @@ -670,7 +670,9 @@ namespace log_space boost::filesystem::create_directories(m_default_log_path_w, ec); boost::filesystem::ofstream* pstream = new boost::filesystem::ofstream; - std::wstring target_path = m_default_log_path_w + L"/" + epee::string_encoding::utf8_to_wstring(pstream_name); + std::wstring target_path = epee::string_encoding::utf8_to_wstring(pstream_name); + if (!m_default_log_path_w.empty()) + target_path = m_default_log_path_w + L"/" + target_path; pstream->open( target_path.c_str(), std::ios_base::out | std::ios::app /*ios_base::trunc */); if(pstream->fail()) diff --git a/contrib/epee/include/net/abstract_tcp_server2.inl b/contrib/epee/include/net/abstract_tcp_server2.inl index 799cfd01..6e57b54a 100644 --- a/contrib/epee/include/net/abstract_tcp_server2.inl +++ b/contrib/epee/include/net/abstract_tcp_server2.inl @@ -326,7 +326,7 @@ bool connection::do_send(const void* ptr, size_t cb) boost::asio::async_write(socket_, boost::asio::buffer(m_send_que.front().data(), m_send_que.front().size()), //strand_.wrap( - boost::bind(&connection::handle_write, self, _1, _2) + boost::bind(&connection::handle_write, self, boost::placeholders::_1, boost::placeholders::_2) //) ); @@ -404,7 +404,7 @@ void connection::handle_write(const boost::system::error_cod //have more data to send boost::asio::async_write(socket_, boost::asio::buffer(m_send_que.front().data(), m_send_que.front().size()), //strand_.wrap( - boost::bind(&connection::handle_write, connection::shared_from_this(), _1, _2)); + boost::bind(&connection::handle_write, connection::shared_from_this(), boost::placeholders::_1, boost::placeholders::_2)); //); } CRITICAL_REGION_END(); diff --git a/contrib/epee/include/reg_exp_definer.h b/contrib/epee/include/reg_exp_definer.h index 807e188e..06e476ff 100644 --- a/contrib/epee/include/reg_exp_definer.h +++ b/contrib/epee/include/reg_exp_definer.h @@ -73,19 +73,6 @@ namespace epee gregexplock.get_lock().lock().unlock();\ } -// #define STATIC_REGEXP_EXPR_2(var_name, xpr_text, reg_exp_flags) \ -// static volatile uint32_t regexp_initialized_2 = 0;\ -// volatile uint32_t local_is_initialized_2 = regexp_initialized_2;\ -// if(!local_is_initialized_2)\ -// gregexplock.get_lock().lock().lock();\ -// static const boost::regex var_name(xpr_text , reg_exp_flags);\ -// if(!local_is_initialized_2)\ -// {\ -// boost::interprocess::ipcdetail::atomic_write32(®exp_initialized_2, 1);\ -// gregexplock.get_lock().lock().unlock();\ -// } - - #define STATIC_REGEXP_EXPR_3(var_name, xpr_text, reg_exp_flags) \ static volatile uint32_t regexp_initialized_3 = 0;\ volatile uint32_t local_is_initialized_3 = regexp_initialized_3;\ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 43c3fd96..4c5d8b1a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -2,38 +2,52 @@ # cmake_policy(SET CMP0043 OLD) # endif() -########### -# using shared PCH -- this is unusual case for MSVC... so mystery, such hack, many wow. See also: https://stackoverflow.com/questions/645747/sharing-precompiled-headers-between-projects-in-visual-studio/4170902#4170902 +##### Precompiled Headers ###### # define USE_PCH to YES for using precomiled headers - -MACRO(INIT_SHARED_PCH pch_cpp_file) - IF(MSVC AND USE_PCH) - set_property(SOURCE ${pch_cpp_file} APPEND_STRING PROPERTY COMPILE_FLAGS " /Fo$(OutDir) /Z7 /Fd$(OutDir)vc$(PlatformToolsetVersion).pdb /Ycstdafx.h /Fp$(TargetDir)pch.pch") - ENDIF(MSVC AND USE_PCH) +# Windows: using custom-made shared PCH -- this is unusual case for MSVC... so mystery, such hack, many wow. See also: https://stackoverflow.com/questions/645747/sharing-precompiled-headers-between-projects-in-visual-studio/4170902#4170902 +# Linux: using CMake-enabled shared PCH (which appeared in CMake 3.16) +MACRO(INIT_SHARED_PCH) + IF(USE_PCH) + MESSAGE( STATUS " ...... enabling precompiled headers, making new library: pch" ) + add_library(pch ${PCH}) + set(PCH_LIB_NAME pch) + IF(MSVC) + set_property(SOURCE "pch/stdafx.cpp" APPEND_STRING PROPERTY COMPILE_FLAGS " /Fo$(OutDir) /Z7 /Fd$(OutDir)vc$(PlatformToolsetVersion).pdb /Ycstdafx.h /Fp$(TargetDir)pch.pch") + ELSEIF(APPLE OR CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + target_precompile_headers(pch PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/pch/stdafx.h") + ENDIF() + ENDIF(USE_PCH) ENDMACRO(INIT_SHARED_PCH) -MACRO(ENABLE_SHARED_PCH sources_var) - IF(MSVC AND USE_PCH) - MESSAGE( STATUS " ...... enabling precompiled headers for: " ${sources_var} ) - SET(precompiled_binary "$(TargetDir)pch.pch") - SET(precompiled_header "${CMAKE_CURRENT_SOURCE_DIR}/pch/stdafx.h") - SET(sources ${${sources_var}}) - foreach(src ${sources}) - if(NOT ${src} MATCHES "\\.rc$") # skip *.rc files - SET_SOURCE_FILES_PROPERTIES(${src} - PROPERTIES COMPILE_FLAGS "/Z7 /Fd$(OutDir)vc$(PlatformToolsetVersion).pdb /Yu\"${precompiled_header}\" /FI\"${precompiled_header}\" /Fp\"${precompiled_binary}\"" - OBJECT_DEPENDS "${precompiled_binary}") - endif() - endforeach() - ENDIF(MSVC AND USE_PCH) +MACRO(ENABLE_SHARED_PCH target sources_var) + IF(USE_PCH) + IF(MSVC) + MESSAGE( STATUS " ...... enabling precompiled headers for: " ${sources_var} ) + SET(precompiled_binary "$(TargetDir)pch.pch") + SET(precompiled_header "${CMAKE_CURRENT_SOURCE_DIR}/pch/stdafx.h") + SET(sources ${${sources_var}}) + foreach(src ${sources}) + if(NOT ${src} MATCHES "\\.rc$") # skip *.rc files + SET_SOURCE_FILES_PROPERTIES(${src} + PROPERTIES COMPILE_FLAGS "/Z7 /Fd$(OutDir)vc$(PlatformToolsetVersion).pdb /Yu\"${precompiled_header}\" /FI\"${precompiled_header}\" /Fp\"${precompiled_binary}\"" + OBJECT_DEPENDS "${precompiled_binary}") + endif() + endforeach() + ELSEIF(APPLE OR CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + MESSAGE( STATUS " ...... enabling precompiled headers for: " ${target} ) + target_precompile_headers(${target} REUSE_FROM pch) + ENDIF() + ENDIF(USE_PCH) ENDMACRO(ENABLE_SHARED_PCH) MACRO(ENABLE_SHARED_PCH_EXECUTABLE target) - IF(MSVC AND USE_PCH) - SET_TARGET_PROPERTIES(${target} PROPERTIES LINK_FLAGS "$(OutDir)stdafx.obj") - ENDIF(MSVC AND USE_PCH) + IF(USE_PCH) + IF(MSVC) + SET_TARGET_PROPERTIES(${target} PROPERTIES LINK_FLAGS "$(OutDir)stdafx.obj") + ENDIF() + ENDIF(USE_PCH) ENDMACRO(ENABLE_SHARED_PCH_EXECUTABLE) -########### +##### End of Precompiled Headers macros ###### @@ -82,15 +96,11 @@ if(BUILD_GUI) endif() -if (USE_PCH) - add_library(pch ${PCH}) - set(PCH_LIB_NAME pch) -endif() -INIT_SHARED_PCH("pch/stdafx.cpp") +INIT_SHARED_PCH() add_library(common ${COMMON}) add_dependencies(common version ${PCH_LIB_NAME}) -ENABLE_SHARED_PCH(COMMON) +ENABLE_SHARED_PCH(common COMMON) if(NOT MSVC AND NOT APPLE AND NOT CLANG) # TODO(unassigned): do we really need the clang equivalent? target_compile_options(common PRIVATE -fno-var-tracking-assignments) @@ -100,7 +110,7 @@ add_library(crypto ${CRYPTO}) add_library(currency_core ${CURRENCY_CORE}) add_dependencies(currency_core version ${PCH_LIB_NAME}) -ENABLE_SHARED_PCH(CURRENCY_CORE) +ENABLE_SHARED_PCH(currency_core CURRENCY_CORE) if(CMAKE_SYSTEM_NAME STREQUAL "Android" ) add_library(wallet ${WALLET}) @@ -109,7 +119,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Android" ) else() add_library(wallet ${WALLET}) add_dependencies(wallet version ${PCH_LIB_NAME}) - ENABLE_SHARED_PCH(WALLET) + ENABLE_SHARED_PCH(wallet WALLET) endif() @@ -129,11 +139,11 @@ endif() add_library(rpc ${RPC}) add_dependencies(rpc version ${PCH_LIB_NAME}) -ENABLE_SHARED_PCH(RPC) +ENABLE_SHARED_PCH(rpc RPC) add_library(stratum ${STRATUM}) add_dependencies(stratum version ${PCH_LIB_NAME}) -ENABLE_SHARED_PCH(STRATUM) +ENABLE_SHARED_PCH(stratum STRATUM) target_link_libraries(currency_core lmdb mdbx) @@ -141,19 +151,19 @@ target_link_libraries(currency_core lmdb mdbx) add_executable(daemon ${DAEMON} ${P2P} ${CURRENCY_PROTOCOL}) add_dependencies(daemon version) target_link_libraries(daemon rpc stratum currency_core crypto common libminiupnpc-static zlibstatic ethash ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) -ENABLE_SHARED_PCH(DAEMON) +ENABLE_SHARED_PCH(daemon DAEMON) ENABLE_SHARED_PCH_EXECUTABLE(daemon) add_executable(connectivity_tool ${CONN_TOOL}) add_dependencies(connectivity_tool version) target_link_libraries(connectivity_tool currency_core crypto common zlibstatic ethash ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) -ENABLE_SHARED_PCH(CONN_TOOL) +ENABLE_SHARED_PCH(connectivity_tool CONN_TOOL) ENABLE_SHARED_PCH_EXECUTABLE(connectivity_tool) add_executable(simplewallet ${SIMPLEWALLET}) add_dependencies(simplewallet version) target_link_libraries(simplewallet wallet rpc currency_core crypto common zlibstatic ethash ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) -ENABLE_SHARED_PCH(SIMPLEWALLET) +ENABLE_SHARED_PCH(simplewallet SIMPLEWALLET) ENABLE_SHARED_PCH_EXECUTABLE(simplewallet) set_property(TARGET common crypto currency_core rpc stratum wallet PROPERTY FOLDER "libs") @@ -170,7 +180,7 @@ if(BUILD_GUI) set(CMAKE_INCLUDE_CURRENT_DIR ON) SET(MACOSX_BUNDLE_ICON_FILE app.icns) add_executable(Zano WIN32 MACOSX_BUNDLE ${QTDAEMON} ) - ENABLE_SHARED_PCH(QTDAEMON) + ENABLE_SHARED_PCH(Zano QTDAEMON) ENABLE_SHARED_PCH_EXECUTABLE(Zano) QT5_USE_MODULES(Zano WebEngineWidgets WebChannel) diff --git a/src/common/encryption_filter.cpp b/src/common/encryption_filter.cpp new file mode 100644 index 00000000..8861fa8c --- /dev/null +++ b/src/common/encryption_filter.cpp @@ -0,0 +1,7 @@ +// Copyright (c) 2014-2019 Zano Project +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + + +#include "encryption_filter.h" +#include "crypto/chacha8_stream.h" \ No newline at end of file diff --git a/src/common/encryption_filter.h b/src/common/encryption_filter.h new file mode 100644 index 00000000..854dc7ad --- /dev/null +++ b/src/common/encryption_filter.h @@ -0,0 +1,244 @@ +// Copyright (c) 2014-2018 Zano Project +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#pragma once + +#include +#include +#include +#include // sink_tag +#include // boost::iostreams::write, boost::iostreams::read +#include "include_base_utils.h" +#include "crypto/chacha8.h" +#include "crypto/chacha8_stream.h" + + +namespace tools +{ + + /************************************************************************/ + /* */ + /************************************************************************/ + + class encrypt_chacha_processer_base + { + public: + typedef char char_type; + //typedef boost::iostreams::multichar_output_filter_tag category; + //typedef boost::iostreams::flushable_tag category; + static const uint32_t block_size = ECRYPT_BLOCKLENGTH; + + encrypt_chacha_processer_base(std::string const &pass, const crypto::chacha8_iv& iv) :m_iv(iv), m_ctx(AUTO_VAL_INIT(m_ctx)) + { + crypto::generate_chacha8_key(pass, m_key); + ECRYPT_keysetup(&m_ctx, &m_key.data[0], sizeof(m_key.data) * 8, sizeof(m_iv.data) * 8); + ECRYPT_ivsetup(&m_ctx, &m_iv.data[0]); + } + ~encrypt_chacha_processer_base() + { + + } + + template + std::streamsize process(char_type const * const buf, std::streamsize const n, cb_handler cb) const + { + if (n == 0) + return n; + if (n%ECRYPT_BLOCKLENGTH == 0 && m_buff.empty()) + { + std::vector buff(n); + ECRYPT_encrypt_blocks(&m_ctx, (u8*)buf, (u8*)&buff[0], (u32)(n / ECRYPT_BLOCKLENGTH)); + cb(&buff[0], n); + //m_underlying_stream.write(&buff[0], n); + return n; + } + else + { + m_buff.append(buf, n); + size_t encr_count = m_buff.size() - m_buff.size() % ECRYPT_BLOCKLENGTH; + if (!encr_count) + return n; + std::vector buff(encr_count); + ECRYPT_encrypt_blocks(&m_ctx, (u8*)m_buff.data(), (u8*)&buff[0], (u32)(m_buff.size() / ECRYPT_BLOCKLENGTH)); + //m_underlying_stream.write(&buff[0], encr_count); + cb(&buff[0], encr_count); + m_buff.erase(0, encr_count); + return encr_count; + } + + } + + template + bool flush(cb_handler cb) + { + if (m_buff.empty()) + return true; + + std::vector buff(m_buff.size()); + ECRYPT_encrypt_bytes(&m_ctx, (u8*)m_buff.data(), (u8*)&buff[0], (u32)m_buff.size()); + cb(&buff[0], m_buff.size()); + //m_underlying_stream.write(&buff[0], m_buff.size()); + return true; + } + + private: + const crypto::chacha8_iv& m_iv; + mutable ECRYPT_ctx m_ctx; + //std::ostream &m_underlying_stream; + crypto::chacha8_key m_key; + mutable std::string m_buff; + }; + + /************************************************************************/ + /* */ + /************************************************************************/ + + + class encrypt_chacha_out_filter : public encrypt_chacha_processer_base + { + public: + typedef char char_type; + struct category : + public boost::iostreams::multichar_output_filter_tag, + public boost::iostreams::flushable_tag + { }; + + encrypt_chacha_out_filter(std::string const &pass, const crypto::chacha8_iv& iv) :encrypt_chacha_processer_base(pass, iv) + { + } + ~encrypt_chacha_out_filter() + { + } + + template + std::streamsize write(t_sink& snk, char_type const * const buf, std::streamsize const n) const + { + return encrypt_chacha_processer_base::process(buf, n, [&](char_type const * const buf_lambda, std::streamsize const n_lambda) { + boost::iostreams::write(snk, &buf_lambda[0], n_lambda); + }); + } + + template + bool flush(Sink& snk) + { + + encrypt_chacha_processer_base::flush([&](char_type const * const buf_lambda, std::streamsize const n_lambda) { + boost::iostreams::write(snk, &buf_lambda[0], n_lambda); + }); + return true; + } + + private: + }; + + + /************************************************************************/ + /* */ + /************************************************************************/ + + class encrypt_chacha_in_filter : public encrypt_chacha_processer_base + { + public: + typedef char char_type; + struct category : //public boost::iostreams::seekable_device_tag, + public boost::iostreams::multichar_input_filter_tag, + public boost::iostreams::flushable_tag + //public boost::iostreams::seekable_filter_tag + { }; + encrypt_chacha_in_filter(std::string const &pass, const crypto::chacha8_iv& iv) :encrypt_chacha_processer_base(pass, iv), m_was_eof(false) + { + } + ~encrypt_chacha_in_filter() + { + } + + template + std::streamsize read(Source& src, char* s, std::streamsize n) + { + if (m_buff.size() >= static_cast(n)) + { + return withdraw_to_read_buff(s, n); + } + if (m_was_eof && m_buff.empty()) + { + return -1; + } + + std::streamsize size_to_read_for_decrypt = (n - m_buff.size()); + size_to_read_for_decrypt += size_to_read_for_decrypt % encrypt_chacha_processer_base::block_size; + size_t offset_in_buff = m_buff.size(); + m_buff.resize(m_buff.size() + size_to_read_for_decrypt); + + std::streamsize result = boost::iostreams::read(src, (char*)&m_buff.data()[offset_in_buff], size_to_read_for_decrypt); + if (result == size_to_read_for_decrypt) + { + //regular read proocess, readed data enought to get decrypteds + encrypt_chacha_processer_base::process(&m_buff.data()[offset_in_buff], size_to_read_for_decrypt, [&](char_type const* const buf_lambda, std::streamsize const n_lambda) + { + CHECK_AND_ASSERT_THROW_MES(n_lambda == size_to_read_for_decrypt, "Error in decrypt: check n_lambda == size_to_read_for_decrypt failed"); + std::memcpy((char*)&m_buff.data()[offset_in_buff], buf_lambda, n_lambda); + }); + return withdraw_to_read_buff(s, n); + } + else + { + //been read some size_but it's basically might be eof + if (!m_was_eof) + { + size_t offset_before_flush = offset_in_buff; + if (result != -1) + { + //eof + encrypt_chacha_processer_base::process(&m_buff.data()[offset_in_buff], result, [&](char_type const* const buf_lambda, std::streamsize const n_lambda) { + std::memcpy((char*)&m_buff.data()[offset_in_buff], buf_lambda, n_lambda); + offset_before_flush = offset_in_buff + n_lambda; + }); + } + + encrypt_chacha_processer_base::flush([&](char_type const* const buf_lambda, std::streamsize const n_lambda) { + if (n_lambda + offset_before_flush > m_buff.size()) + { + m_buff.resize(n_lambda + offset_before_flush); + } + std::memcpy((char*)&m_buff.data()[offset_before_flush], buf_lambda, n_lambda); + m_buff.resize(offset_before_flush + n_lambda); + }); + + //just to make sure that it's over + std::string buff_stub(10, ' '); + std::streamsize r = boost::iostreams::read(src, (char*)&buff_stub.data()[0], 10); + CHECK_AND_ASSERT_THROW_MES(r == -1, "expected EOF"); + m_was_eof = true; + return withdraw_to_read_buff(s, n); + } + else + { + return -1; + } + } + } + + + template + bool flush(Sink& snk) + { + + return true; + } + + private: + + std::streamsize withdraw_to_read_buff(char* s, std::streamsize n) + { + + size_t copy_size = m_buff.size() > static_cast(n) ? static_cast(n) : m_buff.size(); + std::memcpy(s, m_buff.data(), copy_size); + m_buff.erase(0, copy_size); + return copy_size; + } + + std::string m_buff; + bool m_was_eof; + }; +} \ No newline at end of file diff --git a/src/common/error_codes.h b/src/common/error_codes.h index f8ad7898..934ac3bc 100644 --- a/src/common/error_codes.h +++ b/src/common/error_codes.h @@ -11,6 +11,7 @@ #define API_RETURN_CODE_ACCESS_DENIED "ACCESS_DENIED" #define API_RETURN_CODE_INTERNAL_ERROR "INTERNAL_ERROR" #define API_RETURN_CODE_NOT_ENOUGH_MONEY "NOT_ENOUGH_MONEY" +#define API_RETURN_CODE_NOT_ENOUGH_OUTPUTS_FOR_MIXING "NOT_ENOUGH_OUTPUTS_FOR_MIXING" #define API_RETURN_CODE_INTERNAL_ERROR_QUE_FULL "INTERNAL_ERROR_QUE_FULL" #define API_RETURN_CODE_BAD_ARG "BAD_ARG" #define API_RETURN_CODE_BAD_ARG_EMPTY_DESTINATIONS "BAD_ARG_EMPTY_DESTINATIONS" @@ -21,6 +22,7 @@ #define API_RETURN_CODE_WRONG_PASSWORD "WRONG_PASSWORD" #define API_RETURN_CODE_WALLET_WRONG_ID "WALLET_WRONG_ID" #define API_RETURN_CODE_WALLET_WATCH_ONLY_NOT_SUPPORTED "WALLET_WATCH_ONLY_NOT_SUPPORTED" +#define API_RETURN_CODE_WALLET_AUDITABLE_NOT_SUPPORTED "WALLET_AUDITABLE_NOT_SUPPORTED" #define API_RETURN_CODE_FILE_NOT_FOUND "FILE_NOT_FOUND" #define API_RETURN_CODE_ALREADY_EXISTS "ALREADY_EXISTS" #define API_RETURN_CODE_CANCELED "CANCELED" diff --git a/src/common/util.h b/src/common/util.h index 6b683082..0c5b0bb1 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -23,6 +23,12 @@ #include #endif +#ifdef NDEBUG + #define BUILD_TYPE "Release" +#else + #define BUILD_TYPE "Debug" +#endif + namespace tools { std::string get_host_computer_name(); diff --git a/src/crypto/chacha8_stream.c b/src/crypto/chacha8_stream.c new file mode 100644 index 00000000..94d9d816 --- /dev/null +++ b/src/crypto/chacha8_stream.c @@ -0,0 +1,115 @@ +/* +chacha-ref.c version 20080118 +D. J. Bernstein +Public domain. +*/ + +#include "ecrypt-sync.h" + +#define ROTATE(v,c) (ROTL32(v,c)) +#define XOR(v,w) ((v) ^ (w)) +#define PLUS(v,w) (U32V((v) + (w))) +#define PLUSONE(v) (PLUS((v),1)) + +#define QUARTERROUND(a,b,c,d) \ + x[a] = PLUS(x[a],x[b]); x[d] = ROTATE(XOR(x[d],x[a]),16); \ + x[c] = PLUS(x[c],x[d]); x[b] = ROTATE(XOR(x[b],x[c]),12); \ + x[a] = PLUS(x[a],x[b]); x[d] = ROTATE(XOR(x[d],x[a]), 8); \ + x[c] = PLUS(x[c],x[d]); x[b] = ROTATE(XOR(x[b],x[c]), 7); + +static void salsa20_wordtobyte(u8 output[64], const u32 input[16]) +{ + u32 x[16]; + int i; + + for (i = 0; i < 16; ++i) x[i] = input[i]; + for (i = 8; i > 0; i -= 2) { + QUARTERROUND(0, 4, 8, 12) + QUARTERROUND(1, 5, 9, 13) + QUARTERROUND(2, 6, 10, 14) + QUARTERROUND(3, 7, 11, 15) + QUARTERROUND(0, 5, 10, 15) + QUARTERROUND(1, 6, 11, 12) + QUARTERROUND(2, 7, 8, 13) + QUARTERROUND(3, 4, 9, 14) + } + for (i = 0; i < 16; ++i) x[i] = PLUS(x[i], input[i]); + for (i = 0; i < 16; ++i) U32TO8_LITTLE(output + 4 * i, x[i]); +} + +void ECRYPT_init(void) +{ + return; +} + +static const char sigma[16] = "expand 32-byte k"; +static const char tau[16] = "expand 16-byte k"; + +void ECRYPT_keysetup(ECRYPT_ctx *x, const u8 *k, u32 kbits, u32 ivbits) +{ + const char *constants; + + x->input[4] = U8TO32_LITTLE(k + 0); + x->input[5] = U8TO32_LITTLE(k + 4); + x->input[6] = U8TO32_LITTLE(k + 8); + x->input[7] = U8TO32_LITTLE(k + 12); + if (kbits == 256) { /* recommended */ + k += 16; + constants = sigma; + } + else { /* kbits == 128 */ + constants = tau; + } + x->input[8] = U8TO32_LITTLE(k + 0); + x->input[9] = U8TO32_LITTLE(k + 4); + x->input[10] = U8TO32_LITTLE(k + 8); + x->input[11] = U8TO32_LITTLE(k + 12); + x->input[0] = U8TO32_LITTLE(constants + 0); + x->input[1] = U8TO32_LITTLE(constants + 4); + x->input[2] = U8TO32_LITTLE(constants + 8); + x->input[3] = U8TO32_LITTLE(constants + 12); +} + +void ECRYPT_ivsetup(ECRYPT_ctx *x, const u8 *iv) +{ + x->input[12] = 0; + x->input[13] = 0; + x->input[14] = U8TO32_LITTLE(iv + 0); + x->input[15] = U8TO32_LITTLE(iv + 4); +} + +void ECRYPT_encrypt_bytes(ECRYPT_ctx *x, const u8 *m, u8 *c, u32 bytes) +{ + u8 output[64]; + int i; + + if (!bytes) return; + for (;;) { + salsa20_wordtobyte(output, x->input); + x->input[12] = PLUSONE(x->input[12]); + if (!x->input[12]) { + x->input[13] = PLUSONE(x->input[13]); + /* stopping at 2^70 bytes per nonce is user's responsibility */ + } + if (bytes <= 64) { + for (i = 0; i < bytes; ++i) c[i] = m[i] ^ output[i]; + return; + } + for (i = 0; i < 64; ++i) c[i] = m[i] ^ output[i]; + bytes -= 64; + c += 64; + m += 64; + } +} + +void ECRYPT_decrypt_bytes(ECRYPT_ctx *x, const u8 *c, u8 *m, u32 bytes) +{ + ECRYPT_encrypt_bytes(x, c, m, bytes); +} + +void ECRYPT_keystream_bytes(ECRYPT_ctx *x, u8 *stream, u32 bytes) +{ + u32 i; + for (i = 0; i < bytes; ++i) stream[i] = 0; + ECRYPT_encrypt_bytes(x, stream, stream, bytes); +} \ No newline at end of file diff --git a/src/crypto/chacha8_stream.h b/src/crypto/chacha8_stream.h new file mode 100644 index 00000000..a2d0b070 --- /dev/null +++ b/src/crypto/chacha8_stream.h @@ -0,0 +1,289 @@ +/* ecrypt-sync.h */ + +/* +* Header file for synchronous stream ciphers without authentication +* mechanism. +* +* *** Please only edit parts marked with "[edit]". *** +*/ + +#ifndef ECRYPT_SYNC +#define ECRYPT_SYNC + +#if defined(__cplusplus) +extern "C" { +#endif + + +#include "ecrypt-portable.h" + + /* ------------------------------------------------------------------------- */ + + /* Cipher parameters */ + + /* + * The name of your cipher. + */ +#define ECRYPT_NAME "ChaCha8" +#define ECRYPT_PROFILE "_____" + + /* + * Specify which key and IV sizes are supported by your cipher. A user + * should be able to enumerate the supported sizes by running the + * following code: + * + * for (i = 0; ECRYPT_KEYSIZE(i) <= ECRYPT_MAXKEYSIZE; ++i) + * { + * keysize = ECRYPT_KEYSIZE(i); + * + * ... + * } + * + * All sizes are in bits. + */ + +#define ECRYPT_MAXKEYSIZE 256 /* [edit] */ +#define ECRYPT_KEYSIZE(i) (128 + (i)*128) /* [edit] */ + +#define ECRYPT_MAXIVSIZE 64 /* [edit] */ +#define ECRYPT_IVSIZE(i) (64 + (i)*64) /* [edit] */ + + /* ------------------------------------------------------------------------- */ + + /* Data structures */ + + /* + * ECRYPT_ctx is the structure containing the representation of the + * internal state of your cipher. + */ + + typedef struct + { + u32 input[16]; /* could be compressed */ + /* + * [edit] + * + * Put here all state variable needed during the encryption process. + */ + } ECRYPT_ctx; + + /* ------------------------------------------------------------------------- */ + + /* Mandatory functions */ + + /* + * Key and message independent initialization. This function will be + * called once when the program starts (e.g., to build expanded S-box + * tables). + */ + void ECRYPT_init(); + + /* + * Key setup. It is the user's responsibility to select the values of + * keysize and ivsize from the set of supported values specified + * above. + */ + void ECRYPT_keysetup( + ECRYPT_ctx* ctx, + const u8* key, + u32 keysize, /* Key size in bits. */ + u32 ivsize); /* IV size in bits. */ + + /* + * IV setup. After having called ECRYPT_keysetup(), the user is + * allowed to call ECRYPT_ivsetup() different times in order to + * encrypt/decrypt different messages with the same key but different + * IV's. + */ + void ECRYPT_ivsetup( + ECRYPT_ctx* ctx, + const u8* iv); + + /* + * Encryption/decryption of arbitrary length messages. + * + * For efficiency reasons, the API provides two types of + * encrypt/decrypt functions. The ECRYPT_encrypt_bytes() function + * (declared here) encrypts byte strings of arbitrary length, while + * the ECRYPT_encrypt_blocks() function (defined later) only accepts + * lengths which are multiples of ECRYPT_BLOCKLENGTH. + * + * The user is allowed to make multiple calls to + * ECRYPT_encrypt_blocks() to incrementally encrypt a long message, + * but he is NOT allowed to make additional encryption calls once he + * has called ECRYPT_encrypt_bytes() (unless he starts a new message + * of course). For example, this sequence of calls is acceptable: + * + * ECRYPT_keysetup(); + * + * ECRYPT_ivsetup(); + * ECRYPT_encrypt_blocks(); + * ECRYPT_encrypt_blocks(); + * ECRYPT_encrypt_bytes(); + * + * ECRYPT_ivsetup(); + * ECRYPT_encrypt_blocks(); + * ECRYPT_encrypt_blocks(); + * + * ECRYPT_ivsetup(); + * ECRYPT_encrypt_bytes(); + * + * The following sequence is not: + * + * ECRYPT_keysetup(); + * ECRYPT_ivsetup(); + * ECRYPT_encrypt_blocks(); + * ECRYPT_encrypt_bytes(); + * ECRYPT_encrypt_blocks(); + */ + + void ECRYPT_encrypt_bytes( + ECRYPT_ctx* ctx, + const u8* plaintext, + u8* ciphertext, + u32 msglen); /* Message length in bytes. */ + + void ECRYPT_decrypt_bytes( + ECRYPT_ctx* ctx, + const u8* ciphertext, + u8* plaintext, + u32 msglen); /* Message length in bytes. */ + + /* ------------------------------------------------------------------------- */ + + /* Optional features */ + + /* + * For testing purposes it can sometimes be useful to have a function + * which immediately generates keystream without having to provide it + * with a zero plaintext. If your cipher cannot provide this function + * (e.g., because it is not strictly a synchronous cipher), please + * reset the ECRYPT_GENERATES_KEYSTREAM flag. + */ + +#define ECRYPT_GENERATES_KEYSTREAM +#ifdef ECRYPT_GENERATES_KEYSTREAM + + void ECRYPT_keystream_bytes( + ECRYPT_ctx* ctx, + u8* keystream, + u32 length); /* Length of keystream in bytes. */ + +#endif + +/* ------------------------------------------------------------------------- */ + +/* Optional optimizations */ + +/* +* By default, the functions in this section are implemented using +* calls to functions declared above. However, you might want to +* implement them differently for performance reasons. +*/ + +/* +* All-in-one encryption/decryption of (short) packets. +* +* The default definitions of these functions can be found in +* "ecrypt-sync.c". If you want to implement them differently, please +* undef the ECRYPT_USES_DEFAULT_ALL_IN_ONE flag. +*/ +#define ECRYPT_USES_DEFAULT_ALL_IN_ONE /* [edit] */ + + void ECRYPT_encrypt_packet( + ECRYPT_ctx* ctx, + const u8* iv, + const u8* plaintext, + u8* ciphertext, + u32 msglen); + + void ECRYPT_decrypt_packet( + ECRYPT_ctx* ctx, + const u8* iv, + const u8* ciphertext, + u8* plaintext, + u32 msglen); + + /* + * Encryption/decryption of blocks. + * + * By default, these functions are defined as macros. If you want to + * provide a different implementation, please undef the + * ECRYPT_USES_DEFAULT_BLOCK_MACROS flag and implement the functions + * declared below. + */ + +#define ECRYPT_BLOCKLENGTH 64 /* [edit] */ + +#define ECRYPT_USES_DEFAULT_BLOCK_MACROS /* [edit] */ +#ifdef ECRYPT_USES_DEFAULT_BLOCK_MACROS + +#define ECRYPT_encrypt_blocks(ctx, plaintext, ciphertext, blocks) \ + ECRYPT_encrypt_bytes(ctx, plaintext, ciphertext, \ + (blocks) * ECRYPT_BLOCKLENGTH) + +#define ECRYPT_decrypt_blocks(ctx, ciphertext, plaintext, blocks) \ + ECRYPT_decrypt_bytes(ctx, ciphertext, plaintext, \ + (blocks) * ECRYPT_BLOCKLENGTH) + +#ifdef ECRYPT_GENERATES_KEYSTREAM + +#define ECRYPT_keystream_blocks(ctx, keystream, blocks) \ + ECRYPT_keystream_bytes(ctx, keystream, \ + (blocks) * ECRYPT_BLOCKLENGTH) + +#endif + +#else + + void ECRYPT_encrypt_blocks( + ECRYPT_ctx* ctx, + const u8* plaintext, + u8* ciphertext, + u32 blocks); /* Message length in blocks. */ + + void ECRYPT_decrypt_blocks( + ECRYPT_ctx* ctx, + const u8* ciphertext, + u8* plaintext, + u32 blocks); /* Message length in blocks. */ + +#ifdef ECRYPT_GENERATES_KEYSTREAM + + void ECRYPT_keystream_blocks( + ECRYPT_ctx* ctx, + const u8* keystream, + u32 blocks); /* Keystream length in blocks. */ + +#endif + +#endif + +/* +* If your cipher can be implemented in different ways, you can use +* the ECRYPT_VARIANT parameter to allow the user to choose between +* them at compile time (e.g., gcc -DECRYPT_VARIANT=3 ...). Please +* only use this possibility if you really think it could make a +* significant difference and keep the number of variants +* (ECRYPT_MAXVARIANT) as small as possible (definitely not more than +* 10). Note also that all variants should have exactly the same +* external interface (i.e., the same ECRYPT_BLOCKLENGTH, etc.). +*/ +#define ECRYPT_MAXVARIANT 1 /* [edit] */ + +#ifndef ECRYPT_VARIANT +#define ECRYPT_VARIANT 1 +#endif + +#if (ECRYPT_VARIANT > ECRYPT_MAXVARIANT) +#error this variant does not exist +#endif + +/* ------------------------------------------------------------------------- */ + +#if defined(__cplusplus) +//extern "C" { +} +#endif + +#endif \ No newline at end of file diff --git a/src/crypto/ecrypt-config.h b/src/crypto/ecrypt-config.h new file mode 100644 index 00000000..9176de17 --- /dev/null +++ b/src/crypto/ecrypt-config.h @@ -0,0 +1,272 @@ +/* ecrypt-config.h */ + +/* *** Normally, it should not be necessary to edit this file. *** */ + +#ifndef ECRYPT_CONFIG +#define ECRYPT_CONFIG + +/* ------------------------------------------------------------------------- */ + +/* Guess the endianness of the target architecture. */ + +/* +* The LITTLE endian machines: +*/ +#if defined(__ultrix) /* Older MIPS */ +#define ECRYPT_LITTLE_ENDIAN +#elif defined(__alpha) /* Alpha */ +#define ECRYPT_LITTLE_ENDIAN +#elif defined(i386) /* x86 (gcc) */ +#define ECRYPT_LITTLE_ENDIAN +#elif defined(__i386) /* x86 (gcc) */ +#define ECRYPT_LITTLE_ENDIAN +#elif defined(_M_IX86) /* x86 (MSC, Borland) */ +#define ECRYPT_LITTLE_ENDIAN +#elif defined(_MSC_VER) /* x86 (surely MSC) */ +#define ECRYPT_LITTLE_ENDIAN +#elif defined(__INTEL_COMPILER) /* x86 (surely Intel compiler icl.exe) */ +#define ECRYPT_LITTLE_ENDIAN + +/* +* The BIG endian machines: +*/ +#elif defined(sun) /* Newer Sparc's */ +#define ECRYPT_BIG_ENDIAN +#elif defined(__ppc__) /* PowerPC */ +#define ECRYPT_BIG_ENDIAN + +/* +* Finally machines with UNKNOWN endianness: +*/ +#elif defined (_AIX) /* RS6000 */ +#define ECRYPT_UNKNOWN +#elif defined(__hpux) /* HP-PA */ +#define ECRYPT_UNKNOWN +#elif defined(__aux) /* 68K */ +#define ECRYPT_UNKNOWN +#elif defined(__dgux) /* 88K (but P6 in latest boxes) */ +#define ECRYPT_UNKNOWN +#elif defined(__sgi) /* Newer MIPS */ +#define ECRYPT_UNKNOWN +#else /* Any other processor */ +#define ECRYPT_UNKNOWN +#endif + +/* ------------------------------------------------------------------------- */ + +/* +* Find minimal-width types to store 8-bit, 16-bit, 32-bit, and 64-bit +* integers. +* +* Note: to enable 64-bit types on 32-bit compilers, it might be +* necessary to switch from ISO C90 mode to ISO C99 mode (e.g., gcc +* -std=c99). +*/ + +#include + +/* --- check char --- */ + +#if (UCHAR_MAX / 0xFU > 0xFU) +#ifndef I8T +#define I8T char +#define U8C(v) (v##U) + +#if (UCHAR_MAX == 0xFFU) +#define ECRYPT_I8T_IS_BYTE +#endif + +#endif + +#if (UCHAR_MAX / 0xFFU > 0xFFU) +#ifndef I16T +#define I16T char +#define U16C(v) (v##U) +#endif + +#if (UCHAR_MAX / 0xFFFFU > 0xFFFFU) +#ifndef I32T +#define I32T char +#define U32C(v) (v##U) +#endif + +#if (UCHAR_MAX / 0xFFFFFFFFU > 0xFFFFFFFFU) +#ifndef I64T +#define I64T char +#define U64C(v) (v##U) +#define ECRYPT_NATIVE64 +#endif + +#endif +#endif +#endif +#endif + +/* --- check short --- */ + +#if (USHRT_MAX / 0xFU > 0xFU) +#ifndef I8T +#define I8T short +#define U8C(v) (v##U) + +#if (USHRT_MAX == 0xFFU) +#define ECRYPT_I8T_IS_BYTE +#endif + +#endif + +#if (USHRT_MAX / 0xFFU > 0xFFU) +#ifndef I16T +#define I16T short +#define U16C(v) (v##U) +#endif + +#if (USHRT_MAX / 0xFFFFU > 0xFFFFU) +#ifndef I32T +#define I32T short +#define U32C(v) (v##U) +#endif + +#if (USHRT_MAX / 0xFFFFFFFFU > 0xFFFFFFFFU) +#ifndef I64T +#define I64T short +#define U64C(v) (v##U) +#define ECRYPT_NATIVE64 +#endif + +#endif +#endif +#endif +#endif + +/* --- check int --- */ + +#if (UINT_MAX / 0xFU > 0xFU) +#ifndef I8T +#define I8T int +#define U8C(v) (v##U) + +#if (ULONG_MAX == 0xFFU) +#define ECRYPT_I8T_IS_BYTE +#endif + +#endif + +#if (UINT_MAX / 0xFFU > 0xFFU) +#ifndef I16T +#define I16T int +#define U16C(v) (v##U) +#endif + +#if (UINT_MAX / 0xFFFFU > 0xFFFFU) +#ifndef I32T +#define I32T int +#define U32C(v) (v##U) +#endif + +#if (UINT_MAX / 0xFFFFFFFFU > 0xFFFFFFFFU) +#ifndef I64T +#define I64T int +#define U64C(v) (v##U) +#define ECRYPT_NATIVE64 +#endif + +#endif +#endif +#endif +#endif + +/* --- check long --- */ + +#if (ULONG_MAX / 0xFUL > 0xFUL) +#ifndef I8T +#define I8T long +#define U8C(v) (v##UL) + +#if (ULONG_MAX == 0xFFUL) +#define ECRYPT_I8T_IS_BYTE +#endif + +#endif + +#if (ULONG_MAX / 0xFFUL > 0xFFUL) +#ifndef I16T +#define I16T long +#define U16C(v) (v##UL) +#endif + +#if (ULONG_MAX / 0xFFFFUL > 0xFFFFUL) +#ifndef I32T +#define I32T long +#define U32C(v) (v##UL) +#endif + +#if (ULONG_MAX / 0xFFFFFFFFUL > 0xFFFFFFFFUL) +#ifndef I64T +#define I64T long +#define U64C(v) (v##UL) +#define ECRYPT_NATIVE64 +#endif + +#endif +#endif +#endif +#endif + +/* --- check long long --- */ + +#ifdef ULLONG_MAX + +#if (ULLONG_MAX / 0xFULL > 0xFULL) +#ifndef I8T +#define I8T long long +#define U8C(v) (v##ULL) + +#if (ULLONG_MAX == 0xFFULL) +#define ECRYPT_I8T_IS_BYTE +#endif + +#endif + +#if (ULLONG_MAX / 0xFFULL > 0xFFULL) +#ifndef I16T +#define I16T long long +#define U16C(v) (v##ULL) +#endif + +#if (ULLONG_MAX / 0xFFFFULL > 0xFFFFULL) +#ifndef I32T +#define I32T long long +#define U32C(v) (v##ULL) +#endif + +#if (ULLONG_MAX / 0xFFFFFFFFULL > 0xFFFFFFFFULL) +#ifndef I64T +#define I64T long long +#define U64C(v) (v##ULL) +#endif + +#endif +#endif +#endif +#endif + +#endif + +/* --- check __int64 --- */ + +#ifdef _UI64_MAX + +#if (_UI64_MAX / 0xFFFFFFFFui64 > 0xFFFFFFFFui64) +#ifndef I64T +#define I64T __int64 +#define U64C(v) (v##ui64) +#endif + +#endif + +#endif + +/* ------------------------------------------------------------------------- */ + +#endif \ No newline at end of file diff --git a/src/crypto/ecrypt-machine.h b/src/crypto/ecrypt-machine.h new file mode 100644 index 00000000..83356b1e --- /dev/null +++ b/src/crypto/ecrypt-machine.h @@ -0,0 +1,46 @@ +/* ecrypt-machine.h */ + +/* +* This file is included by 'ecrypt-portable.h'. It allows to override +* the default macros for specific platforms. Please carefully check +* the machine code generated by your compiler (with optimisations +* turned on) before deciding to edit this file. +*/ + +/* ------------------------------------------------------------------------- */ + +#if (defined(ECRYPT_DEFAULT_ROT) && !defined(ECRYPT_MACHINE_ROT)) + +#define ECRYPT_MACHINE_ROT + +#if (defined(WIN32) && defined(_MSC_VER)) + +#undef ROTL32 +#undef ROTR32 +#undef ROTL64 +#undef ROTR64 + +#include + +#define ROTL32(v, n) _lrotl(v, n) +#define ROTR32(v, n) _lrotr(v, n) +#define ROTL64(v, n) _rotl64(v, n) +#define ROTR64(v, n) _rotr64(v, n) + +#endif + +#endif + +/* ------------------------------------------------------------------------- */ + +#if (defined(ECRYPT_DEFAULT_SWAP) && !defined(ECRYPT_MACHINE_SWAP)) + +#define ECRYPT_MACHINE_SWAP + +/* +* If you want to overwrite the default swap macros, put it here. And so on. +*/ + +#endif + +/* ------------------------------------------------------------------------- */ \ No newline at end of file diff --git a/src/crypto/ecrypt-portable.h b/src/crypto/ecrypt-portable.h new file mode 100644 index 00000000..4baa4d6a --- /dev/null +++ b/src/crypto/ecrypt-portable.h @@ -0,0 +1,303 @@ +/* ecrypt-portable.h */ + +/* +* WARNING: the conversions defined below are implemented as macros, +* and should be used carefully. They should NOT be used with +* parameters which perform some action. E.g., the following two lines +* are not equivalent: +* +* 1) ++x; y = ROTL32(x, n); +* 2) y = ROTL32(++x, n); +*/ + +/* +* *** Please do not edit this file. *** +* +* The default macros can be overridden for specific architectures by +* editing 'ecrypt-machine.h'. +*/ + +#ifndef ECRYPT_PORTABLE +#define ECRYPT_PORTABLE + +#include "ecrypt-config.h" + +/* ------------------------------------------------------------------------- */ + +/* +* The following types are defined (if available): +* +* u8: unsigned integer type, at least 8 bits +* u16: unsigned integer type, at least 16 bits +* u32: unsigned integer type, at least 32 bits +* u64: unsigned integer type, at least 64 bits +* +* s8, s16, s32, s64 -> signed counterparts of u8, u16, u32, u64 +* +* The selection of minimum-width integer types is taken care of by +* 'ecrypt-config.h'. Note: to enable 64-bit types on 32-bit +* compilers, it might be necessary to switch from ISO C90 mode to ISO +* C99 mode (e.g., gcc -std=c99). +*/ + +#ifdef I8T +typedef signed I8T s8; +typedef unsigned I8T u8; +#endif + +#ifdef I16T +typedef signed I16T s16; +typedef unsigned I16T u16; +#endif + +#ifdef I32T +typedef signed I32T s32; +typedef unsigned I32T u32; +#endif + +#ifdef I64T +typedef signed I64T s64; +typedef unsigned I64T u64; +#endif + +/* +* The following macros are used to obtain exact-width results. +*/ + +#define U8V(v) ((u8)(v) & U8C(0xFF)) +#define U16V(v) ((u16)(v) & U16C(0xFFFF)) +#define U32V(v) ((u32)(v) & U32C(0xFFFFFFFF)) +#define U64V(v) ((u64)(v) & U64C(0xFFFFFFFFFFFFFFFF)) + +/* ------------------------------------------------------------------------- */ + +/* +* The following macros return words with their bits rotated over n +* positions to the left/right. +*/ + +#define ECRYPT_DEFAULT_ROT + +#define ROTL8(v, n) \ + (U8V((v) << (n)) | ((v) >> (8 - (n)))) + +#define ROTL16(v, n) \ + (U16V((v) << (n)) | ((v) >> (16 - (n)))) + +#define ROTL32(v, n) \ + (U32V((v) << (n)) | ((v) >> (32 - (n)))) + +#define ROTL64(v, n) \ + (U64V((v) << (n)) | ((v) >> (64 - (n)))) + +#define ROTR8(v, n) ROTL8(v, 8 - (n)) +#define ROTR16(v, n) ROTL16(v, 16 - (n)) +#define ROTR32(v, n) ROTL32(v, 32 - (n)) +#define ROTR64(v, n) ROTL64(v, 64 - (n)) + +#include "ecrypt-machine.h" + +/* ------------------------------------------------------------------------- */ + +/* +* The following macros return a word with bytes in reverse order. +*/ + +#define ECRYPT_DEFAULT_SWAP + +#define SWAP16(v) \ + ROTL16(v, 8) + +#define SWAP32(v) \ + ((ROTL32(v, 8) & U32C(0x00FF00FF)) | \ + (ROTL32(v, 24) & U32C(0xFF00FF00))) + +#ifdef ECRYPT_NATIVE64 +#define SWAP64(v) \ + ((ROTL64(v, 8) & U64C(0x000000FF000000FF)) | \ + (ROTL64(v, 24) & U64C(0x0000FF000000FF00)) | \ + (ROTL64(v, 40) & U64C(0x00FF000000FF0000)) | \ + (ROTL64(v, 56) & U64C(0xFF000000FF000000))) +#else +#define SWAP64(v) \ + (((u64)SWAP32(U32V(v)) << 32) | (u64)SWAP32(U32V(v >> 32))) +#endif + +#include "ecrypt-machine.h" + +#define ECRYPT_DEFAULT_WTOW + +#ifdef ECRYPT_LITTLE_ENDIAN +#define U16TO16_LITTLE(v) (v) +#define U32TO32_LITTLE(v) (v) +#define U64TO64_LITTLE(v) (v) + +#define U16TO16_BIG(v) SWAP16(v) +#define U32TO32_BIG(v) SWAP32(v) +#define U64TO64_BIG(v) SWAP64(v) +#endif + +#ifdef ECRYPT_BIG_ENDIAN +#define U16TO16_LITTLE(v) SWAP16(v) +#define U32TO32_LITTLE(v) SWAP32(v) +#define U64TO64_LITTLE(v) SWAP64(v) + +#define U16TO16_BIG(v) (v) +#define U32TO32_BIG(v) (v) +#define U64TO64_BIG(v) (v) +#endif + +#include "ecrypt-machine.h" + +/* +* The following macros load words from an array of bytes with +* different types of endianness, and vice versa. +*/ + +#define ECRYPT_DEFAULT_BTOW + +#if (!defined(ECRYPT_UNKNOWN) && defined(ECRYPT_I8T_IS_BYTE)) + +#define U8TO16_LITTLE(p) U16TO16_LITTLE(((u16*)(p))[0]) +#define U8TO32_LITTLE(p) U32TO32_LITTLE(((u32*)(p))[0]) +#define U8TO64_LITTLE(p) U64TO64_LITTLE(((u64*)(p))[0]) + +#define U8TO16_BIG(p) U16TO16_BIG(((u16*)(p))[0]) +#define U8TO32_BIG(p) U32TO32_BIG(((u32*)(p))[0]) +#define U8TO64_BIG(p) U64TO64_BIG(((u64*)(p))[0]) + +#define U16TO8_LITTLE(p, v) (((u16*)(p))[0] = U16TO16_LITTLE(v)) +#define U32TO8_LITTLE(p, v) (((u32*)(p))[0] = U32TO32_LITTLE(v)) +#define U64TO8_LITTLE(p, v) (((u64*)(p))[0] = U64TO64_LITTLE(v)) + +#define U16TO8_BIG(p, v) (((u16*)(p))[0] = U16TO16_BIG(v)) +#define U32TO8_BIG(p, v) (((u32*)(p))[0] = U32TO32_BIG(v)) +#define U64TO8_BIG(p, v) (((u64*)(p))[0] = U64TO64_BIG(v)) + +#else + +#define U8TO16_LITTLE(p) \ + (((u16)((p)[0]) ) | \ + ((u16)((p)[1]) << 8)) + +#define U8TO32_LITTLE(p) \ + (((u32)((p)[0]) ) | \ + ((u32)((p)[1]) << 8) | \ + ((u32)((p)[2]) << 16) | \ + ((u32)((p)[3]) << 24)) + +#ifdef ECRYPT_NATIVE64 +#define U8TO64_LITTLE(p) \ + (((u64)((p)[0]) ) | \ + ((u64)((p)[1]) << 8) | \ + ((u64)((p)[2]) << 16) | \ + ((u64)((p)[3]) << 24) | \ + ((u64)((p)[4]) << 32) | \ + ((u64)((p)[5]) << 40) | \ + ((u64)((p)[6]) << 48) | \ + ((u64)((p)[7]) << 56)) +#else +#define U8TO64_LITTLE(p) \ + ((u64)U8TO32_LITTLE(p) | ((u64)U8TO32_LITTLE((p) + 4) << 32)) +#endif + +#define U8TO16_BIG(p) \ + (((u16)((p)[0]) << 8) | \ + ((u16)((p)[1]) )) + +#define U8TO32_BIG(p) \ + (((u32)((p)[0]) << 24) | \ + ((u32)((p)[1]) << 16) | \ + ((u32)((p)[2]) << 8) | \ + ((u32)((p)[3]) )) + +#ifdef ECRYPT_NATIVE64 +#define U8TO64_BIG(p) \ + (((u64)((p)[0]) << 56) | \ + ((u64)((p)[1]) << 48) | \ + ((u64)((p)[2]) << 40) | \ + ((u64)((p)[3]) << 32) | \ + ((u64)((p)[4]) << 24) | \ + ((u64)((p)[5]) << 16) | \ + ((u64)((p)[6]) << 8) | \ + ((u64)((p)[7]) )) +#else +#define U8TO64_BIG(p) \ + (((u64)U8TO32_BIG(p) << 32) | (u64)U8TO32_BIG((p) + 4)) +#endif + +#define U16TO8_LITTLE(p, v) \ + do { \ + (p)[0] = U8V((v) ); \ + (p)[1] = U8V((v) >> 8); \ + } while (0) + +#define U32TO8_LITTLE(p, v) \ + do { \ + (p)[0] = U8V((v) ); \ + (p)[1] = U8V((v) >> 8); \ + (p)[2] = U8V((v) >> 16); \ + (p)[3] = U8V((v) >> 24); \ + } while (0) + +#ifdef ECRYPT_NATIVE64 +#define U64TO8_LITTLE(p, v) \ + do { \ + (p)[0] = U8V((v) ); \ + (p)[1] = U8V((v) >> 8); \ + (p)[2] = U8V((v) >> 16); \ + (p)[3] = U8V((v) >> 24); \ + (p)[4] = U8V((v) >> 32); \ + (p)[5] = U8V((v) >> 40); \ + (p)[6] = U8V((v) >> 48); \ + (p)[7] = U8V((v) >> 56); \ + } while (0) +#else +#define U64TO8_LITTLE(p, v) \ + do { \ + U32TO8_LITTLE((p), U32V((v) )); \ + U32TO8_LITTLE((p) + 4, U32V((v) >> 32)); \ + } while (0) +#endif + +#define U16TO8_BIG(p, v) \ + do { \ + (p)[0] = U8V((v) ); \ + (p)[1] = U8V((v) >> 8); \ + } while (0) + +#define U32TO8_BIG(p, v) \ + do { \ + (p)[0] = U8V((v) >> 24); \ + (p)[1] = U8V((v) >> 16); \ + (p)[2] = U8V((v) >> 8); \ + (p)[3] = U8V((v) ); \ + } while (0) + +#ifdef ECRYPT_NATIVE64 +#define U64TO8_BIG(p, v) \ + do { \ + (p)[0] = U8V((v) >> 56); \ + (p)[1] = U8V((v) >> 48); \ + (p)[2] = U8V((v) >> 40); \ + (p)[3] = U8V((v) >> 32); \ + (p)[4] = U8V((v) >> 24); \ + (p)[5] = U8V((v) >> 16); \ + (p)[6] = U8V((v) >> 8); \ + (p)[7] = U8V((v) ); \ + } while (0) +#else +#define U64TO8_BIG(p, v) \ + do { \ + U32TO8_BIG((p), U32V((v) >> 32)); \ + U32TO8_BIG((p) + 4, U32V((v) )); \ + } while (0) +#endif + +#endif + +#include "ecrypt-machine.h" + +/* ------------------------------------------------------------------------- */ + +#endif \ No newline at end of file diff --git a/src/crypto/ecrypt-sync.h b/src/crypto/ecrypt-sync.h new file mode 100644 index 00000000..cd5f5d43 --- /dev/null +++ b/src/crypto/ecrypt-sync.h @@ -0,0 +1,258 @@ +/* ecrypt-sync.h */ + +/* +* Header file for synchronous stream ciphers without authentication +* mechanism. +* +* *** Please only edit parts marked with "[edit]". *** +*/ + +#ifndef ECRYPT_SYNC_AE +#define ECRYPT_SYNC_AE + +#include "ecrypt-portable.h" + +/* ------------------------------------------------------------------------- */ + +/* Cipher parameters */ + +/* +* The name of your cipher. +*/ +#define ECRYPT_NAME "Salsa20 stream cipher" /* [edit] */ + +/* +* Specify which key and IV sizes are supported by your cipher. A user +* should be able to enumerate the supported sizes by running the +* following code: +* +* for (i = 0; ECRYPT_KEYSIZE(i) <= ECRYPT_MAXKEYSIZE; ++i) +* { +* keysize = ECRYPT_KEYSIZE(i); +* +* ... +* } +* +* All sizes are in bits. +*/ + +#define ECRYPT_MAXKEYSIZE 256 /* [edit] */ +#define ECRYPT_KEYSIZE(i) (128 + (i)*128) /* [edit] */ + +#define ECRYPT_MAXIVSIZE 64 /* [edit] */ +#define ECRYPT_IVSIZE(i) (64 + (i)*64) /* [edit] */ + +/* ------------------------------------------------------------------------- */ + +/* Data structures */ + +/* +* ECRYPT_ctx is the structure containing the representation of the +* internal state of your cipher. +*/ + +typedef struct +{ + u32 input[16]; /* could be compressed */ + /* + * [edit] + * + * Put here all state variable needed during the encryption process. + */ +} ECRYPT_ctx; + +/* ------------------------------------------------------------------------- */ + +/* Mandatory functions */ + +/* +* Key and message independent initialization. This function will be +* called once when the program starts (e.g., to build expanded S-box +* tables). +*/ +void ECRYPT_init(); + +/* +* Key setup. It is the user's responsibility to select the values of +* keysize and ivsize from the set of supported values specified +* above. +*/ +void ECRYPT_keysetup( + ECRYPT_ctx* ctx, + const u8* key, + u32 keysize, /* Key size in bits. */ + u32 ivsize); /* IV size in bits. */ + + /* + * IV setup. After having called ECRYPT_keysetup(), the user is + * allowed to call ECRYPT_ivsetup() different times in order to + * encrypt/decrypt different messages with the same key but different + * IV's. + */ +void ECRYPT_ivsetup( + ECRYPT_ctx* ctx, + const u8* iv); + +/* +* Encryption/decryption of arbitrary length messages. +* +* For efficiency reasons, the API provides two types of +* encrypt/decrypt functions. The ECRYPT_encrypt_bytes() function +* (declared here) encrypts byte strings of arbitrary length, while +* the ECRYPT_encrypt_blocks() function (defined later) only accepts +* lengths which are multiples of ECRYPT_BLOCKLENGTH. +* +* The user is allowed to make multiple calls to +* ECRYPT_encrypt_blocks() to incrementally encrypt a long message, +* but he is NOT allowed to make additional encryption calls once he +* has called ECRYPT_encrypt_bytes() (unless he starts a new message +* of course). For example, this sequence of calls is acceptable: +* +* ECRYPT_keysetup(); +* +* ECRYPT_ivsetup(); +* ECRYPT_encrypt_blocks(); +* ECRYPT_encrypt_blocks(); +* ECRYPT_encrypt_bytes(); +* +* ECRYPT_ivsetup(); +* ECRYPT_encrypt_blocks(); +* ECRYPT_encrypt_blocks(); +* +* ECRYPT_ivsetup(); +* ECRYPT_encrypt_bytes(); +* +* The following sequence is not: +* +* ECRYPT_keysetup(); +* ECRYPT_ivsetup(); +* ECRYPT_encrypt_blocks(); +* ECRYPT_encrypt_bytes(); +* ECRYPT_encrypt_blocks(); +*/ + +void ECRYPT_encrypt_bytes( + ECRYPT_ctx* ctx, + const u8* plaintext, + u8* ciphertext, + u32 msglen); /* Message length in bytes. */ + +void ECRYPT_decrypt_bytes( + ECRYPT_ctx* ctx, + const u8* ciphertext, + u8* plaintext, + u32 msglen); /* Message length in bytes. */ + + /* ------------------------------------------------------------------------- */ + + /* Optional features */ + + /* + * For testing purposes it can sometimes be useful to have a function + * which immediately generates keystream without having to provide it + * with a zero plaintext. If your cipher cannot provide this function + * (e.g., because it is not strictly a synchronous cipher), please + * reset the ECRYPT_GENERATES_KEYSTREAM flag. + */ + +#define ECRYPT_GENERATES_KEYSTREAM +#ifdef ECRYPT_GENERATES_KEYSTREAM + +void ECRYPT_keystream_bytes( + ECRYPT_ctx* ctx, + u8* keystream, + u32 length); /* Length of keystream in bytes. */ + +#endif + + /* ------------------------------------------------------------------------- */ + + /* Optional optimizations */ + + /* + * By default, the functions in this section are implemented using + * calls to functions declared above. However, you might want to + * implement them differently for performance reasons. + */ + + /* + * All-in-one encryption/decryption of (short) packets. + * + * The default definitions of these functions can be found in + * "ecrypt-sync.c". If you want to implement them differently, please + * undef the ECRYPT_USES_DEFAULT_ALL_IN_ONE flag. + */ +#define ECRYPT_USES_DEFAULT_ALL_IN_ONE /* [edit] */ + +void ECRYPT_encrypt_packet( + ECRYPT_ctx* ctx, + const u8* iv, + const u8* plaintext, + u8* ciphertext, + u32 msglen); + +void ECRYPT_decrypt_packet( + ECRYPT_ctx* ctx, + const u8* iv, + const u8* ciphertext, + u8* plaintext, + u32 msglen); + +/* +* Encryption/decryption of blocks. +* +* By default, these functions are defined as macros. If you want to +* provide a different implementation, please undef the +* ECRYPT_USES_DEFAULT_BLOCK_MACROS flag and implement the functions +* declared below. +*/ + +#define ECRYPT_BLOCKLENGTH 64 /* [edit] */ + +#define ECRYPT_USES_DEFAULT_BLOCK_MACROS /* [edit] */ +#ifdef ECRYPT_USES_DEFAULT_BLOCK_MACROS + +#define ECRYPT_encrypt_blocks(ctx, plaintext, ciphertext, blocks) \ + ECRYPT_encrypt_bytes(ctx, plaintext, ciphertext, \ + (blocks) * ECRYPT_BLOCKLENGTH) + +#define ECRYPT_decrypt_blocks(ctx, ciphertext, plaintext, blocks) \ + ECRYPT_decrypt_bytes(ctx, ciphertext, plaintext, \ + (blocks) * ECRYPT_BLOCKLENGTH) + +#ifdef ECRYPT_GENERATES_KEYSTREAM + +#define ECRYPT_keystream_blocks(ctx, keystream, blocks) \ + ECRYPT_AE_keystream_bytes(ctx, keystream, \ + (blocks) * ECRYPT_BLOCKLENGTH) + +#endif + +#else + +void ECRYPT_encrypt_blocks( + ECRYPT_ctx* ctx, + const u8* plaintext, + u8* ciphertext, + u32 blocks); /* Message length in blocks. */ + +void ECRYPT_decrypt_blocks( + ECRYPT_ctx* ctx, + const u8* ciphertext, + u8* plaintext, + u32 blocks); /* Message length in blocks. */ + +#ifdef ECRYPT_GENERATES_KEYSTREAM + +void ECRYPT_keystream_blocks( + ECRYPT_AE_ctx* ctx, + const u8* keystream, + u32 blocks); /* Keystream length in blocks. */ + +#endif + +#endif + + /* ------------------------------------------------------------------------- */ + +#endif \ No newline at end of file diff --git a/src/currency_core/account.cpp b/src/currency_core/account.cpp index b3dd880d..ada25025 100644 --- a/src/currency_core/account.cpp +++ b/src/currency_core/account.cpp @@ -81,7 +81,7 @@ namespace currency if (m_keys.account_address.flags & ACCOUNT_PUBLIC_ADDRESS_FLAG_AUDITABLE) auditable_flag = 1; - uint64_t auditable_flag_and_checksum = (auditable_flag & 1) | (checksum << 1); + uint32_t auditable_flag_and_checksum = (auditable_flag & 1) | (checksum << 1); std::string auditable_flag_and_checksum_word = tools::mnemonic_encoding::word_by_num(auditable_flag_and_checksum); return keys_seed_text + " " + timestamp_word + " " + auditable_flag_and_checksum_word; @@ -148,7 +148,7 @@ namespace currency if (auditable_flag_and_checksum != UINT64_MAX) { auditable_flag = (auditable_flag_and_checksum & 1) != 0; // auditable flag is the lower 1 bit - uint16_t checksum = auditable_flag_and_checksum >> 1; // checksum -- everything else + uint16_t checksum = static_cast(auditable_flag_and_checksum >> 1); // checksum -- everything else constexpr uint16_t checksum_max = tools::mnemonic_encoding::NUMWORDS >> 1; // maximum value of checksum crypto::hash h = crypto::cn_fast_hash(keys_seed_binary.data(), keys_seed_binary.size()); *reinterpret_cast(&h) = m_creation_timestamp; diff --git a/src/currency_core/blockchain_storage_boost_serialization.h b/src/currency_core/blockchain_storage_boost_serialization.h index 709f0629..ce1babf8 100644 --- a/src/currency_core/blockchain_storage_boost_serialization.h +++ b/src/currency_core/blockchain_storage_boost_serialization.h @@ -6,6 +6,8 @@ #pragma once +#include "currency_boost_serialization.h" + namespace boost { namespace serialization @@ -21,6 +23,8 @@ namespace boost ar & te.m_spent_flags; } + // The following method is used in tests only atm + // TODO: Consider to remove completely template void serialize(archive_t & ar, currency::block_extended_info& ei, const unsigned int version) { @@ -32,6 +36,11 @@ namespace boost ar & ei.block_cumulative_size; ar & ei.already_generated_coins; ar & ei.stake_hash; + + ar & ei.cumulative_diff_precise_adjusted; + //ar & ei.version; + ar & ei.this_block_tx_fee_median; + ar & ei.effective_tx_fee_median; } } diff --git a/src/currency_core/currency_basic.h b/src/currency_core/currency_basic.h index f3972253..8ac26a6f 100644 --- a/src/currency_core/currency_basic.h +++ b/src/currency_core/currency_basic.h @@ -508,7 +508,7 @@ namespace currency END_SERIALIZE() }; - struct etc_tx_uint16_t + struct etc_tx_flags16_t { uint16_t v; BEGIN_SERIALIZE() @@ -518,7 +518,7 @@ namespace currency typedef boost::mpl::vector21< tx_service_attachment, tx_comment, tx_payer_old, tx_receiver_old, tx_derivation_hint, std::string, tx_crypto_checksum, etc_tx_time, etc_tx_details_unlock_time, etc_tx_details_expiration_time, - etc_tx_details_flags, crypto::public_key, extra_attachment_info, extra_alias_entry_old, extra_user_data, extra_padding, etc_tx_uint16_t, etc_tx_details_unlock_time2, + etc_tx_details_flags, crypto::public_key, extra_attachment_info, extra_alias_entry_old, extra_user_data, extra_padding, etc_tx_flags16_t, etc_tx_details_unlock_time2, tx_payer, tx_receiver, extra_alias_entry > all_payload_types; @@ -749,7 +749,7 @@ SET_VARIANT_TAGS(currency::extra_user_data, 19, "user_data"); SET_VARIANT_TAGS(currency::extra_alias_entry_old, 20, "alias_entry"); SET_VARIANT_TAGS(currency::extra_padding, 21, "extra_padding"); SET_VARIANT_TAGS(crypto::public_key, 22, "pub_key"); -SET_VARIANT_TAGS(currency::etc_tx_uint16_t, 23, "etc_tx_uint16"); +SET_VARIANT_TAGS(currency::etc_tx_flags16_t, 23, "etc_tx_flags16"); SET_VARIANT_TAGS(uint16_t, 24, "derive_xor"); //txout_v SET_VARIANT_TAGS(currency::ref_by_id, 25, "ref_by_id"); diff --git a/src/currency_core/currency_boost_serialization.h b/src/currency_core/currency_boost_serialization.h index 0b6622e3..93e240cb 100644 --- a/src/currency_core/currency_boost_serialization.h +++ b/src/currency_core/currency_boost_serialization.h @@ -208,7 +208,7 @@ namespace boost inline void serialize(Archive &a, currency::keypair &kp, const boost::serialization::version_type ver) { a & kp.pub; - a & kp.sec; + a & kp.sec; } template @@ -252,7 +252,7 @@ namespace boost } template - inline void serialize(Archive &a, currency::etc_tx_uint16_t&at, const boost::serialization::version_type ver) + inline void serialize(Archive &a, currency::etc_tx_flags16_t&at, const boost::serialization::version_type ver) { a & at.v; } diff --git a/src/currency_core/currency_config.h b/src/currency_core/currency_config.h index 958b0c5d..4e06493b 100644 --- a/src/currency_core/currency_config.h +++ b/src/currency_core/currency_config.h @@ -146,7 +146,8 @@ #define WALLET_FILE_SIGNATURE_OLD 0x1111012101101011LL // Bender's nightmare #define WALLET_FILE_SIGNATURE_V2 0x1111011201101011LL // another Bender's nightmare -#define WALLET_FILE_MAX_BODY_SIZE 0x88888888L //2GB +#define WALLET_FILE_BINARY_HEADER_VERSION 1001 + #define WALLET_FILE_MAX_KEYS_SIZE 10000 // #define WALLET_BRAIN_DATE_OFFSET 1543622400 #define WALLET_BRAIN_DATE_QUANTUM 604800 //by last word we encode a number of week since launch of the project, @@ -220,7 +221,7 @@ #define BC_OFFERS_CURRENCY_MARKET_FILENAME "market.bin" -#define WALLET_FILE_SERIALIZATION_VERSION (CURRENCY_FORMATION_VERSION+67) +#define WALLET_FILE_SERIALIZATION_VERSION (CURRENCY_FORMATION_VERSION+68) #define CURRENT_MEMPOOL_ARCHIVE_VER (CURRENCY_FORMATION_VERSION+31) diff --git a/src/currency_core/currency_format_utils.cpp b/src/currency_core/currency_format_utils.cpp index ed017a34..740c7afc 100644 --- a/src/currency_core/currency_format_utils.cpp +++ b/src/currency_core/currency_format_utils.cpp @@ -710,6 +710,16 @@ namespace currency crypto::chacha_crypt(m.acc_addr, m_key); m_was_crypted_entries = true; } + void operator()(tx_payer_old& pr) + { + crypto::chacha_crypt(pr.acc_addr, m_key); + m_was_crypted_entries = true; + } + void operator()(tx_receiver_old& m) + { + crypto::chacha_crypt(m.acc_addr, m_key); + m_was_crypted_entries = true; + } void operator()(tx_service_attachment& sa) { if (sa.flags&TX_SERVICE_ATTACHMENT_DEFLATE_BODY) @@ -772,7 +782,18 @@ namespace currency crypto::chacha_crypt(receiver_local.acc_addr, rkey); rdecrypted_att.push_back(receiver_local); } - + void operator()(const tx_payer_old& pr) + { + tx_payer_old payer_local = pr; + crypto::chacha_crypt(payer_local.acc_addr, rkey); + rdecrypted_att.push_back(payer_local); + } + void operator()(const tx_receiver_old& pr) + { + tx_receiver_old receiver_local = pr; + crypto::chacha_crypt(receiver_local.acc_addr, rkey); + rdecrypted_att.push_back(receiver_local); + } template void operator()(const attachment_t& att) { @@ -1049,6 +1070,11 @@ namespace currency add_tx_pub_key_to_extra(tx, txkey.pub); one_time_secret_key = txkey.sec; + //add flags + etc_tx_flags16_t e = AUTO_VAL_INIT(e); + //todo: add some flags here + update_or_add_field_to_extra(tx.extra, e); + //include offers if need tx.attachment = attachments; encrypt_attachments(tx, sender_account_keys, crypt_destination_addr, txkey); @@ -2316,18 +2342,15 @@ namespace currency return true; } - bool operator()(const etc_tx_uint16_t& dh) + bool operator()(const etc_tx_flags16_t& dh) { - tv.type = "XOR"; + tv.type = "FLAGS16"; tv.short_view = epee::string_tools::pod_to_hex(dh); tv.datails_view = epee::string_tools::pod_to_hex(dh); return true; } - }; - - //------------------------------------------------------------------ template bool fill_tx_rpc_payload_items(std::vector& target_vector, const t_container& tc) diff --git a/src/currency_core/currency_format_utils.h b/src/currency_core/currency_format_utils.h index c17d3f14..b53931e3 100644 --- a/src/currency_core/currency_format_utils.h +++ b/src/currency_core/currency_format_utils.h @@ -433,8 +433,7 @@ namespace currency ai.m_alias = ard.alias; return true; } - - + //--------------------------------------------------------------- template extra_t& get_or_add_field_to_extra(std::vector& extra) { @@ -446,6 +445,7 @@ namespace currency extra.push_back(extra_t()); return boost::get(extra.back()); } + //--------------------------------------------------------------- template void update_or_add_field_to_extra(std::vector& variant_container, const variant_type_t& v) { @@ -459,7 +459,22 @@ namespace currency } variant_container.push_back(v); } - + //--------------------------------------------------------------- + template + void remove_field_of_type_from_extra(std::vector& variant_container) + { + for (size_t i = 0; i != variant_container.size();) + { + if (variant_container[i].type() == typeid(variant_type_t)) + { + variant_container.erase(variant_container.begin()+i); + } + else + { + i++; + } + } + } //--------------------------------------------------------------- template bool get_payment_id_from_tx(const t_container& att, std::string& payment_id) diff --git a/src/daemon/daemon_commands_handler.h b/src/daemon/daemon_commands_handler.h index 844da14f..b6ede7e7 100644 --- a/src/daemon/daemon_commands_handler.h +++ b/src/daemon/daemon_commands_handler.h @@ -317,21 +317,24 @@ private: std::cout << "specified key_image parameter '" << args[0] << "' is wrong" << ENDL; return false; } + + currency::blockchain_storage& bcs = m_srv.get_payload_object().get_core().get_blockchain_storage(); + std::list res_list; crypto::hash tx_id = currency::null_hash; - auto tx_chain_entry = m_srv.get_payload_object().get_core().get_blockchain_storage().find_key_image_and_related_tx(ki, tx_id); + auto tx_chain_entry = bcs.find_key_image_and_related_tx(ki, tx_id); if (tx_chain_entry) { - LOG_PRINT_L0("Found tx: " << ENDL << obj_to_json_str(tx_chain_entry->tx) << ENDL << "height: " << tx_chain_entry->m_keeper_block_height); - } - if (tx_id == currency::null_hash) - { - LOG_PRINT_L0("Not found any related tx."); + currency::block_extended_info bei = AUTO_VAL_INIT(bei); + CHECK_AND_ASSERT_MES(bcs.get_block_extended_info_by_height(tx_chain_entry->m_keeper_block_height, bei), false, "cannot find block by height " << tx_chain_entry->m_keeper_block_height); + + LOG_PRINT_L0("Key image found in tx: " << tx_id << " height " << tx_chain_entry->m_keeper_block_height << " (ts: " << epee::misc_utils::get_time_str_v2(currency::get_actual_timestamp(bei.bl)) << ")" << ENDL + << obj_to_json_str(tx_chain_entry->tx)); } else { - LOG_PRINT_L0("TxID: " << tx_id); + LOG_PRINT_L0("Not found any related tx."); } return true; } diff --git a/src/gui/qt-daemon/application/mainwindow.cpp b/src/gui/qt-daemon/application/mainwindow.cpp index dd8983f5..bdd261eb 100644 --- a/src/gui/qt-daemon/application/mainwindow.cpp +++ b/src/gui/qt-daemon/application/mainwindow.cpp @@ -405,8 +405,8 @@ bool MainWindow::init(const std::string& html_path) } //---- - //this->setContextMenuPolicy(Qt::ContextMenuPolicy::NoContextMenu); - //m_view->setContextMenuPolicy(Qt::ContextMenuPolicy::NoContextMenu); + this->setContextMenuPolicy(Qt::ContextMenuPolicy::NoContextMenu); + m_view->setContextMenuPolicy(Qt::ContextMenuPolicy::NoContextMenu); return true; CATCH_ENTRY2(false); @@ -826,6 +826,11 @@ bool MainWindow::money_transfer(const view::transfer_event_info& tei) //don't show unconfirmed tx if (tei.ti.height == 0) return true; + if (tei.is_wallet_in_sync_process) + { + //don't show notification if it long sync process(mmight cause system freeze) + return true; + } auto amount_str = currency::print_money(tei.ti.amount); std::string title, msg; @@ -1651,7 +1656,7 @@ QString MainWindow::open_wallet(const QString& param) //return que_call2("open_wallet", param, [this](const view::open_wallet_request& owd, view::api_response& ar){ PREPARE_ARG_FROM_JSON(view::open_wallet_request, owd); PREPARE_RESPONSE(view::open_wallet_response, ar); - ar.error_code = m_backend.open_wallet(epee::string_encoding::utf8_to_wstring(owd.path), owd.pass, owd.txs_to_return, ar.response_data); + ar.error_code = m_backend.open_wallet(epee::string_encoding::utf8_to_wstring(owd.path), owd.pass, owd.txs_to_return, ar.response_data, owd.exclude_mining_txs); return MAKE_RESPONSE(ar); CATCH_ENTRY_FAIL_API_RESPONCE(); } @@ -1795,7 +1800,7 @@ QString MainWindow::get_recent_transfers(const QString& param) LOG_API_TIMING(); PREPARE_ARG_FROM_JSON(view::get_recent_transfers_request, a); PREPARE_RESPONSE(view::transfers_array, ar); - ar.error_code = m_backend.get_recent_transfers(a.wallet_id, a.offset, a.count, ar.response_data); + ar.error_code = m_backend.get_recent_transfers(a.wallet_id, a.offset, a.count, ar.response_data, a.exclude_mining_txs); return MAKE_RESPONSE(ar); CATCH_ENTRY_FAIL_API_RESPONCE(); } diff --git a/src/gui/qt-daemon/html/main.js b/src/gui/qt-daemon/html/main.js index bea9ca00..2b396b28 100644 --- a/src/gui/qt-daemon/html/main.js +++ b/src/gui/qt-daemon/html/main.js @@ -1815,6 +1815,7 @@ var BackendService = /** @class */ (function () { error_translate = 'ERRORS.NO_MONEY'; } break; + case 'NOT_ENOUGH_OUTPUTS_FOR_MIXING': case 'INTERNAL_ERROR:not enough outputs to mix': error_translate = 'ERRORS.NOT_ENOUGH_OUTPUTS_TO_MIX'; break; diff --git a/src/gui/qt-daemon/html_source/src/app/_helpers/services/backend.service.ts b/src/gui/qt-daemon/html_source/src/app/_helpers/services/backend.service.ts index eb90c830..a2dbdcd2 100644 --- a/src/gui/qt-daemon/html_source/src/app/_helpers/services/backend.service.ts +++ b/src/gui/qt-daemon/html_source/src/app/_helpers/services/backend.service.ts @@ -81,6 +81,7 @@ export class BackendService { error_translate = 'ERRORS.NO_MONEY'; } break; + case 'NOT_ENOUGH_OUTPUTS_FOR_MIXING': case 'INTERNAL_ERROR:not enough outputs to mix': error_translate = 'ERRORS.NOT_ENOUGH_OUTPUTS_TO_MIX'; break; diff --git a/src/pch/stdafx.h b/src/pch/stdafx.h index 88ac8014..7aec3431 100644 --- a/src/pch/stdafx.h +++ b/src/pch/stdafx.h @@ -1,3 +1,4 @@ +// Copyright (c) 2014-2020 Zano Project // Copyright (c) 2014-2017 The The Louisdor Project // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index c37fef0a..3770251a 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -756,8 +756,9 @@ bool simple_wallet::list_recent_transfers(const std::vector& args) std::vector unconfirmed; std::vector recent; uint64_t total = 0; - m_wallet->get_recent_transfers_history(recent, 0, 0, total); - m_wallet->get_unconfirmed_transfers(unconfirmed); + uint64_t last_index = 0; + m_wallet->get_recent_transfers_history(recent, 0, 0, total, last_index, false); + m_wallet->get_unconfirmed_transfers(unconfirmed, false); //workaround for missed fee success_msg_writer() << "Unconfirmed transfers: "; @@ -809,8 +810,9 @@ bool simple_wallet::export_recent_transfers(const std::vector& args std::vector unconfirmed; std::vector recent; uint64_t total = 0; - m_wallet->get_recent_transfers_history(recent, 0, 0, total); - m_wallet->get_unconfirmed_transfers(unconfirmed); + uint64_t last_index = 0; + m_wallet->get_recent_transfers_history(recent, 0, 0, total, last_index, false); + m_wallet->get_unconfirmed_transfers(unconfirmed, false); //workaround for missed fee stringstream ss; LOG_PRINT_GREEN("Generating text....", LOG_LEVEL_0); diff --git a/src/simplewallet/simplewallet.h b/src/simplewallet/simplewallet.h index 051201b0..8fc44fc9 100644 --- a/src/simplewallet/simplewallet.h +++ b/src/simplewallet/simplewallet.h @@ -122,7 +122,7 @@ namespace currency m_blockchain_height = (std::max)(m_blockchain_height, height); } - if (std::chrono::milliseconds(1) < current_time - m_print_time || force) + if (std::chrono::milliseconds(100) < current_time - m_print_time || force) { std::cout << "Height " << height << " of " << m_blockchain_height << '\r'; m_print_time = current_time; diff --git a/src/version.h.in b/src/version.h.in index 0fe50c93..f873f50c 100644 --- a/src/version.h.in +++ b/src/version.h.in @@ -8,6 +8,6 @@ #define PROJECT_REVISION "7" #define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION -#define PROJECT_VERSION_BUILD_NO 96 +#define PROJECT_VERSION_BUILD_NO 103 #define PROJECT_VERSION_BUILD_NO_STR STRINGIFY_EXPAND(PROJECT_VERSION_BUILD_NO) #define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO_STR "[" BUILD_COMMIT_ID "]" diff --git a/src/wallet/core_default_rpc_proxy.cpp b/src/wallet/core_default_rpc_proxy.cpp index 5e624506..9de9f344 100644 --- a/src/wallet/core_default_rpc_proxy.cpp +++ b/src/wallet/core_default_rpc_proxy.cpp @@ -146,8 +146,8 @@ namespace tools bool r = m_http_client.connect(u.host, std::to_string(u.port), m_connection_timeout); if (r) { - *m_plast_daemon_is_disconnected = false; - m_last_success_interract_time = time(nullptr); + m_pdiganostic_info->last_daemon_is_disconnected = false; + m_pdiganostic_info->last_success_interract_time = time(nullptr); } return r; } @@ -178,11 +178,11 @@ namespace tools return tools::get_transfer_address(adr_str, addr, payment_id, this); } //------------------------------------------------------------------------------------------------------------------------------ - void default_http_core_proxy::set_plast_daemon_is_disconnected(std::atomic *plast_daemon_is_disconnected) - { - CRITICAL_REGION_LOCAL(m_lock); - m_plast_daemon_is_disconnected = plast_daemon_is_disconnected ? plast_daemon_is_disconnected : &m_last_daemon_is_disconnected_stub; - } +// void default_http_core_proxy::set_plast_daemon_is_disconnected(std::atomic *plast_daemon_is_disconnected) +// { +// CRITICAL_REGION_LOCAL(m_lock); +// m_plast_daemon_is_disconnected = plast_daemon_is_disconnected ? plast_daemon_is_disconnected : &m_last_daemon_is_disconnected_stub; +// } //------------------------------------------------------------------------------------------------------------------------------ bool default_http_core_proxy::set_connectivity(unsigned int connection_timeout, size_t repeats_count) { @@ -191,8 +191,8 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - default_http_core_proxy::default_http_core_proxy() :m_plast_daemon_is_disconnected(&m_last_daemon_is_disconnected_stub), - m_last_success_interract_time(0), + default_http_core_proxy::default_http_core_proxy(): //:m_plast_daemon_is_disconnected(&m_last_daemon_is_disconnected_stub), + //m_last_success_interract_time(0), m_connection_timeout(WALLET_RCP_CONNECTION_TIMEOUT), m_attempts_count(WALLET_RCP_COUNT_ATTEMNTS) { diff --git a/src/wallet/core_default_rpc_proxy.h b/src/wallet/core_default_rpc_proxy.h index ba241e51..77d3a4f3 100644 --- a/src/wallet/core_default_rpc_proxy.h +++ b/src/wallet/core_default_rpc_proxy.h @@ -73,11 +73,11 @@ namespace tools if (ret) { - m_last_success_interract_time = time(nullptr); - *m_plast_daemon_is_disconnected = false; + m_pdiganostic_info->last_success_interract_time = time(nullptr); + m_pdiganostic_info->last_daemon_is_disconnected = false; } else - *m_plast_daemon_is_disconnected = true; + m_pdiganostic_info->last_daemon_is_disconnected = true; return ret; } @@ -128,15 +128,13 @@ namespace tools //------------------------------------------------------------------------------------------------------------------------------ virtual time_t get_last_success_interract_time() override { - return m_last_success_interract_time; + return m_pdiganostic_info->last_success_interract_time; } epee::critical_section m_lock; epee::net_utils::http::http_simple_client m_http_client; std::string m_daemon_address; - std::atomic m_last_success_interract_time; - std::atomic *m_plast_daemon_is_disconnected; - std::atomic m_last_daemon_is_disconnected_stub; + unsigned int m_connection_timeout; size_t m_attempts_count; diff --git a/src/wallet/core_rpc_proxy.h b/src/wallet/core_rpc_proxy.h index 184e8a4b..b8d2e303 100644 --- a/src/wallet/core_rpc_proxy.h +++ b/src/wallet/core_rpc_proxy.h @@ -11,6 +11,15 @@ namespace tools { + struct proxy_diagnostic_info + { + proxy_diagnostic_info():is_busy(false), last_success_interract_time(0), last_daemon_is_disconnected(0) + {} + std::atomic is_busy; + std::atomic last_success_interract_time; + std::atomic last_daemon_is_disconnected; + }; + /* wrapper to core api (rpc/direct call) */ @@ -44,10 +53,18 @@ namespace tools virtual bool call_COMMAND_RPC_GET_CURRENT_CORE_TX_EXPIRATION_MEDIAN(const currency::COMMAND_RPC_GET_CURRENT_CORE_TX_EXPIRATION_MEDIAN::request& req, currency::COMMAND_RPC_GET_CURRENT_CORE_TX_EXPIRATION_MEDIAN::response& res){ return false; } virtual bool call_COMMAND_RPC_GET_POOL_INFO(const currency::COMMAND_RPC_GET_POOL_INFO::request& req, currency::COMMAND_RPC_GET_POOL_INFO::response& res) { return false; } + i_core_proxy() + { + m_pdiganostic_info.reset(new proxy_diagnostic_info()); + } virtual bool check_connection(){ return false; } virtual time_t get_last_success_interract_time() { return 0; } + std::shared_ptr get_proxy_diagnostic_info() const { return m_pdiganostic_info; } + std::shared_ptr get_editable_proxy_diagnostic_info() { return m_pdiganostic_info; } virtual bool get_transfer_address(const std::string& adr_str, currency::account_public_address& addr, std::string& payment_id){ return false; } + protected: + std::shared_ptr m_pdiganostic_info; }; } diff --git a/src/wallet/plain_wallet_api.cpp b/src/wallet/plain_wallet_api.cpp index 084112d6..ef8e0ff9 100644 --- a/src/wallet/plain_wallet_api.cpp +++ b/src/wallet/plain_wallet_api.cpp @@ -187,7 +187,6 @@ namespace plain_wallet epee::static_helpers::set_or_call_on_destruct(true, static_destroy_handler); - std::cout << "[INIT PLAIN_WALLET_INSTANCE]" << ENDL; std::shared_ptr ptr(new plain_wallet_instance()); set_bundle_working_dir(working_dir); @@ -208,13 +207,15 @@ namespace plain_wallet } ptr->gwm.set_use_deffered_global_outputs(true); - + if(!ptr->gwm.start()) { LOG_ERROR("Failed to start wallets_manager"); return GENERAL_INTERNAL_ERRROR_INIT; } + LOG_PRINT_L0("[INIT PLAIN_WALLET_INSTANCE] Ver:" << PROJECT_VERSION_LONG << "(" << BUILD_TYPE << ")"); + std::string wallets_folder = get_wallets_folder(); boost::system::error_code ec; boost::filesystem::create_directories(wallets_folder, ec); diff --git a/src/wallet/view_iface.h b/src/wallet/view_iface.h index 29f5744c..4dfbba80 100644 --- a/src/wallet/view_iface.h +++ b/src/wallet/view_iface.h @@ -356,6 +356,7 @@ public: uint64_t balance; uint64_t total_mined; uint64_t wallet_id; + bool is_wallet_in_sync_process; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(ti) @@ -363,6 +364,7 @@ public: KV_SERIALIZE(balance) KV_SERIALIZE(total_mined) KV_SERIALIZE(wallet_id) + KV_SERIALIZE(is_wallet_in_sync_process) END_KV_SERIALIZE_MAP() }; @@ -371,11 +373,13 @@ public: std::vector unconfirmed; std::vector history; uint64_t total_history_items; + uint64_t last_item_index; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(unconfirmed) KV_SERIALIZE(history) KV_SERIALIZE(total_history_items) + KV_SERIALIZE(last_item_index) END_KV_SERIALIZE_MAP() }; @@ -385,11 +389,13 @@ public: std::string pass; std::string path; uint64_t txs_to_return; + bool exclude_mining_txs; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(pass) KV_SERIALIZE(path) KV_SERIALIZE(txs_to_return) + KV_SERIALIZE(exclude_mining_txs) END_KV_SERIALIZE_MAP() }; @@ -398,6 +404,7 @@ public: uint64_t wallet_id; uint64_t offset; uint64_t count; + bool exclude_mining_txs; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(wallet_id) @@ -467,10 +474,12 @@ public: { bool is_online; bool last_daemon_is_disconnected; + bool is_server_busy; uint64_t last_proxy_communicate_timestamp; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(is_online) + KV_SERIALIZE(is_server_busy) KV_SERIALIZE(last_daemon_is_disconnected) KV_SERIALIZE(last_proxy_communicate_timestamp) END_KV_SERIALIZE_MAP() diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 33e18f82..cf6e7987 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -7,6 +7,8 @@ #include #include #include +#include +#include #include #include #include @@ -26,6 +28,7 @@ using namespace epee; #include "serialization/binary_utils.h" #include "currency_core/bc_payments_id_service.h" #include "version.h" +#include "common/encryption_filter.h" using namespace currency; #define MINIMUM_REQUIRED_WALLET_FREE_SPACE_BYTES (100*1024*1024) // 100 MB @@ -493,7 +496,6 @@ void wallet2::process_new_transaction(const currency::transaction& tx, uint64_t td.m_ptx_wallet_info = pwallet_info; td.m_internal_output_index = o; td.m_key_image = ki; - LOG_PRINT_L0("pglobal_indexes = " << pglobal_indexes); if (m_use_deffered_global_outputs) { if (pglobal_indexes && pglobal_indexes->size() > o) @@ -1153,6 +1155,15 @@ void wallet2::prepare_wti(wallet_public::wallet_transfer_info& wti, uint64_t hei decrypt_payload_items(decrypt_attachment_as_income, tx, m_account.get_keys(), decrypted_att); + if ((is_watch_only() && !wti.is_income)|| (height > 638000 && !have_type_in_variant_container(decrypted_att))) + { + remove_field_of_type_from_extra(decrypted_att); + remove_field_of_type_from_extra(decrypted_att); + } + if (is_watch_only() && !wti.is_income) + { + remove_field_of_type_from_extra(decrypted_att); + } prepare_wti_decrypted_attachments(wti, decrypted_att); process_contract_info(wti, decrypted_att); } @@ -1164,7 +1175,7 @@ void wallet2::handle_money_received2(const currency::block& b, const currency::t wallet_public::wallet_transfer_info& wti = m_transfer_history.back(); wti.is_income = true; prepare_wti(wti, get_block_height(b), get_actual_timestamp(b), tx, amount, td); - + WLT_LOG_L1("[MONEY RECEIVED]: " << epee::serialization::store_t_to_json(wti)); rise_on_transfer2(wti); } //---------------------------------------------------------------------------------------------------- @@ -1194,6 +1205,7 @@ void wallet2::handle_money_spent2(const currency::block& b, wti.remote_addresses = recipients; wti.recipients_aliases = recipients_aliases; prepare_wti(wti, get_block_height(b), get_actual_timestamp(b), in_tx, amount, td); + WLT_LOG_L1("[MONEY SPENT]: " << epee::serialization::store_t_to_json(wti)); rise_on_transfer2(wti); } //---------------------------------------------------------------------------------------------------- @@ -1310,6 +1322,8 @@ void wallet2::pull_blocks(size_t& blocks_added, std::atomic& stop) req.minimum_height = get_wallet_minimum_height(); if (is_auditable()) req.need_global_indexes = true; + if (req.minimum_height > m_height_of_start_sync) + m_height_of_start_sync = req.minimum_height; m_chain.get_short_chain_history(req.block_ids); bool r = m_core_proxy->call_COMMAND_RPC_GET_BLOCKS_DIRECT(req, res); @@ -1341,9 +1355,11 @@ void wallet2::pull_blocks(size_t& blocks_added, std::atomic& stop) if (res.status == API_RETURN_CODE_BUSY) { WLT_LOG_L1("Core is busy, pull cancelled"); + m_core_proxy->get_editable_proxy_diagnostic_info()->is_busy = true; stop = true; return; } + m_core_proxy->get_editable_proxy_diagnostic_info()->is_busy = false; THROW_IF_TRUE_WALLET_EX(res.status != API_RETURN_CODE_OK, error::get_blocks_error, res.status); THROW_IF_TRUE_WALLET_EX(get_blockchain_current_size() && get_blockchain_current_size() <= res.start_height && res.start_height != m_minimum_height, error::wallet_internal_error, "wrong daemon response: m_start_height=" + std::to_string(res.start_height) + @@ -1454,7 +1470,7 @@ void wallet2::handle_pulled_blocks(size_t& blocks_added, std::atomic& stop } } - WLT_LOG_L1("[PULL BLOCKS] " << res.start_height << " --> " << get_blockchain_current_size()); + WLT_LOG_L2("[PULL BLOCKS] " << res.start_height << " --> " << get_blockchain_current_size() - 1); } //---------------------------------------------------------------------------------------------------- uint64_t wallet2::get_sync_progress() @@ -1471,6 +1487,7 @@ void wallet2::refresh() void wallet2::refresh(size_t & blocks_fetched) { bool received_money = false; + m_stop = false; refresh(blocks_fetched, received_money, m_stop); } //---------------------------------------------------------------------------------------------------- @@ -1937,7 +1954,7 @@ void wallet2::refresh(size_t & blocks_fetched, bool& received_money, std::atomic } - WLT_LOG_L1("Refresh done, blocks received: " << blocks_fetched << ", balance: " << print_money(balance()) << ", unlocked: " << print_money(unlocked_balance())); + WLT_LOG("Refresh done, blocks received: " << blocks_fetched << ", balance: " << print_money(balance()) << ", unlocked: " << print_money(unlocked_balance()), blocks_fetched > 0 ? LOG_LEVEL_1 : LOG_LEVEL_2); } //---------------------------------------------------------------------------------------------------- bool wallet2::handle_expiration_list(uint64_t tx_expiration_ts_median) @@ -2150,7 +2167,7 @@ bool wallet2::reset_all() return true; } //---------------------------------------------------------------------------------------------------- -bool wallet2::store_keys(std::string& buff, const std::string& password, bool store_as_watch_only /* = false */) +bool wallet2::store_keys(std::string& buff, const std::string& password, wallet2::keys_file_data& keys_file_data, bool store_as_watch_only /* = false */) { currency::account_base acc = m_account; if (store_as_watch_only) @@ -2160,8 +2177,6 @@ bool wallet2::store_keys(std::string& buff, const std::string& password, bool st bool r = epee::serialization::store_t_to_binary(acc, account_data); WLT_CHECK_AND_ASSERT_MES(r, false, "failed to serialize wallet keys"); - wallet2::keys_file_data keys_file_data = boost::value_initialized(); - crypto::chacha8_key key; crypto::generate_chacha8_key(password, key); std::string cipher; @@ -2178,7 +2193,8 @@ bool wallet2::store_keys(std::string& buff, const std::string& password, bool st bool wallet2::backup_keys(const std::string& path) { std::string buff; - bool r = store_keys(buff, m_password); + wallet2::keys_file_data keys_file_data = AUTO_VAL_INIT(keys_file_data); + bool r = store_keys(buff, m_password, keys_file_data); WLT_CHECK_AND_ASSERT_MES(r, false, "Failed to store keys"); r = file_io_utils::save_string_to_file(path, buff); @@ -2264,10 +2280,9 @@ bool wallet2::prepare_file_names(const std::wstring& file_path) return true; } //---------------------------------------------------------------------------------------------------- -void wallet2::load_keys(const std::string& buff, const std::string& password, uint64_t file_signature) +void wallet2::load_keys(const std::string& buff, const std::string& password, uint64_t file_signature, keys_file_data& kf_data) { bool r = false; - wallet2::keys_file_data kf_data = AUTO_VAL_INIT(kf_data); if (file_signature == WALLET_FILE_SIGNATURE_OLD) { wallet2::keys_file_data_old kf_data_old; @@ -2314,8 +2329,6 @@ void wallet2::generate(const std::wstring& path, const std::string& pass, bool a clear(); prepare_file_names(path); - check_for_free_space_and_throw_if_it_lacks(m_wallet_file); - m_password = pass; m_account.generate(auditable_wallet); init_log_prefix(); @@ -2365,8 +2378,6 @@ void wallet2::load(const std::wstring& wallet_, const std::string& password) clear(); prepare_file_names(wallet_); - check_for_free_space_and_throw_if_it_lacks(m_wallet_file); - m_password = password; std::string keys_buff; @@ -2386,16 +2397,30 @@ void wallet2::load(const std::wstring& wallet_, const std::string& password) THROW_IF_TRUE_WALLET_EX(data_file.fail(), error::file_read_error, epee::string_encoding::convert_to_ansii(m_wallet_file)); THROW_IF_TRUE_WALLET_EX(wbh.m_signature != WALLET_FILE_SIGNATURE_OLD && wbh.m_signature != WALLET_FILE_SIGNATURE_V2, error::file_read_error, epee::string_encoding::convert_to_ansii(m_wallet_file)); - THROW_IF_TRUE_WALLET_EX(wbh.m_cb_body > WALLET_FILE_MAX_BODY_SIZE || + THROW_IF_TRUE_WALLET_EX( wbh.m_cb_keys > WALLET_FILE_MAX_KEYS_SIZE, error::file_read_error, epee::string_encoding::convert_to_ansii(m_wallet_file)); keys_buff.resize(wbh.m_cb_keys); data_file.read((char*)keys_buff.data(), wbh.m_cb_keys); + wallet2::keys_file_data kf_data = AUTO_VAL_INIT(kf_data); + load_keys(keys_buff, password, wbh.m_signature, kf_data); - load_keys(keys_buff, password, wbh.m_signature); - - bool need_to_resync = !tools::portable_unserialize_obj_from_stream(*this, data_file); + bool need_to_resync = false; + if (wbh.m_ver == 1000) + { + need_to_resync = !tools::portable_unserialize_obj_from_stream(*this, data_file); + } + else + { + tools::encrypt_chacha_in_filter decrypt_filter(password, kf_data.iv); + boost::iostreams::filtering_istream in; + in.push(decrypt_filter); + in.push(data_file); + need_to_resync = !tools::portable_unserialize_obj_from_stream(*this, in); + } + + if (m_watch_only && !is_auditable()) load_keys2ki(true, need_to_resync); @@ -2429,13 +2454,12 @@ void wallet2::store(const std::wstring& path_to_save, const std::string& passwor { LOG_PRINT_L0("(before storing: pending_key_images: " << m_pending_key_images.size() << ", pki file elements: " << m_pending_key_images_file_container.size() << ", tx_keys: " << m_tx_keys.size() << ")"); - // check_for_free_space_and_throw_if_it_lacks(path_to_save); temporary disabled, wallet saving implemented in two-stage scheme to avoid data loss due to lack of space - std::string ascii_path_to_save = epee::string_encoding::convert_to_ansii(path_to_save); //prepare data std::string keys_buff; - bool r = store_keys(keys_buff, password, m_watch_only); + wallet2::keys_file_data keys_file_data = AUTO_VAL_INIT(keys_file_data); + bool r = store_keys(keys_buff, password, keys_file_data, m_watch_only); WLT_THROW_IF_FALSE_WALLET_CMN_ERR_EX(r, "failed to store_keys for wallet " << ascii_path_to_save); //store data @@ -2443,7 +2467,7 @@ void wallet2::store(const std::wstring& path_to_save, const std::string& passwor wbh.m_signature = WALLET_FILE_SIGNATURE_V2; wbh.m_cb_keys = keys_buff.size(); //@#@ change it to proper - wbh.m_cb_body = 1000; + wbh.m_ver = WALLET_FILE_BINARY_HEADER_VERSION; std::string header_buff((const char*)&wbh, sizeof(wbh)); uint64_t ts = m_core_runtime_config.get_core_time(); @@ -2458,8 +2482,13 @@ void wallet2::store(const std::wstring& path_to_save, const std::string& passwor data_file << header_buff << keys_buff; WLT_LOG_L0("Storing to temporary file " << tmp_file_path.string() << " ..."); + //creating encryption stream + tools::encrypt_chacha_out_filter decrypt_filter(m_password, keys_file_data.iv); + boost::iostreams::filtering_ostream out; + out.push(decrypt_filter); + out.push(data_file); - r = tools::portble_serialize_obj_to_stream(*this, data_file); + r = tools::portble_serialize_obj_to_stream(*this, out); if (!r) { data_file.close(); @@ -2567,49 +2596,6 @@ void wallet2::store_watch_only(const std::wstring& path_to_save, const std::stri wo.store(path_to_save, password); } //---------------------------------------------------------------------------------------------------- -void wallet2::check_for_free_space_and_throw_if_it_lacks(const std::wstring& wallet_filename, uint64_t exact_size_needed_if_known /* = UINT64_MAX */) -{ - namespace fs = boost::filesystem; - - try - { - fs::path wallet_file_path(wallet_filename); - fs::path base_path = wallet_file_path.parent_path(); - if (base_path.empty()) - base_path = fs::path("."); - WLT_THROW_IF_FALSE_WALLET_CMN_ERR_EX(fs::is_directory(base_path), "directory does not exist: " << base_path.string()); - - uint64_t min_free_size = exact_size_needed_if_known; - if (min_free_size == UINT64_MAX) - { - // if exact size needed is unknown -- determine it as - // twice the original wallet file size or MINIMUM_REQUIRED_WALLET_FREE_SPACE_BYTES, which one is bigger - min_free_size = MINIMUM_REQUIRED_WALLET_FREE_SPACE_BYTES; - if (fs::is_regular_file(wallet_file_path)) - min_free_size = std::max(min_free_size, 2 * static_cast(fs::file_size(wallet_file_path))); - } - else - { - min_free_size += 1024 * 1024 * 10; // add a little for FS overhead and so - } - - fs::space_info si = fs::space(base_path); - WLT_THROW_IF_FALSE_WALLET_CMN_ERR_EX(si.available > min_free_size, "free space at " << base_path.string() << " is too low: " << si.available << ", required minimum is: " << min_free_size); - } - catch (tools::error::wallet_common_error&) - { - throw; - } - catch (std::exception& e) - { - WLT_THROW_IF_FALSE_WALLET_CMN_ERR_EX(false, "failed to determine free space: " << e.what()); - } - catch (...) - { - WLT_THROW_IF_FALSE_WALLET_CMN_ERR_EX(false, "failed to determine free space: unknown exception"); - } -} -//---------------------------------------------------------------------------------------------------- uint64_t wallet2::unlocked_balance() const { uint64_t stub = 0; @@ -2944,17 +2930,27 @@ uint64_t wallet2::get_transfer_entries_count() return m_transfers.size(); } //---------------------------------------------------------------------------------------------------- -void wallet2::get_recent_transfers_history(std::vector& trs, size_t offset, size_t count, uint64_t& total) +void wallet2::get_recent_transfers_history(std::vector& trs, size_t offset, size_t count, uint64_t& total, uint64_t& last_item_index, bool exclude_mining_txs) { - if (offset >= m_transfer_history.size()) + if (!count || offset >= m_transfer_history.size()) return; auto start = m_transfer_history.rbegin() + offset; - auto stop = m_transfer_history.size() - offset >= count ? start + count : m_transfer_history.rend(); - if (!count) - stop = m_transfer_history.rend(); - - trs.insert(trs.end(), start, stop); + for (auto it = m_transfer_history.rbegin() + offset; it != m_transfer_history.rend(); it++) + { + if (exclude_mining_txs) + { + if(it->is_mining) + continue; + } + trs.push_back(*it); + last_item_index = it - m_transfer_history.rbegin(); + + if (trs.size() >= count) + { + break; + } + } total = m_transfer_history.size(); } //---------------------------------------------------------------------------------------------------- @@ -3277,10 +3273,16 @@ bool wallet2::build_minted_block(const currency::COMMAND_RPC_SCAN_POS::request& return true; } //---------------------------------------------------------------------------------------------------- -void wallet2::get_unconfirmed_transfers(std::vector& trs) +void wallet2::get_unconfirmed_transfers(std::vector& trs, bool exclude_mining_txs) { for (auto& u : m_unconfirmed_txs) + { + if (exclude_mining_txs && u.second.is_mining) + { + continue; + } trs.push_back(u.second); + } } //---------------------------------------------------------------------------------------------------- void wallet2::set_core_runtime_config(const currency::core_runtime_config& pc) @@ -3893,7 +3895,7 @@ bool wallet2::prepare_tx_sources_for_packing(uint64_t items_to_pack, size_t fake bool wallet2::prepare_tx_sources(uint64_t needed_money, size_t fake_outputs_count, uint64_t dust_threshold, std::vector& sources, std::vector& selected_indicies, uint64_t& found_money) { found_money = select_transfers(needed_money, fake_outputs_count, dust_threshold, selected_indicies); - THROW_IF_FALSE_WALLET_EX_MES(found_money >= needed_money, error::not_enough_money, "wallet_dump: " << ENDL << dump_trunsfers(false), found_money, needed_money, 0); + WLT_THROW_IF_FALSE_WALLET_EX_MES(found_money >= needed_money, error::not_enough_money, "", found_money, needed_money, 0); return prepare_tx_sources(fake_outputs_count, sources, selected_indicies, found_money); } //---------------------------------------------------------------------------------------------------- @@ -4217,8 +4219,8 @@ bool wallet2::extract_offers_from_transfer_entry(size_t i, std::unordered_map& selected_in WLT_LOG_GREEN("Selecting indices for transfer of " << print_money_brief(needed_money) << " with " << fake_outputs_count << " fake outs, found_free_amounts.size()=" << found_free_amounts.size() << "...", LOG_LEVEL_0); uint64_t found_money = 0; std::string selected_amounts_str; - while(found_money < needed_money && found_free_amounts.size()) + while (found_money < needed_money && found_free_amounts.size()) { auto it = found_free_amounts.lower_bound(needed_money - found_money); if (!(it != found_free_amounts.end() && it->second.size())) @@ -4307,6 +4309,23 @@ bool wallet2::is_transfer_ready_to_go(const transfer_details& td, uint64_t fake_ return false; } //---------------------------------------------------------------------------------------------------- +void wallet2::wipeout_extra_if_needed(std::vector& transfer_history) +{ + WLT_LOG_L0("Processing [wipeout_extra_if_needed]..."); + for (auto it = transfer_history.begin(); it != transfer_history.end(); it++ ) + { + if (it->height > 638000) + { + it->remote_addresses.clear(); + if (is_watch_only() && !it->is_income) + { + it->comment.clear(); + } + } + } + WLT_LOG_L0("Processing [wipeout_extra_if_needed] DONE"); +} +//---------------------------------------------------------------------------------------------------- bool wallet2::is_transfer_able_to_go(const transfer_details& td, uint64_t fake_outputs_count) { if (!td.is_spendable()) diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 349750db..e0507696 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -62,6 +62,7 @@ const uint64_t WALLET_GLOBAL_OUTPUT_INDEX_UNDEFINED = std::numeric_limits& trs, size_t offset, size_t count, uint64_t& total); + void get_recent_transfers_history(std::vector& trs, size_t offset, size_t count, uint64_t& total, uint64_t& last_item_index, bool exclude_mining_txs = false); uint64_t get_recent_transfers_total_count(); uint64_t get_transfer_entries_count(); - void get_unconfirmed_transfers(std::vector& trs); + void get_unconfirmed_transfers(std::vector& trs, bool exclude_mining_txs = false); void init(const std::string& daemon_address = "http://localhost:8080"); bool deinit(); @@ -726,8 +730,14 @@ namespace tools a & m_tx_keys; a & m_last_pow_block_h; + //after processing + if (ver < 152) + { + wipeout_extra_if_needed(m_transfer_history); + } } + void wipeout_extra_if_needed(std::vector& transfer_history); bool is_transfer_ready_to_go(const transfer_details& td, uint64_t fake_outputs_count); bool is_transfer_able_to_go(const transfer_details& td, uint64_t fake_outputs_count); uint64_t select_indices_for_transfer(std::vector& ind, free_amounts_cache_type& found_free_amounts, uint64_t needed_money, uint64_t fake_outputs_count); @@ -803,7 +813,7 @@ private: void add_transfers_to_expiration_list(const std::vector& selected_transfers, uint64_t expiration, uint64_t change_amount, const crypto::hash& related_tx_id); void remove_transfer_from_expiration_list(uint64_t transfer_index); - void load_keys(const std::string& keys_file_name, const std::string& password, uint64_t file_signature); + void load_keys(const std::string& keys_file_name, const std::string& password, uint64_t file_signature, keys_file_data& kf_data); void process_new_transaction(const currency::transaction& tx, uint64_t height, const currency::block& b, const std::vector* pglobal_indexes); void fetch_tx_global_indixes(const currency::transaction& tx, std::vector& goutputs_indexes); void fetch_tx_global_indixes(const std::list>& txs, std::vector>& goutputs_indexes); @@ -917,7 +927,6 @@ private: void exception_handler(); void exception_handler() const; uint64_t get_minimum_allowed_fee_for_contract(const crypto::hash& ms_id); - void check_for_free_space_and_throw_if_it_lacks(const std::wstring& path, uint64_t exact_size_needed_if_known = UINT64_MAX); bool generate_packing_transaction_if_needed(currency::transaction& tx, uint64_t fake_outputs_number); bool store_unsigned_tx_to_file_and_reserve_transfers(const finalize_tx_param& ftp, const std::string& filename, std::string* p_unsigned_tx_blob_str = nullptr); void check_and_throw_if_self_directed_tx_with_payment_id_requested(const construct_tx_param& ctp); @@ -1244,6 +1253,7 @@ namespace tools } // namespace tools #if !defined(KEEP_WALLET_LOG_MACROS) +#undef WLT_LOG #undef WLT_LOG_L0 #undef WLT_LOG_L1 #undef WLT_LOG_L2 @@ -1258,7 +1268,9 @@ namespace tools #undef WLT_LOG_YELLOW #undef WLT_CHECK_AND_ASSERT_MES #undef WLT_CHECK_AND_ASSERT_MES_NO_RET -// TODO update this list +#undef WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX +#undef WLT_THROW_IF_FALSE_WALLET_CMN_ERR_EX +#undef WLT_THROW_IF_FALSE_WALLET_EX_MES #endif diff --git a/src/wallet/wallet_public_structs_defs.h b/src/wallet/wallet_public_structs_defs.h index da115c33..420c4953 100644 --- a/src/wallet/wallet_public_structs_defs.h +++ b/src/wallet/wallet_public_structs_defs.h @@ -275,11 +275,13 @@ namespace wallet_public of GET_RECENT_TXS_AND_INFO with offsets) */ bool update_provision_info; + bool exclude_mining_txs; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(offset) KV_SERIALIZE(count) KV_SERIALIZE(update_provision_info) + KV_SERIALIZE(exclude_mining_txs) END_KV_SERIALIZE_MAP() }; @@ -288,11 +290,13 @@ namespace wallet_public wallet_provision_info pi; std::vector transfers; uint64_t total_transfers; + uint64_t last_item_index; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(pi) KV_SERIALIZE(transfers) KV_SERIALIZE(total_transfers) + KV_SERIALIZE(last_item_index) END_KV_SERIALIZE_MAP() }; }; diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index edcbfc41..a2ea9db3 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -223,9 +223,9 @@ namespace tools } if (req.offset == 0) - m_wallet.get_unconfirmed_transfers(res.transfers); + m_wallet.get_unconfirmed_transfers(res.transfers, req.exclude_mining_txs); - m_wallet.get_recent_transfers_history(res.transfers, req.offset, req.count, res.total_transfers); + m_wallet.get_recent_transfers_history(res.transfers, req.offset, req.count, res.total_transfers, res.last_item_index, req.exclude_mining_txs); return true; } diff --git a/src/wallet/wallets_manager.cpp b/src/wallet/wallets_manager.cpp index 0faa603a..ccaca324 100644 --- a/src/wallet/wallets_manager.cpp +++ b/src/wallet/wallets_manager.cpp @@ -32,6 +32,13 @@ return API_RETURN_CODE_WALLET_WRONG_ID; \ auto& name = it->second.w; +#define GET_WALLET_OPTIONS_BY_ID_VOID_RET(wallet_id, name) \ + SHARED_CRITICAL_REGION_LOCAL(m_wallets_lock); \ + auto it = m_wallets.find(wallet_id); \ + if (it == m_wallets.end()) \ + return; \ + auto& name = it->second; + #ifdef MOBILE_WALLET_BUILD #define DAEMON_IDLE_UPDATE_TIME_MS 10000 #define TX_POOL_SCAN_INTERVAL 5 @@ -56,8 +63,7 @@ wallets_manager::wallets_manager():m_pview(&m_view_stub), m_rpc_proxy(new tools::default_http_core_proxy()), #endif - m_last_daemon_height(0), - m_last_daemon_is_disconnected(false), + m_last_daemon_height(0), m_wallet_id_counter(0), m_ui_opt(AUTO_VAL_INIT(m_ui_opt)), m_remote_node_mode(false), @@ -68,6 +74,7 @@ wallets_manager::wallets_manager():m_pview(&m_view_stub), { #ifndef MOBILE_WALLET_BUILD m_offers_service.set_disabled(true); + m_pproxy_diganostic_info = m_rpc_proxy->get_proxy_diagnostic_info(); #endif //m_ccore.get_blockchain_storage().get_attachment_services_manager().add_service(&m_offers_service); } @@ -272,10 +279,10 @@ bool wallets_manager::init(view::i_view* pview_handler) { m_remote_node_mode = true; auto proxy_ptr = new tools::default_http_core_proxy(); - proxy_ptr->set_plast_daemon_is_disconnected(&m_last_daemon_is_disconnected); proxy_ptr->set_connectivity(HTTP_PROXY_TIMEOUT, HTTP_PROXY_ATTEMPTS_COUNT); m_rpc_proxy.reset(proxy_ptr); m_rpc_proxy->set_connection_addr(command_line::get_arg(m_vm, arg_remote_node)); + m_pproxy_diganostic_info = m_rpc_proxy->get_proxy_diagnostic_info(); } if(!command_line::has_arg(m_vm, arg_disable_logs_init)) @@ -706,7 +713,8 @@ void wallets_manager::init_wallet_entry(wallet_vs_options& wo, uint64_t id) wo.stop_for_refresh = false; wo.plast_daemon_height = &m_last_daemon_height; wo.plast_daemon_network_state = &m_last_daemon_network_state; - wo.plast_daemon_is_disconnected = &m_last_daemon_is_disconnected; + //wo.plast_daemon_is_disconnected = &(m_rpc_proxy->get_proxy_diagnostic_info().last_daemon_is_disconnected; + wo.m_pproxy_diagnostig_info = m_rpc_proxy->get_proxy_diagnostic_info(); wo.pview = m_pview; wo.has_related_alias_in_unconfirmed = false; wo.rpc_wrapper.reset(new tools::wallet_rpc_server(*wo.w.unlocked_get().get())); @@ -814,7 +822,7 @@ std::string wallets_manager::get_my_offers(const bc_services::core_offers_filter #endif } -std::string wallets_manager::open_wallet(const std::wstring& path, const std::string& password, uint64_t txs_to_return, view::open_wallet_response& owr) +std::string wallets_manager::open_wallet(const std::wstring& path, const std::string& password, uint64_t txs_to_return, view::open_wallet_response& owr, bool exclude_mining_txs) { // check if that file already opened SHARED_CRITICAL_REGION_BEGIN(m_wallets_lock); @@ -852,9 +860,10 @@ std::string wallets_manager::open_wallet(const std::wstring& path, const std::st w->load(path, password); if (w->is_watch_only() && !w->is_auditable()) return API_RETURN_CODE_WALLET_WATCH_ONLY_NOT_SUPPORTED; - w->get_recent_transfers_history(owr.recent_history.history, 0, txs_to_return, owr.recent_history.total_history_items); + + w->get_recent_transfers_history(owr.recent_history.history, 0, txs_to_return, owr.recent_history.total_history_items, owr.recent_history.last_item_index, exclude_mining_txs); //w->get_unconfirmed_transfers(owr.recent_history.unconfirmed); - w->get_unconfirmed_transfers(owr.recent_history.history); + w->get_unconfirmed_transfers(owr.recent_history.history, exclude_mining_txs); owr.wallet_local_bc_size = w->get_blockchain_current_size(); //workaround for missed fee owr.seed = w->get_account().get_seed_phrase(); @@ -910,7 +919,7 @@ bool wallets_manager::get_opened_wallets(std::list& return true; } -std::string wallets_manager::get_recent_transfers(size_t wallet_id, uint64_t offset, uint64_t count, view::transfers_array& tr_hist) +std::string wallets_manager::get_recent_transfers(size_t wallet_id, uint64_t offset, uint64_t count, view::transfers_array& tr_hist, bool exclude_mining_txs) { GET_WALLET_BY_ID(wallet_id, w); auto wallet_locked = w.try_lock(); @@ -919,8 +928,8 @@ std::string wallets_manager::get_recent_transfers(size_t wallet_id, uint64_t off return API_RETURN_CODE_CORE_BUSY; } - w->get()->get_unconfirmed_transfers(tr_hist.unconfirmed); - w->get()->get_recent_transfers_history(tr_hist.history, offset, count, tr_hist.total_history_items); + w->get()->get_unconfirmed_transfers(tr_hist.unconfirmed, exclude_mining_txs); + w->get()->get_recent_transfers_history(tr_hist.history, offset, count, tr_hist.total_history_items, tr_hist.last_item_index, exclude_mining_txs); auto fix_tx = [](tools::wallet_public::wallet_transfer_info& wti) -> void { wti.show_sender = currency::is_showing_sender_addres(wti.tx); @@ -1054,7 +1063,7 @@ std::string wallets_manager::restore_wallet(const std::wstring& path, const std: try { bool auditable_watch_only = restore_key.find(':') != std::string::npos; - w->restore(path, password, restore_key, auditable_watch_only); + w->restore(path, password, restore_key, auditable_watch_only); owr.seed = w->get_account().get_seed_phrase(); } catch (const tools::error::file_exists&) @@ -1339,7 +1348,16 @@ std::string wallets_manager::transfer(size_t wallet_id, const view::transfer_par } } w->get()->transfer(dsts, tp.mixin_count, unlock_time ? unlock_time + 1 : 0, fee, extra, attachments, res_tx); - //update_wallets_info(); + } + catch (const tools::error::not_enough_money& e) + { + LOG_ERROR(get_wallet_log_prefix(wallet_id) + "Transfer error: not enough money: " << e.what()); + return API_RETURN_CODE_NOT_ENOUGH_MONEY; + } + catch (const tools::error::not_enough_outs_to_mix& e) + { + LOG_ERROR(get_wallet_log_prefix(wallet_id) + "Transfer error: not outs to mix: " << e.what()); + return API_RETURN_CODE_NOT_ENOUGH_OUTPUTS_FOR_MIXING; } catch (const std::exception& e) { @@ -1361,7 +1379,9 @@ bool wallets_manager::get_is_remote_daemon_connected() { if (!m_remote_node_mode) return true; - if (m_last_daemon_is_disconnected) + if (m_pproxy_diganostic_info->last_daemon_is_disconnected) + return false; + if (m_pproxy_diganostic_info->is_busy) return false; if (time(nullptr) - m_rpc_proxy->get_last_success_interract_time() > DAEMON_IDLE_UPDATE_TIME_MS * 2) return false; @@ -1372,7 +1392,8 @@ std::string wallets_manager::get_connectivity_status() { view::general_connectivity_info gci = AUTO_VAL_INIT(gci); gci.is_online = get_is_remote_daemon_connected(); - gci.last_daemon_is_disconnected = m_last_daemon_is_disconnected; + gci.last_daemon_is_disconnected = m_pproxy_diganostic_info->last_daemon_is_disconnected; + gci.is_server_busy = m_pproxy_diganostic_info->is_busy; gci.last_proxy_communicate_timestamp = m_rpc_proxy->get_last_success_interract_time(); return epee::serialization::store_t_to_json(gci); } @@ -1599,8 +1620,12 @@ std::string wallets_manager::get_mining_history(uint64_t wallet_id, tools::walle std::string wallets_manager::get_wallet_restore_info(uint64_t wallet_id, std::string& restore_key) { GET_WALLET_OPT_BY_ID(wallet_id, wo); + + if (wo.wallet_state != view::wallet_status_info::wallet_state_ready || wo.long_refresh_in_progress) + return API_RETURN_CODE_CORE_BUSY; + restore_key = wo.w->get()->get_account().get_seed_phrase(); -// restore_key = tools::base58::encode(rst_data); + return API_RETURN_CODE_OK; } void wallets_manager::prepare_wallet_status_info(wallet_vs_options& wo, view::wallet_status_info& wsi) @@ -1745,12 +1770,15 @@ void wallets_manager::on_new_block(size_t wallet_id, uint64_t /*height*/, const } void wallets_manager::on_transfer2(size_t wallet_id, const tools::wallet_public::wallet_transfer_info& wti, uint64_t balance, uint64_t unlocked_balance, uint64_t total_mined) -{ +{ view::transfer_event_info tei = AUTO_VAL_INIT(tei); tei.ti = wti; tei.balance = balance; tei.unlocked_balance = unlocked_balance; tei.wallet_id = wallet_id; + + GET_WALLET_OPTIONS_BY_ID_VOID_RET(wallet_id, w); + tei.is_wallet_in_sync_process = w.long_refresh_in_progress; m_pview->money_transfer(tei); } void wallets_manager::on_pos_block_found(size_t wallet_id, const currency::block& b) @@ -1798,7 +1826,7 @@ void wallets_manager::wallet_vs_options::worker_func() try { wsi.wallet_state = view::wallet_status_info::wallet_state_ready; - if (plast_daemon_is_disconnected && plast_daemon_is_disconnected->load()) + if (m_pproxy_diagnostig_info->last_daemon_is_disconnected.load()) { std::this_thread::sleep_for(std::chrono::milliseconds(1000)); continue; diff --git a/src/wallet/wallets_manager.h b/src/wallet/wallets_manager.h index dd2797ca..75cd8827 100644 --- a/src/wallet/wallets_manager.h +++ b/src/wallet/wallets_manager.h @@ -69,7 +69,8 @@ public: std::atomic last_wallet_synch_height; std::atomic* plast_daemon_height; std::atomic* plast_daemon_network_state; - std::atomic* plast_daemon_is_disconnected; + //std::atomic* plast_daemon_is_disconnected; + std::shared_ptr m_pproxy_diagnostig_info; std::atomic has_related_alias_in_unconfirmed; std::atomic need_to_update_wallet_info; std::atomic long_refresh_in_progress; @@ -96,13 +97,13 @@ public: bool quick_clear_wallets_no_save(); bool send_stop_signal(); bool get_opened_wallets(std::list& result); - std::string open_wallet(const std::wstring& path, const std::string& password, uint64_t txs_to_return, view::open_wallet_response& owr); + std::string open_wallet(const std::wstring& path, const std::string& password, uint64_t txs_to_return, view::open_wallet_response& owr, bool exclude_mining_txs = false); std::string generate_wallet(const std::wstring& path, const std::string& password, view::open_wallet_response& owr); std::string restore_wallet(const std::wstring& path, const std::string& password, const std::string& restore_key, view::open_wallet_response& owr); std::string invoke(uint64_t wallet_id, std::string params); std::string get_wallet_status(uint64_t wallet_id); std::string run_wallet(uint64_t wallet_id); - std::string get_recent_transfers(size_t wallet_id, uint64_t offset, uint64_t count, view::transfers_array& tr_hist); + std::string get_recent_transfers(size_t wallet_id, uint64_t offset, uint64_t count, view::transfers_array& tr_hist, bool exclude_mining_txs = false); std::string get_wallet_info(size_t wallet_id, view::wallet_info& wi); std::string get_contracts(size_t wallet_id, std::vector& contracts); std::string create_proposal(const view::create_proposal_param_gui& cpp); @@ -192,7 +193,8 @@ private: bool m_use_deffered_global_outputs; std::atomic m_last_daemon_height; std::atomic m_last_daemon_network_state; - std::atomic m_last_daemon_is_disconnected; + std::shared_ptr m_pproxy_diganostic_info; + //std::atomic m_last_daemon_is_disconnected; // std::atomic m_last_wallet_synch_height; std::atomic m_wallet_id_counter; std::atomic m_dont_save_wallet_at_stop; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 4d92a620..5e6a9006 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -28,12 +28,12 @@ add_executable(net_load_tests_srv net_load_tests/srv.cpp) add_dependencies(coretests version) -target_link_libraries(coretests rpc currency_core common crypto wallet zlibstatic ethash ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) +target_link_libraries(coretests rpc wallet currency_core common crypto zlibstatic ethash ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) target_link_libraries(functional_tests rpc wallet currency_core crypto common zlibstatic ethash libminiupnpc-static ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) target_link_libraries(hash-tests crypto ethash) target_link_libraries(hash-target-tests crypto currency_core ethash ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) target_link_libraries(performance_tests currency_core common crypto zlibstatic ethash ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) -target_link_libraries(unit_tests wallet currency_core crypto common gtest_main zlibstatic ethash ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) +target_link_libraries(unit_tests wallet currency_core common crypto gtest_main zlibstatic ethash ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) target_link_libraries(net_load_tests_clt currency_core common crypto gtest_main ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) target_link_libraries(net_load_tests_srv currency_core common crypto gtest_main ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) diff --git a/tests/core_tests/chain_switch_1.cpp b/tests/core_tests/chain_switch_1.cpp index 2f11dbab..2657ba5c 100644 --- a/tests/core_tests/chain_switch_1.cpp +++ b/tests/core_tests/chain_switch_1.cpp @@ -435,7 +435,7 @@ bool chain_switching_when_gindex_spent_in_both_chains::generate(std::vector& event // 0 1 11 12 13 14 // (0 )- (1 )-...(1r)- (2 )- (3 )- // \ tx_0 - // \ + // \ // \- (2a)- (3a)- (4 )- // tx_0 diff --git a/tests/core_tests/multisig_wallet_tests.cpp b/tests/core_tests/multisig_wallet_tests.cpp index 9bc3be84..88c86b24 100644 --- a/tests/core_tests/multisig_wallet_tests.cpp +++ b/tests/core_tests/multisig_wallet_tests.cpp @@ -1622,7 +1622,7 @@ multisig_and_checkpoints::multisig_and_checkpoints() bool multisig_and_checkpoints::set_cp(currency::core& c, size_t ev_index, const std::vector& events) { currency::checkpoints checkpoints; - checkpoints.add_checkpoint(15, "72d63d6500c62d6783108f5a2e2c9f1dc1f0aae57011cf123583eec679a52cf9"); + checkpoints.add_checkpoint(15, "6f9194c144afd73077478e7f04e947c50160b5673558e6f696a4f662a3ca261e"); c.set_checkpoints(std::move(checkpoints)); return true; diff --git a/tests/core_tests/pos_validation.cpp b/tests/core_tests/pos_validation.cpp index df2afe97..2fb6de17 100644 --- a/tests/core_tests/pos_validation.cpp +++ b/tests/core_tests/pos_validation.cpp @@ -923,7 +923,7 @@ bool pos_altblocks_validation::generate(std::vector& events) c // +-----------------------+ // | tx_0 tx_0 spends all outputs in blk_1 (main chain) // (0 )- (1 )-...(1r)- (2 )- (3 )-...(3r)- (4 )- (5 )- <- main chain - // | \ + // | \ // | \- (2a)- <- alt chain // +--------------+ PoS block 2a uses stake already spent in main chain @@ -941,7 +941,7 @@ bool pos_altblocks_validation::generate(std::vector& events) c // +-----------------------+ // | tx_0 tx_0 spends all outputs in blk_1 (main chain) // (0 )- (1 )-...(1r)- (2 )- (3 )-...(3r)- (4 )- (5 )- <- main chain - // || \ + // || \ // || \- (2a)- #3a#- <- alt chain // |+--------------+ | PoS block 2a uses stake already spent in main chain (okay) // +-----------------------+ PoS block 3a uses stake already spent in current alt chain (fail) @@ -962,11 +962,11 @@ bool pos_altblocks_validation::generate(std::vector& events) c // +-----------------------+ // | tx_0 tx_0 spends all outputs in blk_1 (main chain) // (0 )- (1 )-...(1r)- (2 )- (3 )- ........ (3r)- (4 )- (5 )- <- main chain - // || \ + // || \ // || \- (2a)- #3a#- <- alt chain // |+--------------+ \ | PoS block 2a uses stake already spent in main chain (okay) // +---------------|-------+ PoS block 3a uses stake already spent in current alt chain (fail) - // | \ + // | \ // | \ ...... (2br)- (3b)- <- alt chain // | | // +-----------------------+ PoS block 3b uses as stake an output, created in current alt chain (2a) @@ -989,7 +989,7 @@ bool pos_altblocks_validation::generate(std::vector& events) c // || \- (2a)- #3a#- | <- alt chain // |+--------------+ \ | \ PoS block 2a uses stake already spent in main chain (okay) // +---------------|-------+ \ PoS block 3a uses stake already spent in current alt chain (fail) - // | \ \ + // | \ \ // | \ ...... (2br)- (3b)- #4b# <- alt chain // | | // +-----------------------+ PoS block 3b uses as stake an output, created in current alt chain (2a) diff --git a/tests/core_tests/tx_validation.cpp b/tests/core_tests/tx_validation.cpp index 83109915..bd23fdf0 100644 --- a/tests/core_tests/tx_validation.cpp +++ b/tests/core_tests/tx_validation.cpp @@ -934,7 +934,7 @@ bool gen_crypted_attachments::check_crypted_tx(currency::core& c, size_t ev_inde std::vector at; bool r = currency::decrypt_payload_items(true, *ptx_from_bc, bob_acc.get_keys(), at); CHECK_EQ(r, true); - CHECK_EQ(at.size(), 7); // custom attachments: 1) tx_payer, 2) tx_comment, 3) std::string; system attachments: 4) tx_crypto_checksum; system extra: 5) tx pub key, 6) extra_attachment_info + CHECK_EQ(at.size(), 8); // custom attachments: 1) tx_payer, 2) tx_comment, 3) std::string; system attachments: 4) tx_crypto_checksum; system extra: 5) tx pub key, 6) extra_attachment_info, 7) etc_tx_flags16_t currency::tx_payer decrypted_pr = AUTO_VAL_INIT(decrypted_pr); r = get_type_in_variant_container(at, decrypted_pr); @@ -1379,7 +1379,7 @@ bool tx_expiration_time_and_chain_switching::generate(std::vector +#include +#include +#include +#include + +#include "common/encryption_filter.h" +#include "crypto/crypto.h" +#include "currency_core/blockchain_storage_basic.h" +#include "currency_core/blockchain_storage_boost_serialization.h" +#include "common/boost_serialization_helper.h" + + +bool perform_crypt_stream_iteration(const std::list& test_list, const crypto::chacha8_iv& iv) +{ + std::list verification_list; + boost::filesystem::ofstream store_data_file; + store_data_file.open("./test.bin", std::ios_base::binary | std::ios_base::out | std::ios::trunc); + tools::encrypt_chacha_out_filter encrypt_filter("pass", iv); + boost::iostreams::filtering_ostream out; + out.push(encrypt_filter); + out.push(store_data_file); + + + //out << buff; + bool res = tools::portble_serialize_obj_to_stream(test_list, out); + + out.flush(); + store_data_file.close(); + + boost::filesystem::ifstream data_file; + data_file.open("./test.bin", std::ios_base::binary | std::ios_base::in); + tools::encrypt_chacha_in_filter decrypt_filter("pass", iv); + + boost::iostreams::filtering_istream in; + in.push(decrypt_filter); + in.push(data_file); + try { + + bool res2 = tools::portable_unserialize_obj_from_stream(verification_list, in); + CHECK_AND_ASSERT_MES(res, false, "Failed to unserialize wallet"); + size_t i = 0; + CHECK_AND_ASSERT_MES(test_list.size() == verification_list.size(), false, "restored list is wrong size"); + return true; + } + catch (std::exception& err) + { + LOG_ERROR("Exception: " << err.what()); + return false; + } + return true; +} + +bool perform_just_substream_stream_iteration(const std::list& test_list, const crypto::chacha8_iv& iv) +{ + std::list verification_list; + boost::filesystem::ofstream store_data_file; + store_data_file.open("./test3.bin", std::ios_base::binary | std::ios_base::out | std::ios::trunc); + //encrypt_chacha_out_filter encrypt_filter("pass", iv); + boost::iostreams::filtering_ostream out; + //out.push(encrypt_filter); + out.push(store_data_file); + + + //out << buff; + bool res = tools::portble_serialize_obj_to_stream(test_list, out); + + out.flush(); + store_data_file.close(); + + boost::filesystem::ifstream data_file; + data_file.open("./test3.bin", std::ios_base::binary | std::ios_base::in); + //encrypt_chacha_in_filter decrypt_filter("pass", iv); + + boost::iostreams::filtering_istream in; + //in.push(decrypt_filter); + in.push(data_file); + try { + + bool res2 = tools::portable_unserialize_obj_from_stream(verification_list, in); + CHECK_AND_ASSERT_MES(res, false, "Failed to unserialize wallet"); + size_t i = 0; + CHECK_AND_ASSERT_MES(test_list.size() == verification_list.size(), false, "restored list is wrong size"); + return true; + } + catch (std::exception& err) + { + LOG_ERROR("Exception: " << err.what()); + return false; + } + return true; +} + + +bool perform_no_crypt_stream_iteration(const std::list& test_list, const crypto::chacha8_iv& iv) +{ + std::list verification_list; + boost::filesystem::ofstream store_data_file; + store_data_file.open("./test2.bin", std::ios_base::binary | std::ios_base::out | std::ios::trunc); +// encrypt_chacha_out_filter encrypt_filter("pass", iv); +// boost::iostreams::filtering_ostream out; +// out.push(encrypt_filter); +// out.push(store_data_file); + + + //out << buff; + bool res = tools::portble_serialize_obj_to_stream(test_list, store_data_file); + + store_data_file.flush(); + store_data_file.close(); + + boost::filesystem::ifstream data_file; + data_file.open("./test2.bin", std::ios_base::binary | std::ios_base::in); +// encrypt_chacha_in_filter decrypt_filter("pass", iv); + +// boost::iostreams::filtering_istream in; +// in.push(decrypt_filter); +// in.push(data_file); + try { + + bool res2 = tools::portable_unserialize_obj_from_stream(verification_list, data_file); + CHECK_AND_ASSERT_MES(res, false, "Failed to unserialize wallet"); + size_t i = 0; + CHECK_AND_ASSERT_MES(test_list.size() == verification_list.size(), false, "restored list is wrong size"); + return true; + } + catch (std::exception& err) + { + LOG_ERROR("Exception: " << err.what()); + return false; + } +} + + + +bool do_chacha_stream_performance_test() +{ + LOG_PRINT_L0("chacha_stream_test"); + std::list test_list; + for (size_t i = 0; i != 10000; i++) { + test_list.push_back(currency::block_extended_info()); + test_list.back().height = i; + test_list.back().this_block_tx_fee_median = i; + } + + + crypto::chacha8_iv iv = crypto::rand(); + LOG_PRINT_L0("Running substream stream performance tests..."); + TIME_MEASURE_START(substream_version); + for (size_t i = 0; i != 100; i++) + { + bool r = perform_just_substream_stream_iteration(test_list, iv); + CHECK_AND_ASSERT_MES(r, false, "Failed to perform_crypt_stream_iteration"); + } + TIME_MEASURE_FINISH(substream_version); + LOG_PRINT_L0("OK.time: " << substream_version); + LOG_PRINT_L0("Running crypt stream performance tests..."); + TIME_MEASURE_START(crypted_version); + for (size_t i = 0; i != 100; i++) + { + bool r = perform_crypt_stream_iteration(test_list, iv); + CHECK_AND_ASSERT_MES(r, false, "Failed to perform_crypt_stream_iteration"); + } + TIME_MEASURE_FINISH(crypted_version); + LOG_PRINT_L0("OK.time: " << crypted_version); + LOG_PRINT_L0("Running non-crypt stream performance tests..."); + TIME_MEASURE_START(non_crypted_version); + for (size_t i = 0; i != 100; i++) + { + bool r = perform_no_crypt_stream_iteration(test_list, iv); + CHECK_AND_ASSERT_MES(r, false, "Failed to perform_crypt_stream_iteration"); + } + TIME_MEASURE_FINISH(non_crypted_version); + LOG_PRINT_L0("OK.time: " << non_crypted_version); + + + +} + + + + diff --git a/tests/performance_tests/chacha_stream_performance_test.h b/tests/performance_tests/chacha_stream_performance_test.h new file mode 100644 index 00000000..791d0bd5 --- /dev/null +++ b/tests/performance_tests/chacha_stream_performance_test.h @@ -0,0 +1,7 @@ +// Copyright (c) 2014-2015 The Boolberry developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#pragma once + +bool do_chacha_stream_performance_test(); diff --git a/tests/performance_tests/main.cpp b/tests/performance_tests/main.cpp index a490ad7b..d4043276 100644 --- a/tests/performance_tests/main.cpp +++ b/tests/performance_tests/main.cpp @@ -17,6 +17,7 @@ #include "is_out_to_acc.h" #include "core_market_performance_test.h" #include "serialization_performance_test.h" +#include "chacha_stream_performance_test.h" #include "keccak_test.h" #include "blake2_test.h" #include "print_struct_to_json.h" @@ -38,9 +39,10 @@ int main(int argc, char** argv) set_process_affinity(1); set_thread_high_priority(); + do_chacha_stream_performance_test(); //test_blake2(); - free_space_check(); + //free_space_check(); //print_struct_to_json(); diff --git a/tests/unit_tests/chacha_stream_test.cpp b/tests/unit_tests/chacha_stream_test.cpp new file mode 100644 index 00000000..3190e792 --- /dev/null +++ b/tests/unit_tests/chacha_stream_test.cpp @@ -0,0 +1,142 @@ +// Copyright (c) 2012-2014 The Boolberry developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "gtest/gtest.h" + +#include +#include +#include +#include +#include + +#include "common/encryption_filter.h" +#include "crypto/crypto.h" +#include "currency_core/blockchain_storage_basic.h" +#include "currency_core/blockchain_storage_boost_serialization.h" +#include "common/boost_serialization_helper.h" + + +TEST(chacha_stream_test, basic_test_with_serialization_on_top) +{ + LOG_PRINT_L0("chacha_stream_test"); + std::list test_list; + for(size_t i = 0; i != 1000; i++) { + test_list.push_back(currency::block_extended_info()); + test_list.back().height = i; + test_list.back().this_block_tx_fee_median = i; + } + + std::list verification_list; + crypto::chacha8_iv iv = crypto::rand(); + boost::filesystem::ofstream store_data_file; + store_data_file.open("./test.bin", std::ios_base::binary | std::ios_base::out | std::ios::trunc); + tools::encrypt_chacha_out_filter encrypt_filter("pass", iv); + boost::iostreams::filtering_ostream out; + out.push(encrypt_filter); + out.push(store_data_file); + + + //out << buff; + bool res = tools::portble_serialize_obj_to_stream(test_list, out); + + out.flush(); + store_data_file.close(); + + boost::filesystem::ifstream data_file; + data_file.open("./test.bin", std::ios_base::binary | std::ios_base::in); + tools::encrypt_chacha_in_filter decrypt_filter("pass", iv); + + boost::iostreams::filtering_istream in; + in.push(decrypt_filter); + in.push(data_file); + try { + + bool res2 = tools::portable_unserialize_obj_from_stream(verification_list, in); + ASSERT_TRUE(res2); + size_t i = 0; + for(auto vle: verification_list) { + ASSERT_TRUE(vle.height == i); + ASSERT_TRUE(vle.this_block_tx_fee_median == i); + i++; + } + //if(verification_list != test_list) + } + catch (std::exception& err) + { + std::cout << err.what(); + ASSERT_TRUE(false); + } + +} + + +TEST(chacha_stream_test, diversity_test_on_different_stream_behaviour) +{ + LOG_PRINT_L0("chacha_stream_test"); + //prepare buff + const size_t buff_size = 10000; + std::string buff(buff_size, ' '); + for(size_t i = 0; i != buff_size; i++) { + buff[i] = i % 255; + } + + crypto::chacha8_iv iv = crypto::rand(); + boost::filesystem::ofstream store_data_file; + store_data_file.open("./test.bin", std::ios_base::binary | std::ios_base::out | std::ios::trunc); + tools::encrypt_chacha_out_filter encrypt_filter("pass", iv); + //boost::iostreams::stream outputStream(sink_encrypt); + boost::iostreams::filtering_ostream out; + out.push(encrypt_filter); + out.push(store_data_file); + + out << buff; + + out.flush(); + store_data_file.close(); + for (size_t d = 0; d != 1000; d++) + { + boost::filesystem::ifstream data_file; + data_file.open("./test.bin", std::ios_base::binary | std::ios_base::in); + tools::encrypt_chacha_in_filter decrypt_filter("pass", iv); + + boost::iostreams::filtering_istream in; + in.push(decrypt_filter); + in.push(data_file); + + std::string str(buff_size + 100, ' '); + try { + + size_t offset = 0; + while (offset < buff_size+1) + { + std::streamsize count = std::rand() % 100; + // if (count + offset > buff_size) + // { + // count = buff_size - offset; + // } + in.read((char*)&str.data()[offset], count); + //self check + size_t readed_sz = in.gcount(); + if (!(count + offset > buff_size || readed_sz == count)) + { + ASSERT_TRUE(count + offset > buff_size || readed_sz == count); + } + offset += readed_sz; + if (!in) { + break; + } + } + if (in) { + ASSERT_TRUE(false); + } + std::cout << "OK"; + } + catch (std::exception& err) { + std::cout << err.what(); + ASSERT_TRUE(false); + } + } + std::cout << "Finished OK!"; + +} \ No newline at end of file diff --git a/utils/build_script_windows.bat b/utils/build_script_windows.bat index 601b65d6..0ae2c6a4 100644 --- a/utils/build_script_windows.bat +++ b/utils/build_script_windows.bat @@ -170,11 +170,11 @@ set installer_path=%BUILDS_PATH%\builds\%installer_file% @echo " SIGNING ...." -%ZANO_SIGN_CMD% %installer_path% -IF %ERRORLEVEL% NEQ 0 ( - @echo "failed to sign installer" - goto error -) +:: %ZANO_SIGN_CMD% %installer_path% +:: IF %ERRORLEVEL% NEQ 0 ( +:: @echo "failed to sign installer" +:: goto error +:: ) @echo " UPLOADING TO SERVER ...." diff --git a/utils/munin_plugins/_link_munin_plugins.sh b/utils/munin_plugins/_link_munin_plugins.sh new file mode 100755 index 00000000..d79aec1d --- /dev/null +++ b/utils/munin_plugins/_link_munin_plugins.sh @@ -0,0 +1,86 @@ +#!/bin/bash +set -e +set -x + + +# Note: if using MDBX engine uncomment corresponding lines below + + +cd /etc/munin/plugins/ + +rm -f aliases +rm -f alt_blocks_count +rm -f block_size +rm -f blockchain_lmdb_data_file_size +rm -f blockchain_mdbx_data_file_size +rm -f db_map_size +rm -f db_transactions_count +rm -f emission +rm -f grey_peerlist_size +rm -f hashrate +rm -f height +rm -f incoming_connections_count +rm -f market +rm -f outgoing_connections_count +rm -f outs_stat +rm -f performance_block +rm -f performance_pool +rm -f performance_transaction +rm -f performance_transaction_inp +rm -f performance_transaction_inp_loop +rm -f performance_transaction_inp_loop_scan_loop +rm -f poolstate_lmdb_data_file_size +rm -f poolstate_mdbx_data_file_size +rm -f pos_block_ts_shift_vs_actual +rm -f pos_dif_to_total_coins +rm -f pos_difficulty +rm -f pow_difficulty +rm -f reward +rm -f seconds_per_blocks +rm -f sequence_factor +rm -f timestamps +rm -f tx_count +rm -f tx_daily_count +rm -f tx_daily_volume +rm -f tx_per_block +rm -f tx_pool_size +rm -f white_peerlist_size + + +ln -s /home/project/zano_for_munin/utils/munin_plugins/aliases +ln -s /home/project/zano_for_munin/utils/munin_plugins/alt_blocks_count +ln -s /home/project/zano_for_munin/utils/munin_plugins/block_size +ln -s /home/project/zano_for_munin/utils/munin_plugins/blockchain_lmdb_data_file_size +#ln -s /home/project/zano_for_munin/utils/munin_plugins/blockchain_mdbx_data_file_size +ln -s /home/project/zano_for_munin/utils/munin_plugins/db_map_size +ln -s /home/project/zano_for_munin/utils/munin_plugins/db_transactions_count +ln -s /home/project/zano_for_munin/utils/munin_plugins/emission +ln -s /home/project/zano_for_munin/utils/munin_plugins/grey_peerlist_size +ln -s /home/project/zano_for_munin/utils/munin_plugins/hashrate +ln -s /home/project/zano_for_munin/utils/munin_plugins/height +ln -s /home/project/zano_for_munin/utils/munin_plugins/incoming_connections_count +ln -s /home/project/zano_for_munin/utils/munin_plugins/market +ln -s /home/project/zano_for_munin/utils/munin_plugins/outgoing_connections_count +ln -s /home/project/zano_for_munin/utils/munin_plugins/outs_stat +ln -s /home/project/zano_for_munin/utils/munin_plugins/performance_block +ln -s /home/project/zano_for_munin/utils/munin_plugins/performance_pool +ln -s /home/project/zano_for_munin/utils/munin_plugins/performance_transaction +ln -s /home/project/zano_for_munin/utils/munin_plugins/performance_transaction_inp +ln -s /home/project/zano_for_munin/utils/munin_plugins/performance_transaction_inp_loop +ln -s /home/project/zano_for_munin/utils/munin_plugins/performance_transaction_inp_loop_scan_loop +ln -s /home/project/zano_for_munin/utils/munin_plugins/poolstate_lmdb_data_file_size +#ln -s /home/project/zano_for_munin/utils/munin_plugins/poolstate_mdbx_data_file_size +ln -s /home/project/zano_for_munin/utils/munin_plugins/pos_block_ts_shift_vs_actual +ln -s /home/project/zano_for_munin/utils/munin_plugins/pos_dif_to_total_coins +ln -s /home/project/zano_for_munin/utils/munin_plugins/pos_difficulty +ln -s /home/project/zano_for_munin/utils/munin_plugins/pow_difficulty +ln -s /home/project/zano_for_munin/utils/munin_plugins/reward +ln -s /home/project/zano_for_munin/utils/munin_plugins/seconds_per_blocks +ln -s /home/project/zano_for_munin/utils/munin_plugins/sequence_factor +ln -s /home/project/zano_for_munin/utils/munin_plugins/timestamps +ln -s /home/project/zano_for_munin/utils/munin_plugins/tx_count +ln -s /home/project/zano_for_munin/utils/munin_plugins/tx_daily_count +ln -s /home/project/zano_for_munin/utils/munin_plugins/tx_daily_volume +ln -s /home/project/zano_for_munin/utils/munin_plugins/tx_per_block +ln -s /home/project/zano_for_munin/utils/munin_plugins/tx_pool_size +ln -s /home/project/zano_for_munin/utils/munin_plugins/white_peerlist_size diff --git a/utils/munin_plugins/blockchain_data_file_size b/utils/munin_plugins/blockchain_data_file_size deleted file mode 100755 index 84405a69..00000000 --- a/utils/munin_plugins/blockchain_data_file_size +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash - -case $1 in - config) - cat <<'EOM' -graph_title blockchain_data_file_size -graph_vlabel blockchain_data_file_size -graph_category daemon -blockchain_data_file_size.label blockchain_data_file_size -EOM - exit 0;; -esac - -printf "blockchain_data_file_size.value " -#sudo ls -l /tmp/ttt | cut -d" " -f5 -sudo ls -l /root/.Zano/blockchain/data.mdb | cut -d" " -f5 diff --git a/utils/munin_plugins/blockchain_lmdb_data_file_size b/utils/munin_plugins/blockchain_lmdb_data_file_size new file mode 100755 index 00000000..274a906e --- /dev/null +++ b/utils/munin_plugins/blockchain_lmdb_data_file_size @@ -0,0 +1,15 @@ +#!/bin/bash + +case $1 in + config) + cat <<'EOM' +graph_title blockchain_lmdb_data_file_size +graph_vlabel blockchain_lmdb_data_file_size +graph_category daemon +blockchain_lmdb_data_file_size.label blockchain_lmdb_data_file_size +EOM + exit 0;; +esac + +printf "blockchain_lmdb_data_file_size.value " +sudo ls -l /root/.Zano/blockchain_lmdb_v1/data.mdb | cut -d" " -f5 diff --git a/utils/munin_plugins/blockchain_mdbx_data_file_size b/utils/munin_plugins/blockchain_mdbx_data_file_size new file mode 100755 index 00000000..af9cd8c5 --- /dev/null +++ b/utils/munin_plugins/blockchain_mdbx_data_file_size @@ -0,0 +1,15 @@ +#!/bin/bash + +case $1 in + config) + cat <<'EOM' +graph_title blockchain_mdbx_data_file_size +graph_vlabel blockchain_mdbx_data_file_size +graph_category daemon +blockchain_mdbx_data_file_size.label blockchain_mdbx_data_file_size +EOM + exit 0;; +esac + +printf "blockchain_mdbx_data_file_size.value " +sudo ls -l /root/.Zano/blockchain_mdbx_v1/mdbx.dat | cut -d" " -f5 diff --git a/utils/munin_plugins/poolstate_data_file_size b/utils/munin_plugins/poolstate_data_file_size deleted file mode 100755 index c5dd9c4e..00000000 --- a/utils/munin_plugins/poolstate_data_file_size +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash - -case $1 in - config) - cat <<'EOM' -graph_title poolstate_data_file_size -graph_vlabel poolstate_data_file_size -graph_category daemon -poolstate_data_file_size.label poolstate_data_file_size -EOM - exit 0;; -esac - -printf "poolstate_data_file_size.value " -#sudo ls -l /tmp/ttt | cut -d" " -f5 -sudo ls -l /root/.Zano/poolstate/data.mdb | cut -d" " -f5 diff --git a/utils/munin_plugins/poolstate_lmdb_data_file_size b/utils/munin_plugins/poolstate_lmdb_data_file_size new file mode 100755 index 00000000..16b6d0d4 --- /dev/null +++ b/utils/munin_plugins/poolstate_lmdb_data_file_size @@ -0,0 +1,15 @@ +#!/bin/bash + +case $1 in + config) + cat <<'EOM' +graph_title poolstate_lmdb_data_file_size +graph_vlabel poolstate_lmdb_data_file_size +graph_category daemon +poolstate_lmdb_data_file_size.label poolstate_lmdb_data_file_size +EOM + exit 0;; +esac + +printf "poolstate_lmdb_data_file_size.value " +sudo ls -l /root/.Zano/poolstate_lmdb_v1/data.mdb | cut -d" " -f5 diff --git a/utils/munin_plugins/poolstate_mdbx_data_file_size b/utils/munin_plugins/poolstate_mdbx_data_file_size new file mode 100755 index 00000000..c3a5e53a --- /dev/null +++ b/utils/munin_plugins/poolstate_mdbx_data_file_size @@ -0,0 +1,15 @@ +#!/bin/bash + +case $1 in + config) + cat <<'EOM' +graph_title poolstate_mdbx_data_file_size +graph_vlabel poolstate_mdbx_data_file_size +graph_category daemon +poolstate_mdbx_data_file_size.label poolstate_mdbx_data_file_size +EOM + exit 0;; +esac + +printf "poolstate_mdbx_data_file_size.value " +sudo ls -l /root/.Zano/poolstate_mdbx_v1/mdbx.dat | cut -d" " -f5 diff --git a/utils/munin_plugins/sequence_factor b/utils/munin_plugins/sequence_factor old mode 100644 new mode 100755