forked from lthn/blockchain
Merge branch 'master' into frontend
This commit is contained in:
commit
ac5ab57337
38 changed files with 1176 additions and 529 deletions
|
|
@ -45,6 +45,10 @@ if (UNIX AND NOT APPLE)
|
|||
find_package(Threads REQUIRED)
|
||||
endif()
|
||||
|
||||
# TODO(unassigned): expand on types and versions, and then refactor.
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
set(CLANG TRUE)
|
||||
endif()
|
||||
|
||||
if(MSVC)
|
||||
add_definitions("/bigobj /Zm1000 /Z7 /MP /W3 /GS- /D_CRT_SECURE_NO_WARNINGS /wd4996 /wd4503 /wd4345 /wd4091 /D_WIN32_WINNT=0x0600 /DWIN32_LEAN_AND_MEAN /DGTEST_HAS_TR1_TUPLE=0 /FIinline_c.h /D__SSE4_1__")
|
||||
|
|
@ -66,7 +70,6 @@ else()
|
|||
# if(NOT APPLE)
|
||||
# set(WARNINGS "${WARNINGS} -Werror")
|
||||
# endif()
|
||||
|
||||
if(CMAKE_C_COMPILER_ID STREQUAL "Clang")
|
||||
set(WARNINGS "${WARNINGS} -Wno-shift-count-overflow -Wno-error=mismatched-tags -Wno-error=null-conversion -Wno-overloaded-shift-op-parentheses -Wno-error=shift-count-overflow -Wno-error=tautological-constant-out-of-range-compare -Wno-error=unused-private-field -Wno-error=unneeded-internal-declaration")
|
||||
else()
|
||||
|
|
@ -103,13 +106,15 @@ else()
|
|||
else()
|
||||
set(STATIC_ASSERT_FLAG "-Dstatic_assert=_Static_assert")
|
||||
endif()
|
||||
set(LINUX_LD_GOLD "")
|
||||
set(LINUX_STATIC_ICU "")
|
||||
if((NOT APPLE) AND (NOT MSVC))
|
||||
set(LINUX_LD_GOLD "-fuse-ld=gold")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11 -D_GNU_SOURCE ${MINGW_FLAG} ${STATIC_ASSERT_FLAG} ${WARNINGS} ${C_WARNINGS} ${ARCH_FLAG}")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fpermissive -ftemplate-depth-1024 -std=c++11 -D_GNU_SOURCE ${APPLE_FLAG} ${MINGW_FLAG} ${WARNINGS} ${CXX_WARNINGS} ${ARCH_FLAG}")
|
||||
if (NOT APPLE AND NOT MSVC)
|
||||
if (CLANG)
|
||||
set(LLVM_USE_LINKER "gold")
|
||||
else()
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=gold")
|
||||
endif()
|
||||
endif()
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${LINUX_LD_GOLD} -std=c11 -D_GNU_SOURCE ${MINGW_FLAG} ${STATIC_ASSERT_FLAG} ${WARNINGS} ${C_WARNINGS} ${ARCH_FLAG}")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${LINUX_LD_GOLD} -fpermissive -ftemplate-depth-1024 -std=c++11 -D_GNU_SOURCE ${APPLE_FLAG} ${MINGW_FLAG} ${WARNINGS} ${CXX_WARNINGS} ${ARCH_FLAG}")
|
||||
if(CMAKE_C_COMPILER_ID STREQUAL "GNU" AND NOT (CMAKE_C_COMPILER_VERSION VERSION_LESS 4.8))
|
||||
set(DEBUG_FLAGS "-g3 -O0") #set(DEBUG_FLAGS "-g3 -Og")
|
||||
else()
|
||||
|
|
|
|||
|
|
@ -4,7 +4,8 @@ Building
|
|||
### Dependencies
|
||||
| component / version | minimum <br>(not recommended but may work) | recommended | most recent of what we have ever tested |
|
||||
|--|--|--|--|
|
||||
| gcc (Linux) | 5.4.0 | 7.2.0 | 7.2.0 |
|
||||
| gcc (Linux) | 5.4.0 | 7.2.0 | 8.2.1 |
|
||||
| llvm/clang (Linux) | UNKNOWN | 7.0.1 | 7.0.1 |
|
||||
| [MSVC](https://visualstudio.microsoft.com/downloads/) (Windows) | 2015 (14.0 update 1) | 2015 (14.0 update 3) | 2017 (15.5.7) |
|
||||
| [XCode](https://developer.apple.com/downloads/) (macOS) | 7.3.1 | 9.2 | 9.2 |
|
||||
| [CMake](https://cmake.org/download/) | 2.8.6 | 3.4.1 | 3.11.0 |
|
||||
|
|
|
|||
|
|
@ -2,6 +2,6 @@ add_subdirectory(liblmdb)
|
|||
if(MSVC)
|
||||
target_compile_options(lmdb PRIVATE /wd4996 /wd4503 /wd4345 /wd4267 /wd4244 /wd4146 /wd4333 /wd4172)
|
||||
else()
|
||||
target_compile_options(lmdb PRIVATE -Wno-discarded-qualifiers -Wno-empty-body -Wno-unused-but-set-variable)
|
||||
# Warnings as used by LMDB itself (LMDB_0.9.23)
|
||||
target_compile_options(lmdb PRIVATE -Wall -Wno-unused-parameter -Wbad-function-cast -Wuninitialized)
|
||||
endif()
|
||||
|
||||
|
|
|
|||
|
|
@ -35,12 +35,11 @@ namespace eos {
|
|||
|
||||
// version of the linked boost archive library
|
||||
const archive_version_type archive_version(
|
||||
11
|
||||
// #if BOOST_VERSION < 103700
|
||||
// boost::archive::ARCHIVE_VERSION()
|
||||
// #else
|
||||
// boost::archive::BOOST_ARCHIVE_VERSION()
|
||||
// #endif
|
||||
#if BOOST_VERSION < 103700
|
||||
boost::archive::ARCHIVE_VERSION()
|
||||
#else
|
||||
boost::archive::BOOST_ARCHIVE_VERSION()
|
||||
#endif
|
||||
);
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
* \file portable_iarchive.hpp
|
||||
* \brief Provides an archive to read from portable binary files.
|
||||
* \author christian.pfligersdorffer@gmx.at
|
||||
* \version 5.0
|
||||
* \version 5.1
|
||||
*
|
||||
* This pair of archives brings the advantages of binary streams to the cross
|
||||
* platform boost::serialization user. While being almost as fast as the native
|
||||
|
|
@ -23,6 +23,9 @@
|
|||
* chance it will instantly work for your specific setup. If you encounter
|
||||
* problems or have suggestions please contact the author.
|
||||
*
|
||||
* \note Version 5.1 is now compatible with boost up to version 1.59. Thanks to
|
||||
* ecotax for pointing to the issue with shared_ptr_helper.
|
||||
*
|
||||
* \note Version 5.0 is now compatible with boost up to version 1.49 and enables
|
||||
* serialization of std::wstring by converting it to/from utf8 (thanks to
|
||||
* Arash Abghari for this suggestion). With that all unit tests from the
|
||||
|
|
@ -89,9 +92,7 @@
|
|||
#include <boost/archive/basic_binary_iprimitive.hpp>
|
||||
#include <boost/archive/basic_binary_iarchive.hpp>
|
||||
|
||||
#if BOOST_VERSION >= 105600
|
||||
#include <boost/serialization/shared_ptr_helper.hpp>
|
||||
#elif BOOST_VERSION >= 103500
|
||||
#if BOOST_VERSION >= 103500 && BOOST_VERSION < 105600
|
||||
#include <boost/archive/shared_ptr_helper.hpp>
|
||||
#endif
|
||||
|
||||
|
|
@ -115,14 +116,15 @@
|
|||
#include <boost/math/fpclassify.hpp>
|
||||
#elif BOOST_VERSION < 104800
|
||||
#include <boost/spirit/home/support/detail/integer/endian.hpp>
|
||||
// Boost 1.69 (Spirit.X2/X3) has dropped their own FP routines in favor of boost::math
|
||||
#elif BOOST_VERSION < 106900
|
||||
#include <boost/spirit/home/support/detail/math/fpclassify.hpp>
|
||||
#else
|
||||
#include <boost/spirit/home/support/detail/endian/endian.hpp>
|
||||
#include <boost/spirit/home/support/detail/math/fpclassify.hpp>
|
||||
#endif
|
||||
|
||||
// namespace alias
|
||||
#if BOOST_VERSION < 103800
|
||||
#if BOOST_VERSION < 103800 || BOOST_VERSION >= 106900
|
||||
namespace fp = boost::math;
|
||||
#else
|
||||
namespace fp = boost::spirit::math;
|
||||
|
|
@ -135,7 +137,7 @@ namespace endian = boost::detail;
|
|||
namespace endian = boost::spirit::detail;
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
#if BOOST_VERSION >= 104500 && !defined BOOST_NO_STD_WSTRING
|
||||
// used for wstring to utf8 conversion
|
||||
#include <boost/program_options/config.hpp>
|
||||
#include <boost/program_options/detail/convert.hpp>
|
||||
|
|
@ -190,9 +192,7 @@ namespace eos {
|
|||
// load_override functions so we chose to stay one level higher
|
||||
, public boost::archive::basic_binary_iarchive<portable_iarchive>
|
||||
|
||||
#if BOOST_VERSION >= 105600
|
||||
// mix-in helper class for serializing shared_ptr does not exist anymore
|
||||
#elif BOOST_VERSION >= 103500
|
||||
#if BOOST_VERSION >= 103500 && BOOST_VERSION < 105600
|
||||
// mix-in helper class for serializing shared_ptr
|
||||
, public boost::archive::detail::shared_ptr_helper
|
||||
#endif
|
||||
|
|
@ -349,7 +349,7 @@ namespace eos {
|
|||
T temp = size < 0 ? -1 : 0;
|
||||
load_binary(&temp, abs(size));
|
||||
|
||||
// load the value from little endian - is is then converted
|
||||
// load the value from little endian - it is then converted
|
||||
// to the target type T and fits it because size <= sizeof(T)
|
||||
t = endian::load_little_endian<T, sizeof(T)>(&temp);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
* \file portable_oarchive.hpp
|
||||
* \brief Provides an archive to create portable binary files.
|
||||
* \author christian.pfligersdorffer@gmx.at
|
||||
* \version 5.0
|
||||
* \version 5.1
|
||||
*
|
||||
* This pair of archives brings the advantages of binary streams to the cross
|
||||
* platform boost::serialization user. While being almost as fast as the native
|
||||
|
|
@ -23,6 +23,9 @@
|
|||
* chance it will instantly work for your specific setup. If you encounter
|
||||
* problems or have suggestions please contact the author.
|
||||
*
|
||||
* \note Version 5.1 is now compatible with boost up to version 1.59. Thanks to
|
||||
* ecotax for pointing to the issue with shared_ptr_helper.
|
||||
*
|
||||
* \note Version 5.0 is now compatible with boost up to version 1.49 and enables
|
||||
* serialization of std::wstring by converting it to/from utf8 (thanks to
|
||||
* Arash Abghari for this suggestion). With that all unit tests from the
|
||||
|
|
@ -91,15 +94,9 @@
|
|||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/archive/basic_binary_oprimitive.hpp>
|
||||
#include <boost/archive/basic_binary_oarchive.hpp>
|
||||
#if BOOST_VERSION >= 105600
|
||||
#include <boost/serialization/shared_ptr_helper.hpp>
|
||||
#elif BOOST_VERSION >= 103500
|
||||
#include <boost/archive/shared_ptr_helper.hpp>
|
||||
#endif
|
||||
|
||||
#if BOOST_VERSION >= 104500
|
||||
#include <boost/program_options/config.hpp>
|
||||
#include <boost/program_options/detail/convert.hpp>
|
||||
#if BOOST_VERSION >= 103500 && BOOST_VERSION < 105600
|
||||
#include <boost/archive/shared_ptr_helper.hpp>
|
||||
#endif
|
||||
|
||||
// funny polymorphics
|
||||
|
|
@ -122,14 +119,15 @@
|
|||
#include <boost/math/fpclassify.hpp>
|
||||
#elif BOOST_VERSION < 104800
|
||||
#include <boost/spirit/home/support/detail/integer/endian.hpp>
|
||||
// Boost 1.69 (Spirit.X2/X3) has dropped their own FP routines in favor of boost::math
|
||||
#elif BOOST_VERSION < 106900
|
||||
#include <boost/spirit/home/support/detail/math/fpclassify.hpp>
|
||||
#else
|
||||
#include <boost/spirit/home/support/detail/endian/endian.hpp>
|
||||
#include <boost/spirit/home/support/detail/math/fpclassify.hpp>
|
||||
#endif
|
||||
|
||||
// namespace alias fp_classify
|
||||
#if BOOST_VERSION < 103800
|
||||
#if BOOST_VERSION < 103800 || BOOST_VERSION >= 106900
|
||||
namespace fp = boost::math;
|
||||
#else
|
||||
namespace fp = boost::spirit::math;
|
||||
|
|
@ -142,7 +140,7 @@ namespace endian = boost::detail;
|
|||
namespace endian = boost::spirit::detail;
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
#if BOOST_VERSION >= 104500 && !defined BOOST_NO_STD_WSTRING
|
||||
// used for wstring to utf8 conversion
|
||||
#include <boost/program_options/config.hpp>
|
||||
#include <boost/program_options/detail/convert.hpp>
|
||||
|
|
@ -195,9 +193,7 @@ namespace eos {
|
|||
// save_override functions so we chose to stay one level higher
|
||||
, public boost::archive::basic_binary_oarchive<portable_oarchive>
|
||||
|
||||
#if BOOST_VERSION >= 105600
|
||||
// mix-in helper class for serializing shared_ptr does not exist anymore
|
||||
#elif BOOST_VERSION >= 103500
|
||||
#if BOOST_VERSION >= 103500 && BOOST_VERSION < 105600
|
||||
// mix-in helper class for serializing shared_ptr
|
||||
, public boost::archive::detail::shared_ptr_helper
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -893,12 +893,10 @@ namespace log_space
|
|||
FAST_CRITICAL_REGION_END();
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string get_thread_prefix()
|
||||
{
|
||||
FAST_CRITICAL_REGION_LOCAL(m_critical_sec);
|
||||
return m_thr_prefix_strings[misc_utils::get_thread_string_id()];
|
||||
|
||||
}
|
||||
|
||||
std::string get_default_log_file()
|
||||
|
|
@ -1160,7 +1158,6 @@ namespace log_space
|
|||
|
||||
}
|
||||
|
||||
|
||||
static bool add_logger( ibase_log_stream* pstream, int log_level_limit = LOG_LEVEL_4 )
|
||||
{
|
||||
logger* plogger = get_or_create_instance();
|
||||
|
|
@ -1234,8 +1231,6 @@ POP_WARNINGS
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
||||
|
||||
|
|
@ -1290,8 +1285,6 @@ POP_WARNINGS
|
|||
return plogger->get_thread_prefix();
|
||||
}
|
||||
|
||||
|
||||
|
||||
static std::string get_prefix_entry()
|
||||
{
|
||||
std::stringstream str_prefix;
|
||||
|
|
@ -1587,8 +1580,6 @@ POP_WARNINGS
|
|||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#define LOG_PRINT_NO_POSTFIX(mess, level) LOG_PRINT_NO_POSTFIX2(LOG_DEFAULT_TARGET, mess, level)
|
||||
#define LOG_PRINT_NO_PREFIX(mess, level) LOG_PRINT_NO_PREFIX2(LOG_DEFAULT_TARGET, mess, level)
|
||||
#define LOG_PRINT_NO_PREFIX_NO_POSTFIX(mess, level) LOG_PRINT_NO_PREFIX_NO_POSTFIX2(LOG_DEFAULT_TARGET, mess, level)
|
||||
|
|
@ -1694,7 +1685,6 @@ POP_WARNINGS
|
|||
#define CHECK_AND_ASSERT_MES2(expr, message) do{if(!(expr)) {LOG_ERROR(message); };}while(0)
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
|
||||
POP_WARNINGS
|
||||
|
|
|
|||
|
|
@ -137,6 +137,7 @@ namespace net_utils
|
|||
bool m_is_stop_handling;
|
||||
http::http_request_info m_query_info;
|
||||
size_t m_len_summary, m_len_remain;
|
||||
size_t m_precommand_line_chars;
|
||||
config_type& m_config;
|
||||
bool m_want_close;
|
||||
protected:
|
||||
|
|
|
|||
|
|
@ -33,8 +33,9 @@
|
|||
#include "file_io_utils.h"
|
||||
#include "net_parse_helpers.h"
|
||||
|
||||
#define HTTP_MAX_URI_LEN 9000
|
||||
#define HTTP_MAX_HEADER_LEN 100000
|
||||
#define HTTP_MAX_URI_LEN 9000
|
||||
#define HTTP_MAX_PRE_COMMAND_LINE_CHARS 20
|
||||
#define HTTP_MAX_HEADER_LEN 100000
|
||||
|
||||
PUSH_WARNINGS
|
||||
DISABLE_GCC_WARNING(maybe-uninitialized)
|
||||
|
|
@ -204,7 +205,8 @@ namespace net_utils
|
|||
m_len_remain(0),
|
||||
m_config(config),
|
||||
m_want_close(false),
|
||||
m_psnd_hndlr(psnd_hndlr)
|
||||
m_psnd_hndlr(psnd_hndlr),
|
||||
m_precommand_line_chars(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -217,6 +219,7 @@ namespace net_utils
|
|||
m_body_transfer_type = http_body_transfer_undefined;
|
||||
m_query_info.clear();
|
||||
m_len_summary = 0;
|
||||
m_precommand_line_chars = 0;
|
||||
return true;
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------
|
||||
|
|
@ -257,11 +260,19 @@ namespace net_utils
|
|||
if((m_cache[0] == '\r' || m_cache[0] == '\n'))
|
||||
{
|
||||
//some times it could be that before query line cold be few line breaks
|
||||
//so we have to be calm without panic with assers
|
||||
//so we have to be calm down without panic and asserts
|
||||
m_cache.erase(0, 1);
|
||||
|
||||
//fixed bug with possible '\r\n' chars flood, thanks to @anonimal (https://github.com/anonimal) for pointing this
|
||||
++m_precommand_line_chars;
|
||||
if (m_precommand_line_chars > HTTP_MAX_PRE_COMMAND_LINE_CHARS)
|
||||
{
|
||||
LOG_ERROR("simple_http_connection_handler::handle_buff_in: Too long URI line");
|
||||
m_state = http_state_error;
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if(std::string::npos != m_cache.find('\n', 0))
|
||||
handle_invoke_query_line();
|
||||
else
|
||||
|
|
@ -269,7 +280,7 @@ namespace net_utils
|
|||
m_is_stop_handling = true;
|
||||
if(m_cache.size() > HTTP_MAX_URI_LEN)
|
||||
{
|
||||
LOG_ERROR("simple_http_connection_handler::handle_buff_out: Too long URI line");
|
||||
LOG_ERROR("simple_http_connection_handler::handle_buff_in: Too long URI line");
|
||||
m_state = http_state_error;
|
||||
return false;
|
||||
}
|
||||
|
|
@ -297,10 +308,10 @@ namespace net_utils
|
|||
case http_state_connection_close:
|
||||
return false;
|
||||
default:
|
||||
LOG_ERROR("simple_http_connection_handler::handle_char_out: Wrong state: " << m_state);
|
||||
LOG_ERROR("simple_http_connection_handler::handle_buff_in: Wrong state: " << m_state);
|
||||
return false;
|
||||
case http_state_error:
|
||||
LOG_ERROR("simple_http_connection_handler::handle_char_out: Error state!!!");
|
||||
LOG_ERROR("simple_http_connection_handler::handle_buff_in: Error state!!!");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -334,10 +345,10 @@ namespace net_utils
|
|||
template<class t_connection_context>
|
||||
bool simple_http_connection_handler<t_connection_context>::handle_invoke_query_line()
|
||||
{
|
||||
LOG_FRAME("simple_http_connection_handler<t_connection_context>::handle_recognize_protocol_out(*)", LOG_LEVEL_3);
|
||||
LOG_FRAME("simple_http_connection_handler<t_connection_context>::handle_invoke_query_line(*)", LOG_LEVEL_3);
|
||||
|
||||
STATIC_REGEXP_EXPR_1(rexp_match_command_line, "^(((OPTIONS)|(GET)|(HEAD)|(POST)|(PUT)|(DELETE)|(TRACE)) (\\S+) HTTP/(\\d+).(\\d+))\r?\n", boost::regex::icase | boost::regex::normal);
|
||||
// 123 4 5 6 7 8 9 10 11 12
|
||||
// 123 4 5 6 7 8 9 10 11 12
|
||||
//size_t match_len = 0;
|
||||
boost::smatch result;
|
||||
if(boost::regex_search(m_cache, result, rexp_match_command_line, boost::match_default) && result[0].matched)
|
||||
|
|
@ -682,4 +693,4 @@ namespace net_utils
|
|||
POP_WARNINGS
|
||||
//--------------------------------------------------------------------------------------------
|
||||
//--------------------------------------------------------------------------------------------
|
||||
//--------------------------------------------------------------------------------------------
|
||||
//--------------------------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -701,6 +701,11 @@ namespace epee
|
|||
#define CRITICAL_REGION_BEGIN1(x) CRITICAL_REGION_BEGIN_VAR(x, critical_region_var1)
|
||||
#define CRITICAL_REGION_END() }
|
||||
|
||||
#define SHARED_CRITICAL_REGION_LOCAL(x) boost::shared_lock< boost::shared_mutex > critical_region_var(x)
|
||||
#define EXCLUSIVE_CRITICAL_REGION_LOCAL(x) boost::unique_lock< boost::shared_mutex > critical_region_var(x)
|
||||
|
||||
#define SHARED_CRITICAL_REGION_BEGIN(x) { SHARED_CRITICAL_REGION_LOCAL(x)
|
||||
#define EXCLUSIVE_CRITICAL_REGION_BEGIN(x) { EXCLUSIVE_CRITICAL_REGION_LOCAL(x)
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ add_library(common ${COMMON})
|
|||
add_dependencies(common version ${PCH_LIB_NAME})
|
||||
ENABLE_SHARED_PCH(COMMON)
|
||||
|
||||
if(NOT MSVC AND NOT APPLE)
|
||||
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)
|
||||
endif()
|
||||
|
||||
|
|
|
|||
36
src/common/crypto_stream_operators.h
Normal file
36
src/common/crypto_stream_operators.h
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
// Copyright (c) 2018-2019 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 <string>
|
||||
#include <sstream>
|
||||
#include "include_base_utils.h"
|
||||
#include "crypto/crypto.h"
|
||||
#include "crypto/hash.h"
|
||||
//------
|
||||
bool parse_hash256(const std::string str_hash, crypto::hash& hash);
|
||||
template <class T>
|
||||
std::ostream &print256(std::ostream &o, const T &v) {
|
||||
return o << "<" << epee::string_tools::pod_to_hex(v) << ">";
|
||||
}
|
||||
|
||||
template <class T>
|
||||
std::ostream &print16(std::ostream &o, const T &v) {
|
||||
return o << "<" << epee::string_tools::pod_to_hex(v).substr(0, 5) << "..>";
|
||||
}
|
||||
|
||||
template <class T>
|
||||
std::string print16(const T &v) {
|
||||
return std::string("<") + epee::string_tools::pod_to_hex(v).substr(0, 5) + "..>";
|
||||
}
|
||||
|
||||
|
||||
namespace crypto {
|
||||
inline std::ostream &operator <<(std::ostream &o, const crypto::public_key &v) { return print256(o, v); }
|
||||
inline std::ostream &operator <<(std::ostream &o, const crypto::secret_key &v) { return print256(o, v); }
|
||||
inline std::ostream &operator <<(std::ostream &o, const crypto::key_derivation &v) { return print256(o, v); }
|
||||
inline std::ostream &operator <<(std::ostream &o, const crypto::key_image &v) { return print256(o, v); }
|
||||
inline std::ostream &operator <<(std::ostream &o, const crypto::signature &v) { return print256(o, v); }
|
||||
inline std::ostream &operator <<(std::ostream &o, const crypto::hash &v) { return print256(o, v); }
|
||||
}
|
||||
|
|
@ -34,11 +34,13 @@
|
|||
// Copyright (c) 2014-2018 Zano Project
|
||||
// Copyright (c) 2014-2018 The Louisdor Project
|
||||
|
||||
|
||||
#include <cassert>
|
||||
#include <map>
|
||||
#include <cstdint>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include "mnemonic-encoding.h"
|
||||
#include "include_base_utils.h"
|
||||
|
||||
namespace tools
|
||||
{
|
||||
|
|
@ -3371,5 +3373,18 @@ namespace tools
|
|||
}
|
||||
return res;
|
||||
}
|
||||
std::string word_by_num(uint32_t n)
|
||||
{
|
||||
if (n >= NUMWORDS)
|
||||
return "";
|
||||
return wordsArray[n];
|
||||
}
|
||||
|
||||
uint64_t num_by_word(const std::string& w)
|
||||
{
|
||||
auto it = wordsMap.find(w);
|
||||
CHECK_AND_ASSERT_THROW_MES(it!= wordsMap.end(), "unable to find word \"" << w << "\" in mnemonic dictionary");
|
||||
return it->second;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,5 +42,7 @@ namespace tools
|
|||
{
|
||||
std::vector<unsigned char> text2binary(const std::string& text);
|
||||
std::string binary2text(const std::vector<unsigned char>& binary);
|
||||
std::string word_by_num(uint32_t n);
|
||||
uint64_t num_by_word(const std::string& w);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "include_base_utils.h"
|
||||
#include "zlib_helper.h"
|
||||
using namespace epee;
|
||||
|
||||
#include "util.h"
|
||||
|
|
@ -526,4 +527,65 @@ std::string get_nix_version_display_string()
|
|||
#endif
|
||||
return std::error_code(code, std::system_category());
|
||||
}
|
||||
|
||||
#define REQUEST_LOG_CHUNK_SIZE_MAX (10 * 1024 * 1024)
|
||||
|
||||
bool get_log_chunk_gzipped(uint64_t offset, uint64_t size, std::string& output, std::string& error)
|
||||
{
|
||||
if (size > REQUEST_LOG_CHUNK_SIZE_MAX)
|
||||
{
|
||||
error = std::string("size is exceeding the limit = ") + epee::string_tools::num_to_string_fast(REQUEST_LOG_CHUNK_SIZE_MAX);
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string log_filename = epee::log_space::log_singletone::get_actual_log_file_path();
|
||||
if (std::ifstream log{ log_filename, std::ifstream::ate | std::ifstream::binary })
|
||||
{
|
||||
uint64_t file_size = log.tellg();
|
||||
|
||||
if (offset >= file_size)
|
||||
{
|
||||
error = "offset is out of bounds";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (offset + size > file_size)
|
||||
{
|
||||
error = "offset + size if out of bounds";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (size != 0)
|
||||
{
|
||||
log.seekg(offset);
|
||||
output.resize(size);
|
||||
log.read(&output.front(), size);
|
||||
uint64_t read_bytes = log.gcount();
|
||||
if (read_bytes != size)
|
||||
{
|
||||
error = std::string("read bytes: ") + epee::string_tools::num_to_string_fast(read_bytes);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!epee::zlib_helper::pack(output))
|
||||
{
|
||||
error = "zlib pack failed";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
error = std::string("can't open ") + log_filename;
|
||||
return false;
|
||||
}
|
||||
|
||||
uint64_t get_log_file_size()
|
||||
{
|
||||
std::string log_filename = epee::log_space::log_singletone::get_actual_log_file_path();
|
||||
std::ifstream in(log_filename, std::ifstream::ate | std::ifstream::binary);
|
||||
return static_cast<uint64_t>(in.tellg());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,6 +48,8 @@ namespace tools
|
|||
return k;
|
||||
}
|
||||
|
||||
bool get_log_chunk_gzipped(uint64_t offset, uint64_t size, std::string& output, std::string& error);
|
||||
uint64_t get_log_file_size();
|
||||
|
||||
class signal_handler
|
||||
{
|
||||
|
|
|
|||
|
|
@ -54,6 +54,8 @@ namespace
|
|||
const command_line::arg_descriptor<std::string> arg_generate_genesis = {"generate-genesis", "Generate genesis coinbase based on config file", "", true };
|
||||
const command_line::arg_descriptor<uint64_t> arg_genesis_split_amount = { "genesis-split-amount", "Set split amount for generating genesis block", 0, true };
|
||||
const command_line::arg_descriptor<std::string> arg_get_info_flags = { "getinfo-flags-hex", "Set of bits for rpc-get-daemon-info", "", true };
|
||||
const command_line::arg_descriptor<int64_t> arg_set_peer_log_level = { "set-peer-log-level", "Set log level for remote peer", 0, true };
|
||||
const command_line::arg_descriptor<uint64_t> arg_download_peer_log = { "download-peer-log", "Download log from remote peer (starting offset)", 0, true };
|
||||
}
|
||||
|
||||
typedef COMMAND_REQUEST_STAT_INFO_T<t_currency_protocol_handler<core>::stat_info> COMMAND_REQUEST_STAT_INFO;
|
||||
|
|
@ -839,7 +841,166 @@ bool generate_and_print_keys()
|
|||
<< "PRIVATE KEY: " << epee::string_tools::pod_to_hex(sk);
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
template<class command_t>
|
||||
bool invoke_debug_command(po::variables_map& vm, const crypto::secret_key& sk, levin::levin_client_impl2& transport, peerid_type& peer_id, typename command_t::request& req, typename command_t::response& rsp)
|
||||
{
|
||||
if (!transport.is_connected())
|
||||
{
|
||||
if (!transport.connect(command_line::get_arg(vm, arg_ip), static_cast<int>(command_line::get_arg(vm, arg_port)), static_cast<int>(command_line::get_arg(vm, arg_timeout))))
|
||||
{
|
||||
std::cout << "{" << ENDL << " \"status\": \"ERROR: " << "Failed to connect to " << command_line::get_arg(vm, arg_ip) << ":" << command_line::get_arg(vm, arg_port) << "\"" << ENDL << "}" << ENDL;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!peer_id)
|
||||
{
|
||||
COMMAND_REQUEST_PEER_ID::request id_req = AUTO_VAL_INIT(id_req);
|
||||
COMMAND_REQUEST_PEER_ID::response id_rsp = AUTO_VAL_INIT(id_rsp);
|
||||
if (!net_utils::invoke_remote_command2(COMMAND_REQUEST_PEER_ID::ID, id_req, id_rsp, transport))
|
||||
{
|
||||
std::cout << "{" << ENDL << " \"status\": \"ERROR: " << "Failed to connect to " << command_line::get_arg(vm, arg_ip) << ":" << command_line::get_arg(vm, arg_port) << "\"" << ENDL << "}" << ENDL;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
peer_id = id_rsp.my_id;
|
||||
}
|
||||
}
|
||||
|
||||
nodetool::proof_of_trust pot = AUTO_VAL_INIT(pot);
|
||||
pot.peer_id = peer_id;
|
||||
pot.time = time(NULL);
|
||||
crypto::public_key pubk = AUTO_VAL_INIT(pubk);
|
||||
string_tools::hex_to_pod(P2P_MAINTAINERS_PUB_KEY, pubk);
|
||||
crypto::hash h = tools::get_proof_of_trust_hash(pot);
|
||||
crypto::generate_signature(h, pubk, sk, pot.sign);
|
||||
|
||||
req.tr = pot;
|
||||
|
||||
return net_utils::invoke_remote_command2(command_t::ID, req, rsp, transport);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
bool handle_set_peer_log_level(po::variables_map& vm)
|
||||
{
|
||||
crypto::secret_key sk = AUTO_VAL_INIT(sk);
|
||||
if (!get_private_key(sk, vm))
|
||||
{
|
||||
std::cout << "ERROR: secret key error" << ENDL;
|
||||
return false;
|
||||
}
|
||||
|
||||
int64_t log_level = command_line::get_arg(vm, arg_set_peer_log_level);
|
||||
if (log_level < LOG_LEVEL_0 || log_level > LOG_LEVEL_MAX)
|
||||
{
|
||||
std::cout << "Error: invalid log level value: " << log_level << ENDL;
|
||||
return false;
|
||||
}
|
||||
|
||||
levin::levin_client_impl2 transport;
|
||||
peerid_type peer_id = 0;
|
||||
|
||||
COMMAND_SET_LOG_LEVEL::request req = AUTO_VAL_INIT(req);
|
||||
req.new_log_level = log_level;
|
||||
|
||||
COMMAND_SET_LOG_LEVEL::response rsp = AUTO_VAL_INIT(rsp);
|
||||
if (!invoke_debug_command<COMMAND_SET_LOG_LEVEL>(vm, sk, transport, peer_id, req, rsp))
|
||||
{
|
||||
std::cout << "ERROR: invoking COMMAND_SET_LOG_LEVEL failed" << ENDL;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::cout << "OK! Log level changed: " << rsp.old_log_level << " -> " << rsp.current_log_level << ENDL;
|
||||
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
bool handle_download_peer_log(po::variables_map& vm)
|
||||
{
|
||||
crypto::secret_key sk = AUTO_VAL_INIT(sk);
|
||||
if (!get_private_key(sk, vm))
|
||||
{
|
||||
std::cout << "ERROR: secret key error" << ENDL;
|
||||
return false;
|
||||
}
|
||||
|
||||
uint64_t start_offset = command_line::get_arg(vm, arg_download_peer_log);
|
||||
|
||||
levin::levin_client_impl2 transport;
|
||||
peerid_type peer_id = 0;
|
||||
|
||||
COMMAND_REQUEST_LOG::request req = AUTO_VAL_INIT(req);
|
||||
COMMAND_REQUEST_LOG::response rsp = AUTO_VAL_INIT(rsp);
|
||||
if (!invoke_debug_command<COMMAND_REQUEST_LOG>(vm, sk, transport, peer_id, req, rsp) || !rsp.error.empty())
|
||||
{
|
||||
std::cout << "ERROR: invoking COMMAND_REQUEST_LOG failed: " << rsp.error << ENDL;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::cout << "Current log level: " << rsp.current_log_level << ENDL;
|
||||
std::cout << "Current log size: " << rsp.current_log_size << ENDL;
|
||||
|
||||
if (start_offset >= rsp.current_log_size)
|
||||
{
|
||||
std::cout << "ERROR: invalid start offset: " << start_offset << ", log size: " << rsp.current_log_size << ENDL;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::cout << "Downloading..." << ENDL;
|
||||
|
||||
std::string local_filename = tools::get_default_data_dir() + "/log_" + epee::string_tools::num_to_string_fast(peer_id) + ".log";
|
||||
std::ofstream log{ local_filename, std::ifstream::binary };
|
||||
if (!log)
|
||||
{
|
||||
std::cout << "Couldn't open " << local_filename << " for writing." << ENDL;
|
||||
return false;
|
||||
}
|
||||
|
||||
const uint64_t chunk_size = 1024 * 1024 * 5;
|
||||
uint64_t end_offset = start_offset;
|
||||
uint64_t bytes = 0;
|
||||
while (true)
|
||||
{
|
||||
req.log_chunk_offset = end_offset;
|
||||
req.log_chunk_size = std::min(chunk_size, rsp.current_log_size - req.log_chunk_offset);
|
||||
if (req.log_chunk_size == 0)
|
||||
break;
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
|
||||
if (!invoke_debug_command<COMMAND_REQUEST_LOG>(vm, sk, transport, peer_id, req, rsp) || !rsp.error.empty())
|
||||
{
|
||||
std::cout << "ERROR: invoking COMMAND_REQUEST_LOG failed: " << rsp.error << ENDL;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!epee::zlib_helper::unpack(rsp.log_chunk))
|
||||
{
|
||||
std::cout << "ERROR: zip unpack failed" << ENDL;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (rsp.log_chunk.size() != req.log_chunk_size)
|
||||
{
|
||||
std::cout << "ERROR: unpacked size: " << rsp.log_chunk.size() << ", requested: " << req.log_chunk_size << ENDL;
|
||||
return false;
|
||||
}
|
||||
|
||||
log.write(rsp.log_chunk.c_str(), rsp.log_chunk.size());
|
||||
|
||||
end_offset += req.log_chunk_size;
|
||||
|
||||
std::cout << end_offset - start_offset << " bytes downloaded" << ENDL;
|
||||
}
|
||||
|
||||
std::cout << "Remote log from offset " << start_offset << " to offset " << end_offset << " (" << end_offset - start_offset << " bytes) " <<
|
||||
"was successfully downloaded to " << local_filename;
|
||||
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
|
||||
|
|
@ -874,7 +1035,9 @@ int main(int argc, char* argv[])
|
|||
command_line::add_arg(desc_params, arg_genesis_split_amount);
|
||||
command_line::add_arg(desc_params, arg_get_info_flags);
|
||||
command_line::add_arg(desc_params, arg_log_journal_len);
|
||||
|
||||
command_line::add_arg(desc_params, arg_set_peer_log_level);
|
||||
command_line::add_arg(desc_params, arg_download_peer_log);
|
||||
|
||||
|
||||
|
||||
po::options_description desc_all;
|
||||
|
|
@ -931,6 +1094,14 @@ int main(int argc, char* argv[])
|
|||
{
|
||||
return generate_genesis(command_line::get_arg(vm, arg_generate_genesis), 10000000000000000) ? 0 : 1;
|
||||
}
|
||||
else if (command_line::has_arg(vm, arg_set_peer_log_level))
|
||||
{
|
||||
return handle_set_peer_log_level(vm) ? 0 : 1;
|
||||
}
|
||||
else if (command_line::has_arg(vm, arg_download_peer_log))
|
||||
{
|
||||
return handle_download_peer_log(vm) ? 0 : 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Not enough arguments." << ENDL;
|
||||
|
|
|
|||
|
|
@ -77,27 +77,16 @@ namespace crypto {
|
|||
memcpy(&res, tmp, 32);
|
||||
}
|
||||
|
||||
void crypto_ops::keys_from_short(unsigned char* a_part, public_key &pub, secret_key &sec)
|
||||
void crypto_ops::keys_from_default(unsigned char* a_part, public_key &pub, secret_key &sec, size_t brain_wallet_seed_size)
|
||||
{
|
||||
unsigned char tmp[64] = { 0 };
|
||||
static_assert(sizeof tmp >= BRAINWALLET_SHORT_SEED_SIZE, "size mismatch");
|
||||
memcpy(tmp, a_part, BRAINWALLET_SHORT_SEED_SIZE);
|
||||
|
||||
cn_fast_hash(tmp, 16, (char*)&tmp[16]);
|
||||
cn_fast_hash(tmp, 32, (char*)&tmp[32]);
|
||||
if (!(sizeof(tmp) >= brain_wallet_seed_size))
|
||||
{
|
||||
throw std::runtime_error("size mismatch");
|
||||
}
|
||||
|
||||
sc_reduce(tmp);
|
||||
memcpy(&sec, tmp, 32);
|
||||
ge_p3 point;
|
||||
ge_scalarmult_base(&point, &sec);
|
||||
ge_p3_tobytes(&pub, &point);
|
||||
}
|
||||
|
||||
void crypto_ops::keys_from_default(unsigned char* a_part, public_key &pub, secret_key &sec)
|
||||
{
|
||||
unsigned char tmp[64] = { 0 };
|
||||
static_assert(sizeof tmp >= BRAINWALLET_DEFAULT_SEED_SIZE, "size mismatch");
|
||||
memcpy(tmp, a_part, BRAINWALLET_DEFAULT_SEED_SIZE);
|
||||
memcpy(tmp, a_part, brain_wallet_seed_size);
|
||||
|
||||
cn_fast_hash(tmp, 32, (char*)&tmp[32]);
|
||||
|
||||
|
|
@ -108,12 +97,14 @@ namespace crypto {
|
|||
ge_p3_tobytes(&pub, &point);
|
||||
}
|
||||
|
||||
void crypto_ops::generate_brain_keys(public_key &pub, secret_key &sec, std::string& seed)
|
||||
void crypto_ops::generate_brain_keys(public_key &pub, secret_key &sec, std::string& seed, size_t brain_wallet_seed_size)
|
||||
{
|
||||
unsigned char tmp[BRAINWALLET_DEFAULT_SEED_SIZE];
|
||||
generate_random_bytes(BRAINWALLET_DEFAULT_SEED_SIZE, tmp);
|
||||
seed.assign((const char*)tmp, BRAINWALLET_DEFAULT_SEED_SIZE);
|
||||
keys_from_default(tmp, pub, sec);
|
||||
std::vector<unsigned char> tmp_vector;
|
||||
tmp_vector.resize(brain_wallet_seed_size, 0);
|
||||
unsigned char *tmp = &tmp_vector[0];
|
||||
generate_random_bytes(brain_wallet_seed_size, tmp);
|
||||
seed.assign((const char*)tmp, brain_wallet_seed_size);
|
||||
keys_from_default(tmp, pub, sec, brain_wallet_seed_size);
|
||||
}
|
||||
|
||||
static inline void hash_to_scalar(const void *data, size_t length, ec_scalar &res)
|
||||
|
|
|
|||
|
|
@ -20,8 +20,6 @@
|
|||
PUSH_WARNINGS
|
||||
DISABLE_CLANG_WARNING(unused-private-field)
|
||||
|
||||
#define BRAINWALLET_DEFAULT_SEED_SIZE 32
|
||||
#define BRAINWALLET_SHORT_SEED_SIZE 16
|
||||
|
||||
namespace crypto {
|
||||
|
||||
|
|
@ -75,12 +73,10 @@ namespace crypto {
|
|||
|
||||
static void generate_keys(public_key &, secret_key &);
|
||||
friend void generate_keys(public_key &, secret_key &);
|
||||
static void generate_brain_keys(public_key &, secret_key &, std::string& seed);
|
||||
friend void generate_brain_keys(public_key &, secret_key &, std::string& seed);
|
||||
static void keys_from_short(unsigned char* a_part, public_key &pub, secret_key &sec);
|
||||
friend void keys_from_short(unsigned char* a_part, public_key &pub, secret_key &sec);
|
||||
static void keys_from_default(unsigned char* a_part, public_key &pub, secret_key &sec);
|
||||
friend void keys_from_default(unsigned char* a_part, public_key &pub, secret_key &sec);
|
||||
static void generate_brain_keys(public_key &, secret_key &, std::string& seed, size_t brain_wallet_seed_size);
|
||||
friend void generate_brain_keys(public_key &, secret_key &, std::string& seed, size_t brain_wallet_seed_size);
|
||||
static void keys_from_default(unsigned char* a_part, public_key &pub, secret_key &sec, size_t brain_wallet_seed_size);
|
||||
friend void keys_from_default(unsigned char* a_part, public_key &pub, secret_key &sec, size_t brain_wallet_seed_size);
|
||||
static void dependent_key(const secret_key& first, secret_key& second);
|
||||
friend void dependent_key(const secret_key& first, secret_key& second);
|
||||
static bool check_key(const public_key &);
|
||||
|
|
@ -139,19 +135,14 @@ namespace crypto {
|
|||
crypto_ops::generate_keys(pub, sec);
|
||||
}
|
||||
|
||||
inline void generate_brain_keys(public_key &pub, secret_key &sec, std::string& seed) {
|
||||
crypto_ops::generate_brain_keys(pub, sec, seed);
|
||||
}
|
||||
|
||||
inline void keys_from_short(unsigned char* a_part, public_key &pub, secret_key &sec)
|
||||
{
|
||||
crypto_ops::keys_from_short(a_part, pub, sec);
|
||||
inline void generate_brain_keys(public_key &pub, secret_key &sec, std::string& seed, size_t brain_wallet_seed_size) {
|
||||
crypto_ops::generate_brain_keys(pub, sec, seed, brain_wallet_seed_size);
|
||||
}
|
||||
|
||||
|
||||
inline void keys_from_default(unsigned char* a_part, public_key &pub, secret_key &sec)
|
||||
inline void keys_from_default(unsigned char* a_part, public_key &pub, secret_key &sec, size_t brain_wallet_seed_size)
|
||||
{
|
||||
crypto_ops::keys_from_default(a_part, pub, sec);
|
||||
crypto_ops::keys_from_default(a_part, pub, sec, brain_wallet_seed_size);
|
||||
}
|
||||
|
||||
inline void dependent_key(const secret_key& first, secret_key& second){
|
||||
|
|
|
|||
|
|
@ -41,9 +41,8 @@ namespace currency
|
|||
}
|
||||
//-----------------------------------------------------------------
|
||||
void account_base::generate()
|
||||
{
|
||||
//generate_keys(m_keys.m_account_address.m_spend_public_key, m_keys.m_spend_secret_key);
|
||||
generate_brain_keys(m_keys.m_account_address.m_spend_public_key, m_keys.m_spend_secret_key, m_seed);
|
||||
{
|
||||
generate_brain_keys(m_keys.m_account_address.m_spend_public_key, m_keys.m_spend_secret_key, m_seed, BRAINWALLET_DEFAULT_SEED_SIZE);
|
||||
dependent_key(m_keys.m_spend_secret_key, m_keys.m_view_secret_key);
|
||||
if (!crypto::secret_key_to_public_key(m_keys.m_view_secret_key, m_keys.m_account_address.m_view_public_key))
|
||||
throw std::runtime_error("Failed to create public view key");
|
||||
|
|
@ -62,12 +61,16 @@ namespace currency
|
|||
return m_seed;
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
std::string account_base::get_restore_braindata() const
|
||||
{
|
||||
std::string restore_buff = get_restore_data();
|
||||
std::vector<unsigned char> v;
|
||||
v.assign((unsigned char*)restore_buff.data(), (unsigned char*)restore_buff.data() + restore_buff.size());
|
||||
return tools::mnemonic_encoding::binary2text(v);
|
||||
std::string seed_brain_data = tools::mnemonic_encoding::binary2text(v);
|
||||
std::string timestamp_word = currency::get_word_from_timstamp(m_creation_timestamp);
|
||||
seed_brain_data = seed_brain_data + timestamp_word;
|
||||
return seed_brain_data;
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
bool account_base::restore_keys(const std::string& restore_data)
|
||||
|
|
@ -75,11 +78,7 @@ namespace currency
|
|||
//CHECK_AND_ASSERT_MES(restore_data.size() == ACCOUNT_RESTORE_DATA_SIZE, false, "wrong restore data size");
|
||||
if (restore_data.size() == BRAINWALLET_DEFAULT_SEED_SIZE)
|
||||
{
|
||||
crypto::keys_from_default((unsigned char*)restore_data.data(), m_keys.m_account_address.m_spend_public_key, m_keys.m_spend_secret_key);
|
||||
}
|
||||
else if(restore_data.size() == BRAINWALLET_SHORT_SEED_SIZE)
|
||||
{
|
||||
crypto::keys_from_short((unsigned char*)restore_data.data(), m_keys.m_account_address.m_spend_public_key, m_keys.m_spend_secret_key);
|
||||
crypto::keys_from_default((unsigned char*)restore_data.data(), m_keys.m_account_address.m_spend_public_key, m_keys.m_spend_secret_key, BRAINWALLET_DEFAULT_SEED_SIZE);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -94,15 +93,27 @@ namespace currency
|
|||
return true;
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
bool account_base::restore_keys_from_braindata(const std::string& restore_data)
|
||||
bool account_base::restore_keys_from_braindata(const std::string& restore_data_)
|
||||
{
|
||||
//cut the last timestamp word from restore_dats
|
||||
std::list<std::string> words;
|
||||
boost::split(words, restore_data_, boost::is_space());
|
||||
CHECK_AND_ASSERT_THROW_MES(words.size() == BRAINWALLET_DEFAULT_WORDS_COUNT, "Words count missmatch: " << words.size());
|
||||
|
||||
std::string timestamp_word = words.back();
|
||||
words.erase(--words.end());
|
||||
|
||||
std::string restore_data_local = boost::algorithm::join(words, " ");
|
||||
|
||||
std::vector<unsigned char> bin = tools::mnemonic_encoding::text2binary(restore_data);
|
||||
std::vector<unsigned char> bin = tools::mnemonic_encoding::text2binary(restore_data_local);
|
||||
if (!bin.size())
|
||||
return false;
|
||||
|
||||
std::string restore_buff((const char*)&bin[0], bin.size());
|
||||
return restore_keys(restore_buff);
|
||||
bool r = restore_keys(restore_buff);
|
||||
CHECK_AND_ASSERT_MES(r, false, "restore_keys failed");
|
||||
m_creation_timestamp = get_timstamp_from_word(timestamp_word);
|
||||
return true;
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
std::string account_base::get_public_address_str()
|
||||
|
|
|
|||
|
|
@ -10,9 +10,9 @@
|
|||
#include "crypto/crypto.h"
|
||||
#include "serialization/keyvalue_serialization.h"
|
||||
|
||||
|
||||
#define BRAINWALLET_DEFAULT_SEED_SIZE 32
|
||||
#define ACCOUNT_RESTORE_DATA_SIZE BRAINWALLET_DEFAULT_SEED_SIZE
|
||||
|
||||
#define BRAINWALLET_DEFAULT_WORDS_COUNT 25
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -4254,7 +4254,7 @@ bool blockchain_storage::handle_block_to_main_chain(const block& bl, const crypt
|
|||
return false;
|
||||
}
|
||||
|
||||
uint64_t h = get_block_height(bl);
|
||||
get_block_height(bl);
|
||||
|
||||
if(!check_block_timestamp_main(bl))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -155,6 +155,10 @@
|
|||
#define WALLET_FILE_SIGNATURE 0x1111012101101011LL //Bender's nightmare
|
||||
#define WALLET_FILE_MAX_BODY_SIZE 0x88888888L //2GB
|
||||
#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,
|
||||
//which let us to address tools::mnemonic_encoding::NUMWORDS weeks after project launch
|
||||
//which is about 30 years
|
||||
|
||||
#define OFFER_MAXIMUM_LIFE_TIME (60*60*24*30) // 30 days
|
||||
|
||||
|
|
|
|||
|
|
@ -26,54 +26,18 @@ using namespace epee;
|
|||
#include "bc_attachments_helpers.h"
|
||||
#include "genesis.h"
|
||||
#include "genesis_acc.h"
|
||||
#include "common/mnemonic-encoding.h"
|
||||
|
||||
namespace currency
|
||||
{
|
||||
//---------------------------------------------------------------
|
||||
void get_transaction_prefix_hash(const transaction_prefix& tx, crypto::hash& h)
|
||||
{
|
||||
std::ostringstream s;
|
||||
binary_archive<true> a(s);
|
||||
::serialization::serialize(a, const_cast<transaction_prefix&>(tx));
|
||||
std::string data = s.str();
|
||||
crypto::cn_fast_hash(data.data(), data.size(), h);
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
crypto::hash get_transaction_prefix_hash(const transaction_prefix& tx)
|
||||
{
|
||||
crypto::hash h = null_hash;
|
||||
get_transaction_prefix_hash(tx, h);
|
||||
return h;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
bool parse_and_validate_tx_from_blob(const blobdata& tx_blob, transaction& tx)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << tx_blob;
|
||||
binary_archive<false> ba(ss);
|
||||
bool r = ::serialization::serialize(ba, tx);
|
||||
CHECK_AND_ASSERT_MES(r, false, "Failed to parse transaction from blob");
|
||||
return true;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------
|
||||
bool add_tx_extra_alias(transaction& tx, const extra_alias_entry& alinfo)
|
||||
{
|
||||
tx.extra.push_back(alinfo);
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
bool parse_and_validate_tx_from_blob(const blobdata& tx_blob, transaction& tx, crypto::hash& tx_hash)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << tx_blob;
|
||||
binary_archive<false> ba(ss);
|
||||
bool r = ::serialization::serialize(ba, tx);
|
||||
CHECK_AND_ASSERT_MES(r, false, "Failed to parse transaction from blob");
|
||||
//TODO: validate tx
|
||||
|
||||
//crypto::cn_fast_hash(tx_blob.data(), tx_blob.size(), tx_hash);
|
||||
get_transaction_prefix_hash(tx, tx_hash);
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
/*
|
||||
bool construct_miner_tx(size_t height, size_t median_size, uint64_t already_generated_coins,
|
||||
|
|
@ -1246,6 +1210,24 @@ namespace currency
|
|||
return reward;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
std::string get_word_from_timstamp(uint64_t timestamp)
|
||||
{
|
||||
uint64_t date_offset = timestamp ? timestamp - WALLET_BRAIN_DATE_OFFSET : 0;
|
||||
uint64_t weeks_count = date_offset / WALLET_BRAIN_DATE_QUANTUM;
|
||||
CHECK_AND_ASSERT_THROW_MES(weeks_count < std::numeric_limits<uint32_t>::max(), "internal error: unable to converto to uint32, val = " << weeks_count);
|
||||
uint32_t weeks_count_32 = static_cast<uint32_t>(weeks_count);
|
||||
|
||||
return tools::mnemonic_encoding::word_by_num(weeks_count_32);
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
uint64_t get_timstamp_from_word(std::string word)
|
||||
{
|
||||
uint64_t count_of_weeks = tools::mnemonic_encoding::num_by_word(word);
|
||||
uint64_t timestamp = count_of_weeks * WALLET_BRAIN_DATE_QUANTUM + WALLET_BRAIN_DATE_OFFSET;
|
||||
|
||||
return timestamp;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
bool sign_multisig_input_in_tx(currency::transaction& tx, size_t ms_input_index, const currency::account_keys& keys, const currency::transaction& source_tx, bool *p_is_input_fully_signed /* = nullptr */)
|
||||
{
|
||||
#define LOC_CHK(cond, msg) CHECK_AND_ASSERT_MES(cond, false, msg << ", ms input index: " << ms_input_index << ", tx: " << get_transaction_hash(tx) << ", source tx: " << get_transaction_hash(source_tx))
|
||||
|
|
@ -1620,11 +1602,7 @@ namespace currency
|
|||
att.push_back(tsa);
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
void get_blob_hash(const blobdata& blob, crypto::hash& res)
|
||||
{
|
||||
cn_fast_hash(blob.data(), blob.size(), res);
|
||||
}
|
||||
|
||||
|
||||
std::string print_fixed_decimal_point(uint64_t amount, size_t decimal_point)
|
||||
{
|
||||
|
|
@ -1648,32 +1626,6 @@ namespace currency
|
|||
return std::to_string(amount) + '.' + r.substr(0, r.find_last_not_of('0') + 1);
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
crypto::hash get_blob_hash(const blobdata& blob)
|
||||
{
|
||||
crypto::hash h = null_hash;
|
||||
get_blob_hash(blob, h);
|
||||
return h;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
crypto::hash get_transaction_hash(const transaction& t)
|
||||
{
|
||||
return get_transaction_prefix_hash(t);
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
bool get_transaction_hash(const transaction& t, crypto::hash& res)
|
||||
{
|
||||
uint64_t blob_size = 0;
|
||||
return get_object_hash(static_cast<const transaction_prefix&>(t), res, blob_size);
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
bool get_transaction_hash(const transaction& t, crypto::hash& res, uint64_t& blob_size)
|
||||
{
|
||||
blob_size = 0;
|
||||
bool r = get_object_hash(static_cast<const transaction_prefix&>(t), res, blob_size);
|
||||
blob_size = get_object_blobsize(t, blob_size);
|
||||
return r;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
/*bool get_transaction_hash(const transaction& t, crypto::hash& res, size_t& blob_size)
|
||||
{
|
||||
|
||||
|
|
@ -1926,27 +1878,6 @@ namespace currency
|
|||
return ss.str();
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
blobdata get_block_hashing_blob(const block& b)
|
||||
{
|
||||
blobdata blob = t_serializable_object_to_blob(static_cast<block_header>(b));
|
||||
crypto::hash tree_root_hash = get_tx_tree_hash(b);
|
||||
blob.append((const char*)&tree_root_hash, sizeof(tree_root_hash));
|
||||
blob.append(tools::get_varint_data(b.tx_hashes.size() + 1));
|
||||
return blob;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
bool get_block_hash(const block& b, crypto::hash& res)
|
||||
{
|
||||
return get_object_hash(get_block_hashing_blob(b), res);
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
crypto::hash get_block_hash(const block& b)
|
||||
{
|
||||
crypto::hash p = null_hash;
|
||||
get_block_hash(b, p);
|
||||
return p;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
bool generate_genesis_block(block& bl)
|
||||
{
|
||||
//genesis block
|
||||
|
|
@ -2052,101 +1983,9 @@ namespace currency
|
|||
//---------------------------------------------------------------
|
||||
bool parse_and_validate_block_from_blob(const blobdata& b_blob, block& b)
|
||||
{
|
||||
return t_unserializable_object_from_blob(b, b_blob);
|
||||
return parse_and_validate_object_from_blob(b_blob, b);
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
size_t get_object_blobsize(const transaction& t)
|
||||
{
|
||||
size_t tx_blob_size = get_object_blobsize(static_cast<const transaction_prefix&>(t));
|
||||
return get_object_blobsize(t, tx_blob_size);
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
size_t get_object_blobsize(const transaction& t, uint64_t prefix_blob_size)
|
||||
{
|
||||
size_t tx_blob_size = prefix_blob_size;
|
||||
|
||||
if (is_coinbase(t))
|
||||
return tx_blob_size;
|
||||
|
||||
// for purged tx, with empty signatures and attachments, this function should return the blob size
|
||||
// which the tx would have if the signatures and attachments were correctly filled with actual data
|
||||
|
||||
// 1. signatures
|
||||
bool separately_signed_tx = get_tx_flags(t) & TX_FLAG_SIGNATURE_MODE_SEPARATE;
|
||||
|
||||
tx_blob_size += tools::get_varint_packed_size(t.vin.size()); // size of transaction::signatures (equals to total inputs count)
|
||||
|
||||
for (size_t i = 0; i != t.vin.size(); i++)
|
||||
{
|
||||
size_t sig_count = get_input_expected_signatures_count(t.vin[i]);
|
||||
if (separately_signed_tx && i == t.vin.size() - 1)
|
||||
++sig_count; // count in one more signature for the last input in a complete separately signed tx
|
||||
tx_blob_size += tools::get_varint_packed_size(sig_count); // size of transaction::signatures[i]
|
||||
tx_blob_size += sizeof(crypto::signature) * sig_count; // size of signatures' data itself
|
||||
}
|
||||
|
||||
// 2. attachments (try to find extra_attachment_info in tx prefix and count it in if succeed)
|
||||
extra_attachment_info eai = AUTO_VAL_INIT(eai);
|
||||
bool got_eai = false;
|
||||
if (separately_signed_tx)
|
||||
{
|
||||
// for separately-signed tx, try to obtain extra_attachment_info from the last input's etc_details
|
||||
const std::vector<txin_etc_details_v>* p_etc_details = get_input_etc_details(t.vin.back());
|
||||
got_eai = p_etc_details != nullptr && get_type_in_variant_container(*p_etc_details, eai);
|
||||
}
|
||||
if (!got_eai)
|
||||
got_eai = get_type_in_variant_container(t.extra, eai); // then from the extra
|
||||
|
||||
if (got_eai)
|
||||
tx_blob_size += eai.sz; // sz is a size of whole serialized attachment blob, including attachments vector size
|
||||
else
|
||||
tx_blob_size += tools::get_varint_packed_size(static_cast<size_t>(0)); // no extra_attachment_info found - just add zero vector's size, 'cause it's serialized anyway
|
||||
|
||||
return tx_blob_size;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
blobdata block_to_blob(const block& b)
|
||||
{
|
||||
return t_serializable_object_to_blob(b);
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
bool block_to_blob(const block& b, blobdata& b_blob)
|
||||
{
|
||||
return t_serializable_object_to_blob(b, b_blob);
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
blobdata tx_to_blob(const transaction& tx)
|
||||
{
|
||||
return t_serializable_object_to_blob(tx);
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
bool tx_to_blob(const transaction& tx, blobdata& b_blob)
|
||||
{
|
||||
return t_serializable_object_to_blob(tx, b_blob);
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
void get_tx_tree_hash(const std::vector<crypto::hash>& tx_hashes, crypto::hash& h)
|
||||
{
|
||||
tree_hash(tx_hashes.data(), tx_hashes.size(), h);
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
crypto::hash get_tx_tree_hash(const std::vector<crypto::hash>& tx_hashes)
|
||||
{
|
||||
crypto::hash h = null_hash;
|
||||
get_tx_tree_hash(tx_hashes, h);
|
||||
return h;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
crypto::hash get_tx_tree_hash(const block& b)
|
||||
{
|
||||
std::vector<crypto::hash> txs_ids;
|
||||
crypto::hash h = null_hash;
|
||||
get_transaction_hash(b.miner_tx, h);
|
||||
txs_ids.push_back(h);
|
||||
BOOST_FOREACH(auto& th, b.tx_hashes)
|
||||
txs_ids.push_back(th);
|
||||
return get_tx_tree_hash(txs_ids);
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
bool is_service_tx(const transaction& tx)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -11,10 +11,12 @@
|
|||
#include <unordered_set>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "currency_protocol/currency_protocol_defs.h"
|
||||
|
||||
#include "account.h"
|
||||
#include "include_base_utils.h"
|
||||
|
||||
#include "currency_format_utils_abstract.h"
|
||||
#include "common/crypto_stream_operators.h"
|
||||
#include "currency_protocol/currency_protocol_defs.h"
|
||||
#include "crypto/crypto.h"
|
||||
#include "crypto/hash.h"
|
||||
#include "difficulty.h"
|
||||
|
|
@ -23,6 +25,8 @@
|
|||
#include "bc_payments_id_service.h"
|
||||
#include "bc_attachments_helpers_basic.h"
|
||||
#include "blockchain_storage_basic.h"
|
||||
#include "currency_format_utils_blocks.h"
|
||||
#include "currency_format_utils_transactions.h"
|
||||
|
||||
// ------ get_tx_type_definition -------------
|
||||
#define GUI_TX_TYPE_NORMAL 0
|
||||
|
|
@ -42,31 +46,8 @@
|
|||
|
||||
|
||||
|
||||
//------
|
||||
bool parse_hash256(const std::string str_hash, crypto::hash& hash);
|
||||
template <class T>
|
||||
std::ostream &print256(std::ostream &o, const T &v) {
|
||||
return o << "<" << epee::string_tools::pod_to_hex(v) << ">";
|
||||
}
|
||||
|
||||
template <class T>
|
||||
std::ostream &print16(std::ostream &o, const T &v) {
|
||||
return o << "<" << epee::string_tools::pod_to_hex(v).substr(0, 5) << "..>";
|
||||
}
|
||||
|
||||
template <class T>
|
||||
std::string print16(const T &v) {
|
||||
return std::string("<") + epee::string_tools::pod_to_hex(v).substr(0, 5) + "..>";
|
||||
}
|
||||
|
||||
namespace crypto {
|
||||
inline std::ostream &operator <<(std::ostream &o, const crypto::public_key &v) { return print256(o, v); }
|
||||
inline std::ostream &operator <<(std::ostream &o, const crypto::secret_key &v) { return print256(o, v); }
|
||||
inline std::ostream &operator <<(std::ostream &o, const crypto::key_derivation &v) { return print256(o, v); }
|
||||
inline std::ostream &operator <<(std::ostream &o, const crypto::key_image &v) { return print256(o, v); }
|
||||
inline std::ostream &operator <<(std::ostream &o, const crypto::signature &v) { return print256(o, v); }
|
||||
inline std::ostream &operator <<(std::ostream &o, const crypto::hash &v) { return print256(o, v); }
|
||||
}
|
||||
|
||||
namespace currency
|
||||
{
|
||||
|
|
@ -182,10 +163,6 @@ namespace currency
|
|||
|
||||
|
||||
//---------------------------------------------------------------
|
||||
void get_transaction_prefix_hash(const transaction_prefix& tx, crypto::hash& h);
|
||||
crypto::hash get_transaction_prefix_hash(const transaction_prefix& tx);
|
||||
bool parse_and_validate_tx_from_blob(const blobdata& tx_blob, transaction& tx, crypto::hash& tx_hash);
|
||||
bool parse_and_validate_tx_from_blob(const blobdata& tx_blob, transaction& tx);
|
||||
bool construct_miner_tx(size_t height, size_t median_size, uint64_t already_generated_coins,
|
||||
size_t current_block_size,
|
||||
uint64_t fee,
|
||||
|
|
@ -234,14 +211,6 @@ namespace currency
|
|||
|
||||
bool is_tx_expired(const transaction& tx, uint64_t expiration_ts_median);
|
||||
|
||||
template<class t_type>
|
||||
std::string print_t_array(const std::vector<t_type>& vec)
|
||||
{
|
||||
std::stringstream ss;
|
||||
for (auto& v : vec)
|
||||
ss << v << " ";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
uint64_t get_string_uint64_hash(const std::string& str);
|
||||
bool construct_tx_out(const tx_destination_entry& de, const crypto::secret_key& tx_sec_key, size_t output_index, transaction& tx, std::set<uint16_t>& deriv_cache, uint8_t tx_outs_attr = CURRENCY_TO_KEY_OUT_RELAXED);
|
||||
|
|
@ -302,8 +271,6 @@ namespace currency
|
|||
bool generate_key_image_helper(const account_keys& ack, const crypto::public_key& tx_public_key, size_t real_output_index, keypair& in_ephemeral, crypto::key_image& ki);
|
||||
bool derive_public_key_from_target_address(const account_public_address& destination_addr, const crypto::secret_key& tx_sec_key, size_t index, crypto::public_key& out_eph_public_key, crypto::key_derivation& derivation);
|
||||
bool derive_public_key_from_target_address(const account_public_address& destination_addr, const crypto::secret_key& tx_sec_key, size_t index, crypto::public_key& out_eph_public_key);
|
||||
void get_blob_hash(const blobdata& blob, crypto::hash& res);
|
||||
crypto::hash get_blob_hash(const blobdata& blob);
|
||||
std::string short_hash_str(const crypto::hash& h);
|
||||
bool is_mixattr_applicable_for_fake_outs_counter(uint8_t mix_attr, uint64_t fake_attr_count);
|
||||
bool is_tx_spendtime_unlocked(uint64_t unlock_time, uint64_t current_blockchain_size, uint64_t current_time);
|
||||
|
|
@ -316,13 +283,7 @@ namespace currency
|
|||
|
||||
uint64_t get_reward_from_miner_tx(const transaction& tx);
|
||||
|
||||
crypto::hash get_transaction_hash(const transaction& t);
|
||||
bool get_transaction_hash(const transaction& t, crypto::hash& res);
|
||||
bool get_transaction_hash(const transaction& t, crypto::hash& res, uint64_t& blob_size);
|
||||
//bool get_transaction_hash(const transaction& t, crypto::hash& res, size_t& blob_size);
|
||||
blobdata get_block_hashing_blob(const block& b);
|
||||
bool get_block_hash(const block& b, crypto::hash& res);
|
||||
crypto::hash get_block_hash(const block& b);
|
||||
bool generate_genesis_block(block& bl);
|
||||
const crypto::hash& get_genesis_hash(bool need_to_set = false, const crypto::hash& h = null_hash);
|
||||
bool parse_and_validate_block_from_blob(const blobdata& b_blob, block& b);
|
||||
|
|
@ -389,18 +350,8 @@ namespace currency
|
|||
bool fill_tx_rpc_details(tx_rpc_extended_info& tei, const transaction& tx, const transaction_chain_entry* ptce, const crypto::hash& h, uint64_t timestamp, bool is_short = false);
|
||||
bool fill_block_rpc_details(block_rpc_extended_info& pei_rpc, const block_extended_info& bei_chain, const crypto::hash& h);
|
||||
void append_per_block_increments_for_tx(const transaction& tx, std::unordered_map<uint64_t, uint32_t>& gindices);
|
||||
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/************************************************************************/
|
||||
template<class t_array>
|
||||
struct array_hasher : std::unary_function<t_array&, std::size_t>
|
||||
{
|
||||
std::size_t operator()(const t_array& val) const
|
||||
{
|
||||
return boost::hash_range(&val.data[0], &val.data[sizeof(val.data)]);
|
||||
}
|
||||
};
|
||||
std::string get_word_from_timstamp(uint64_t timestamp);
|
||||
uint64_t get_timstamp_from_word(std::string word);
|
||||
|
||||
template<class t_txin_v>
|
||||
typename std::conditional<std::is_const<t_txin_v>::value, const std::vector<txin_etc_details_v>, std::vector<txin_etc_details_v> >::type& get_txin_etc_options(t_txin_v& in)
|
||||
|
|
@ -450,17 +401,6 @@ namespace currency
|
|||
bool have_attachment_service_in_container(const std::vector<attachment_v>& av, const std::string& service_id, const std::string& instruction);
|
||||
crypto::hash prepare_prefix_hash_for_sign(const transaction& tx, uint64_t in_index, const crypto::hash& tx_id);
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
template<class t_pod_type, class result_type>
|
||||
result_type get_pod_checksum(const t_pod_type& bl)
|
||||
{
|
||||
const unsigned char* pbuf = reinterpret_cast<const unsigned char*>(&bl);
|
||||
result_type summ = 0;
|
||||
for (size_t i = 0; i != sizeof(t_pod_type)-1; i++)
|
||||
summ += pbuf[i];
|
||||
|
||||
return summ;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
template<class tx_out_t>
|
||||
bool is_out_to_acc(const account_keys& acc, const tx_out_t& out_key, const crypto::public_key& tx_pub_key, size_t output_index)
|
||||
|
|
@ -469,83 +409,6 @@ namespace currency
|
|||
generate_key_derivation(tx_pub_key, acc.m_view_secret_key, derivation);
|
||||
return is_out_to_acc(acc, out_key, derivation, output_index);
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
template<typename specic_type_t, typename variant_t_container>
|
||||
bool have_type_in_variant_container(const variant_t_container& av)
|
||||
{
|
||||
for (auto& ai : av)
|
||||
{
|
||||
if (ai.type() == typeid(specic_type_t))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
template<typename specic_type_t, typename variant_t_container>
|
||||
size_t count_type_in_variant_container(const variant_t_container& av)
|
||||
{
|
||||
size_t result = 0;
|
||||
for (auto& ai : av)
|
||||
{
|
||||
if (ai.type() == typeid(specic_type_t))
|
||||
++result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
template<typename specic_type_t, typename variant_t_container>
|
||||
bool get_type_in_variant_container(const variant_t_container& av, specic_type_t& a)
|
||||
{
|
||||
for (auto& ai : av)
|
||||
{
|
||||
if (ai.type() == typeid(specic_type_t))
|
||||
{
|
||||
a = boost::get<specic_type_t>(ai);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
template<typename variant_container_t>
|
||||
bool check_allowed_types_in_variant_container(const variant_container_t& container, const std::unordered_set<std::type_index>& allowed_types, bool elements_must_be_unique = true)
|
||||
{
|
||||
for (auto it = container.begin(); it != container.end(); ++it)
|
||||
{
|
||||
if (allowed_types.count(std::type_index(it->type())) == 0)
|
||||
return false;
|
||||
|
||||
if (elements_must_be_unique)
|
||||
{
|
||||
for (auto jt = it + 1; jt != container.end(); ++jt)
|
||||
if (it->type().hash_code() == jt->type().hash_code())
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
template<typename variant_container_t>
|
||||
bool check_allowed_types_in_variant_container(const variant_container_t& container, const variant_container_t& allowed_types_examples, bool elements_must_be_unique = true)
|
||||
{
|
||||
std::unordered_set<std::type_index> allowed_types;
|
||||
for (auto& el : allowed_types_examples)
|
||||
if (!allowed_types.insert(std::type_index(el.type())).second)
|
||||
return false; // invalid allowed_types_examples container
|
||||
|
||||
return check_allowed_types_in_variant_container(container, allowed_types, elements_must_be_unique);
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
template<typename variant_container_t>
|
||||
std::string stringize_types_in_variant_container(const variant_container_t& container)
|
||||
{
|
||||
std::string result;
|
||||
for (auto it = container.begin(); it != container.end(); ++it)
|
||||
result = (result + it->type().name()) + (it + 1 != container.end() ? ", " : "");
|
||||
return result;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
template<class t_container>
|
||||
bool validate_attachment_info(const t_container& container, const std::vector<attachment_v>& attachments, bool allow_no_info_for_non_empty_attachments_container)
|
||||
|
|
@ -692,51 +555,7 @@ namespace currency
|
|||
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
template<class t_object>
|
||||
bool get_object_hash(const t_object& o, crypto::hash& res)
|
||||
{
|
||||
get_blob_hash(t_serializable_object_to_blob(o), res);
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
template<class t_object>
|
||||
crypto::hash get_object_hash(const t_object& o)
|
||||
{
|
||||
crypto::hash h;
|
||||
get_object_hash(o, h);
|
||||
return h;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
|
||||
template<class t_object>
|
||||
size_t get_object_blobsize(const t_object& o)
|
||||
{
|
||||
blobdata b = t_serializable_object_to_blob(o);
|
||||
return b.size();
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
size_t get_object_blobsize(const transaction& t);
|
||||
size_t get_object_blobsize(const transaction& t, uint64_t prefix_blob_size);
|
||||
//---------------------------------------------------------------
|
||||
template<class t_object>
|
||||
bool get_object_hash(const t_object& o, crypto::hash& res, uint64_t& blob_size)
|
||||
{
|
||||
blobdata bl = t_serializable_object_to_blob(o);
|
||||
blob_size = bl.size();
|
||||
get_blob_hash(bl, res);
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
template <typename T>
|
||||
std::string obj_to_json_str(const T& obj)
|
||||
{
|
||||
std::stringstream ss;
|
||||
json_archive<true> ar(ss, true);
|
||||
bool r = ::serialization::serialize(ar, const_cast<T&>(obj));
|
||||
CHECK_AND_ASSERT_MES(r, "", "obj_to_json_str failed: serialization::serialize returned false");
|
||||
return ss.str();
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
// 62387455827 -> 455827 + 7000000 + 80000000 + 300000000 + 2000000000 + 60000000000, where 455827 <= dust_threshold
|
||||
template<typename chunk_handler_t, typename dust_handler_t>
|
||||
|
|
@ -843,18 +662,6 @@ namespace currency
|
|||
}
|
||||
//---------------------------------------------------------------
|
||||
|
||||
blobdata block_to_blob(const block& b);
|
||||
bool block_to_blob(const block& b, blobdata& b_blob);
|
||||
blobdata tx_to_blob(const transaction& b);
|
||||
bool tx_to_blob(const transaction& b, blobdata& b_blob);
|
||||
void get_tx_tree_hash(const std::vector<crypto::hash>& tx_hashes, crypto::hash& h);
|
||||
crypto::hash get_tx_tree_hash(const std::vector<crypto::hash>& tx_hashes);
|
||||
crypto::hash get_tx_tree_hash(const block& b);
|
||||
|
||||
#define CHECKED_GET_SPECIFIC_VARIANT(variant_var, specific_type, variable_name, fail_return_val) \
|
||||
CHECK_AND_ASSERT_MES(variant_var.type() == typeid(specific_type), fail_return_val, "wrong variant type: " << variant_var.type().name() << ", expected " << typeid(specific_type).name()); \
|
||||
specific_type& variable_name = boost::get<specific_type>(variant_var);
|
||||
|
||||
struct input_amount_getter : public boost::static_visitor<uint64_t>
|
||||
{
|
||||
template<class t_input>
|
||||
|
|
@ -866,7 +673,6 @@ namespace currency
|
|||
{
|
||||
return boost::apply_visitor(input_amount_getter(), v);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------
|
||||
std::ostream& operator <<(std::ostream& o, const ref_by_id& r);
|
||||
//---------------------------------------------------------------
|
||||
|
|
|
|||
218
src/currency_core/currency_format_utils_abstract.h
Normal file
218
src/currency_core/currency_format_utils_abstract.h
Normal file
|
|
@ -0,0 +1,218 @@
|
|||
// Copyright (c) 2018-2019 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 <typeindex>
|
||||
#include <unordered_set>
|
||||
#include <unordered_map>
|
||||
#include <list>
|
||||
#include <memory>
|
||||
|
||||
|
||||
#include "include_base_utils.h"
|
||||
#include "serialization/keyvalue_serialization.h"
|
||||
#include "storages/portable_storage_template_helper.h"
|
||||
#include "crypto/crypto.h"
|
||||
#include "crypto/hash.h"
|
||||
#include "currency_core/currency_basic.h"
|
||||
#include "currency_protocol/blobdatatype.h"
|
||||
#include "common/crypto_stream_operators.h"
|
||||
|
||||
namespace currency
|
||||
{
|
||||
|
||||
template<typename type_t>
|
||||
std::string print_kv_structure(const type_t& v)
|
||||
{
|
||||
return epee::serialization::store_t_to_json(v);
|
||||
}
|
||||
|
||||
template<class t_type>
|
||||
std::string print_t_array(const std::vector<t_type>& vec)
|
||||
{
|
||||
std::stringstream ss;
|
||||
for (auto& v : vec)
|
||||
ss << v << " ";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/************************************************************************/
|
||||
template<class t_array>
|
||||
struct array_hasher : std::unary_function<t_array&, std::size_t>
|
||||
{
|
||||
std::size_t operator()(const t_array& val) const
|
||||
{
|
||||
return boost::hash_range(&val.data[0], &val.data[sizeof(val.data)]);
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
template<class t_pod_type, class result_type>
|
||||
result_type get_pod_checksum(const t_pod_type& bl)
|
||||
{
|
||||
const unsigned char* pbuf = reinterpret_cast<const unsigned char*>(&bl);
|
||||
result_type summ = 0;
|
||||
for (size_t i = 0; i != sizeof(t_pod_type)-1; i++)
|
||||
summ += pbuf[i];
|
||||
|
||||
return summ;
|
||||
}
|
||||
|
||||
template<typename object_t>
|
||||
bool parse_and_validate_object_from_blob(const blobdata& b_blob, object_t& b)
|
||||
{
|
||||
return t_unserializable_object_from_blob(b, b_blob);
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
template<typename specic_type_t, typename variant_t_container>
|
||||
bool have_type_in_variant_container(const variant_t_container& av)
|
||||
{
|
||||
for (auto& ai : av)
|
||||
{
|
||||
if (ai.type() == typeid(specic_type_t))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
template<typename specic_type_t, typename variant_t_container>
|
||||
size_t count_type_in_variant_container(const variant_t_container& av)
|
||||
{
|
||||
size_t result = 0;
|
||||
for (auto& ai : av)
|
||||
{
|
||||
if (ai.type() == typeid(specic_type_t))
|
||||
++result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
template<typename specic_type_t, typename variant_t_container>
|
||||
bool get_type_in_variant_container(const variant_t_container& av, specic_type_t& a)
|
||||
{
|
||||
for (auto& ai : av)
|
||||
{
|
||||
if (ai.type() == typeid(specic_type_t))
|
||||
{
|
||||
a = boost::get<specic_type_t>(ai);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
template<typename variant_container_t>
|
||||
bool check_allowed_types_in_variant_container(const variant_container_t& container, const std::unordered_set<std::type_index>& allowed_types, bool elements_must_be_unique = true)
|
||||
{
|
||||
for (auto it = container.begin(); it != container.end(); ++it)
|
||||
{
|
||||
if (allowed_types.count(std::type_index(it->type())) == 0)
|
||||
return false;
|
||||
|
||||
if (elements_must_be_unique)
|
||||
{
|
||||
for (auto jt = it + 1; jt != container.end(); ++jt)
|
||||
if (it->type().hash_code() == jt->type().hash_code())
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
template<typename variant_container_t>
|
||||
bool check_allowed_types_in_variant_container(const variant_container_t& container, const variant_container_t& allowed_types_examples, bool elements_must_be_unique = true)
|
||||
{
|
||||
std::unordered_set<std::type_index> allowed_types;
|
||||
for (auto& el : allowed_types_examples)
|
||||
if (!allowed_types.insert(std::type_index(el.type())).second)
|
||||
return false; // invalid allowed_types_examples container
|
||||
|
||||
return check_allowed_types_in_variant_container(container, allowed_types, elements_must_be_unique);
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
template<typename variant_container_t>
|
||||
std::string stringize_types_in_variant_container(const variant_container_t& container)
|
||||
{
|
||||
std::string result;
|
||||
for (auto it = container.begin(); it != container.end(); ++it)
|
||||
result = (result + it->type().name()) + (it + 1 != container.end() ? ", " : "");
|
||||
return result;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
inline
|
||||
void get_blob_hash(const blobdata& blob, crypto::hash& res)
|
||||
{
|
||||
cn_fast_hash(blob.data(), blob.size(), res);
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
inline
|
||||
crypto::hash get_blob_hash(const blobdata& blob)
|
||||
{
|
||||
crypto::hash h = null_hash;
|
||||
get_blob_hash(blob, h);
|
||||
return h;
|
||||
}
|
||||
|
||||
template<class t_object>
|
||||
bool get_object_hash(const t_object& o, crypto::hash& res)
|
||||
{
|
||||
get_blob_hash(t_serializable_object_to_blob(o), res);
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
template<class t_object>
|
||||
crypto::hash get_object_hash(const t_object& o)
|
||||
{
|
||||
crypto::hash h;
|
||||
get_object_hash(o, h);
|
||||
return h;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
|
||||
template<class t_object>
|
||||
size_t get_object_blobsize(const t_object& o)
|
||||
{
|
||||
blobdata b = t_serializable_object_to_blob(o);
|
||||
return b.size();
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
template<class t_object>
|
||||
bool get_object_hash(const t_object& o, crypto::hash& res, uint64_t& blob_size)
|
||||
{
|
||||
blobdata bl = t_serializable_object_to_blob(o);
|
||||
blob_size = bl.size();
|
||||
get_blob_hash(bl, res);
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
template <typename T>
|
||||
std::string obj_to_json_str(const T& obj)
|
||||
{
|
||||
std::stringstream ss;
|
||||
json_archive<true> ar(ss, true);
|
||||
bool r = ::serialization::serialize(ar, const_cast<T&>(obj));
|
||||
CHECK_AND_ASSERT_MES(r, "", "obj_to_json_str failed: serialization::serialize returned false");
|
||||
return ss.str();
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
|
||||
//---------------------------------------------------------------
|
||||
size_t get_object_blobsize(const transaction& t);
|
||||
size_t get_object_blobsize(const transaction& t, uint64_t prefix_blob_size);
|
||||
|
||||
|
||||
|
||||
#define CHECKED_GET_SPECIFIC_VARIANT(variant_var, specific_type, variable_name, fail_return_val) \
|
||||
CHECK_AND_ASSERT_MES(variant_var.type() == typeid(specific_type), fail_return_val, "wrong variant type: " << variant_var.type().name() << ", expected " << typeid(specific_type).name()); \
|
||||
specific_type& variable_name = boost::get<specific_type>(variant_var);
|
||||
|
||||
} // namespace currency
|
||||
|
||||
|
||||
|
||||
67
src/currency_core/currency_format_utils_blocks.cpp
Normal file
67
src/currency_core/currency_format_utils_blocks.cpp
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
// Copyright (c) 2018-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 "currency_format_utils_blocks.h"
|
||||
#include "serialization/serialization.h"
|
||||
#include "currency_format_utils_abstract.h"
|
||||
#include "currency_format_utils_transactions.h"
|
||||
namespace currency
|
||||
{
|
||||
//---------------------------------------------------------------
|
||||
blobdata get_block_hashing_blob(const block& b)
|
||||
{
|
||||
blobdata blob = t_serializable_object_to_blob(static_cast<block_header>(b));
|
||||
crypto::hash tree_root_hash = get_tx_tree_hash(b);
|
||||
blob.append((const char*)&tree_root_hash, sizeof(tree_root_hash));
|
||||
blob.append(tools::get_varint_data(b.tx_hashes.size() + 1));
|
||||
return blob;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
bool get_block_hash(const block& b, crypto::hash& res)
|
||||
{
|
||||
return get_object_hash(get_block_hashing_blob(b), res);
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
crypto::hash get_block_hash(const block& b)
|
||||
{
|
||||
crypto::hash p = null_hash;
|
||||
get_block_hash(b, p);
|
||||
return p;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
blobdata block_to_blob(const block& b)
|
||||
{
|
||||
return t_serializable_object_to_blob(b);
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
bool block_to_blob(const block& b, blobdata& b_blob)
|
||||
{
|
||||
return t_serializable_object_to_blob(b, b_blob);
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
void get_tx_tree_hash(const std::vector<crypto::hash>& tx_hashes, crypto::hash& h)
|
||||
{
|
||||
tree_hash(tx_hashes.data(), tx_hashes.size(), h);
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
crypto::hash get_tx_tree_hash(const std::vector<crypto::hash>& tx_hashes)
|
||||
{
|
||||
crypto::hash h = null_hash;
|
||||
get_tx_tree_hash(tx_hashes, h);
|
||||
return h;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
crypto::hash get_tx_tree_hash(const block& b)
|
||||
{
|
||||
std::vector<crypto::hash> txs_ids;
|
||||
crypto::hash h = null_hash;
|
||||
get_transaction_hash(b.miner_tx, h);
|
||||
txs_ids.push_back(h);
|
||||
BOOST_FOREACH(auto& th, b.tx_hashes)
|
||||
txs_ids.push_back(th);
|
||||
return get_tx_tree_hash(txs_ids);
|
||||
}
|
||||
}
|
||||
25
src/currency_core/currency_format_utils_blocks.h
Normal file
25
src/currency_core/currency_format_utils_blocks.h
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
// Copyright (c) 2018-2019 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_base_utils.h"
|
||||
#include "crypto/crypto.h"
|
||||
#include "currency_core/currency_basic.h"
|
||||
#include "currency_protocol/blobdatatype.h"
|
||||
|
||||
namespace currency
|
||||
{
|
||||
blobdata get_block_hashing_blob(const block& b);
|
||||
bool get_block_hash(const block& b, crypto::hash& res);
|
||||
crypto::hash get_block_hash(const block& b);
|
||||
|
||||
blobdata block_to_blob(const block& b);
|
||||
bool block_to_blob(const block& b, blobdata& b_blob);
|
||||
void get_tx_tree_hash(const std::vector<crypto::hash>& tx_hashes, crypto::hash& h);
|
||||
crypto::hash get_tx_tree_hash(const std::vector<crypto::hash>& tx_hashes);
|
||||
crypto::hash get_tx_tree_hash(const block& b);
|
||||
|
||||
}
|
||||
134
src/currency_core/currency_format_utils_transactions.cpp
Normal file
134
src/currency_core/currency_format_utils_transactions.cpp
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
// Copyright (c) 2018-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 "currency_format_utils_transactions.h"
|
||||
#include "serialization/serialization.h"
|
||||
#include "currency_format_utils_abstract.h"
|
||||
#include "currency_format_utils.h"
|
||||
|
||||
namespace currency
|
||||
{
|
||||
//---------------------------------------------------------------
|
||||
void get_transaction_prefix_hash(const transaction_prefix& tx, crypto::hash& h)
|
||||
{
|
||||
std::ostringstream s;
|
||||
binary_archive<true> a(s);
|
||||
::serialization::serialize(a, const_cast<transaction_prefix&>(tx));
|
||||
std::string data = s.str();
|
||||
crypto::cn_fast_hash(data.data(), data.size(), h);
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
crypto::hash get_transaction_prefix_hash(const transaction_prefix& tx)
|
||||
{
|
||||
crypto::hash h = null_hash;
|
||||
get_transaction_prefix_hash(tx, h);
|
||||
return h;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
bool parse_and_validate_tx_from_blob(const blobdata& tx_blob, transaction& tx)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << tx_blob;
|
||||
binary_archive<false> ba(ss);
|
||||
bool r = ::serialization::serialize(ba, tx);
|
||||
CHECK_AND_ASSERT_MES(r, false, "Failed to parse transaction from blob");
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
bool parse_and_validate_tx_from_blob(const blobdata& tx_blob, transaction& tx, crypto::hash& tx_hash)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << tx_blob;
|
||||
binary_archive<false> ba(ss);
|
||||
bool r = ::serialization::serialize(ba, tx);
|
||||
CHECK_AND_ASSERT_MES(r, false, "Failed to parse transaction from blob");
|
||||
//TODO: validate tx
|
||||
|
||||
//crypto::cn_fast_hash(tx_blob.data(), tx_blob.size(), tx_hash);
|
||||
get_transaction_prefix_hash(tx, tx_hash);
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
crypto::hash get_transaction_hash(const transaction& t)
|
||||
{
|
||||
return get_transaction_prefix_hash(t);
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
bool get_transaction_hash(const transaction& t, crypto::hash& res)
|
||||
{
|
||||
uint64_t blob_size = 0;
|
||||
return get_object_hash(static_cast<const transaction_prefix&>(t), res, blob_size);
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
bool get_transaction_hash(const transaction& t, crypto::hash& res, uint64_t& blob_size)
|
||||
{
|
||||
blob_size = 0;
|
||||
bool r = get_object_hash(static_cast<const transaction_prefix&>(t), res, blob_size);
|
||||
blob_size = get_object_blobsize(t, blob_size);
|
||||
return r;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
size_t get_object_blobsize(const transaction& t)
|
||||
{
|
||||
size_t tx_blob_size = get_object_blobsize(static_cast<const transaction_prefix&>(t));
|
||||
return get_object_blobsize(t, tx_blob_size);
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
size_t get_object_blobsize(const transaction& t, uint64_t prefix_blob_size)
|
||||
{
|
||||
size_t tx_blob_size = prefix_blob_size;
|
||||
|
||||
if (is_coinbase(t))
|
||||
return tx_blob_size;
|
||||
|
||||
// for purged tx, with empty signatures and attachments, this function should return the blob size
|
||||
// which the tx would have if the signatures and attachments were correctly filled with actual data
|
||||
|
||||
// 1. signatures
|
||||
bool separately_signed_tx = get_tx_flags(t) & TX_FLAG_SIGNATURE_MODE_SEPARATE;
|
||||
|
||||
tx_blob_size += tools::get_varint_packed_size(t.vin.size()); // size of transaction::signatures (equals to total inputs count)
|
||||
|
||||
for (size_t i = 0; i != t.vin.size(); i++)
|
||||
{
|
||||
size_t sig_count = get_input_expected_signatures_count(t.vin[i]);
|
||||
if (separately_signed_tx && i == t.vin.size() - 1)
|
||||
++sig_count; // count in one more signature for the last input in a complete separately signed tx
|
||||
tx_blob_size += tools::get_varint_packed_size(sig_count); // size of transaction::signatures[i]
|
||||
tx_blob_size += sizeof(crypto::signature) * sig_count; // size of signatures' data itself
|
||||
}
|
||||
|
||||
// 2. attachments (try to find extra_attachment_info in tx prefix and count it in if succeed)
|
||||
extra_attachment_info eai = AUTO_VAL_INIT(eai);
|
||||
bool got_eai = false;
|
||||
if (separately_signed_tx)
|
||||
{
|
||||
// for separately-signed tx, try to obtain extra_attachment_info from the last input's etc_details
|
||||
const std::vector<txin_etc_details_v>* p_etc_details = get_input_etc_details(t.vin.back());
|
||||
got_eai = p_etc_details != nullptr && get_type_in_variant_container(*p_etc_details, eai);
|
||||
}
|
||||
if (!got_eai)
|
||||
got_eai = get_type_in_variant_container(t.extra, eai); // then from the extra
|
||||
|
||||
if (got_eai)
|
||||
tx_blob_size += eai.sz; // sz is a size of whole serialized attachment blob, including attachments vector size
|
||||
else
|
||||
tx_blob_size += tools::get_varint_packed_size(static_cast<size_t>(0)); // no extra_attachment_info found - just add zero vector's size, 'cause it's serialized anyway
|
||||
|
||||
return tx_blob_size;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
blobdata tx_to_blob(const transaction& tx)
|
||||
{
|
||||
return t_serializable_object_to_blob(tx);
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
bool tx_to_blob(const transaction& tx, blobdata& b_blob)
|
||||
{
|
||||
return t_serializable_object_to_blob(tx, b_blob);
|
||||
}
|
||||
|
||||
}
|
||||
27
src/currency_core/currency_format_utils_transactions.h
Normal file
27
src/currency_core/currency_format_utils_transactions.h
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
// Copyright (c) 2018-2019 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_base_utils.h"
|
||||
#include "crypto/crypto.h"
|
||||
#include "currency_core/currency_basic.h"
|
||||
#include "currency_protocol/blobdatatype.h"
|
||||
|
||||
|
||||
namespace currency
|
||||
{
|
||||
void get_transaction_prefix_hash(const transaction_prefix& tx, crypto::hash& h);
|
||||
crypto::hash get_transaction_prefix_hash(const transaction_prefix& tx);
|
||||
bool parse_and_validate_tx_from_blob(const blobdata& tx_blob, transaction& tx, crypto::hash& tx_hash);
|
||||
bool parse_and_validate_tx_from_blob(const blobdata& tx_blob, transaction& tx);
|
||||
crypto::hash get_transaction_hash(const transaction& t);
|
||||
bool get_transaction_hash(const transaction& t, crypto::hash& res);
|
||||
bool get_transaction_hash(const transaction& t, crypto::hash& res, uint64_t& blob_size);
|
||||
size_t get_object_blobsize(const transaction& t);
|
||||
size_t get_object_blobsize(const transaction& t, uint64_t prefix_blob_size);
|
||||
blobdata tx_to_blob(const transaction& b);
|
||||
bool tx_to_blob(const transaction& b, blobdata& b_blob);
|
||||
}
|
||||
|
|
@ -104,7 +104,7 @@ namespace currency
|
|||
{
|
||||
std::list<blobdata> txs;
|
||||
std::list<block_complete_entry> blocks;
|
||||
std::list<crypto::hash> missed_ids;
|
||||
std::list<crypto::hash> missed_ids;
|
||||
uint64_t current_blockchain_height;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
|
|
@ -168,3 +168,5 @@ namespace currency
|
|||
};
|
||||
|
||||
}
|
||||
|
||||
#include "currency_protocol_defs_print.h"
|
||||
|
|
|
|||
89
src/currency_protocol/currency_protocol_defs_print.h
Normal file
89
src/currency_protocol/currency_protocol_defs_print.h
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
// 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 "currency_core/currency_format_utils_abstract.h"
|
||||
#include "currency_core/currency_format_utils_blocks.h"
|
||||
#include "storages/portable_storage_to_json.h"
|
||||
|
||||
namespace currency
|
||||
{
|
||||
//------------------------------------------------------------------------------------------------------------------------
|
||||
inline std::string print_complete_block_entry_list(const std::list<block_complete_entry>& blocks)
|
||||
{
|
||||
std::stringstream ss;
|
||||
size_t i = 0;
|
||||
for (const block_complete_entry& block_entry : blocks)
|
||||
{
|
||||
ss << "[" << i << "]";
|
||||
block b = AUTO_VAL_INIT(b);
|
||||
if (!parse_and_validate_object_from_blob(block_entry.block, b))
|
||||
{
|
||||
ss << "UNPARSED" << ENDL;
|
||||
}
|
||||
ss << get_block_hash(b) << "{....parent: " << b.prev_id << "....}" << ENDL;
|
||||
|
||||
i++;
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
template<typename container_t>
|
||||
std::string print_container_of_hashs(const container_t& cont, size_t indent)
|
||||
{
|
||||
std::stringstream ss;
|
||||
std::string indent_str(indent, ' ');
|
||||
for (const auto& h : cont)
|
||||
{
|
||||
ss << indent_str << h << ENDL;
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
inline
|
||||
std::string print_kv_structure(const NOTIFY_REQUEST_GET_OBJECTS::request& v)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "blocks: {" << ENDL << print_container_of_hashs(v.blocks, 2) << ENDL << "}";
|
||||
ss << "txs: {" << ENDL << print_container_of_hashs(v.txs, 2) << ENDL << "}";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
inline
|
||||
std::string print_kv_structure(const NOTIFY_RESPONSE_GET_OBJECTS::request& v)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "\"blocks\":{" << ENDL << print_complete_block_entry_list(v.blocks) << ENDL << "}, " << ENDL;
|
||||
ss << "\"missed_ids\":" << ENDL;
|
||||
::epee::serialization::dump_as_json(ss, v.missed_ids, 2);
|
||||
ss << ENDL << "\"current_blockchain_height\":" << v.current_blockchain_height;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
inline
|
||||
std::string print_kv_structure(const NOTIFY_REQUEST_CHAIN::request& v)
|
||||
{
|
||||
std::stringstream ss;
|
||||
size_t i = 0;
|
||||
ss << "block_ids: {" << ENDL << print_container_of_hashs(v.block_ids, 2) << ENDL << "}";
|
||||
return ss.str();
|
||||
}
|
||||
inline
|
||||
std::string print_kv_structure(const NOTIFY_RESPONSE_CHAIN_ENTRY::request& v)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "start_height:" << v.start_height << ENDL;
|
||||
ss << "total_height:" << v.total_height << ENDL;
|
||||
ss << "block_ids: {" << ENDL;
|
||||
for (const block_context_info& bei : v.m_block_ids)
|
||||
{
|
||||
ss << bei.h << ":" << bei.cumul_size << ENDL;
|
||||
}
|
||||
ss << "}";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2014-2018 Zano Project
|
||||
// Copyright (c) 2014-2018 Zano Project
|
||||
// Copyright (c) 2014-2018 The Louisdor Project
|
||||
// Copyright (c) 2012-2013 The Cryptonote developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
|
|
@ -70,6 +70,8 @@ namespace currency
|
|||
{
|
||||
NOTIFY_REQUEST_CHAIN::request r = boost::value_initialized<NOTIFY_REQUEST_CHAIN::request>();
|
||||
m_core.get_short_chain_history(r.block_ids);
|
||||
LOG_PRINT_L2("[NOTIFY]NOTIFY_REQUEST_CHAIN(on_callback): m_block_ids.size()=" << r.block_ids.size());
|
||||
LOG_PRINT_L3("[NOTIFY]NOTIFY_REQUEST_CHAIN(on_callback): " << ENDL << print_kv_structure(r));
|
||||
post_notify<NOTIFY_REQUEST_CHAIN>(r, context);
|
||||
}
|
||||
|
||||
|
|
@ -308,7 +310,8 @@ namespace currency
|
|||
NOTIFY_REQUEST_CHAIN::request r = boost::value_initialized<NOTIFY_REQUEST_CHAIN::request>();
|
||||
m_core.get_short_chain_history(r.block_ids);
|
||||
LOG_PRINT_MAGENTA("State changed to state_synchronizing.", LOG_LEVEL_2);
|
||||
LOG_PRINT_L2("[REQUEST]NOTIFY_REQUEST_CHAIN: m_block_ids.size()=" << r.block_ids.size() );
|
||||
LOG_PRINT_L2("[NOTIFY]NOTIFY_REQUEST_CHAIN(on_orphaned): m_block_ids.size()=" << r.block_ids.size() );
|
||||
LOG_PRINT_L3("[NOTIFY]NOTIFY_REQUEST_CHAIN(on_orphaned): " << ENDL << print_kv_structure(r));
|
||||
post_notify<NOTIFY_REQUEST_CHAIN>(r, context);
|
||||
}
|
||||
|
||||
|
|
@ -355,6 +358,9 @@ namespace currency
|
|||
template<class t_core>
|
||||
int t_currency_protocol_handler<t_core>::handle_request_get_objects(int command, NOTIFY_REQUEST_GET_OBJECTS::request& arg, currency_connection_context& context)
|
||||
{
|
||||
LOG_PRINT_L2("[HANDLE]NOTIFY_REQUEST_GET_OBJECTS: arg.blocks.size() = " << arg.blocks.size() << ", arg.txs.size()="<< arg.txs.size());
|
||||
LOG_PRINT_L3("[HANDLE]NOTIFY_REQUEST_GET_OBJECTS: " << ENDL << currency::print_kv_structure(arg));
|
||||
|
||||
if (arg.blocks.size() > CURRENCY_PROTOCOL_MAX_BLOCKS_REQUEST_COUNT)
|
||||
{
|
||||
LOG_ERROR_CCONTEXT("Requested objects count is to big (" << arg.blocks.size() <<")expected not more then " << CURRENCY_PROTOCOL_MAX_BLOCKS_REQUEST_COUNT);
|
||||
|
|
@ -367,8 +373,12 @@ namespace currency
|
|||
LOG_ERROR_CCONTEXT("failed to handle request NOTIFY_REQUEST_GET_OBJECTS, dropping connection");
|
||||
m_p2p->drop_connection(context);
|
||||
}
|
||||
LOG_PRINT_L2("[HANDLE]NOTIFY_RESPONSE_GET_OBJECTS: blocks.size()=" << rsp.blocks.size() << ", txs.size()=" << rsp.txs.size()
|
||||
|
||||
LOG_PRINT_L2("[NOTIFY]NOTIFY_RESPONSE_GET_OBJECTS: blocks.size()=" << rsp.blocks.size() << ", txs.size()=" << rsp.txs.size()
|
||||
<< ", rsp.m_current_blockchain_height=" << rsp.current_blockchain_height << ", missed_ids.size()=" << rsp.missed_ids.size());
|
||||
|
||||
|
||||
LOG_PRINT_L3("[NOTIFY]NOTIFY_RESPONSE_GET_OBJECTS: " << ENDL << currency::print_kv_structure(rsp));
|
||||
post_notify<NOTIFY_RESPONSE_GET_OBJECTS>(rsp, context);
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -383,12 +393,17 @@ namespace currency
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#define CHECK_STOP_FLAG__DROP_AND_RETURN_IF_SET(ret_v, msg) if (check_stop_flag_and_drop_cc(context)) { LOG_PRINT_YELLOW("Stop flag detected within NOTIFY_RESPONSE_GET_OBJECTS. " << msg, LOG_LEVEL_0); return ret_v; }
|
||||
//------------------------------------------------------------------------------------------------------------------------
|
||||
template<class t_core>
|
||||
int t_currency_protocol_handler<t_core>::handle_response_get_objects(int command, NOTIFY_RESPONSE_GET_OBJECTS::request& arg, currency_connection_context& context)
|
||||
{
|
||||
LOG_PRINT_L2("NOTIFY_RESPONSE_GET_OBJECTS");
|
||||
LOG_PRINT_L2("[HANDLE]NOTIFY_RESPONSE_GET_OBJECTS: arg.blocks.size()=" << arg.blocks.size() << ", arg.missed_ids.size()=" << arg.missed_ids.size() << ", arg.txs.size()=" << arg.txs.size());
|
||||
LOG_PRINT_L3("[HANDLE]NOTIFY_RESPONSE_GET_OBJECTS: " << ENDL << currency::print_kv_structure(arg));
|
||||
if(context.m_last_response_height > arg.current_blockchain_height)
|
||||
{
|
||||
LOG_ERROR_CCONTEXT("sent wrong NOTIFY_HAVE_OBJECTS: arg.m_current_blockchain_height=" << arg.current_blockchain_height
|
||||
|
|
@ -420,7 +435,7 @@ namespace currency
|
|||
total_blocks_parsing_time += block_parsing_time;
|
||||
|
||||
//to avoid concurrency in core between connections, suspend connections which delivered block later then first one
|
||||
if(count = 2)
|
||||
if(count == 2)
|
||||
{
|
||||
if(m_core.have_block(get_block_hash(b)))
|
||||
{
|
||||
|
|
@ -511,7 +526,8 @@ namespace currency
|
|||
}
|
||||
if(bvc.m_marked_as_orphaned)
|
||||
{
|
||||
LOG_PRINT_L0("Block received at sync phase was marked as orphaned, dropping connection");
|
||||
LOG_PRINT_L0("Block received at sync phase was marked as orphaned, dropping connection, details on response: " << ENDL << print_kv_structure(arg));
|
||||
|
||||
m_p2p->drop_connection(context);
|
||||
m_p2p->add_ip_fail(context.m_remote_ip);
|
||||
return 1;
|
||||
|
|
@ -565,13 +581,16 @@ namespace currency
|
|||
template<class t_core>
|
||||
int t_currency_protocol_handler<t_core>::handle_request_chain(int command, NOTIFY_REQUEST_CHAIN::request& arg, currency_connection_context& context)
|
||||
{
|
||||
LOG_PRINT_L2("[HANDLE]NOTIFY_REQUEST_CHAIN: block_ids.size()=" << arg.block_ids.size());
|
||||
LOG_PRINT_L3("[HANDLE]NOTIFY_REQUEST_CHAIN: " << print_kv_structure(arg));
|
||||
NOTIFY_RESPONSE_CHAIN_ENTRY::request r;
|
||||
if(!m_core.find_blockchain_supplement(arg.block_ids, r))
|
||||
{
|
||||
LOG_ERROR_CCONTEXT("Failed to handle NOTIFY_REQUEST_CHAIN.");
|
||||
return 1;
|
||||
}
|
||||
LOG_PRINT_L2("[HANDLE]NOTIFY_RESPONSE_CHAIN_ENTRY: m_start_height=" << r.start_height << ", m_total_height=" << r.total_height << ", m_block_ids.size()=" << r.m_block_ids.size());
|
||||
LOG_PRINT_L2("[NOTIFY]NOTIFY_RESPONSE_CHAIN_ENTRY: m_start_height=" << r.start_height << ", m_total_height=" << r.total_height << ", m_block_ids.size()=" << r.m_block_ids.size());
|
||||
LOG_PRINT_L3("[NOTIFY]NOTIFY_RESPONSE_CHAIN_ENTRY: " << print_kv_structure(r));
|
||||
post_notify<NOTIFY_RESPONSE_CHAIN_ENTRY>(r, context);
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -599,14 +618,16 @@ namespace currency
|
|||
context.m_priv.m_needed_objects.erase(it++);
|
||||
}
|
||||
|
||||
LOG_PRINT_L2("[REQUESTING]NOTIFY_REQUEST_GET_OBJECTS: requested_cumulative_size=" << requested_cumulative_size << ", blocks.size()=" << req.blocks.size() << ", txs.size()=" << req.txs.size());
|
||||
LOG_PRINT_L2("[NOTIFY]NOTIFY_REQUEST_GET_OBJECTS(req_missing): requested_cumulative_size=" << requested_cumulative_size << ", blocks.size()=" << req.blocks.size() << ", txs.size()=" << req.txs.size());
|
||||
LOG_PRINT_L3("[NOTIFY]NOTIFY_REQUEST_GET_OBJECTS(req_missing): " << ENDL << currency::print_kv_structure(req));
|
||||
post_notify<NOTIFY_REQUEST_GET_OBJECTS>(req, context);
|
||||
}else if(context.m_last_response_height < context.m_remote_blockchain_height-1)
|
||||
{//we have to fetch more objects ids, request blockchain entry
|
||||
|
||||
NOTIFY_REQUEST_CHAIN::request r = boost::value_initialized<NOTIFY_REQUEST_CHAIN::request>();
|
||||
m_core.get_short_chain_history(r.block_ids);
|
||||
LOG_PRINT_L2("[REQUESTING]NOTIFY_REQUEST_CHAIN: m_block_ids.size()=" << r.block_ids.size() );
|
||||
LOG_PRINT_L2("[NOTIFY]NOTIFY_REQUEST_CHAIN: m_block_ids.size()=" << r.block_ids.size() );
|
||||
LOG_PRINT_L3("[NOTIFY]NOTIFY_REQUEST_CHAIN: " << ENDL << print_kv_structure(r) );
|
||||
post_notify<NOTIFY_REQUEST_CHAIN>(r, context);
|
||||
}else
|
||||
{
|
||||
|
|
@ -620,7 +641,7 @@ namespace currency
|
|||
<< "\r\non connection [" << net_utils::print_connection_context_short(context)<< "]");
|
||||
|
||||
context.m_state = currency_connection_context::state_normal;
|
||||
LOG_PRINT_GREEN("[HANDLE]NOTIFY_REQUEST_GET_OBJECTS: SYNCHRONIZED OK", LOG_LEVEL_0);
|
||||
LOG_PRINT_GREEN("[REQUEST_MISSING_OBJECTS]: SYNCHRONIZED OK", LOG_LEVEL_0);
|
||||
on_connection_synchronized();
|
||||
}
|
||||
return true;
|
||||
|
|
@ -725,8 +746,9 @@ namespace currency
|
|||
template<class t_core>
|
||||
int t_currency_protocol_handler<t_core>::handle_response_chain_entry(int command, NOTIFY_RESPONSE_CHAIN_ENTRY::request& arg, currency_connection_context& context)
|
||||
{
|
||||
LOG_PRINT_L2("NOTIFY_RESPONSE_CHAIN_ENTRY: m_block_ids.size()=" << arg.m_block_ids.size()
|
||||
LOG_PRINT_L2("[HANDLE]NOTIFY_RESPONSE_CHAIN_ENTRY: m_block_ids.size()=" << arg.m_block_ids.size()
|
||||
<< ", m_start_height=" << arg.start_height << ", m_total_height=" << arg.total_height);
|
||||
LOG_PRINT_L3("[HANDLE]NOTIFY_RESPONSE_CHAIN_ENTRY: " << ENDL << currency::print_kv_structure(arg));
|
||||
|
||||
if(!arg.m_block_ids.size())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -124,6 +124,8 @@ namespace nodetool
|
|||
HANDLE_INVOKE_T2(COMMAND_REQUEST_STAT_INFO, &node_server::handle_get_stat_info)
|
||||
HANDLE_INVOKE_T2(COMMAND_REQUEST_NETWORK_STATE, &node_server::handle_get_network_state)
|
||||
HANDLE_INVOKE_T2(COMMAND_REQUEST_PEER_ID, &node_server::handle_get_peer_id)
|
||||
HANDLE_INVOKE_T2(COMMAND_REQUEST_LOG, &node_server::handle_request_log)
|
||||
HANDLE_INVOKE_T2(COMMAND_SET_LOG_LEVEL, &node_server::handle_set_log_level)
|
||||
#endif
|
||||
CHAIN_INVOKE_MAP_TO_OBJ_FORCE_CONTEXT(m_payload_handler, typename t_payload_net_handler::connection_context&)
|
||||
END_INVOKE_MAP2()
|
||||
|
|
@ -137,6 +139,8 @@ namespace nodetool
|
|||
int handle_get_stat_info(int command, typename COMMAND_REQUEST_STAT_INFO::request& arg, typename COMMAND_REQUEST_STAT_INFO::response& rsp, p2p_connection_context& context);
|
||||
int handle_get_network_state(int command, COMMAND_REQUEST_NETWORK_STATE::request& arg, COMMAND_REQUEST_NETWORK_STATE::response& rsp, p2p_connection_context& context);
|
||||
int handle_get_peer_id(int command, COMMAND_REQUEST_PEER_ID::request& arg, COMMAND_REQUEST_PEER_ID::response& rsp, p2p_connection_context& context);
|
||||
int handle_request_log(int command, COMMAND_REQUEST_LOG::request& arg, COMMAND_REQUEST_LOG::response& rsp, p2p_connection_context& context);
|
||||
int handle_set_log_level(int command, COMMAND_SET_LOG_LEVEL::request& arg, COMMAND_SET_LOG_LEVEL::response& rsp, p2p_connection_context& context);
|
||||
private:
|
||||
#endif
|
||||
bool init_config();
|
||||
|
|
|
|||
|
|
@ -1039,6 +1039,7 @@ namespace nodetool
|
|||
rsp.connections_count = m_net_server.get_config_object().get_connections_count();
|
||||
rsp.incoming_connections_count = rsp.connections_count - get_outgoing_connections_count();
|
||||
rsp.version = PROJECT_VERSION_LONG;
|
||||
rsp.current_log_size = tools::get_log_file_size();
|
||||
m_payload_handler.get_stat_info(arg.pr, rsp.payload_info);
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -1080,7 +1081,44 @@ namespace nodetool
|
|||
rsp.my_id = m_config.m_peer_id;
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
//-----------------------------------------------------------------------------------
|
||||
template<class t_payload_net_handler>
|
||||
int node_server<t_payload_net_handler>::handle_request_log(int command, COMMAND_REQUEST_LOG::request& req, COMMAND_REQUEST_LOG::response& rsp, p2p_connection_context& context)
|
||||
{
|
||||
if (!check_trust(req.tr))
|
||||
{
|
||||
drop_connection(context);
|
||||
return 1;
|
||||
}
|
||||
|
||||
rsp.current_log_level = static_cast<int64_t>(log_space::get_set_log_detalisation_level());
|
||||
tools::get_log_chunk_gzipped(req.log_chunk_offset, req.log_chunk_size, rsp.log_chunk, rsp.error);
|
||||
rsp.current_log_size = tools::get_log_file_size();
|
||||
|
||||
return 1;
|
||||
}
|
||||
//-----------------------------------------------------------------------------------
|
||||
template<class t_payload_net_handler>
|
||||
int node_server<t_payload_net_handler>::handle_set_log_level(int command, COMMAND_SET_LOG_LEVEL::request& req, COMMAND_SET_LOG_LEVEL::response& rsp, p2p_connection_context& context)
|
||||
{
|
||||
if (!check_trust(req.tr))
|
||||
{
|
||||
drop_connection(context);
|
||||
return 1;
|
||||
}
|
||||
|
||||
rsp.old_log_level = static_cast<int64_t>(log_space::get_set_log_detalisation_level());
|
||||
log_space::get_set_log_detalisation_level(true, static_cast<int>(req.new_log_level));
|
||||
rsp.current_log_level = static_cast<int64_t>(log_space::get_set_log_detalisation_level());
|
||||
|
||||
if (rsp.old_log_level != rsp.current_log_level)
|
||||
{
|
||||
LOG_PRINT_CC(context, "log level changed by debug command: " << rsp.old_log_level << " -> " << rsp.current_log_level, LOG_LEVEL_0);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif // #ifdef ALLOW_DEBUG_COMMANDS
|
||||
//-----------------------------------------------------------------------------------
|
||||
template<class t_payload_net_handler>
|
||||
void node_server<t_payload_net_handler>::request_callback(const epee::net_utils::connection_context_base& context)
|
||||
|
|
|
|||
|
|
@ -328,12 +328,14 @@ namespace nodetool
|
|||
std::string version;
|
||||
uint64_t connections_count;
|
||||
uint64_t incoming_connections_count;
|
||||
uint64_t current_log_size;
|
||||
payload_stat_info payload_info;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(version)
|
||||
KV_SERIALIZE(connections_count)
|
||||
KV_SERIALIZE(incoming_connections_count)
|
||||
KV_SERIALIZE(current_log_size)
|
||||
KV_SERIALIZE(payload_info)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
|
@ -397,7 +399,73 @@ namespace nodetool
|
|||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/************************************************************************/
|
||||
struct COMMAND_REQUEST_LOG
|
||||
{
|
||||
const static int ID = P2P_COMMANDS_POOL_BASE + 7;
|
||||
|
||||
struct request
|
||||
{
|
||||
proof_of_trust tr;
|
||||
uint64_t log_chunk_offset;
|
||||
uint64_t log_chunk_size;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(tr)
|
||||
KV_SERIALIZE(log_chunk_offset)
|
||||
KV_SERIALIZE(log_chunk_size)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
struct response
|
||||
{
|
||||
int64_t current_log_level;
|
||||
uint64_t current_log_size;
|
||||
std::string error;
|
||||
std::string log_chunk;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(current_log_level)
|
||||
KV_SERIALIZE(current_log_size)
|
||||
KV_SERIALIZE(error)
|
||||
KV_SERIALIZE(log_chunk)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
};
|
||||
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/************************************************************************/
|
||||
struct COMMAND_SET_LOG_LEVEL
|
||||
{
|
||||
const static int ID = P2P_COMMANDS_POOL_BASE + 8;
|
||||
|
||||
struct request
|
||||
{
|
||||
proof_of_trust tr;
|
||||
int64_t new_log_level;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(tr)
|
||||
KV_SERIALIZE(new_log_level)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
struct response
|
||||
{
|
||||
int64_t old_log_level;
|
||||
int64_t current_log_level;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(old_log_level)
|
||||
KV_SERIALIZE(current_log_level)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
};
|
||||
|
||||
#endif // #ifdef ALLOW_DEBUG_COMMANDS
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -35,9 +35,13 @@ int test_big_difficulties(const char* dataFile)
|
|||
end = n - DIFFICULTY_LAG;
|
||||
begin = end - DIFFICULTY_WINDOW;
|
||||
}
|
||||
auto stamps = vector<uint64_t>(timestamps.begin() + begin, timestamps.begin() + end);
|
||||
auto cumulative_diffs = vector<currency::wide_difficulty_type>(cumulative_difficulties.begin() + begin, cumulative_difficulties.begin() + end);
|
||||
currency::wide_difficulty_type res = currency::next_difficulty(
|
||||
vector<uint64_t>(timestamps.begin() + begin, timestamps.begin() + end),
|
||||
vector<currency::wide_difficulty_type>(cumulative_difficulties.begin() + begin, cumulative_difficulties.begin() + end), DEFAULT_TEST_DIFFICULTY_TARGET);
|
||||
stamps,
|
||||
cumulative_diffs,
|
||||
DEFAULT_TEST_DIFFICULTY_TARGET
|
||||
);
|
||||
if (res != difficulty) {
|
||||
cerr << "Wrong wide difficulty for block " << n << endl
|
||||
<< "Expected: " << difficulty << endl
|
||||
|
|
@ -90,9 +94,13 @@ int main(int argc, char *argv[]) {
|
|||
<< "Found: " << res << endl;
|
||||
return 1;
|
||||
}
|
||||
auto stamps = vector<uint64_t>(timestamps.begin() + begin, timestamps.begin() + end);
|
||||
auto cumulative_diffs = vector<currency::wide_difficulty_type>(wide_cumulative_difficulties.begin() + begin, wide_cumulative_difficulties.begin() + end);
|
||||
currency::wide_difficulty_type wide_res = currency::next_difficulty(
|
||||
vector<uint64_t>(timestamps.begin() + begin, timestamps.begin() + end),
|
||||
vector<currency::wide_difficulty_type>(wide_cumulative_difficulties.begin() + begin, wide_cumulative_difficulties.begin() + end), DEFAULT_TEST_DIFFICULTY_TARGET);
|
||||
stamps,
|
||||
cumulative_diffs,
|
||||
DEFAULT_TEST_DIFFICULTY_TARGET
|
||||
);
|
||||
if (wide_res.convert_to<uint64_t>() != res) {
|
||||
cerr << "Wrong wide difficulty for block " << n << endl
|
||||
<< "Expected: " << res << endl
|
||||
|
|
@ -110,3 +118,4 @@ int main(int argc, char *argv[]) {
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -147,16 +147,16 @@ currency::wide_difficulty_type bbr_next_difficulty_configurable(std::vector<uint
|
|||
return res.convert_to<currency::wide_difficulty_type>();
|
||||
}
|
||||
|
||||
|
||||
|
||||
currency::wide_difficulty_type bbr_next_difficulty_composit(std::vector<uint64_t>& timestamps, std::vector<currency::wide_difficulty_type>& cumulative_difficulties, size_t target_seconds, size_t REDEF_DIFFICULTY_WINDOW, size_t REDEF_DIFFICULTY_CUT_OLD, size_t REDEF_DIFFICULTY_CUT_LAST)
|
||||
{
|
||||
sort(timestamps.begin(), timestamps.end(), std::greater<uint64_t>());
|
||||
std::vector<uint64_t> timestamps_local = timestamps;
|
||||
currency::wide_difficulty_type dif = bbr_next_difficulty_configurable(timestamps_local, cumulative_difficulties, target_seconds, REDEF_DIFFICULTY_WINDOW, REDEF_DIFFICULTY_CUT_OLD, REDEF_DIFFICULTY_CUT_LAST);
|
||||
currency::wide_difficulty_type dif2 = bbr_next_difficulty_configurable(timestamps_local, cumulative_difficulties, target_seconds, 300, 20, 5);
|
||||
if (dif < dif2)
|
||||
return dif;
|
||||
else
|
||||
return dif2;
|
||||
currency::wide_difficulty_type dif2 = bbr_next_difficulty_configurable(timestamps_local, cumulative_difficulties, target_seconds, 200, 5, 5);
|
||||
currency::wide_difficulty_type dif3 = bbr_next_difficulty_configurable(timestamps_local, cumulative_difficulties, target_seconds, 40, 1, 1);
|
||||
return (dif3 + dif2 + dif) / 3;
|
||||
}
|
||||
|
||||
currency::wide_difficulty_type bbr_next_difficulty2(std::vector<uint64_t>& timestamps, std::vector<currency::wide_difficulty_type>& cumulative_difficulties, size_t target_seconds)
|
||||
|
|
@ -202,7 +202,7 @@ uint64_t get_hashrate_by_timestamp(const std::map<uint64_t, uint64_t> timestamp_
|
|||
return 0;
|
||||
}
|
||||
|
||||
return (--it)->second;
|
||||
return (--it)->second;;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -252,6 +252,12 @@ void perform_simulation_for_function(const std::map<uint64_t, uint64_t>& timesta
|
|||
index_in_result_blocks++;
|
||||
std::cout << index_in_result_blocks << "\r";
|
||||
}
|
||||
if (index_in_result_blocks < 410)
|
||||
{
|
||||
for (size_t k = index_in_result_blocks; k != 410; k++)
|
||||
result_blocks[k][index_in_result] = result_blocks[k-1][index_in_result];
|
||||
}
|
||||
|
||||
std::cout << "\n";
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue