diff --git a/CMakeLists.txt b/CMakeLists.txt index d6b61e72..f21fb093 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -185,10 +185,7 @@ endif() message("CMAKE_SYSTEM_NAME: ${CMAKE_SYSTEM_NAME}") if(CMAKE_SYSTEM_NAME STREQUAL "iOS") - set(Boost_INCLUDE_DIRS "/Users/roky/projects/Zano/mobile_repo/ofxiOSBoost/libs/boost/include") - set(Boost_LIBRARY_DIRS "/Users/roky/projects/Zano/mobile_repo/ofxiOSBoost/libs/boost/ios/") set(Boost_LIBRARIES "libboost.a") - set(Boost_VERSION "ofxiOSBoost 1.60.0") #workaround for new XCode 12 policy for builds(now it includes a slice for the "arm64" when builds for simulator) set(__iphoneos_archs "armv7 armv7s arm64") set(__iphonesimulator_archs "i386 x86_64") @@ -197,10 +194,8 @@ if(CMAKE_SYSTEM_NAME STREQUAL "iOS") set(CMAKE_XCODE_ATTRIBUTE_ARCHS[sdk=iphonesimulator*] "${__iphonesimulator_archs}") set(CMAKE_XCODE_ATTRIBUTE_VALID_ARCHS[sdk=iphonesimulator*] "${__iphonesimulator_archs}") elseif(CMAKE_SYSTEM_NAME STREQUAL "Android") - set(Boost_INCLUDE_DIRS "/Users/roky/projects/Zano/mobile_repo/Boost-for-Android-Prebuilt/1.69.0/include") - set(Boost_LIBRARY_DIRS "/Users/roky/projects/Zano/mobile_repo/Boost-for-Android-Prebuilt/1.69.0/libs/llvm/${CMAKE_ANDROID_ARCH_ABI}/") + set(Boost_LIBRARY_DIRS "${Boost_LIBRARY_DIRS}/${CMAKE_ANDROID_ARCH_ABI}/") set(Boost_LIBRARIES "${Boost_LIBRARY_DIRS}libboost_system.a;${Boost_LIBRARY_DIRS}libboost_filesystem.a;${Boost_LIBRARY_DIRS}libboost_thread.a;${Boost_LIBRARY_DIRS}libboost_timer.a;${Boost_LIBRARY_DIRS}libboost_date_time.a;${Boost_LIBRARY_DIRS}libboost_chrono.a;${Boost_LIBRARY_DIRS}libboost_regex.a;${Boost_LIBRARY_DIRS}libboost_serialization.a;${Boost_LIBRARY_DIRS}libboost_atomic.a;${Boost_LIBRARY_DIRS}libboost_program_options.a") - set(Boost_VERSION "PurpleI2PBoost 1.69.0") else() find_package(Boost 1.55 REQUIRED COMPONENTS system filesystem thread timer date_time chrono regex serialization atomic program_options locale) endif() diff --git a/contrib/epee/include/net/abstract_tcp_server2.inl b/contrib/epee/include/net/abstract_tcp_server2.inl index 6e57b54a..2bb45f69 100644 --- a/contrib/epee/include/net/abstract_tcp_server2.inl +++ b/contrib/epee/include/net/abstract_tcp_server2.inl @@ -588,10 +588,18 @@ bool boosted_tcp_server::timed_wait_server_stop(uint64_t wai TRY_ENTRY(); boost::chrono::milliseconds ms(wait_mseconds); for(std::size_t i = 0; i < m_threads.size(); ++i) { - if(m_threads[i]->joinable() && !m_threads[i]->try_join_for(ms)) { +#ifdef ANDROID_BUILD + if (m_threads[i]->joinable()) + { + m_threads[i]->join(); + } +#else + if (m_threads[i]->joinable() && !m_threads[i]->try_join_for(ms)) + { LOG_PRINT_L0("Interrupting thread " << m_threads[i]->native_handle()); m_threads[i]->interrupt(); } +#endif } return true; CATCH_ENTRY_L0("boosted_tcp_server::timed_wait_server_stop", false); diff --git a/contrib/epee/include/serialization/keyvalue_serialization.h b/contrib/epee/include/serialization/keyvalue_serialization.h index 31a4fb8b..31c90df7 100644 --- a/contrib/epee/include/serialization/keyvalue_serialization.h +++ b/contrib/epee/include/serialization/keyvalue_serialization.h @@ -115,7 +115,7 @@ public: \ template inline static bool get_value_of_flag_by_mask(const t_uint& given_flags) { - return given_flags&mask == 0 ? false : true; + return (given_flags&mask) == 0 ? false : true; } }; diff --git a/src/common/boost_serialization_helper.h b/src/common/boost_serialization_helper.h index 2ba8a52c..5ad68a05 100644 --- a/src/common/boost_serialization_helper.h +++ b/src/common/boost_serialization_helper.h @@ -12,6 +12,7 @@ + #define CHECK_PROJECT_NAME() std::string project_name = CURRENCY_NAME; ar & project_name; if(!(project_name == CURRENCY_NAME) ) {throw std::runtime_error(std::string("wrong storage file: project name in file: ") + project_name + ", expected: " + CURRENCY_NAME );} diff --git a/src/common/error_codes.h b/src/common/error_codes.h index 648bd6fd..7b77fec3 100644 --- a/src/common/error_codes.h +++ b/src/common/error_codes.h @@ -40,3 +40,4 @@ #define API_RETURN_CODE_TX_IS_TOO_BIG "TX_IS_TOO_BIG" #define API_RETURN_CODE_TX_REJECTED "TX_REJECTED" #define API_RETURN_CODE_HTLC_ORIGIN_HASH_MISSMATCHED "HTLC_ORIGIN_HASH_MISSMATCHED" +#define API_RETURN_CODE_WRAP "WRAP" \ No newline at end of file diff --git a/src/currency_core/currency_config.h b/src/currency_core/currency_config.h index 1b658a69..bda8f652 100644 --- a/src/currency_core/currency_config.h +++ b/src/currency_core/currency_config.h @@ -148,7 +148,9 @@ #define WALLET_FILE_SIGNATURE_OLD 0x1111012101101011LL // Bender's nightmare #define WALLET_FILE_SIGNATURE_V2 0x1111011201101011LL // another Bender's nightmare -#define WALLET_FILE_BINARY_HEADER_VERSION 1001 +#define WALLET_FILE_BINARY_HEADER_VERSION_INITAL 1000 +#define WALLET_FILE_BINARY_HEADER_VERSION_2 1001 +//#define WALLET_FILE_BINARY_HEADER_VERSION_3 1002 #define WALLET_FILE_MAX_KEYS_SIZE 10000 // #define WALLET_BRAIN_DATE_OFFSET 1543622400 @@ -223,9 +225,11 @@ #define BC_OFFERS_CURRENT_OFFERS_SERVICE_ARCHIVE_VER CURRENCY_FORMATION_VERSION + BLOCKCHAIN_STORAGE_MAJOR_COMPATIBILITY_VERSION + 9 #define BC_OFFERS_CURRENCY_MARKET_FILENAME "market.bin" - +#ifndef TESTNET +#define WALLET_FILE_SERIALIZATION_VERSION 153 +#else #define WALLET_FILE_SERIALIZATION_VERSION (CURRENCY_FORMATION_VERSION+69) - +#endif #define CURRENT_MEMPOOL_ARCHIVE_VER (CURRENCY_FORMATION_VERSION+31) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 10bb0475..f8cc2fb6 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -2669,18 +2669,25 @@ void wallet2::load(const std::wstring& wallet_, const std::string& password) load_keys(keys_buff, password, wbh.m_signature, kf_data); bool need_to_resync = false; - if (wbh.m_ver == 1000) + if (wbh.m_ver == WALLET_FILE_BINARY_HEADER_VERSION_INITAL) { // old WALLET_FILE_BINARY_HEADER_VERSION version means no encryption need_to_resync = !tools::portable_unserialize_obj_from_stream(*this, data_file); + WLT_LOG_L0("Detected format: WALLET_FILE_BINARY_HEADER_VERSION_INITAL(need_to_resync=" << need_to_resync << ")"); } - else + else if (wbh.m_ver == WALLET_FILE_BINARY_HEADER_VERSION_2) { tools::encrypt_chacha_in_filter decrypt_filter(password, kf_data.iv); boost::iostreams::filtering_istream in; in.push(decrypt_filter); in.push(data_file); need_to_resync = !tools::portable_unserialize_obj_from_stream(*this, in); + WLT_LOG_L0("Detected format: WALLET_FILE_BINARY_HEADER_VERSION_2(need_to_resync=" << need_to_resync << ")"); + } + else + { + WLT_LOG_L0("Unknown wallet body version(" << wbh.m_ver << "), resync initiated."); + need_to_resync = true; } @@ -2688,7 +2695,17 @@ void wallet2::load(const std::wstring& wallet_, const std::string& password) if (m_watch_only && !is_auditable()) load_keys2ki(true, need_to_resync); - WLT_LOG_L0("Loaded wallet file" << (m_watch_only ? " (WATCH ONLY) " : " ") << string_encoding::convert_to_ansii(m_wallet_file) << " with public address: " << m_account.get_public_address_str()); + boost::system::error_code ec = AUTO_VAL_INIT(ec); + m_current_wallet_file_size = boost::filesystem::file_size(wallet_, ec); + + WLT_LOG_L0("Loaded wallet file" << (m_watch_only ? " (WATCH ONLY) " : " ") << string_encoding::convert_to_ansii(m_wallet_file) + << " with public address: " << m_account.get_public_address_str() + << ", file_size=" << m_current_wallet_file_size + << ", blockchain_size: " << m_chain.get_blockchain_current_size() + ); + WLT_LOG_L0("[LOADING]Blockchain shortener state: " << ENDL << m_chain.get_internal_state_text()); + + WLT_LOG_L0("(after loading: pending_key_images: " << m_pending_key_images.size() << ", pki file elements: " << m_pending_key_images_file_container.size() << ", tx_keys: " << m_tx_keys.size() << ")"); if (need_to_resync) @@ -2697,9 +2714,6 @@ void wallet2::load(const std::wstring& wallet_, const std::string& password) WLT_LOG_L0("Unable to load history data from wallet file, wallet will be resynced!"); } - boost::system::error_code ec = AUTO_VAL_INIT(ec); - m_current_wallet_file_size = boost::filesystem::file_size(wallet_, ec); - THROW_IF_TRUE_WALLET_EX(need_to_resync, error::wallet_load_notice_wallet_restored, epee::string_encoding::convert_to_ansii(m_wallet_file)); } //---------------------------------------------------------------------------------------------------- @@ -2730,7 +2744,7 @@ void wallet2::store(const std::wstring& path_to_save, const std::string& passwor wbh.m_signature = WALLET_FILE_SIGNATURE_V2; wbh.m_cb_keys = keys_buff.size(); //@#@ change it to proper - wbh.m_ver = WALLET_FILE_BINARY_HEADER_VERSION; + wbh.m_ver = WALLET_FILE_BINARY_HEADER_VERSION_2; std::string header_buff((const char*)&wbh, sizeof(wbh)); uint64_t ts = m_core_runtime_config.get_core_time(); @@ -2761,8 +2775,10 @@ void wallet2::store(const std::wstring& path_to_save, const std::string& passwor data_file.flush(); data_file.close(); + boost::uintmax_t tmp_file_size = boost::filesystem::file_size(tmp_file_path); + WLT_LOG_L0("Stored successfully to temporary file " << tmp_file_path.string() << ", file size=" << tmp_file_size); - WLT_LOG_L1("Stored successfully to temporary file " << tmp_file_path.string()); + WLT_LOG_L0("[LOADING]Blockchain shortener state: " << ENDL << m_chain.get_internal_state_text()); // for the sake of safety perform a double-renaming: wallet file -> old tmp, new tmp -> wallet file, remove old tmp @@ -2791,7 +2807,9 @@ void wallet2::store(const std::wstring& path_to_save, const std::string& passwor m_current_wallet_file_size = boost::filesystem::file_size(path_to_save, ec); if (path_to_save_exists && !tmp_file_path_exists && !tmp_old_file_path_exists) { - WLT_LOG_L0("Wallet was successfully stored to " << ascii_path_to_save); + + WLT_LOG_L0("Wallet was successfully stored to " << ascii_path_to_save << ", file size=" << m_current_wallet_file_size + << " blockchain_size: " << m_chain.get_blockchain_current_size()); } else { diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 10d79bf6..fd79042a 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -698,6 +698,12 @@ namespace tools template inline void serialize(t_archive &a, const unsigned int ver) { + if (t_archive::is_saving::value) + { + WLT_LOG_MAGENTA("Serializing file with ver: " << ver, LOG_LEVEL_0); + } + + // do not load wallet if data version is greather than the code version if (ver > WALLET_FILE_SERIALIZATION_VERSION) { @@ -707,7 +713,7 @@ namespace tools if (ver < 149) { - WLT_LOG_MAGENTA("Wallet file truncated due to old version: " << ver, LOG_LEVEL_0); + WLT_LOG_MAGENTA("Wallet file truncated due to old version. ver: " << ver << ", WALLET_FILE_SERIALIZATION_VERSION=" << WALLET_FILE_SERIALIZATION_VERSION, LOG_LEVEL_0); return; } diff --git a/src/wallet/wallet_chain_shortener.cpp b/src/wallet/wallet_chain_shortener.cpp index 9d30cb5f..e353c1a6 100644 --- a/src/wallet/wallet_chain_shortener.cpp +++ b/src/wallet/wallet_chain_shortener.cpp @@ -274,6 +274,23 @@ void wallet_chain_shortener::check_if_block_matched(uint64_t i, const crypto::ha } } //---------------------------------------------------------------------------------------------------- +std::string wallet_chain_shortener::get_internal_state_text() const +{ + std::stringstream ss; +#define PRINT_CHAIN_SHORTENER_STATE_INFO(cont_name) \ + if (cont_name.size()) \ + { \ + ss << #cont_name << ".size(): [" << cont_name.begin()->first << ": " << cont_name.begin()->second << "]" << ENDL; \ + } + + PRINT_CHAIN_SHORTENER_STATE_INFO(m_last_20_blocks); + PRINT_CHAIN_SHORTENER_STATE_INFO(m_last_144_blocks_every_10); + PRINT_CHAIN_SHORTENER_STATE_INFO(m_last_144_blocks_every_100); + PRINT_CHAIN_SHORTENER_STATE_INFO(m_last_144_blocks_every_1000); + ss << "m_local_bc_size = " << m_local_bc_size << ENDL; + return ss.str(); +} +//---------------------------------------------------------------------------------------------------- void clean_map_from_items_above(std::map& container, uint64_t height) { while (container.size() && (--container.end())->first >= height) diff --git a/src/wallet/wallet_chain_shortener.h b/src/wallet/wallet_chain_shortener.h index 2ea61366..500c2494 100644 --- a/src/wallet/wallet_chain_shortener.h +++ b/src/wallet/wallet_chain_shortener.h @@ -46,7 +46,7 @@ public: } //debug functions - + std::string get_internal_state_text() const; private: std::atomic m_local_bc_size; //temporary workaround crypto::hash m_genesis; diff --git a/src/wallet/wallet_errors.h b/src/wallet/wallet_errors.h index efafaf97..c2636d70 100644 --- a/src/wallet/wallet_errors.h +++ b/src/wallet/wallet_errors.h @@ -385,14 +385,20 @@ namespace tools std::string to_string() const { std::ostringstream ss; - ss << transfer_error::to_string() << ", mixin_count = " << m_mixin_count << ", scanty_outs:"; - for (const auto& outs_for_amount : m_scanty_outs) - { - ss << '\n' << currency::print_money(outs_for_amount.amount) << " - " << outs_for_amount.outs.size(); - } + ss << API_RETURN_CODE_NOT_ENOUGH_OUTPUTS_FOR_MIXING; + //ss << transfer_error::to_string() << ", mixin_count = " << m_mixin_count << ", scanty_outs:"; + //for (const auto& outs_for_amount : m_scanty_outs) + //{ + // ss << '\n' << currency::print_money(outs_for_amount.amount) << " - " << outs_for_amount.outs.size(); + //} return ss.str(); } + virtual const char* what() const noexcept + { + return API_RETURN_CODE_NOT_ENOUGH_OUTPUTS_FOR_MIXING; + } + private: scanty_outs_t m_scanty_outs; size_t m_mixin_count; @@ -534,14 +540,18 @@ namespace tools std::string to_string() const { std::ostringstream ss; - currency::transaction tx = m_tx; - ss << transfer_error::to_string() << - ", tx_size_limit = " << m_tx_size_limit << - ", tx size = " << get_object_blobsize(m_tx) << - ", tx:\n" << currency::obj_to_json_str(tx); + ss << API_RETURN_CODE_TX_IS_TOO_BIG; + //currency::transaction tx = m_tx; + //ss << transfer_error::to_string() << + // ", tx_size_limit = " << m_tx_size_limit << + // ", tx size = " << get_object_blobsize(m_tx) << + // ", tx:\n" << currency::obj_to_json_str(tx); return ss.str(); } - + virtual const char* what() const noexcept + { + return API_RETURN_CODE_TX_IS_TOO_BIG; + } private: currency::transaction m_tx; uint64_t m_tx_size_limit; diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index aca13701..dd11b4ba 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -16,6 +16,7 @@ using namespace epee; #include "crypto/hash.h" #include "wallet_rpc_server_error_codes.h" #include "wallet_helpers.h" +#include "wrap_service.h" #define WALLET_RPC_BEGIN_TRY_ENTRY() try { #define WALLET_RPC_CATCH_TRY_ENTRY() } \ @@ -303,7 +304,24 @@ namespace tools currency::tx_destination_entry de; de.addr.resize(1); std::string embedded_payment_id; - if(!m_wallet.get_transfer_address(it->address, de.addr.back(), embedded_payment_id)) + //check if address looks like wrapped address + if (currency::is_address_like_wrapped(it->address)) + { + LOG_PRINT_L0("Address " << it->address << " recognized as wrapped address, creating wrapping transaction..."); + //put into service attachment specially encrypted entry which will contain wrap address and network + currency::tx_service_attachment sa = AUTO_VAL_INIT(sa); + sa.service_id = BC_WRAP_SERVICE_ID; + sa.instruction = BC_WRAP_SERVICE_INSTRUCTION_ERC20; + sa.flags = TX_SERVICE_ATTACHMENT_ENCRYPT_BODY | TX_SERVICE_ATTACHMENT_ENCRYPT_BODY_ISOLATE_AUDITABLE; + sa.body = it->address; + ctp.extra.push_back(sa); + + currency::account_public_address acc = AUTO_VAL_INIT(acc); + currency::get_account_address_from_str(acc, BC_WRAP_SERVICE_CUSTODY_WALLET); + de.addr.front() = acc; + //encrypt body with a special way + } + else if(!m_wallet.get_transfer_address(it->address, de.addr.back(), embedded_payment_id)) { er.code = WALLET_RPC_ERROR_CODE_WRONG_ADDRESS; er.message = std::string("WALLET_RPC_ERROR_CODE_WRONG_ADDRESS: ") + it->address; diff --git a/src/wallet/wallets_manager.cpp b/src/wallet/wallets_manager.cpp index 4dbba747..6d8d6456 100644 --- a/src/wallet/wallets_manager.cpp +++ b/src/wallet/wallets_manager.cpp @@ -1755,7 +1755,7 @@ std::string wallets_manager::validate_address(const std::string& addr_str, std:: currency::account_public_address acc = AUTO_VAL_INIT(acc); if (currency::is_address_like_wrapped(addr_str)) { - return API_RETURN_CODE_TRUE; + return API_RETURN_CODE_WRAP; } else if (currency::get_account_address_and_payment_id_from_str(acc, payment_id, addr_str)) return API_RETURN_CODE_TRUE; diff --git a/tests/functional_tests/plain_wallet_tests.cpp b/tests/functional_tests/plain_wallet_tests.cpp index f6efe29f..f1f9f36b 100644 --- a/tests/functional_tests/plain_wallet_tests.cpp +++ b/tests/functional_tests/plain_wallet_tests.cpp @@ -40,11 +40,19 @@ void run_plain_wallet_api_test() std::string res = plain_wallet::sync_call("get_seed_phrase_info", 0, "{\"seed_phrase\":\"aZxat4HAWriVQ3enkGcVsrZRdMseAJswG3CSEwTqZS246VsFQ53w26eZstYsu1jWE74Atz9ajLxFnBsVTafncWNH5SMv4zHFaTS:1780c4d5dd7e97cc4a75ea8baa7977d12ef948b9a6dddc2a9a37e5e22ac7180e:1599495055\"}"); - res = plain_wallet::restore("footstep knowledge fur capture honey minute carefully peaceful lovely crawl lunch government nightmare friendship myself sign possibly plan flower depression bread rainbow wrong hardly dark chest", - "test_wall2.zan", "111", ""); +// res = plain_wallet::restore("footstep knowledge fur capture honey minute carefully peaceful lovely crawl lunch government nightmare friendship myself sign possibly plan flower depression bread rainbow wrong hardly dark chest", +// "test_wall2.zan", "111", ""); + +// epee::misc_utils::sleep_no_w(30000); + +// plain_wallet::close_wallet(0); + res = plain_wallet::open("test_wall2.zan", "111"); + res = plain_wallet::close_wallet(0); - epee::misc_utils::sleep_no_w(10000000); + res = plain_wallet::invoke(0, "{\"method\":\"transfer\",\"params\":{\"destinations\":[{\"amount\":10000000000,\"address\":\"aZxat4HAWriVQ3enkGcVsrZRdMseAJswG3CSEwTqZS246VsFQ53w26eZstYsu1jWE74Atz9ajLxFnBsVTafncWNH5SMv4zHFaTS\"}],\"fee\":10000000000,\"mixin\":1011111,\"payment_id\":\"\",\"push_payer\":true,\"hide_receiver\":false}}"); + + //epee::misc_utils::sleep_no_w(10000000); //std::string key = plain_wallet::generate_random_key(10); //std::string test_data = "1234567890 test test ";