From 128ce34cf5d58d9e0f44979f5327223c19eb78e1 Mon Sep 17 00:00:00 2001 From: "crypro.zoidberg" Date: Thu, 7 Feb 2019 20:10:39 +0100 Subject: [PATCH 01/20] final adjustment and emulation --- tests/functional_tests/difficulty_analysis.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/tests/functional_tests/difficulty_analysis.cpp b/tests/functional_tests/difficulty_analysis.cpp index 4d70b31f..6a11e4d4 100644 --- a/tests/functional_tests/difficulty_analysis.cpp +++ b/tests/functional_tests/difficulty_analysis.cpp @@ -152,11 +152,8 @@ currency::wide_difficulty_type bbr_next_difficulty_composit(std::vector()); std::vector 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); + return (dif2 + dif) / 2; } currency::wide_difficulty_type bbr_next_difficulty2(std::vector& timestamps, std::vector& cumulative_difficulties, size_t target_seconds) @@ -202,7 +199,7 @@ uint64_t get_hashrate_by_timestamp(const std::map timestamp_ return 0; } - return (--it)->second; + return (--it)->second;; } @@ -252,6 +249,12 @@ void perform_simulation_for_function(const std::map& 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"; } From 257d63d2b18f5c505ad8f5a956902571ed061594 Mon Sep 17 00:00:00 2001 From: "crypro.zoidberg" Date: Fri, 8 Feb 2019 21:33:26 +0100 Subject: [PATCH 02/20] fixed bug with possible http server flood --- .../epee/include/net/http_protocol_handler.h | 1 + .../include/net/http_protocol_handler.inl | 27 +++++++++++++------ .../functional_tests/difficulty_analysis.cpp | 5 +++- 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/contrib/epee/include/net/http_protocol_handler.h b/contrib/epee/include/net/http_protocol_handler.h index 569b6128..aa4dfa9a 100644 --- a/contrib/epee/include/net/http_protocol_handler.h +++ b/contrib/epee/include/net/http_protocol_handler.h @@ -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: diff --git a/contrib/epee/include/net/http_protocol_handler.inl b/contrib/epee/include/net/http_protocol_handler.inl index d981cdc8..41d1384f 100644 --- a/contrib/epee/include/net/http_protocol_handler.inl +++ b/contrib/epee/include/net/http_protocol_handler.inl @@ -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; } diff --git a/tests/functional_tests/difficulty_analysis.cpp b/tests/functional_tests/difficulty_analysis.cpp index 6a11e4d4..9dfef6f2 100644 --- a/tests/functional_tests/difficulty_analysis.cpp +++ b/tests/functional_tests/difficulty_analysis.cpp @@ -147,13 +147,16 @@ currency::wide_difficulty_type bbr_next_difficulty_configurable(std::vector(); } + + currency::wide_difficulty_type bbr_next_difficulty_composit(std::vector& timestamps, std::vector& 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()); std::vector 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, 200, 5, 5); - return (dif2 + dif) / 2; + 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& timestamps, std::vector& cumulative_difficulties, size_t target_seconds) From 68b01b800f27b2498d64ee1933f12a8865677ba9 Mon Sep 17 00:00:00 2001 From: "crypro.zoidberg" Date: Fri, 8 Feb 2019 21:40:42 +0100 Subject: [PATCH 03/20] removed warning --- src/currency_core/blockchain_storage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index 77ac9a71..dfe9c6a4 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -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)) { From fead09cb1ef4701fe188bd00ebcfe68d9040f3b8 Mon Sep 17 00:00:00 2001 From: alfred <> Date: Fri, 8 Feb 2019 14:07:30 -0800 Subject: [PATCH 04/20] l-value assignement error --- tests/difficulty/difficulty.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/tests/difficulty/difficulty.cpp b/tests/difficulty/difficulty.cpp index fc6133e6..5cc53014 100644 --- a/tests/difficulty/difficulty.cpp +++ b/tests/difficulty/difficulty.cpp @@ -35,9 +35,13 @@ int test_big_difficulties(const char* dataFile) end = n - DIFFICULTY_LAG; begin = end - DIFFICULTY_WINDOW; } + auto stamps = vector(timestamps.begin() + begin, timestamps.begin() + end); + auto cumulative_diffs = vector(cumulative_difficulties.begin() + begin, cumulative_difficulties.begin() + end); currency::wide_difficulty_type res = currency::next_difficulty( - vector(timestamps.begin() + begin, timestamps.begin() + end), - vector(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(timestamps.begin() + begin, timestamps.begin() + end); + auto cumulative_diffs = vector(wide_cumulative_difficulties.begin() + begin, wide_cumulative_difficulties.begin() + end); currency::wide_difficulty_type wide_res = currency::next_difficulty( - vector(timestamps.begin() + begin, timestamps.begin() + end), - vector(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() != res) { cerr << "Wrong wide difficulty for block " << n << endl << "Expected: " << res << endl @@ -110,3 +118,4 @@ int main(int argc, char *argv[]) { return 0; } + From a3da8ba81977d49509077af0d4ba616fdebaaafc Mon Sep 17 00:00:00 2001 From: alfred <> Date: Fri, 8 Feb 2019 14:08:25 -0800 Subject: [PATCH 05/20] wrong assignement --- src/currency_protocol/currency_protocol_handler.inl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/currency_protocol/currency_protocol_handler.inl b/src/currency_protocol/currency_protocol_handler.inl index 119d234d..7fa2e80c 100644 --- a/src/currency_protocol/currency_protocol_handler.inl +++ b/src/currency_protocol/currency_protocol_handler.inl @@ -420,7 +420,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))) { From 6e050fce8bf3bc93cc5c2aef829ec2693fe1af1c Mon Sep 17 00:00:00 2001 From: "crypro.zoidberg" Date: Thu, 14 Feb 2019 02:00:24 +0100 Subject: [PATCH 06/20] added more logs, changed structure of furmat_utils --- .../include/net/http_protocol_handler.inl | 2 +- src/common/crypto_stream_operators.h | 36 +++ src/common/mnemonic-encoding.h | 2 + src/currency_core/account.cpp | 5 +- src/currency_core/currency_config.h | 4 + src/currency_core/currency_format_utils.cpp | 198 ++-------------- src/currency_core/currency_format_utils.h | 208 +---------------- .../currency_format_utils_abstract.h | 217 ++++++++++++++++++ .../currency_format_utils_blocks.cpp | 67 ++++++ .../currency_format_utils_blocks.h | 25 ++ .../currency_format_utils_transactions.cpp | 134 +++++++++++ .../currency_format_utils_transactions.h | 27 +++ .../currency_protocol_defs.h | 4 +- .../currency_protocol_defs_print.h | 44 ++++ .../currency_protocol_handler.inl | 20 +- 15 files changed, 601 insertions(+), 392 deletions(-) create mode 100644 src/common/crypto_stream_operators.h create mode 100644 src/currency_core/currency_format_utils_abstract.h create mode 100644 src/currency_core/currency_format_utils_blocks.cpp create mode 100644 src/currency_core/currency_format_utils_blocks.h create mode 100644 src/currency_core/currency_format_utils_transactions.cpp create mode 100644 src/currency_core/currency_format_utils_transactions.h create mode 100644 src/currency_protocol/currency_protocol_defs_print.h diff --git a/contrib/epee/include/net/http_protocol_handler.inl b/contrib/epee/include/net/http_protocol_handler.inl index 41d1384f..dbc424af 100644 --- a/contrib/epee/include/net/http_protocol_handler.inl +++ b/contrib/epee/include/net/http_protocol_handler.inl @@ -348,7 +348,7 @@ namespace net_utils LOG_FRAME("simple_http_connection_handler::handle_recognize_protocol_out(*)", 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) diff --git a/src/common/crypto_stream_operators.h b/src/common/crypto_stream_operators.h new file mode 100644 index 00000000..8ae7f53a --- /dev/null +++ b/src/common/crypto_stream_operators.h @@ -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 +#include +#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 +std::ostream &print256(std::ostream &o, const T &v) { + return o << "<" << epee::string_tools::pod_to_hex(v) << ">"; +} + +template +std::ostream &print16(std::ostream &o, const T &v) { + return o << "<" << epee::string_tools::pod_to_hex(v).substr(0, 5) << "..>"; +} + +template +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); } +} \ No newline at end of file diff --git a/src/common/mnemonic-encoding.h b/src/common/mnemonic-encoding.h index 443da308..a66167ec 100644 --- a/src/common/mnemonic-encoding.h +++ b/src/common/mnemonic-encoding.h @@ -42,5 +42,7 @@ namespace tools { std::vector text2binary(const std::string& text); std::string binary2text(const std::vector& binary); + std::string word_by_num(uint64_t n); + uint64_t num_by_word(const std::string& w); } } diff --git a/src/currency_core/account.cpp b/src/currency_core/account.cpp index 8c57de43..a0612a58 100644 --- a/src/currency_core/account.cpp +++ b/src/currency_core/account.cpp @@ -62,12 +62,15 @@ namespace currency return m_seed; } //----------------------------------------------------------------- + std::string account_base::get_restore_braindata() const { std::string restore_buff = get_restore_data(); std::vector 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); + //m_creation_timestamp + return seed_brain_data; } //----------------------------------------------------------------- bool account_base::restore_keys(const std::string& restore_data) diff --git a/src/currency_core/currency_config.h b/src/currency_core/currency_config.h index 78114d74..ccae4dae 100644 --- a/src/currency_core/currency_config.h +++ b/src/currency_core/currency_config.h @@ -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 diff --git a/src/currency_core/currency_format_utils.cpp b/src/currency_core/currency_format_utils.cpp index a590a94a..903683e9 100644 --- a/src/currency_core/currency_format_utils.cpp +++ b/src/currency_core/currency_format_utils.cpp @@ -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 a(s); - ::serialization::serialize(a, const_cast(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 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 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,15 @@ namespace currency return reward; } //--------------------------------------------------------------- +// std::string get_word_from_timstamp(uint64_t timestamp) +// { +// uint64_t date_offset = timestamp ? timestamp - WALLET_BRAIN_DATE_OFFSET : 0; +// date_offset = date_offset / WALLET_BRAIN_DATE_QUANTUM; +// +// return tools::mnemonic_encoding::word_by_num(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 +1593,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 +1617,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(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(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 +1869,6 @@ namespace currency return ss.str(); } //--------------------------------------------------------------- - blobdata get_block_hashing_blob(const block& b) - { - blobdata blob = t_serializable_object_to_blob(static_cast(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 +1974,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(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* 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(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& tx_hashes, crypto::hash& h) - { - tree_hash(tx_hashes.data(), tx_hashes.size(), h); - } - //--------------------------------------------------------------- - crypto::hash get_tx_tree_hash(const std::vector& 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 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) { diff --git a/src/currency_core/currency_format_utils.h b/src/currency_core/currency_format_utils.h index bc6d7da3..6932fa85 100644 --- a/src/currency_core/currency_format_utils.h +++ b/src/currency_core/currency_format_utils.h @@ -11,10 +11,12 @@ #include #include -#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 -std::ostream &print256(std::ostream &o, const T &v) { - return o << "<" << epee::string_tools::pod_to_hex(v) << ">"; -} -template -std::ostream &print16(std::ostream &o, const T &v) { - return o << "<" << epee::string_tools::pod_to_hex(v).substr(0, 5) << "..>"; -} -template -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 - std::string print_t_array(const std::vector& 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& 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); @@ -390,18 +351,6 @@ namespace currency 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& gindices); - /************************************************************************/ - /* */ - /************************************************************************/ - template - struct array_hasher : std::unary_function - { - std::size_t operator()(const t_array& val) const - { - return boost::hash_range(&val.data[0], &val.data[sizeof(val.data)]); - } - }; - template typename std::conditional::value, const std::vector, std::vector >::type& get_txin_etc_options(t_txin_v& in) { @@ -450,17 +399,6 @@ namespace currency bool have_attachment_service_in_container(const std::vector& 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 - result_type get_pod_checksum(const t_pod_type& bl) - { - const unsigned char* pbuf = reinterpret_cast(&bl); - result_type summ = 0; - for (size_t i = 0; i != sizeof(t_pod_type)-1; i++) - summ += pbuf[i]; - - return summ; - } //--------------------------------------------------------------- template 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 +407,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 - 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 - 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 - 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(ai); - return true; - } - } - return false; - } - //--------------------------------------------------------------- - template - bool check_allowed_types_in_variant_container(const variant_container_t& container, const std::unordered_set& 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 - 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 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 - 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 bool validate_attachment_info(const t_container& container, const std::vector& attachments, bool allow_no_info_for_non_empty_attachments_container) @@ -692,51 +553,7 @@ namespace currency return true; } - //--------------------------------------------------------------- - template - bool get_object_hash(const t_object& o, crypto::hash& res) - { - get_blob_hash(t_serializable_object_to_blob(o), res); - return true; - } - //--------------------------------------------------------------- - template - crypto::hash get_object_hash(const t_object& o) - { - crypto::hash h; - get_object_hash(o, h); - return h; - } - //--------------------------------------------------------------- - template - 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 - 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 - std::string obj_to_json_str(const T& obj) - { - std::stringstream ss; - json_archive ar(ss, true); - bool r = ::serialization::serialize(ar, const_cast(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 @@ -843,18 +660,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& tx_hashes, crypto::hash& h); - crypto::hash get_tx_tree_hash(const std::vector& 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(variant_var); - struct input_amount_getter : public boost::static_visitor { template @@ -866,7 +671,6 @@ namespace currency { return boost::apply_visitor(input_amount_getter(), v); } - //--------------------------------------------------------------- std::ostream& operator <<(std::ostream& o, const ref_by_id& r); //--------------------------------------------------------------- diff --git a/src/currency_core/currency_format_utils_abstract.h b/src/currency_core/currency_format_utils_abstract.h new file mode 100644 index 00000000..6908c5cd --- /dev/null +++ b/src/currency_core/currency_format_utils_abstract.h @@ -0,0 +1,217 @@ +// 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 +#include +#include +#include + + +#include "include_base_utils.h" +#include "serialization/keyvalue_serialization.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 + std::string print_kv_structure(const type_t& v) + { + return epee::serialization::store_t_to_json(v); + } + + template + std::string print_t_array(const std::vector& vec) + { + std::stringstream ss; + for (auto& v : vec) + ss << v << " "; + return ss.str(); + } + + /************************************************************************/ + /* */ + /************************************************************************/ + template + struct array_hasher : std::unary_function + { + std::size_t operator()(const t_array& val) const + { + return boost::hash_range(&val.data[0], &val.data[sizeof(val.data)]); + } + }; + + //------------------------------------------------------------------------------------ + template + result_type get_pod_checksum(const t_pod_type& bl) + { + const unsigned char* pbuf = reinterpret_cast(&bl); + result_type summ = 0; + for (size_t i = 0; i != sizeof(t_pod_type)-1; i++) + summ += pbuf[i]; + + return summ; + } + + template + bool parse_and_validate_object_from_blob(const blobdata& b_blob, object_t& b) + { + return t_unserializable_object_from_blob(b, b_blob); + } + //--------------------------------------------------------------- + template + 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 + 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 + 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(ai); + return true; + } + } + return false; + } + //--------------------------------------------------------------- + template + bool check_allowed_types_in_variant_container(const variant_container_t& container, const std::unordered_set& 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 + 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 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 + 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 + bool get_object_hash(const t_object& o, crypto::hash& res) + { + get_blob_hash(t_serializable_object_to_blob(o), res); + return true; + } + //--------------------------------------------------------------- + template + crypto::hash get_object_hash(const t_object& o) + { + crypto::hash h; + get_object_hash(o, h); + return h; + } + //--------------------------------------------------------------- + + template + size_t get_object_blobsize(const t_object& o) + { + blobdata b = t_serializable_object_to_blob(o); + return b.size(); + } + //--------------------------------------------------------------- + template + 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 + std::string obj_to_json_str(const T& obj) + { + std::stringstream ss; + json_archive ar(ss, true); + bool r = ::serialization::serialize(ar, const_cast(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(variant_var); + +} // namespace currency + + + diff --git a/src/currency_core/currency_format_utils_blocks.cpp b/src/currency_core/currency_format_utils_blocks.cpp new file mode 100644 index 00000000..b1ec69b9 --- /dev/null +++ b/src/currency_core/currency_format_utils_blocks.cpp @@ -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(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& tx_hashes, crypto::hash& h) + { + tree_hash(tx_hashes.data(), tx_hashes.size(), h); + } + //--------------------------------------------------------------- + crypto::hash get_tx_tree_hash(const std::vector& 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 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); + } +} diff --git a/src/currency_core/currency_format_utils_blocks.h b/src/currency_core/currency_format_utils_blocks.h new file mode 100644 index 00000000..e1a3eb41 --- /dev/null +++ b/src/currency_core/currency_format_utils_blocks.h @@ -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& tx_hashes, crypto::hash& h); + crypto::hash get_tx_tree_hash(const std::vector& tx_hashes); + crypto::hash get_tx_tree_hash(const block& b); + +} diff --git a/src/currency_core/currency_format_utils_transactions.cpp b/src/currency_core/currency_format_utils_transactions.cpp new file mode 100644 index 00000000..533313ae --- /dev/null +++ b/src/currency_core/currency_format_utils_transactions.cpp @@ -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 a(s); + ::serialization::serialize(a, const_cast(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 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 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(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(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(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* 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(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); + } + +} \ No newline at end of file diff --git a/src/currency_core/currency_format_utils_transactions.h b/src/currency_core/currency_format_utils_transactions.h new file mode 100644 index 00000000..a4937fae --- /dev/null +++ b/src/currency_core/currency_format_utils_transactions.h @@ -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); +} \ No newline at end of file diff --git a/src/currency_protocol/currency_protocol_defs.h b/src/currency_protocol/currency_protocol_defs.h index 3164749c..73b85e17 100644 --- a/src/currency_protocol/currency_protocol_defs.h +++ b/src/currency_protocol/currency_protocol_defs.h @@ -104,7 +104,7 @@ namespace currency { std::list txs; std::list blocks; - std::list missed_ids; + std::list missed_ids; uint64_t current_blockchain_height; BEGIN_KV_SERIALIZE_MAP() @@ -168,3 +168,5 @@ namespace currency }; } + +#include "currency_protocol_defs_print.h" diff --git a/src/currency_protocol/currency_protocol_defs_print.h b/src/currency_protocol/currency_protocol_defs_print.h new file mode 100644 index 00000000..67442ecf --- /dev/null +++ b/src/currency_protocol/currency_protocol_defs_print.h @@ -0,0 +1,44 @@ +// 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& 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; + + i++; + } + 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(); + } + +} \ No newline at end of file diff --git a/src/currency_protocol/currency_protocol_handler.inl b/src/currency_protocol/currency_protocol_handler.inl index 7fa2e80c..f81d261a 100644 --- a/src/currency_protocol/currency_protocol_handler.inl +++ b/src/currency_protocol/currency_protocol_handler.inl @@ -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 @@ -355,6 +355,8 @@ namespace currency template int t_currency_protocol_handler::handle_request_get_objects(int command, NOTIFY_REQUEST_GET_OBJECTS::request& arg, currency_connection_context& context) { + 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 +369,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("[HANDLE]NOTIFY_REQUEST_GET_OBJECTS, response 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(rsp, context); return 1; } @@ -383,11 +389,16 @@ 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 int t_currency_protocol_handler::handle_response_get_objects(int command, NOTIFY_RESPONSE_GET_OBJECTS::request& arg, currency_connection_context& context) { + LOG_PRINT_L3("[HANDLE]NOTIFY_RESPONSE_GET_OBJECTS: " << ENDL << currency::print_kv_structure(arg)); LOG_PRINT_L2("NOTIFY_RESPONSE_GET_OBJECTS"); if(context.m_last_response_height > arg.current_blockchain_height) { @@ -511,7 +522,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; @@ -600,6 +612,7 @@ namespace currency } 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_L3("[NOTIFY]NOTIFY_REQUEST_GET_OBJECTS: " << ENDL << currency::print_kv_structure(req)); post_notify(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 @@ -725,6 +738,7 @@ namespace currency template int t_currency_protocol_handler::handle_response_chain_entry(int command, NOTIFY_RESPONSE_CHAIN_ENTRY::request& arg, currency_connection_context& context) { + LOG_PRINT_L3("[HANDLE]NOTIFY_RESPONSE_CHAIN_ENTRY: " << ENDL << currency::print_kv_structure(arg)); LOG_PRINT_L2("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); From c121c7f20fc1b74a275c60c87d5906ed9b8b670a Mon Sep 17 00:00:00 2001 From: "crypro.zoidberg" Date: Thu, 14 Feb 2019 02:13:35 +0100 Subject: [PATCH 07/20] fixed linux build --- src/currency_core/currency_format_utils_abstract.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/currency_core/currency_format_utils_abstract.h b/src/currency_core/currency_format_utils_abstract.h index 6908c5cd..01c88c26 100644 --- a/src/currency_core/currency_format_utils_abstract.h +++ b/src/currency_core/currency_format_utils_abstract.h @@ -13,6 +13,8 @@ #include "include_base_utils.h" #include "serialization/keyvalue_serialization.h" +#include "storages/portable_storage_from_json.h" +#include "storages/portable_storage_to_json.h" #include "crypto/crypto.h" #include "crypto/hash.h" #include "currency_core/currency_basic.h" From 1c508a7abc7628bec4f267b3e10eb67b9f68cbd4 Mon Sep 17 00:00:00 2001 From: "crypro.zoidberg" Date: Thu, 14 Feb 2019 02:25:48 +0100 Subject: [PATCH 08/20] fixed linux build2 --- src/currency_core/currency_format_utils_abstract.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/currency_core/currency_format_utils_abstract.h b/src/currency_core/currency_format_utils_abstract.h index 01c88c26..142740ad 100644 --- a/src/currency_core/currency_format_utils_abstract.h +++ b/src/currency_core/currency_format_utils_abstract.h @@ -13,8 +13,7 @@ #include "include_base_utils.h" #include "serialization/keyvalue_serialization.h" -#include "storages/portable_storage_from_json.h" -#include "storages/portable_storage_to_json.h" +#include "storages/portable_storage_template_helper.h" #include "crypto/crypto.h" #include "crypto/hash.h" #include "currency_core/currency_basic.h" From 85eb6b0f08baa2fa92afda335cd18036f73f1008 Mon Sep 17 00:00:00 2001 From: "crypro.zoidberg" Date: Thu, 14 Feb 2019 03:11:03 +0100 Subject: [PATCH 09/20] more logs added --- src/currency_protocol/currency_protocol_handler.inl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/currency_protocol/currency_protocol_handler.inl b/src/currency_protocol/currency_protocol_handler.inl index f81d261a..d4382219 100644 --- a/src/currency_protocol/currency_protocol_handler.inl +++ b/src/currency_protocol/currency_protocol_handler.inl @@ -577,13 +577,15 @@ namespace currency template int t_currency_protocol_handler::handle_request_chain(int command, NOTIFY_REQUEST_CHAIN::request& arg, currency_connection_context& context) { + LOG_PRINT_L2("[HANDLE]NOTIFY_REQUEST_CHAIN: m_start_height=" << r.start_height << ", m_total_height=" << r.total_height << ", m_block_ids.size()=" << r.m_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_L3("[NOTIFY]NOTIFY_RESPONSE_CHAIN_ENTRY: " << print_kv_structure(r)); post_notify(r, context); return 1; } From 1f7da10b6667347a69efb58a89eb8cef54ce7f7d Mon Sep 17 00:00:00 2001 From: "crypro.zoidberg" Date: Thu, 14 Feb 2019 03:19:28 +0100 Subject: [PATCH 10/20] fixed bugs --- src/currency_protocol/currency_protocol_handler.inl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/currency_protocol/currency_protocol_handler.inl b/src/currency_protocol/currency_protocol_handler.inl index d4382219..4c37b5db 100644 --- a/src/currency_protocol/currency_protocol_handler.inl +++ b/src/currency_protocol/currency_protocol_handler.inl @@ -577,7 +577,7 @@ namespace currency template int t_currency_protocol_handler::handle_request_chain(int command, NOTIFY_REQUEST_CHAIN::request& arg, currency_connection_context& context) { - LOG_PRINT_L2("[HANDLE]NOTIFY_REQUEST_CHAIN: m_start_height=" << r.start_height << ", m_total_height=" << r.total_height << ", m_block_ids.size()=" << r.m_block_ids.size()); + 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)) @@ -585,6 +585,7 @@ namespace currency LOG_ERROR_CCONTEXT("Failed to handle NOTIFY_REQUEST_CHAIN."); return 1; } + 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(r, context); return 1; From 336b3b7d6772d4a0e0b47cbf4cd9484f71522528 Mon Sep 17 00:00:00 2001 From: "crypro.zoidberg" Date: Thu, 14 Feb 2019 04:01:01 +0100 Subject: [PATCH 11/20] added more logs --- .../currency_protocol_handler.inl | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/currency_protocol/currency_protocol_handler.inl b/src/currency_protocol/currency_protocol_handler.inl index 4c37b5db..617fb862 100644 --- a/src/currency_protocol/currency_protocol_handler.inl +++ b/src/currency_protocol/currency_protocol_handler.inl @@ -70,6 +70,8 @@ namespace currency { NOTIFY_REQUEST_CHAIN::request r = boost::value_initialized(); 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(r, context); } @@ -308,7 +310,8 @@ namespace currency NOTIFY_REQUEST_CHAIN::request r = boost::value_initialized(); 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(r, context); } @@ -355,6 +358,7 @@ namespace currency template int t_currency_protocol_handler::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) @@ -370,7 +374,7 @@ namespace currency m_p2p->drop_connection(context); } - LOG_PRINT_L2("[HANDLE]NOTIFY_REQUEST_GET_OBJECTS, response 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()); @@ -398,8 +402,8 @@ namespace currency template int t_currency_protocol_handler::handle_response_get_objects(int command, NOTIFY_RESPONSE_GET_OBJECTS::request& arg, currency_connection_context& context) { + 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)); - LOG_PRINT_L2("NOTIFY_RESPONSE_GET_OBJECTS"); 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 @@ -614,15 +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_L3("[NOTIFY]NOTIFY_REQUEST_GET_OBJECTS: " << ENDL << currency::print_kv_structure(req)); + 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(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(); 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(r, context); }else { @@ -636,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; @@ -741,9 +746,9 @@ namespace currency template int t_currency_protocol_handler::handle_response_chain_entry(int command, NOTIFY_RESPONSE_CHAIN_ENTRY::request& arg, currency_connection_context& context) { - LOG_PRINT_L3("[HANDLE]NOTIFY_RESPONSE_CHAIN_ENTRY: " << ENDL << currency::print_kv_structure(arg)); - 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()) { From d1d048f4b05debdb440794da0ef259ec952afb07 Mon Sep 17 00:00:00 2001 From: "crypro.zoidberg" Date: Thu, 14 Feb 2019 04:43:31 +0100 Subject: [PATCH 12/20] rewritten prining function to avoid binary output --- .../currency_protocol_defs_print.h | 49 ++++++++++++++++++- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/src/currency_protocol/currency_protocol_defs_print.h b/src/currency_protocol/currency_protocol_defs_print.h index 67442ecf..05ef76ee 100644 --- a/src/currency_protocol/currency_protocol_defs_print.h +++ b/src/currency_protocol/currency_protocol_defs_print.h @@ -23,17 +23,38 @@ namespace currency { ss << "UNPARSED" << ENDL; } - ss << get_block_hash(b) << ", parent: " << b.prev_id; + ss << get_block_hash(b) << "{....parent: " << b.prev_id << "....}" << ENDL; i++; } return ss.str(); } + template + 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; + 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); @@ -41,4 +62,28 @@ namespace currency 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(); + } + + } \ No newline at end of file From dc27c1404acb0640753f98c637d7c14953f6502b Mon Sep 17 00:00:00 2001 From: anonimal Date: Fri, 15 Feb 2019 23:19:10 +0000 Subject: [PATCH 13/20] contrib: update EOS portable archive to 5.1 Source: https://epa.codeplex.com/ --- .../eos/portable_archive_exception.hpp | 11 +++++----- .../eos/portable_iarchive.hpp | 17 +++++++-------- .../eos/portable_oarchive.hpp | 21 +++++++------------ 3 files changed, 21 insertions(+), 28 deletions(-) diff --git a/contrib/eos_portable_archive/eos/portable_archive_exception.hpp b/contrib/eos_portable_archive/eos/portable_archive_exception.hpp index fad9ed5f..719fc004 100644 --- a/contrib/eos_portable_archive/eos/portable_archive_exception.hpp +++ b/contrib/eos_portable_archive/eos/portable_archive_exception.hpp @@ -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 ); /** diff --git a/contrib/eos_portable_archive/eos/portable_iarchive.hpp b/contrib/eos_portable_archive/eos/portable_iarchive.hpp index 54540989..67763f22 100644 --- a/contrib/eos_portable_archive/eos/portable_iarchive.hpp +++ b/contrib/eos_portable_archive/eos/portable_iarchive.hpp @@ -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 #include -#if BOOST_VERSION >= 105600 -#include -#elif BOOST_VERSION >= 103500 +#if BOOST_VERSION >= 103500 && BOOST_VERSION < 105600 #include #endif @@ -135,7 +136,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 #include @@ -190,9 +191,7 @@ namespace eos { // load_override functions so we chose to stay one level higher , public boost::archive::basic_binary_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 +348,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(&temp); } diff --git a/contrib/eos_portable_archive/eos/portable_oarchive.hpp b/contrib/eos_portable_archive/eos/portable_oarchive.hpp index 67f3a695..01fc4497 100644 --- a/contrib/eos_portable_archive/eos/portable_oarchive.hpp +++ b/contrib/eos_portable_archive/eos/portable_oarchive.hpp @@ -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 #include #include -#if BOOST_VERSION >= 105600 -#include -#elif BOOST_VERSION >= 103500 -#include -#endif -#if BOOST_VERSION >= 104500 -#include -#include +#if BOOST_VERSION >= 103500 && BOOST_VERSION < 105600 +#include #endif // funny polymorphics @@ -142,7 +139,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 #include @@ -195,9 +192,7 @@ namespace eos { // save_override functions so we chose to stay one level higher , public boost::archive::basic_binary_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 From 3fa6bad35f5926b02991c090dfc73158f7e2f2b4 Mon Sep 17 00:00:00 2001 From: anonimal Date: Fri, 15 Feb 2019 23:33:16 +0000 Subject: [PATCH 14/20] contrib: fix EOS portable archive for Boost 1.69 Boost 1.69 (Spirit.X2/X3) has dropped their own FP routines in favor of boost::math. https://www.boost.org/users/history/version_1_69_0.html --- contrib/eos_portable_archive/eos/portable_iarchive.hpp | 5 +++-- contrib/eos_portable_archive/eos/portable_oarchive.hpp | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/contrib/eos_portable_archive/eos/portable_iarchive.hpp b/contrib/eos_portable_archive/eos/portable_iarchive.hpp index 67763f22..5d34b1d1 100644 --- a/contrib/eos_portable_archive/eos/portable_iarchive.hpp +++ b/contrib/eos_portable_archive/eos/portable_iarchive.hpp @@ -116,14 +116,15 @@ #include #elif BOOST_VERSION < 104800 #include +// Boost 1.69 (Spirit.X2/X3) has dropped their own FP routines in favor of boost::math +#elif BOOST_VERSION < 106900 #include #else #include -#include #endif // namespace alias -#if BOOST_VERSION < 103800 +#if BOOST_VERSION < 103800 || BOOST_VERSION >= 106900 namespace fp = boost::math; #else namespace fp = boost::spirit::math; diff --git a/contrib/eos_portable_archive/eos/portable_oarchive.hpp b/contrib/eos_portable_archive/eos/portable_oarchive.hpp index 01fc4497..ca94858b 100644 --- a/contrib/eos_portable_archive/eos/portable_oarchive.hpp +++ b/contrib/eos_portable_archive/eos/portable_oarchive.hpp @@ -119,14 +119,15 @@ #include #elif BOOST_VERSION < 104800 #include +// Boost 1.69 (Spirit.X2/X3) has dropped their own FP routines in favor of boost::math +#elif BOOST_VERSION < 106900 #include #else #include -#include #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; From f68a7cfa7acfec709f61ebb7d0429e3ce825f414 Mon Sep 17 00:00:00 2001 From: dev Date: Sat, 16 Feb 2019 03:04:08 +0300 Subject: [PATCH 15/20] peer log downloading --- src/common/util.cpp | 61 ++++++++++ src/common/util.h | 2 + src/connectivity_tool/conn_tool.cpp | 173 +++++++++++++++++++++++++++- src/p2p/net_node.h | 4 + src/p2p/net_node.inl | 40 ++++++- src/p2p/p2p_protocol_defs.h | 70 ++++++++++- 6 files changed, 347 insertions(+), 3 deletions(-) diff --git a/src/common/util.cpp b/src/common/util.cpp index 338e07dc..f470a5e6 100644 --- a/src/common/util.cpp +++ b/src/common/util.cpp @@ -526,4 +526,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(in.tellg()); + } + } diff --git a/src/common/util.h b/src/common/util.h index 2166b6ca..11374f8c 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -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 { diff --git a/src/connectivity_tool/conn_tool.cpp b/src/connectivity_tool/conn_tool.cpp index 1678ed4c..e73cbe49 100644 --- a/src/connectivity_tool/conn_tool.cpp +++ b/src/connectivity_tool/conn_tool.cpp @@ -54,6 +54,8 @@ namespace const command_line::arg_descriptor arg_generate_genesis = {"generate-genesis", "Generate genesis coinbase based on config file", "", true }; const command_line::arg_descriptor arg_genesis_split_amount = { "genesis-split-amount", "Set split amount for generating genesis block", 0, true }; const command_line::arg_descriptor arg_get_info_flags = { "getinfo-flags-hex", "Set of bits for rpc-get-daemon-info", "", true }; + const command_line::arg_descriptor arg_set_peer_log_level = { "set-peer-log-level", "Set log level for remote peer", 0, true }; + const command_line::arg_descriptor arg_download_peer_log = { "download-peer-log", "Download log from remote peer (starting offset)", 0, true }; } typedef COMMAND_REQUEST_STAT_INFO_T::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 +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(command_line::get_arg(vm, arg_port)), static_cast(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(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(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(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; diff --git a/src/p2p/net_node.h b/src/p2p/net_node.h index 6ae42925..b80d1639 100644 --- a/src/p2p/net_node.h +++ b/src/p2p/net_node.h @@ -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(); diff --git a/src/p2p/net_node.inl b/src/p2p/net_node.inl index 0ba340e4..b4813725 100644 --- a/src/p2p/net_node.inl +++ b/src/p2p/net_node.inl @@ -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 + int node_server::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(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 + int node_server::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(log_space::get_set_log_detalisation_level()); + log_space::get_set_log_detalisation_level(true, static_cast(req.new_log_level)); + rsp.current_log_level = static_cast(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 void node_server::request_callback(const epee::net_utils::connection_context_base& context) diff --git a/src/p2p/p2p_protocol_defs.h b/src/p2p/p2p_protocol_defs.h index ed245e39..fe1225f4 100644 --- a/src/p2p/p2p_protocol_defs.h +++ b/src/p2p/p2p_protocol_defs.h @@ -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 } From a870677f61ce685496c1f786cc82423cb3a9291b Mon Sep 17 00:00:00 2001 From: sowle Date: Sat, 16 Feb 2019 04:31:57 +0300 Subject: [PATCH 16/20] linux compilation fixed --- src/common/util.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/common/util.cpp b/src/common/util.cpp index f470a5e6..b2198312 100644 --- a/src/common/util.cpp +++ b/src/common/util.cpp @@ -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" From 2c7befce02e6a7d277c948ddc91055850c636805 Mon Sep 17 00:00:00 2001 From: anonimal Date: Sat, 16 Feb 2019 01:44:59 +0000 Subject: [PATCH 17/20] CMake: add Clang support for Linux --- CMakeLists.txt | 19 ++++++++++++------- contrib/db/CMakeLists.txt | 4 ++-- src/CMakeLists.txt | 2 +- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 911d69c1..6adb8998 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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() diff --git a/contrib/db/CMakeLists.txt b/contrib/db/CMakeLists.txt index bdd4381b..eb5c8415 100644 --- a/contrib/db/CMakeLists.txt +++ b/contrib/db/CMakeLists.txt @@ -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() - diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 44941fc2..85cb0d56 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -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() From 4997f1f9136f314155a8cad11e26762393804830 Mon Sep 17 00:00:00 2001 From: anonimal Date: Sat, 16 Feb 2019 01:48:21 +0000 Subject: [PATCH 18/20] README: update compiler type and version support --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ee524731..8d8c7a58 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,8 @@ Building ### Dependencies | component / version | minimum
(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 | From 2fc055ff15c076b6f2a20b0bcb1e76aa16820b7b Mon Sep 17 00:00:00 2001 From: "crypro.zoidberg" Date: Mon, 18 Feb 2019 14:40:48 +0100 Subject: [PATCH 19/20] sync some of epee libs with boolberry --- contrib/epee/include/misc_log_ex.h | 10 ---------- contrib/epee/include/net/http_protocol_handler.inl | 4 ++-- contrib/epee/include/syncobj.h | 5 +++++ 3 files changed, 7 insertions(+), 12 deletions(-) diff --git a/contrib/epee/include/misc_log_ex.h b/contrib/epee/include/misc_log_ex.h index c74378fc..412cb504 100644 --- a/contrib/epee/include/misc_log_ex.h +++ b/contrib/epee/include/misc_log_ex.h @@ -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 diff --git a/contrib/epee/include/net/http_protocol_handler.inl b/contrib/epee/include/net/http_protocol_handler.inl index dbc424af..b84bf47c 100644 --- a/contrib/epee/include/net/http_protocol_handler.inl +++ b/contrib/epee/include/net/http_protocol_handler.inl @@ -345,7 +345,7 @@ namespace net_utils template bool simple_http_connection_handler::handle_invoke_query_line() { - LOG_FRAME("simple_http_connection_handler::handle_recognize_protocol_out(*)", LOG_LEVEL_3); + LOG_FRAME("simple_http_connection_handler::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 @@ -693,4 +693,4 @@ namespace net_utils POP_WARNINGS //-------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------- -//-------------------------------------------------------------------------------------------- \ No newline at end of file +//-------------------------------------------------------------------------------------------- diff --git a/contrib/epee/include/syncobj.h b/contrib/epee/include/syncobj.h index f20bff07..c31b5e0c 100644 --- a/contrib/epee/include/syncobj.h +++ b/contrib/epee/include/syncobj.h @@ -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) } From 7676fc99b78511e90b494d00575c60329394bb1e Mon Sep 17 00:00:00 2001 From: "crypro.zoidberg" Date: Mon, 18 Feb 2019 19:40:12 +0100 Subject: [PATCH 20/20] mved to 25 word seed phrase --- src/common/mnemonic-encoding.cpp | 15 +++++++++ src/common/mnemonic-encoding.h | 2 +- src/crypto/crypto.cpp | 35 ++++++++------------- src/crypto/crypto.h | 25 +++++---------- src/currency_core/account.cpp | 32 ++++++++++++------- src/currency_core/account.h | 4 +-- src/currency_core/currency_format_utils.cpp | 23 +++++++++----- src/currency_core/currency_format_utils.h | 2 ++ 8 files changed, 77 insertions(+), 61 deletions(-) diff --git a/src/common/mnemonic-encoding.cpp b/src/common/mnemonic-encoding.cpp index 3b769860..e5f46641 100644 --- a/src/common/mnemonic-encoding.cpp +++ b/src/common/mnemonic-encoding.cpp @@ -34,11 +34,13 @@ // Copyright (c) 2014-2018 Zano Project // Copyright (c) 2014-2018 The Louisdor Project + #include #include #include #include #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; + } } } diff --git a/src/common/mnemonic-encoding.h b/src/common/mnemonic-encoding.h index a66167ec..409a935b 100644 --- a/src/common/mnemonic-encoding.h +++ b/src/common/mnemonic-encoding.h @@ -42,7 +42,7 @@ namespace tools { std::vector text2binary(const std::string& text); std::string binary2text(const std::vector& binary); - std::string word_by_num(uint64_t n); + std::string word_by_num(uint32_t n); uint64_t num_by_word(const std::string& w); } } diff --git a/src/crypto/crypto.cpp b/src/crypto/crypto.cpp index fab703cf..df6c31ed 100644 --- a/src/crypto/crypto.cpp +++ b/src/crypto/crypto.cpp @@ -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 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) diff --git a/src/crypto/crypto.h b/src/crypto/crypto.h index 0019c48e..d039eee8 100644 --- a/src/crypto/crypto.h +++ b/src/crypto/crypto.h @@ -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){ diff --git a/src/currency_core/account.cpp b/src/currency_core/account.cpp index a0612a58..ce8b177c 100644 --- a/src/currency_core/account.cpp +++ b/src/currency_core/account.cpp @@ -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"); @@ -69,7 +68,8 @@ namespace currency std::vector v; v.assign((unsigned char*)restore_buff.data(), (unsigned char*)restore_buff.data() + restore_buff.size()); std::string seed_brain_data = tools::mnemonic_encoding::binary2text(v); - //m_creation_timestamp + std::string timestamp_word = currency::get_word_from_timstamp(m_creation_timestamp); + seed_brain_data = seed_brain_data + timestamp_word; return seed_brain_data; } //----------------------------------------------------------------- @@ -78,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 { @@ -97,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 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 bin = tools::mnemonic_encoding::text2binary(restore_data); + std::vector 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() diff --git a/src/currency_core/account.h b/src/currency_core/account.h index b7569ae6..7e259731 100644 --- a/src/currency_core/account.h +++ b/src/currency_core/account.h @@ -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 diff --git a/src/currency_core/currency_format_utils.cpp b/src/currency_core/currency_format_utils.cpp index 903683e9..673092ca 100644 --- a/src/currency_core/currency_format_utils.cpp +++ b/src/currency_core/currency_format_utils.cpp @@ -1210,14 +1210,23 @@ namespace currency return reward; } //--------------------------------------------------------------- -// std::string get_word_from_timstamp(uint64_t timestamp) -// { -// uint64_t date_offset = timestamp ? timestamp - WALLET_BRAIN_DATE_OFFSET : 0; -// date_offset = date_offset / WALLET_BRAIN_DATE_QUANTUM; -// -// return tools::mnemonic_encoding::word_by_num(timestamp); -// } + 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::max(), "internal error: unable to converto to uint32, val = " << weeks_count); + uint32_t weeks_count_32 = static_cast(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 */) { diff --git a/src/currency_core/currency_format_utils.h b/src/currency_core/currency_format_utils.h index 6932fa85..263e258c 100644 --- a/src/currency_core/currency_format_utils.h +++ b/src/currency_core/currency_format_utils.h @@ -350,6 +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& gindices); + std::string get_word_from_timstamp(uint64_t timestamp); + uint64_t get_timstamp_from_word(std::string word); template typename std::conditional::value, const std::vector, std::vector >::type& get_txin_etc_options(t_txin_v& in)