From 1c92def934f179209a600f7fda970c1327006236 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Sat, 11 Jul 2020 18:42:59 +0200 Subject: [PATCH 1/5] implemented export of mobile app data --- src/common/util.cpp | 56 +++++++++++++++++++ src/common/util.h | 1 + src/wallet/plain_wallet_api.cpp | 25 +++++++++ src/wallet/plain_wallet_api.h | 1 + tests/core_tests/chaingen_helpers.h | 1 + .../core_concurrency_test.cpp | 6 +- tests/functional_tests/plain_wallet_tests.cpp | 1 + 7 files changed, 88 insertions(+), 3 deletions(-) diff --git a/src/common/util.cpp b/src/common/util.cpp index 6fa15854..f5d4baa9 100644 --- a/src/common/util.cpp +++ b/src/common/util.cpp @@ -695,4 +695,60 @@ std::string get_nix_version_display_string() return true; } + //this code was taken from https://stackoverflow.com/a/8594696/5566653 + //credits goes to @nijansen: https://stackoverflow.com/users/1056003/nijansen + bool copy_dir( boost::filesystem::path const & source, boost::filesystem::path const & destination) + { + namespace fs = boost::filesystem; + try + { + // Check whether the function call is valid + if (!fs::exists(source) ||!fs::is_directory(source)) + { + LOG_ERROR("Source directory " << source.string() << " does not exist or is not a directory."); + return false; + } + if (!fs::exists(destination)) + { + if (!fs::create_directory(destination)) + { + LOG_ERROR("Unable to create destination directory" << destination.string()); + return false; + } + } + // Create the destination directory + } + catch (fs::filesystem_error const & e) + { + LOG_ERROR("Exception: " << e.what()); + return false; + } + // Iterate through the source directory + for (fs::directory_iterator file(source); file != fs::directory_iterator(); ++file) + { + try + { + fs::path current(file->path()); + if (fs::is_directory(current)) + { + // Found directory: Recursion + if (!copy_dir(current, destination / current.filename())) + { + return false; + } + } + else + { + // Found file: Copy + fs::copy_file( current, destination / current.filename()); + } + } + catch (fs::filesystem_error const & e) + { + LOG_ERROR("Exception: " << e.what()); + } + } + return true; + } + } // namespace tools diff --git a/src/common/util.h b/src/common/util.h index 1f31d263..6b683082 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -30,6 +30,7 @@ namespace tools std::string get_default_user_dir(); std::string get_current_username(); std::string get_os_version_string(); + bool copy_dir(boost::filesystem::path const & source, boost::filesystem::path const & destination); bool check_remote_client_version(const std::string& client_ver); bool create_directories_if_necessary(const std::string& path); diff --git a/src/wallet/plain_wallet_api.cpp b/src/wallet/plain_wallet_api.cpp index 259fa4cb..90b34f17 100644 --- a/src/wallet/plain_wallet_api.cpp +++ b/src/wallet/plain_wallet_api.cpp @@ -324,6 +324,31 @@ namespace plain_wallet return epee::serialization::store_t_to_json(sl); } + std::string get_export_private_info(const std::string& target_dir) + { + const std::string src_folder_path = get_bundle_working_dir(); + boost::system::error_code ec; + const std::string full_target_path = target_dir + "/Zano_export" + std::to_string(epee::misc_utils::get_tick_count()); + boost::filesystem::create_directory(full_target_path, ec); + if (ec) + { + LOG_ERROR("Failed to create target directory"); + epee::json_rpc::response ok_response = AUTO_VAL_INIT(ok_response); + ok_response.result.return_code = API_RETURN_CODE_FAIL; + return epee::serialization::store_t_to_json(ok_response); + } + if(!tools::copy_dir(src_folder_path, full_target_path)) + { + LOG_ERROR("Failed to copy target directory"); + epee::json_rpc::response ok_response = AUTO_VAL_INIT(ok_response); + ok_response.result.return_code = API_RETURN_CODE_FAIL; + return epee::serialization::store_t_to_json(ok_response); + } + epee::json_rpc::response ok_response = AUTO_VAL_INIT(ok_response); + ok_response.result.return_code = API_RETURN_CODE_OK; + return epee::serialization::store_t_to_json(ok_response); + } + std::string delete_wallet(const std::string& file_name) { std::string wallet_files_path = get_wallets_folder(); diff --git a/src/wallet/plain_wallet_api.h b/src/wallet/plain_wallet_api.h index c938ff30..610a96a3 100644 --- a/src/wallet/plain_wallet_api.h +++ b/src/wallet/plain_wallet_api.h @@ -15,6 +15,7 @@ namespace plain_wallet std::string set_log_level(int log_level); std::string get_version(); std::string get_wallet_files(); + std::string get_export_private_info(const std::string& target_dir); std::string delete_wallet(const std::string& file_name); std::string get_address_info(const std::string& addr); diff --git a/tests/core_tests/chaingen_helpers.h b/tests/core_tests/chaingen_helpers.h index 2e35652e..56cf4696 100644 --- a/tests/core_tests/chaingen_helpers.h +++ b/tests/core_tests/chaingen_helpers.h @@ -8,6 +8,7 @@ #include "currency_core/miner.h" #include "wallet/wallet2.h" #include "test_core_time.h" +#include "chaingen.h" // chaingen-independent helpers that may be used outside of core_tests (for ex. in functional_tests) diff --git a/tests/functional_tests/core_concurrency_test.cpp b/tests/functional_tests/core_concurrency_test.cpp index 52ff1b8c..42dd7d9a 100644 --- a/tests/functional_tests/core_concurrency_test.cpp +++ b/tests/functional_tests/core_concurrency_test.cpp @@ -26,7 +26,7 @@ std::atomic test_core_time::m_time_shift; #include "../core_tests/chaingen_helpers.h" #include "../core_tests/core_state_helper.h" -#define TESTS_DEFAULT_FEE TX_DEFAULT_FEE +//#define TESTS_DEFAULT_FEE TX_DEFAULT_FEE static std::atomic s_generated_money_total(0); // TODO: consiger changing to boost::multiprecision::uint128_t static size_t s_wallets_total_count = 10; // total number of wallet that will be randomly used to generate transactions @@ -40,8 +40,8 @@ typedef std::vector cct_events_t; typedef std::vector cct_accounts_t; typedef std::vector> cct_wallets_t; -static const std::vector empty_extra; -static const std::vector empty_attachment; +//static const std::vector empty_extra; +//static const std::vector empty_attachment; bool create_block_template_manually(const currency::block& prev_block, boost::multiprecision::uint128_t already_generated_coins, const std::vector& txs, const currency::account_public_address& miner_addr, currency::block& result) { diff --git a/tests/functional_tests/plain_wallet_tests.cpp b/tests/functional_tests/plain_wallet_tests.cpp index ad31d0f1..457dcefc 100644 --- a/tests/functional_tests/plain_wallet_tests.cpp +++ b/tests/functional_tests/plain_wallet_tests.cpp @@ -32,6 +32,7 @@ void run_plain_wallet_api_test() { LOG_PRINT_L0("Creating instance..."); std::string s = plain_wallet::init("195.201.107.230", "11211", boost::dll::program_location().parent_path().string(), 1); + s = plain_wallet::get_export_private_info("E:\\tmp\\check_export"); std::string key = plain_wallet::generate_random_key(10); std::string test_data = "1234567890 test test "; From 1110fb48eb95b1d7872739e5abac3afb401659aa Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Sat, 11 Jul 2020 20:00:15 +0200 Subject: [PATCH 2/5] added extra info to logs --- src/wallet/plain_wallet_api.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/plain_wallet_api.cpp b/src/wallet/plain_wallet_api.cpp index 90b34f17..084112d6 100644 --- a/src/wallet/plain_wallet_api.cpp +++ b/src/wallet/plain_wallet_api.cpp @@ -332,7 +332,7 @@ namespace plain_wallet boost::filesystem::create_directory(full_target_path, ec); if (ec) { - LOG_ERROR("Failed to create target directory"); + LOG_ERROR("Failed to create target directory(" << full_target_path << "):" << ec.message()); epee::json_rpc::response ok_response = AUTO_VAL_INIT(ok_response); ok_response.result.return_code = API_RETURN_CODE_FAIL; return epee::serialization::store_t_to_json(ok_response); From 315a601081b220d45c012bc4344800c6093adcd9 Mon Sep 17 00:00:00 2001 From: sowle Date: Mon, 13 Jul 2020 14:51:39 +0300 Subject: [PATCH 3/5] simplewallet: restore auditable watch-only wallets the same way as normals, --restore-awo-wallet option removed --- src/simplewallet/simplewallet.cpp | 28 ++++------------------------ src/simplewallet/simplewallet.h | 1 - 2 files changed, 4 insertions(+), 25 deletions(-) diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 975d2abe..0c6de832 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -52,7 +52,6 @@ namespace const command_line::arg_descriptor arg_do_pos_mining = { "do-pos-mining", "Do PoS mining", false, false }; const command_line::arg_descriptor arg_pos_mining_reward_address = { "pos-mining-reward-address", "Block reward will be sent to the giving address if specified", "" }; const command_line::arg_descriptor arg_restore_wallet = { "restore-wallet", "Restore wallet from the seed phrase and save it to ", "" }; - const command_line::arg_descriptor arg_restore_awo_wallet = { "restore-awo-wallet", "Restore auditable watch-only wallet from address and view key. Use \"address:viewkey\" as argument", "" }; const command_line::arg_descriptor arg_offline_mode = { "offline-mode", "Don't connect to daemon, work offline (for cold-signing process)", false, true }; const command_line::arg_descriptor< std::vector > arg_command = {"command", ""}; @@ -274,7 +273,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) return false; } - if (m_wallet_file.empty() && m_generate_new.empty() && m_restore_wallet.empty() && m_restore_awo_wallet.empty() && m_generate_new_aw.empty()) + if (m_wallet_file.empty() && m_generate_new.empty() && m_restore_wallet.empty() && m_generate_new_aw.empty()) { fail_msg_writer() << "you must specify --wallet-file, --generate-new-wallet, --generate-new-auditable-wallet, --restore-wallet or --restore-awo-wallet"; return false; @@ -332,31 +331,14 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) } tools::password_container restore_seed_container; - if (!restore_seed_container.read_password("please, enter wallet seed phrase:\n")) - { - fail_msg_writer() << "failed to read seed phrase"; - return false; - } - - bool r = restore_wallet(m_restore_wallet, restore_seed_container.password(), pwd_container.password(), false); - CHECK_AND_ASSERT_MES(r, false, "wallet restoring failed"); - } - else if (!m_restore_awo_wallet.empty()) - { - if (boost::filesystem::exists(m_restore_awo_wallet)) - { - fail_msg_writer() << "file " << m_restore_awo_wallet << " already exists"; - return false; - } - - tools::password_container restore_addr_and_viewkey_container; - if (!restore_addr_and_viewkey_container.read_password("please, enter wallet auditable address, viewkey and timestamp, separated by a colon (\"address:viewkey:timestamp\"):\n")) + if (!restore_seed_container.read_password("please, enter wallet seed phrase or an auditable wallet tracking key:\n")) { fail_msg_writer() << "failed to read seed phrase"; return false; } - bool r = restore_wallet(m_restore_awo_wallet, restore_addr_and_viewkey_container.password(), pwd_container.password(), true); + bool looks_like_tracking_seed = restore_seed_container.password().find(':') != std::string::npos; + bool r = restore_wallet(m_restore_wallet, restore_seed_container.password(), pwd_container.password(), looks_like_tracking_seed); CHECK_AND_ASSERT_MES(r, false, "wallet restoring failed"); } else @@ -387,7 +369,6 @@ void simple_wallet::handle_command_line(const boost::program_options::variables_ m_do_not_set_date = command_line::get_arg(vm, arg_dont_set_date); m_do_pos_mining = command_line::get_arg(vm, arg_do_pos_mining); m_restore_wallet = command_line::get_arg(vm, arg_restore_wallet); - m_restore_awo_wallet = command_line::get_arg(vm, arg_restore_awo_wallet); } //---------------------------------------------------------------------------------------------------- bool simple_wallet::try_connect_to_daemon() @@ -1778,7 +1759,6 @@ int main(int argc, char* argv[]) command_line::add_arg(desc_params, arg_do_pos_mining); command_line::add_arg(desc_params, arg_pos_mining_reward_address); command_line::add_arg(desc_params, arg_restore_wallet); - command_line::add_arg(desc_params, arg_restore_awo_wallet); command_line::add_arg(desc_params, arg_offline_mode); command_line::add_arg(desc_params, command_line::arg_log_file); command_line::add_arg(desc_params, command_line::arg_log_level); diff --git a/src/simplewallet/simplewallet.h b/src/simplewallet/simplewallet.h index 47d040a8..42862a59 100644 --- a/src/simplewallet/simplewallet.h +++ b/src/simplewallet/simplewallet.h @@ -167,7 +167,6 @@ namespace currency bool m_do_pos_mining; bool m_offline_mode; std::string m_restore_wallet; - std::string m_restore_awo_wallet; epee::console_handlers_binder m_cmd_binder; From b695cda21b330cb93ec7dd71cf70aa76a0ed50e3 Mon Sep 17 00:00:00 2001 From: sowle Date: Mon, 13 Jul 2020 14:54:32 +0300 Subject: [PATCH 4/5] rebuild m_db_addr_to_alias container as well when migrating to DB v95 --- src/currency_core/blockchain_storage.cpp | 41 ++++++++++++++++++++++-- src/currency_core/currency_basic.h | 1 + 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index 7fca4c8c..c22f9ad9 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -305,12 +305,19 @@ bool blockchain_storage::init(const std::string& config_folder, const boost::pro LOG_PRINT_MAGENTA("Migrating DB: " << m_db_storage_major_compatibility_version << " -> " << BLOCKCHAIN_STORAGE_MAJOR_COMPATIBILITY_VERSION, LOG_LEVEL_0); res = m_db_aliases.deinit(); - CHECK_AND_ASSERT_MES(res, false, "Unable to deinit db container"); + CHECK_AND_ASSERT_MES(res, false, "Unable to deinit m_db_aliases"); + res = m_db_addr_to_alias.deinit(); + CHECK_AND_ASSERT_MES(res, false, "Unable to deinit m_db_addr_to_alias"); typedef tools::db::cached_key_value_accessor, true, true> aliases_container_old; aliases_container_old db_aliases_old(m_db); res = db_aliases_old.init(BLOCKCHAIN_STORAGE_CONTAINER_ALIASES); - CHECK_AND_ASSERT_MES(res, false, "Unable to init db container"); + CHECK_AND_ASSERT_MES(res, false, "Unable to init db_aliases_old"); + + typedef tools::db::cached_key_value_accessor, true, false> address_to_aliases_container_old; + address_to_aliases_container_old db_addr_to_alias_old(m_db); + res = db_addr_to_alias_old.init(BLOCKCHAIN_STORAGE_CONTAINER_ADDR_TO_ALIAS); + CHECK_AND_ASSERT_MES(res, false, "Unable to init db_addr_to_alias_old"); // temporary set db compatibility version to zero during migration in order to trigger db reinit on the next lanunch in case the process stops in the middle m_db.begin_transaction(); @@ -329,19 +336,33 @@ bool blockchain_storage::init(const std::string& config_folder, const boost::pro return true; }); + typedef std::vector>> add_to_alias_container_t; + add_to_alias_container_t addr_to_alias_container; + db_addr_to_alias_old.enumerate_items([&addr_to_alias_container](uint64_t n, const account_public_address_old& addr_old, const std::set& aliases){ + addr_to_alias_container.emplace_back(std::make_pair(account_public_address::from_old(addr_old), aliases)); + return true; + }); + // clear and close old format container m_db.begin_transaction(); db_aliases_old.clear(); + db_addr_to_alias_old.clear(); m_db.commit_transaction(); db_aliases_old.deinit(); + db_addr_to_alias_old.deinit(); res = m_db_aliases.init(BLOCKCHAIN_STORAGE_CONTAINER_ALIASES); - CHECK_AND_ASSERT_MES(res, false, "Unable to init db container"); + CHECK_AND_ASSERT_MES(res, false, "Unable to init m_db_aliases"); + res = m_db_addr_to_alias.init(BLOCKCHAIN_STORAGE_CONTAINER_ADDR_TO_ALIAS); + CHECK_AND_ASSERT_MES(res, false, "Unable to init m_db_addr_to_alias"); // re-populate all alias entries back m_db.begin_transaction(); for(auto& el : temp_container) m_db_aliases.set(el.first, el.second); + + for(auto& el : addr_to_alias_container) + m_db_addr_to_alias.set(el.first, el.second); m_db.commit_transaction(); // restore db maj compartibility @@ -3511,6 +3532,20 @@ bool blockchain_storage::put_alias_info(const transaction & tx, extra_alias_entr else { LOG_ERROR("Wrong m_addr_to_alias state: address not found " << get_account_address_as_str(local_alias_history.back().m_address)); + + std::stringstream ss; + ss << "History for alias " << ai.m_alias << ":" << ENDL; + size_t i = 0; + for (auto el : local_alias_history) + { + ss << std::setw(2) << i++ << " " + << get_account_address_as_str(el.m_address) << " " + << (el.m_sign.empty() ? " no sig " : " SIGNED ") << " " + << el.m_text_comment << ENDL; + } + + LOG_PRINT_L0(ss.str()); + } //update alias db diff --git a/src/currency_core/currency_basic.h b/src/currency_core/currency_basic.h index b51834b5..f3972253 100644 --- a/src/currency_core/currency_basic.h +++ b/src/currency_core/currency_basic.h @@ -711,6 +711,7 @@ namespace currency } // namespace currency POD_MAKE_HASHABLE(currency, account_public_address); +POD_MAKE_HASHABLE(currency, account_public_address_old); BLOB_SERIALIZER(currency::txout_to_key); From 6fe7c49e4b6350039c2707b314695e7ee0671cf2 Mon Sep 17 00:00:00 2001 From: sowle Date: Mon, 13 Jul 2020 14:57:12 +0300 Subject: [PATCH 5/5] === build number: 94 -> 95 === --- src/version.h.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h.in b/src/version.h.in index f8fc35ff..fef5b4a2 100644 --- a/src/version.h.in +++ b/src/version.h.in @@ -8,6 +8,6 @@ #define PROJECT_REVISION "7" #define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION -#define PROJECT_VERSION_BUILD_NO 94 +#define PROJECT_VERSION_BUILD_NO 95 #define PROJECT_VERSION_BUILD_NO_STR STRINGIFY_EXPAND(PROJECT_VERSION_BUILD_NO) #define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO_STR "[" BUILD_COMMIT_ID "]"